JNI_OnLoad is a pre-DT_INIT in a shared library.
This commit is contained in:
+177
-77
@@ -195,6 +195,7 @@ PackLinuxElf::PackLinuxElf(InputFile *f)
|
|||||||
: super(f), e_phnum(0), file_image(NULL), dynstr(NULL),
|
: super(f), e_phnum(0), file_image(NULL), dynstr(NULL),
|
||||||
sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0),
|
sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0),
|
||||||
lg2_page(12), page_size(1u<<lg2_page), xct_off(0), xct_va(0),
|
lg2_page(12), page_size(1u<<lg2_page), xct_off(0), xct_va(0),
|
||||||
|
jni_onload_va(0),
|
||||||
e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(NULL),
|
e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(NULL),
|
||||||
o_elf_shnum(0)
|
o_elf_shnum(0)
|
||||||
{
|
{
|
||||||
@@ -205,6 +206,51 @@ PackLinuxElf::~PackLinuxElf()
|
|||||||
delete[] file_image; file_image = NULL;
|
delete[] file_image; file_image = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackLinuxElf32::PackLinuxElf32help1(InputFile *f)
|
||||||
|
{
|
||||||
|
e_type = get_te16(&ehdri.e_type);
|
||||||
|
e_phnum = get_te16(&ehdri.e_phnum);
|
||||||
|
e_shnum = get_te16(&ehdri.e_shnum);
|
||||||
|
e_phoff = get_te32(&ehdri.e_phoff);
|
||||||
|
e_shoff = get_te32(&ehdri.e_shoff);
|
||||||
|
sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
|
||||||
|
|
||||||
|
if (f && Elf32_Ehdr::ET_DYN!=e_type) {
|
||||||
|
unsigned const len = sz_phdrs + e_phoff;
|
||||||
|
file_image = new char[len];
|
||||||
|
f->seek(0, SEEK_SET);
|
||||||
|
f->readx(file_image, len);
|
||||||
|
phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !!
|
||||||
|
}
|
||||||
|
if (f && Elf32_Ehdr::ET_DYN==e_type) {
|
||||||
|
// The DT_STRTAB has no designated length. Read the whole file.
|
||||||
|
file_image = new char[file_size];
|
||||||
|
f->seek(0, SEEK_SET);
|
||||||
|
f->readx(file_image, file_size);
|
||||||
|
phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !!
|
||||||
|
shdri= (Elf32_Shdr const *)(e_shoff + file_image); // do not free() !!
|
||||||
|
sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
|
||||||
|
if (sec_dynsym)
|
||||||
|
sec_dynstr = get_te32(&sec_dynsym->sh_link) + shdri;
|
||||||
|
|
||||||
|
Elf32_Phdr const *phdr= phdri;
|
||||||
|
for (int j = e_phnum; --j>=0; ++phdr)
|
||||||
|
if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
||||||
|
dynseg= (Elf32_Dyn const *)(get_te32(&phdr->p_offset) + file_image);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// elf_find_dynamic() returns 0 if 0==dynseg.
|
||||||
|
dynstr = (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
|
||||||
|
dynsym = (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);
|
||||||
|
gashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);
|
||||||
|
hashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);
|
||||||
|
jni_onload_sym = elf_lookup("JNI_OnLoad");
|
||||||
|
if (jni_onload_sym)
|
||||||
|
jni_onload_va = get_te32(&jni_onload_sym->st_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PackLinuxElf::pack3(OutputFile *fo, Filter &ft)
|
void PackLinuxElf::pack3(OutputFile *fo, Filter &ft)
|
||||||
{
|
{
|
||||||
unsigned disp;
|
unsigned disp;
|
||||||
@@ -223,7 +269,10 @@ void PackLinuxElf::pack3(OutputFile *fo, Filter &ft)
|
|||||||
len += sizeof(disp);
|
len += sizeof(disp);
|
||||||
|
|
||||||
if (xct_off) { // is_shlib
|
if (xct_off) { // is_shlib
|
||||||
set_te32(&disp, elf_unsigned_dynamic(Elf32_Dyn::DT_INIT) - load_va);
|
upx_uint64_t const firstpc_va = (jni_onload_va
|
||||||
|
? jni_onload_va
|
||||||
|
: elf_unsigned_dynamic(Elf32_Dyn::DT_INIT) );
|
||||||
|
set_te32(&disp, firstpc_va - load_va);
|
||||||
fo->write(&disp, sizeof(disp));
|
fo->write(&disp, sizeof(disp));
|
||||||
len += sizeof(disp);
|
len += sizeof(disp);
|
||||||
|
|
||||||
@@ -305,7 +354,7 @@ void PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||||||
continue; // all done with this PT_LOAD
|
continue; // all done with this PT_LOAD
|
||||||
}
|
}
|
||||||
// Compute new offset of &DT_INIT.d_val.
|
// Compute new offset of &DT_INIT.d_val.
|
||||||
if (phdr->PT_DYNAMIC==type) {
|
if (0==jni_onload_sym && phdr->PT_DYNAMIC==type) {
|
||||||
off_init = rel + ioff;
|
off_init = rel + ioff;
|
||||||
fi->seek(ioff, SEEK_SET);
|
fi->seek(ioff, SEEK_SET);
|
||||||
fi->read(ibuf, len);
|
fi->read(ibuf, len);
|
||||||
@@ -475,7 +524,8 @@ PackLinuxElf32::PackLinuxElf32(InputFile *f)
|
|||||||
: super(f), phdri(NULL), note_body(NULL), shdri(NULL),
|
: super(f), phdri(NULL), note_body(NULL), shdri(NULL),
|
||||||
page_mask(~0u<<lg2_page),
|
page_mask(~0u<<lg2_page),
|
||||||
dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
|
dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
|
||||||
shstrtab(NULL), n_elf_shnum(0),
|
jni_onload_sym(NULL),
|
||||||
|
shstrtab(NULL),
|
||||||
sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL)
|
sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL)
|
||||||
{
|
{
|
||||||
memset(&ehdri, 0, sizeof(ehdri));
|
memset(&ehdri, 0, sizeof(ehdri));
|
||||||
@@ -488,14 +538,14 @@ PackLinuxElf32::PackLinuxElf32(InputFile *f)
|
|||||||
PackLinuxElf32::~PackLinuxElf32()
|
PackLinuxElf32::~PackLinuxElf32()
|
||||||
{
|
{
|
||||||
delete[] note_body;
|
delete[] note_body;
|
||||||
delete[] phdri; phdri = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PackLinuxElf64::PackLinuxElf64(InputFile *f)
|
PackLinuxElf64::PackLinuxElf64(InputFile *f)
|
||||||
: super(f), phdri(NULL), note_body(NULL), shdri(NULL),
|
: super(f), phdri(NULL), note_body(NULL), shdri(NULL),
|
||||||
page_mask(~0ull<<lg2_page),
|
page_mask(~0ull<<lg2_page),
|
||||||
dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
|
dynseg(NULL), hashtab(NULL), gashtab(NULL), dynsym(NULL),
|
||||||
shstrtab(NULL), n_elf_shnum(0),
|
jni_onload_sym(NULL),
|
||||||
|
shstrtab(NULL),
|
||||||
sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL)
|
sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL)
|
||||||
{
|
{
|
||||||
memset(&ehdri, 0, sizeof(ehdri));
|
memset(&ehdri, 0, sizeof(ehdri));
|
||||||
@@ -508,7 +558,52 @@ PackLinuxElf64::PackLinuxElf64(InputFile *f)
|
|||||||
PackLinuxElf64::~PackLinuxElf64()
|
PackLinuxElf64::~PackLinuxElf64()
|
||||||
{
|
{
|
||||||
delete[] note_body;
|
delete[] note_body;
|
||||||
delete[] phdri; phdri = NULL;
|
}
|
||||||
|
|
||||||
|
// FIXME: should be templated with PackLinuxElf32help1
|
||||||
|
void
|
||||||
|
PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
|
||||||
|
{
|
||||||
|
e_type = get_te16(&ehdri.e_type);
|
||||||
|
e_phnum = get_te16(&ehdri.e_phnum);
|
||||||
|
e_shnum = get_te16(&ehdri.e_shnum);
|
||||||
|
e_phoff = get_te64(&ehdri.e_phoff);
|
||||||
|
e_shoff = get_te64(&ehdri.e_shoff);
|
||||||
|
sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
|
||||||
|
|
||||||
|
if (f && Elf64_Ehdr::ET_DYN!=e_type) {
|
||||||
|
unsigned const len = sz_phdrs + e_phoff;
|
||||||
|
file_image = new char[len];
|
||||||
|
f->seek(0, SEEK_SET);
|
||||||
|
f->readx(file_image, len);
|
||||||
|
phdri= (Elf64_Phdr *)(e_phoff + file_image); // do not free() !!
|
||||||
|
}
|
||||||
|
if (f && Elf64_Ehdr::ET_DYN==e_type) {
|
||||||
|
// The DT_STRTAB has no designated length. Read the whole file.
|
||||||
|
file_image = new char[file_size];
|
||||||
|
f->seek(0, SEEK_SET);
|
||||||
|
f->readx(file_image, file_size);
|
||||||
|
phdri= (Elf64_Phdr *)(e_phoff + file_image); // do not free() !!
|
||||||
|
shdri= (Elf64_Shdr const *)(e_shoff + file_image); // do not free() !!
|
||||||
|
sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
|
||||||
|
if (sec_dynsym)
|
||||||
|
sec_dynstr = get_te64(&sec_dynsym->sh_link) + shdri;
|
||||||
|
|
||||||
|
Elf64_Phdr const *phdr= phdri;
|
||||||
|
for (int j = e_phnum; --j>=0; ++phdr)
|
||||||
|
if (Elf64_Phdr::PT_DYNAMIC==get_te64(&phdr->p_type)) {
|
||||||
|
dynseg= (Elf64_Dyn const *)(get_te64(&phdr->p_offset) + file_image);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// elf_find_dynamic() returns 0 if 0==dynseg.
|
||||||
|
dynstr = (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB);
|
||||||
|
dynsym = (Elf64_Sym const *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB);
|
||||||
|
gashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH);
|
||||||
|
hashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH);
|
||||||
|
jni_onload_sym = elf_lookup("JNI_OnLoad");
|
||||||
|
if (jni_onload_sym)
|
||||||
|
jni_onload_va = get_te64(&jni_onload_sym->st_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker* PackLinuxElf64amd::newLinker() const
|
Linker* PackLinuxElf64amd::newLinker() const
|
||||||
@@ -1168,7 +1263,7 @@ Elf32_Shdr const *PackLinuxElf32::elf_find_section_name(
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
Elf32_Shdr const *shdr = shdri;
|
Elf32_Shdr const *shdr = shdri;
|
||||||
int j = n_elf_shnum;
|
int j = e_shnum;
|
||||||
for (; 0 <=--j; ++shdr) {
|
for (; 0 <=--j; ++shdr) {
|
||||||
if (0==strcmp(name, &shstrtab[get_te32(&shdr->sh_name)])) {
|
if (0==strcmp(name, &shstrtab[get_te32(&shdr->sh_name)])) {
|
||||||
return shdr;
|
return shdr;
|
||||||
@@ -1182,7 +1277,7 @@ Elf64_Shdr const *PackLinuxElf64::elf_find_section_name(
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
Elf64_Shdr const *shdr = shdri;
|
Elf64_Shdr const *shdr = shdri;
|
||||||
int j = n_elf_shnum;
|
int j = e_shnum;
|
||||||
for (; 0 <=--j; ++shdr) {
|
for (; 0 <=--j; ++shdr) {
|
||||||
unsigned ndx = get_te64(&shdr->sh_name);
|
unsigned ndx = get_te64(&shdr->sh_name);
|
||||||
if (0==strcmp(name, &shstrtab[ndx])) {
|
if (0==strcmp(name, &shstrtab[ndx])) {
|
||||||
@@ -1197,7 +1292,7 @@ Elf32_Shdr const *PackLinuxElf32::elf_find_section_type(
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
Elf32_Shdr const *shdr = shdri;
|
Elf32_Shdr const *shdr = shdri;
|
||||||
int j = n_elf_shnum;
|
int j = e_shnum;
|
||||||
for (; 0 <=--j; ++shdr) {
|
for (; 0 <=--j; ++shdr) {
|
||||||
if (type==get_te32(&shdr->sh_type)) {
|
if (type==get_te32(&shdr->sh_type)) {
|
||||||
return shdr;
|
return shdr;
|
||||||
@@ -1211,7 +1306,7 @@ Elf64_Shdr const *PackLinuxElf64::elf_find_section_type(
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
Elf64_Shdr const *shdr = shdri;
|
Elf64_Shdr const *shdr = shdri;
|
||||||
int j = n_elf_shnum;
|
int j = e_shnum;
|
||||||
for (; 0 <=--j; ++shdr) {
|
for (; 0 <=--j; ++shdr) {
|
||||||
if (type==get_te32(&shdr->sh_type)) {
|
if (type==get_te32(&shdr->sh_type)) {
|
||||||
return shdr;
|
return shdr;
|
||||||
@@ -1242,8 +1337,6 @@ bool PackLinuxElf32::canPack()
|
|||||||
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
|
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned const e_shoff = get_te32(&ehdr->e_shoff);
|
|
||||||
unsigned const e_phoff = get_te32(&ehdr->e_phoff);
|
|
||||||
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
|
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
|
||||||
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
|
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
|
||||||
return false;
|
return false;
|
||||||
@@ -1328,31 +1421,7 @@ bool PackLinuxElf32::canPack()
|
|||||||
// Also allow __uClibc_main and __uClibc_start_main .
|
// Also allow __uClibc_main and __uClibc_start_main .
|
||||||
|
|
||||||
if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
|
if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) {
|
||||||
// The DT_STRTAB has no designated length. Read the whole file.
|
|
||||||
file_image = new char[file_size];
|
|
||||||
fi->seek(0, SEEK_SET);
|
|
||||||
fi->readx(file_image, file_size);
|
|
||||||
memcpy(&ehdri, ehdr, sizeof(Elf32_Ehdr));
|
memcpy(&ehdri, ehdr, sizeof(Elf32_Ehdr));
|
||||||
phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !!
|
|
||||||
shdri= (Elf32_Shdr const *)(e_shoff + file_image); // do not free() !!
|
|
||||||
|
|
||||||
n_elf_shnum = get_te16(&ehdr->e_shnum);
|
|
||||||
//sec_strndx = &shdri[ehdr->e_shstrndx];
|
|
||||||
//shstrtab = (char const *)(sec_strndx->sh_offset + file_image);
|
|
||||||
sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);
|
|
||||||
if (sec_dynsym)
|
|
||||||
sec_dynstr = get_te32(&sec_dynsym->sh_link) + shdri;
|
|
||||||
|
|
||||||
int j= e_phnum;
|
|
||||||
phdr= phdri;
|
|
||||||
for (; --j>=0; ++phdr)
|
|
||||||
if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
|
||||||
dynseg= (Elf32_Dyn const *)(get_te32(&phdr->p_offset) + file_image);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// elf_find_dynamic() returns 0 if 0==dynseg.
|
|
||||||
dynstr= (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);
|
|
||||||
dynsym= (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);
|
|
||||||
|
|
||||||
// Modified 2009-10-10 to detect a ProgramLinkageTable relocation
|
// Modified 2009-10-10 to detect a ProgramLinkageTable relocation
|
||||||
// which references the symbol, because DT_GNU_HASH contains only
|
// which references the symbol, because DT_GNU_HASH contains only
|
||||||
@@ -1389,19 +1458,17 @@ bool PackLinuxElf32::canPack()
|
|||||||
// 2011-06-01: stub.shlib-init.S works around by installing hatch
|
// 2011-06-01: stub.shlib-init.S works around by installing hatch
|
||||||
// at end of .text.
|
// at end of .text.
|
||||||
|
|
||||||
if (elf_find_dynamic(Elf32_Dyn::DT_INIT)) {
|
if (jni_onload_sym || elf_find_dynamic(Elf32_Dyn::DT_INIT)) {
|
||||||
if (this->e_machine!=Elf32_Ehdr::EM_386
|
if (this->e_machine!=Elf32_Ehdr::EM_386
|
||||||
&& this->e_machine!=Elf32_Ehdr::EM_ARM)
|
&& this->e_machine!=Elf32_Ehdr::EM_ARM)
|
||||||
goto abandon; // need stub: EM_MIPS EM_PPC
|
goto abandon; // need stub: EM_MIPS EM_PPC
|
||||||
if (elf_has_dynamic(Elf32_Dyn::DT_TEXTREL)) {
|
if (elf_has_dynamic(Elf32_Dyn::DT_TEXTREL)) {
|
||||||
shdri = NULL;
|
|
||||||
phdri = NULL;
|
|
||||||
throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
|
throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
|
||||||
goto abandon;
|
goto abandon;
|
||||||
}
|
}
|
||||||
Elf32_Shdr const *shdr = shdri;
|
Elf32_Shdr const *shdr = shdri;
|
||||||
xct_va = ~0u;
|
xct_va = ~0u;
|
||||||
for (j= n_elf_shnum; --j>=0; ++shdr) {
|
for (int j= e_shnum; --j>=0; ++shdr) {
|
||||||
if (Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
if (Elf32_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
||||||
xct_va = umin(xct_va, get_te32(&shdr->sh_addr));
|
xct_va = umin(xct_va, get_te32(&shdr->sh_addr));
|
||||||
}
|
}
|
||||||
@@ -1418,12 +1485,11 @@ bool PackLinuxElf32::canPack()
|
|||||||
|| xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERDEF)
|
|| xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERDEF)
|
||||||
|| xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERSYM)
|
|| xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERSYM)
|
||||||
|| xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERNEEDED) ) {
|
|| xct_va < elf_unsigned_dynamic(Elf32_Dyn::DT_VERNEEDED) ) {
|
||||||
phdri = NULL;
|
|
||||||
shdri = NULL;
|
|
||||||
throwCantPack("DT_ tag above stub");
|
throwCantPack("DT_ tag above stub");
|
||||||
goto abandon;
|
goto abandon;
|
||||||
}
|
}
|
||||||
for ((shdr= shdri), (j= n_elf_shnum); --j>=0; ++shdr) {
|
shdr= shdri;
|
||||||
|
for (int j= e_shnum; --j>=0; ++shdr) {
|
||||||
unsigned const sh_addr = get_te32(&shdr->sh_addr);
|
unsigned const sh_addr = get_te32(&shdr->sh_addr);
|
||||||
if ( sh_addr==va_gash
|
if ( sh_addr==va_gash
|
||||||
|| (sh_addr==va_hash && 0==va_gash) ) {
|
|| (sh_addr==va_hash && 0==va_gash) ) {
|
||||||
@@ -1436,14 +1502,10 @@ bool PackLinuxElf32::canPack()
|
|||||||
goto proceed; // But proper packing depends on checking xct_va.
|
goto proceed; // But proper packing depends on checking xct_va.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
infoWarning("no DT_INIT: %s", fi->getName());
|
infoWarning("no DT_INIT or JNI_OnLoad: %s", fi->getName());
|
||||||
abandon:
|
abandon:
|
||||||
phdri = NULL; // Done with this
|
|
||||||
shdri = NULL;
|
|
||||||
return false;
|
return false;
|
||||||
proceed:
|
proceed: ;
|
||||||
phdri = NULL;
|
|
||||||
shdri = NULL;
|
|
||||||
}
|
}
|
||||||
// XXX Theoretically the following test should be first,
|
// XXX Theoretically the following test should be first,
|
||||||
// but PackUnix::canPack() wants 0!=exetype ?
|
// but PackUnix::canPack() wants 0!=exetype ?
|
||||||
@@ -1479,8 +1541,6 @@ PackLinuxElf64amd::canPack()
|
|||||||
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
|
throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
upx_uint64_t const e_shoff = get_te64(&ehdr->e_shoff);
|
|
||||||
upx_uint64_t const e_phoff = get_te64(&ehdr->e_phoff);
|
|
||||||
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
|
if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr
|
||||||
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
|
throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");
|
||||||
return false;
|
return false;
|
||||||
@@ -1525,7 +1585,6 @@ PackLinuxElf64amd::canPack()
|
|||||||
phdri= (Elf64_Phdr *)((size_t)e_phoff + file_image); // do not free() !!
|
phdri= (Elf64_Phdr *)((size_t)e_phoff + file_image); // do not free() !!
|
||||||
shdri= (Elf64_Shdr const *)((size_t)e_shoff + file_image); // do not free() !!
|
shdri= (Elf64_Shdr const *)((size_t)e_shoff + file_image); // do not free() !!
|
||||||
|
|
||||||
n_elf_shnum = get_te16(&ehdr->e_shnum);
|
|
||||||
//sec_strndx = &shdri[ehdr->e_shstrndx];
|
//sec_strndx = &shdri[ehdr->e_shstrndx];
|
||||||
//shstrtab = (char const *)(sec_strndx->sh_offset + file_image);
|
//shstrtab = (char const *)(sec_strndx->sh_offset + file_image);
|
||||||
sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
|
sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
|
||||||
@@ -1575,14 +1634,12 @@ PackLinuxElf64amd::canPack()
|
|||||||
|
|
||||||
if (elf_find_dynamic(Elf64_Dyn::DT_INIT)) {
|
if (elf_find_dynamic(Elf64_Dyn::DT_INIT)) {
|
||||||
if (elf_has_dynamic(Elf64_Dyn::DT_TEXTREL)) {
|
if (elf_has_dynamic(Elf64_Dyn::DT_TEXTREL)) {
|
||||||
shdri = NULL;
|
|
||||||
phdri = NULL;
|
|
||||||
throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
|
throwCantPack("DT_TEXTREL found; re-compile with -fPIC");
|
||||||
goto abandon;
|
goto abandon;
|
||||||
}
|
}
|
||||||
Elf64_Shdr const *shdr = shdri;
|
Elf64_Shdr const *shdr = shdri;
|
||||||
xct_va = ~0ull;
|
xct_va = ~0ull;
|
||||||
for (j= n_elf_shnum; --j>=0; ++shdr) {
|
for (j= e_shnum; --j>=0; ++shdr) {
|
||||||
if (Elf64_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
if (Elf64_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) {
|
||||||
xct_va = umin64(xct_va, get_te64(&shdr->sh_addr));
|
xct_va = umin64(xct_va, get_te64(&shdr->sh_addr));
|
||||||
}
|
}
|
||||||
@@ -1599,12 +1656,10 @@ PackLinuxElf64amd::canPack()
|
|||||||
|| xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERDEF)
|
|| xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERDEF)
|
||||||
|| xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM)
|
|| xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM)
|
||||||
|| xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEEDED) ) {
|
|| xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEEDED) ) {
|
||||||
phdri = NULL;
|
|
||||||
shdri = NULL;
|
|
||||||
throwCantPack("DT_ tag above stub");
|
throwCantPack("DT_ tag above stub");
|
||||||
goto abandon;
|
goto abandon;
|
||||||
}
|
}
|
||||||
for ((shdr= shdri), (j= n_elf_shnum); --j>=0; ++shdr) {
|
for ((shdr= shdri), (j= e_shnum); --j>=0; ++shdr) {
|
||||||
upx_uint64_t const sh_addr = get_te64(&shdr->sh_addr);
|
upx_uint64_t const sh_addr = get_te64(&shdr->sh_addr);
|
||||||
if ( sh_addr==va_gash
|
if ( sh_addr==va_gash
|
||||||
|| (sh_addr==va_hash && 0==va_gash) ) {
|
|| (sh_addr==va_hash && 0==va_gash) ) {
|
||||||
@@ -1617,10 +1672,8 @@ PackLinuxElf64amd::canPack()
|
|||||||
goto proceed; // But proper packing depends on checking xct_va.
|
goto proceed; // But proper packing depends on checking xct_va.
|
||||||
}
|
}
|
||||||
abandon:
|
abandon:
|
||||||
phdri = 0; // Done with this
|
|
||||||
return false;
|
return false;
|
||||||
proceed:
|
proceed: ;
|
||||||
phdri = 0;
|
|
||||||
}
|
}
|
||||||
// XXX Theoretically the following test should be first,
|
// XXX Theoretically the following test should be first,
|
||||||
// but PackUnix::canPack() wants 0!=exetype ?
|
// but PackUnix::canPack() wants 0!=exetype ?
|
||||||
@@ -1978,14 +2031,9 @@ void PackLinuxElf32::pack1(OutputFile *fo, Filter & /*ft*/)
|
|||||||
{
|
{
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdri, sizeof(ehdri));
|
fi->readx(&ehdri, sizeof(ehdri));
|
||||||
unsigned const e_phoff = get_te32(&ehdri.e_phoff);
|
|
||||||
assert(e_phoff == sizeof(Elf32_Ehdr)); // checked by canPack()
|
assert(e_phoff == sizeof(Elf32_Ehdr)); // checked by canPack()
|
||||||
sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
|
sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
|
||||||
|
|
||||||
phdri = new Elf32_Phdr[e_phnum];
|
|
||||||
fi->seek(e_phoff, SEEK_SET);
|
|
||||||
fi->readx(phdri, sz_phdrs);
|
|
||||||
|
|
||||||
// Remember all PT_NOTE, and find lg2_page from PT_LOAD.
|
// Remember all PT_NOTE, and find lg2_page from PT_LOAD.
|
||||||
Elf32_Phdr const *phdr = phdri;
|
Elf32_Phdr const *phdr = phdri;
|
||||||
note_size = 0;
|
note_size = 0;
|
||||||
@@ -2030,13 +2078,12 @@ void PackLinuxElf32::pack1(OutputFile *fo, Filter & /*ft*/)
|
|||||||
|
|
||||||
// if the preserve build-id option was specified
|
// if the preserve build-id option was specified
|
||||||
if (opt->o_unix.preserve_build_id) {
|
if (opt->o_unix.preserve_build_id) {
|
||||||
n_elf_shnum = ehdri.e_shnum;
|
|
||||||
Elf32_Shdr *shdr = NULL;
|
Elf32_Shdr *shdr = NULL;
|
||||||
|
|
||||||
Elf32_Shdr const *tmp = shdri;
|
Elf32_Shdr const *tmp = shdri;
|
||||||
|
|
||||||
if (! shdri) {
|
if (! shdri) {
|
||||||
shdr = new Elf32_Shdr[n_elf_shnum];
|
shdr = new Elf32_Shdr[e_shnum];
|
||||||
|
|
||||||
fi->seek(0,SEEK_SET);
|
fi->seek(0,SEEK_SET);
|
||||||
fi->seek(ehdri.e_shoff,SEEK_SET);
|
fi->seek(ehdri.e_shoff,SEEK_SET);
|
||||||
@@ -2170,14 +2217,9 @@ void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
|
|||||||
{
|
{
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdri, sizeof(ehdri));
|
fi->readx(&ehdri, sizeof(ehdri));
|
||||||
unsigned const e_phoff = get_te32(&ehdri.e_phoff);
|
|
||||||
assert(e_phoff == sizeof(Elf64_Ehdr)); // checked by canPack()
|
assert(e_phoff == sizeof(Elf64_Ehdr)); // checked by canPack()
|
||||||
sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
|
sz_phdrs = e_phnum * get_te16(&ehdri.e_phentsize);
|
||||||
|
|
||||||
phdri = new Elf64_Phdr[e_phnum];
|
|
||||||
fi->seek(e_phoff, SEEK_SET);
|
|
||||||
fi->readx(phdri, sz_phdrs);
|
|
||||||
|
|
||||||
Elf64_Phdr const *phdr = phdri;
|
Elf64_Phdr const *phdr = phdri;
|
||||||
note_size = 0;
|
note_size = 0;
|
||||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||||
@@ -2222,7 +2264,7 @@ void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
|
|||||||
// only execute if option present
|
// only execute if option present
|
||||||
if (opt->o_unix.preserve_build_id) {
|
if (opt->o_unix.preserve_build_id) {
|
||||||
// set this so we can use elf_find_section_name
|
// set this so we can use elf_find_section_name
|
||||||
n_elf_shnum = ehdri.e_shnum;
|
e_shnum = ehdri.e_shnum;
|
||||||
|
|
||||||
// there is a class member similar to this, but I did not
|
// there is a class member similar to this, but I did not
|
||||||
// want to assume it would be available
|
// want to assume it would be available
|
||||||
@@ -2231,7 +2273,7 @@ void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
|
|||||||
Elf64_Shdr *shdr = NULL;
|
Elf64_Shdr *shdr = NULL;
|
||||||
|
|
||||||
if (! shdri) {
|
if (! shdri) {
|
||||||
shdr = new Elf64_Shdr[n_elf_shnum];
|
shdr = new Elf64_Shdr[e_shnum];
|
||||||
|
|
||||||
fi->seek(0,SEEK_SET);
|
fi->seek(0,SEEK_SET);
|
||||||
fi->seek(ehdri.e_shoff,SEEK_SET);
|
fi->seek(ehdri.e_shoff,SEEK_SET);
|
||||||
@@ -2821,6 +2863,15 @@ void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
|
|||||||
fo->rewrite(phdri, e_phnum * sizeof(*phdri));
|
fo->rewrite(phdri, e_phnum * sizeof(*phdri));
|
||||||
fo->seek(sz_elf_hdrs, SEEK_SET);
|
fo->seek(sz_elf_hdrs, SEEK_SET);
|
||||||
fo->rewrite(&linfo, sizeof(linfo));
|
fo->rewrite(&linfo, sizeof(linfo));
|
||||||
|
|
||||||
|
if (jni_onload_va) {
|
||||||
|
unsigned tmp = sz_pack2 + get_te32(&elfout.phdr[0].p_vaddr);
|
||||||
|
tmp |= (Elf32_Ehdr::EM_ARM==e_machine); // THUMB mode
|
||||||
|
set_te32(&tmp, tmp);
|
||||||
|
fo->seek((char const *)&jni_onload_sym->st_value - file_image, SEEK_SET);
|
||||||
|
fo->rewrite(&tmp, sizeof(tmp));
|
||||||
|
fo->seek(0, SEEK_SET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned const reloc = get_te32(&elfout.phdr[0].p_vaddr);
|
unsigned const reloc = get_te32(&elfout.phdr[0].p_vaddr);
|
||||||
@@ -3283,7 +3334,7 @@ PackLinuxElf64::elf_unsigned_dynamic(unsigned int const key) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PackLinuxElf32::gnu_hash(char const *q)
|
unsigned PackLinuxElf::gnu_hash(char const *q)
|
||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)q;
|
unsigned char const *p = (unsigned char const *)q;
|
||||||
unsigned h;
|
unsigned h;
|
||||||
@@ -3294,7 +3345,7 @@ unsigned PackLinuxElf32::gnu_hash(char const *q)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PackLinuxElf32::elf_hash(char const *p)
|
unsigned PackLinuxElf::elf_hash(char const *p)
|
||||||
{
|
{
|
||||||
unsigned h;
|
unsigned h;
|
||||||
for (h= 0; 0!=*p; ++p) {
|
for (h= 0; 0!=*p; ++p) {
|
||||||
@@ -3357,6 +3408,55 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
|
||||||
|
{
|
||||||
|
if (hashtab && dynsym && dynstr) {
|
||||||
|
unsigned const nbucket = get_te32(&hashtab[0]);
|
||||||
|
unsigned const *const buckets = &hashtab[2];
|
||||||
|
unsigned const *const chains = &buckets[nbucket];
|
||||||
|
unsigned const m = elf_hash(name) % nbucket;
|
||||||
|
unsigned si;
|
||||||
|
for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
|
||||||
|
char const *const p= get_te64(&dynsym[si].st_name) + dynstr;
|
||||||
|
if (0==strcmp(name, p)) {
|
||||||
|
return &dynsym[si];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gashtab && dynsym && dynstr) {
|
||||||
|
unsigned const n_bucket = get_te32(&gashtab[0]);
|
||||||
|
unsigned const symbias = get_te32(&gashtab[1]);
|
||||||
|
unsigned const n_bitmask = get_te32(&gashtab[2]);
|
||||||
|
unsigned const gnu_shift = get_te32(&gashtab[3]);
|
||||||
|
unsigned long const *const bitmask = (unsigned long const *)&gashtab[4];
|
||||||
|
unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask];
|
||||||
|
|
||||||
|
unsigned const h = gnu_hash(name);
|
||||||
|
unsigned const hbit1 = 077& h;
|
||||||
|
unsigned const hbit2 = 077& (h>>gnu_shift);
|
||||||
|
unsigned long const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
|
||||||
|
|
||||||
|
if (1& (w>>hbit1) & (w>>hbit2)) {
|
||||||
|
unsigned bucket = get_te32(&buckets[h % n_bucket]);
|
||||||
|
if (0!=bucket) {
|
||||||
|
Elf64_Sym const *dsp = dynsym;
|
||||||
|
unsigned const *const hasharr = &buckets[n_bucket];
|
||||||
|
unsigned const *hp = &hasharr[bucket - symbias];
|
||||||
|
|
||||||
|
dsp += bucket;
|
||||||
|
do if (0==((h ^ get_te32(hp))>>1)) {
|
||||||
|
char const *const p = get_te64(&dsp->st_name) + dynstr;
|
||||||
|
if (0==strcmp(name, p)) {
|
||||||
|
return dsp;
|
||||||
|
}
|
||||||
|
} while (++dsp, 0==(1u& get_te32(hp++)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void PackLinuxElf32::unpack(OutputFile *fo)
|
void PackLinuxElf32::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
#define MAX_ELF_HDR 512
|
#define MAX_ELF_HDR 512
|
||||||
|
|||||||
+15
-7
@@ -65,9 +65,15 @@ protected:
|
|||||||
|
|
||||||
//virtual void const *elf_find_dynamic(unsigned) const = 0;
|
//virtual void const *elf_find_dynamic(unsigned) const = 0;
|
||||||
virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const = 0;
|
virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const = 0;
|
||||||
|
static unsigned elf_hash(char const *) /*const*/;
|
||||||
|
static unsigned gnu_hash(char const *) /*const*/;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
unsigned e_type;
|
||||||
unsigned e_phnum; /* Program header table entry count */
|
unsigned e_phnum; /* Program header table entry count */
|
||||||
|
unsigned e_shnum;
|
||||||
|
unsigned e_phoff;
|
||||||
|
unsigned e_shoff;
|
||||||
char *file_image; // if ET_DYN investigation
|
char *file_image; // if ET_DYN investigation
|
||||||
char const *dynstr; // from DT_STRTAB
|
char const *dynstr; // from DT_STRTAB
|
||||||
|
|
||||||
@@ -81,6 +87,7 @@ protected:
|
|||||||
unsigned hatch_off; // file offset of escape hatch
|
unsigned hatch_off; // file offset of escape hatch
|
||||||
upx_uint64_t load_va; // PT_LOAD[0].p_vaddr
|
upx_uint64_t load_va; // PT_LOAD[0].p_vaddr
|
||||||
upx_uint64_t xct_va; // minimum SHT_EXECINSTR virtual address
|
upx_uint64_t xct_va; // minimum SHT_EXECINSTR virtual address
|
||||||
|
upx_uint64_t jni_onload_va; // runtime &JNI_OnLoad
|
||||||
|
|
||||||
unsigned short e_machine;
|
unsigned short e_machine;
|
||||||
unsigned char ei_class;
|
unsigned char ei_class;
|
||||||
@@ -100,6 +107,7 @@ public:
|
|||||||
PackLinuxElf32(InputFile *f);
|
PackLinuxElf32(InputFile *f);
|
||||||
virtual ~PackLinuxElf32();
|
virtual ~PackLinuxElf32();
|
||||||
protected:
|
protected:
|
||||||
|
virtual void PackLinuxElf32help1(InputFile *f);
|
||||||
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
|
|
||||||
@@ -134,8 +142,6 @@ protected:
|
|||||||
unsigned const e_phnum);
|
unsigned const e_phnum);
|
||||||
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||||
|
|
||||||
static unsigned elf_hash(char const *) /*const*/;
|
|
||||||
static unsigned gnu_hash(char const *) /*const*/;
|
|
||||||
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
||||||
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
||||||
Elf32_Shdr const *elf_find_section_name(char const *) const;
|
Elf32_Shdr const *elf_find_section_name(char const *) const;
|
||||||
@@ -156,8 +162,8 @@ protected:
|
|||||||
unsigned int const *hashtab; // from DT_HASH
|
unsigned int const *hashtab; // from DT_HASH
|
||||||
unsigned int const *gashtab; // from DT_GNU_HASH
|
unsigned int const *gashtab; // from DT_GNU_HASH
|
||||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||||
|
Elf32_Sym const *jni_onload_sym;
|
||||||
char const *shstrtab; // via Elf32_Shdr
|
char const *shstrtab; // via Elf32_Shdr
|
||||||
int n_elf_shnum; // via e_shnum
|
|
||||||
|
|
||||||
Elf32_Shdr const *sec_strndx;
|
Elf32_Shdr const *sec_strndx;
|
||||||
Elf32_Shdr const *sec_dynsym;
|
Elf32_Shdr const *sec_dynsym;
|
||||||
@@ -224,6 +230,7 @@ public:
|
|||||||
/*virtual void buildLoader(const Filter *);*/
|
/*virtual void buildLoader(const Filter *);*/
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void PackLinuxElf64help1(InputFile *f);
|
||||||
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
@@ -250,6 +257,7 @@ protected:
|
|||||||
virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
|
virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
|
||||||
unsigned const e_phnum);
|
unsigned const e_phnum);
|
||||||
|
|
||||||
|
virtual Elf64_Sym const *elf_lookup(char const *) const;
|
||||||
virtual upx_uint64_t elf_get_offset_from_address(upx_uint64_t) const;
|
virtual upx_uint64_t elf_get_offset_from_address(upx_uint64_t) const;
|
||||||
Elf64_Shdr const *elf_find_section_name(char const *) const;
|
Elf64_Shdr const *elf_find_section_name(char const *) const;
|
||||||
Elf64_Shdr const *elf_find_section_type(unsigned) const;
|
Elf64_Shdr const *elf_find_section_type(unsigned) const;
|
||||||
@@ -269,8 +277,8 @@ protected:
|
|||||||
unsigned int const *hashtab; // from DT_HASH
|
unsigned int const *hashtab; // from DT_HASH
|
||||||
unsigned int const *gashtab; // from DT_GNU_HASH
|
unsigned int const *gashtab; // from DT_GNU_HASH
|
||||||
Elf64_Sym const *dynsym; // from DT_SYMTAB
|
Elf64_Sym const *dynsym; // from DT_SYMTAB
|
||||||
|
Elf64_Sym const *jni_onload_sym;
|
||||||
char const *shstrtab; // via Elf64_Shdr
|
char const *shstrtab; // via Elf64_Shdr
|
||||||
int n_elf_shnum; // via e_shnum
|
|
||||||
|
|
||||||
Elf64_Shdr const *sec_strndx;
|
Elf64_Shdr const *sec_strndx;
|
||||||
Elf64_Shdr const *sec_dynsym;
|
Elf64_Shdr const *sec_dynsym;
|
||||||
@@ -326,7 +334,7 @@ class PackLinuxElf32Be : public PackLinuxElf32
|
|||||||
protected:
|
protected:
|
||||||
PackLinuxElf32Be(InputFile *f) : super(f) {
|
PackLinuxElf32Be(InputFile *f) : super(f) {
|
||||||
bele = &N_BELE_RTP::be_policy;
|
bele = &N_BELE_RTP::be_policy;
|
||||||
e_phnum = get_te16(&ehdri.e_phnum);
|
PackLinuxElf32help1(f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -336,7 +344,7 @@ class PackLinuxElf32Le : public PackLinuxElf32
|
|||||||
protected:
|
protected:
|
||||||
PackLinuxElf32Le(InputFile *f) : super(f) {
|
PackLinuxElf32Le(InputFile *f) : super(f) {
|
||||||
bele = &N_BELE_RTP::le_policy;
|
bele = &N_BELE_RTP::le_policy;
|
||||||
e_phnum = get_te16(&ehdri.e_phnum);
|
PackLinuxElf32help1(f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -346,7 +354,7 @@ class PackLinuxElf64Le : public PackLinuxElf64
|
|||||||
protected:
|
protected:
|
||||||
PackLinuxElf64Le(InputFile *f) : super(f) {
|
PackLinuxElf64Le(InputFile *f) : super(f) {
|
||||||
bele = &N_BELE_RTP::le_policy;
|
bele = &N_BELE_RTP::le_policy;
|
||||||
e_phnum = get_te16(&ehdri.e_phnum);
|
PackLinuxElf64help1(f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user