mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
debug PackLinuxElf32armBe. Also unify subroutines.
This commit is contained in:
parent
bd8acbde97
commit
dcc704a357
|
@ -337,11 +337,11 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
|||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
||||
|
||||
typedef TT_Elf ::Ehdr<BE32,BE32,BE32,LE16> Elf_BE32_Ehdr;
|
||||
typedef TT_Elf ::Ehdr<BE32,BE32,BE32,BE16> Elf_BE32_Ehdr;
|
||||
typedef TT_Elf32::Phdr<BE32,BE32,BE32> Elf_BE32_Phdr;
|
||||
typedef TT_Elf32::Shdr<BE32,BE32,BE32> Elf_BE32_Shdr;
|
||||
typedef TT_Elf ::Dyn <BE32,BE32> Elf_BE32_Dyn;
|
||||
typedef TT_Elf32::Sym <LE16,BE32,void> Elf_BE32_Sym;
|
||||
typedef TT_Elf32::Sym <BE16,BE32,void> Elf_BE32_Sym;
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)
|
||||
|
|
|
@ -46,12 +46,7 @@
|
|||
|
||||
|
||||
int
|
||||
PackLinuxElf32::checkEhdr(
|
||||
Elf32_Ehdr const *ehdr,
|
||||
unsigned char e_machine,
|
||||
unsigned char ei_class,
|
||||
unsigned char ei_data
|
||||
) const
|
||||
PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const
|
||||
{
|
||||
const unsigned char * const buf = ehdr->e_ident;
|
||||
|
||||
|
@ -94,12 +89,7 @@ PackLinuxElf32::checkEhdr(
|
|||
}
|
||||
|
||||
int
|
||||
PackLinuxElf64::checkEhdr(
|
||||
Elf64_Ehdr const *ehdr,
|
||||
unsigned char e_machine,
|
||||
unsigned char ei_class,
|
||||
unsigned char ei_data
|
||||
) const
|
||||
PackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const
|
||||
{
|
||||
const unsigned char * const buf = ehdr->e_ident;
|
||||
|
||||
|
@ -141,7 +131,9 @@ PackLinuxElf64::checkEhdr(
|
|||
}
|
||||
|
||||
PackLinuxElf::PackLinuxElf(InputFile *f)
|
||||
: super(f)
|
||||
: super(f), file_image(NULL), dynstr(NULL),
|
||||
sz_phdrs(0), sz_elf_hdrs(0),
|
||||
e_machine(0), ei_class(0), ei_data(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -151,7 +143,7 @@ PackLinuxElf::~PackLinuxElf()
|
|||
|
||||
PackLinuxElf32::PackLinuxElf32(InputFile *f)
|
||||
: super(f), phdri(NULL),
|
||||
file_image(NULL), dynseg(NULL), hashtab(NULL), dynstr(NULL), dynsym(NULL)
|
||||
dynseg(NULL), hashtab(NULL), dynsym(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -264,6 +256,9 @@ void PackLinuxElf64::updateLoader(OutputFile *fo)
|
|||
PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f)
|
||||
: super(f)
|
||||
{
|
||||
e_machine = Elf32_Ehdr::EM_PPC;
|
||||
ei_class = Elf32_Ehdr::ELFCLASS32;
|
||||
ei_data = Elf32_Ehdr::ELFDATA2MSB;
|
||||
}
|
||||
|
||||
PackLinuxElf32ppc::~PackLinuxElf32ppc()
|
||||
|
@ -273,6 +268,9 @@ PackLinuxElf32ppc::~PackLinuxElf32ppc()
|
|||
PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f)
|
||||
: super(f)
|
||||
{
|
||||
e_machine = Elf64_Ehdr::EM_X86_64;
|
||||
ei_class = Elf64_Ehdr::ELFCLASS64;
|
||||
ei_data = Elf64_Ehdr::ELFDATA2LSB;
|
||||
}
|
||||
|
||||
PackLinuxElf64amd::~PackLinuxElf64amd()
|
||||
|
@ -590,6 +588,7 @@ static void
|
|||
ehdr_bele(Elf_BE32_Ehdr *const ehdr_be, Elf_LE32_Ehdr const *const ehdr_le)
|
||||
{
|
||||
memcpy(&ehdr_be->e_ident, &ehdr_le->e_ident, sizeof(ehdr_be->e_ident));
|
||||
ehdr_be->e_ident[Elf32_Ehdr::EI_DATA] = Elf32_Ehdr::ELFDATA2MSB;
|
||||
ehdr_be->e_type = ehdr_le->e_type;
|
||||
ehdr_be->e_machine = ehdr_le->e_machine;
|
||||
ehdr_be->e_version = ehdr_le->e_version;
|
||||
|
@ -614,7 +613,7 @@ PackLinuxElf32armBe::buildLoader(const Filter *ft) // FIXME
|
|||
MemBuffer brev_fold (sz_fold);
|
||||
brev(brev_loader, linux_elf32arm_loader, sz_loader);
|
||||
brev(brev_fold, linux_elf32arm_fold, sz_fold);
|
||||
ehdr_bele((Elf_BE32_Ehdr *)&brev_fold, (Elf_LE32_Ehdr const *)linux_elf32arm_fold);
|
||||
ehdr_bele((Elf_BE32_Ehdr *)brev_fold.getVoidPtr(), (Elf_LE32_Ehdr const *)linux_elf32arm_fold);
|
||||
return buildLinuxLoader(brev_loader, sz_loader, brev_fold, sz_fold, ft);
|
||||
}
|
||||
|
||||
|
@ -657,8 +656,7 @@ PackLinuxElf32ppc::canPack()
|
|||
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
|
||||
|
||||
// now check the ELF header
|
||||
if (checkEhdr(ehdr, Elf32_Ehdr::EM_PPC,
|
||||
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0)
|
||||
if (checkEhdr(ehdr) != 0)
|
||||
return false;
|
||||
|
||||
// additional requirements for linux/elf386
|
||||
|
@ -719,8 +717,7 @@ PackLinuxElf64amd::canPack()
|
|||
Elf64_Ehdr const *const ehdr = (Elf64_Ehdr const *)buf;
|
||||
|
||||
// now check the ELF header
|
||||
if (checkEhdr(ehdr, Elf64_Ehdr::EM_X86_64,
|
||||
Elf64_Ehdr::ELFCLASS64, Elf64_Ehdr::ELFDATA2LSB) != 0)
|
||||
if (checkEhdr(ehdr) != 0)
|
||||
return false;
|
||||
|
||||
// additional requirements for linux/elf386
|
||||
|
@ -943,7 +940,7 @@ void PackLinuxElf32armBe::pack1(OutputFile *fo, Filter &ft) // FIXME
|
|||
cprElfHdr3 h3;
|
||||
ehdr_bele((Elf_BE32_Ehdr *)&h3.ehdr, (Elf_LE32_Ehdr const *)linux_elf32arm_fold);
|
||||
brev((unsigned char *)&h3.phdr[0],
|
||||
(unsigned char const *)(sizeof(Elf32_Ehdr) + &linux_elf32arm_fold),
|
||||
(unsigned char const *)(sizeof(Elf32_Ehdr) + (char const *)&linux_elf32arm_fold),
|
||||
3*sizeof(Elf32_Phdr) );
|
||||
|
||||
generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum) );
|
||||
|
@ -1369,14 +1366,14 @@ void PackLinuxElf32armBe::pack3(OutputFile *fo, Filter &ft)
|
|||
adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary
|
||||
|
||||
// patch in order of descending address
|
||||
patch_be32(p,lsize,"ADRX", adrx); // compressed input for eXpansion
|
||||
patch_be32(p,lsize,"LENX", len0 - hlen);
|
||||
patch_be32(p,lsize,"XRDA", adrx); // compressed input for eXpansion
|
||||
patch_be32(p,lsize,"XNEL", len0 - hlen);
|
||||
|
||||
patch_be32(p,lsize,"CNTC", cntc); // count for copy
|
||||
patch_be32(p,lsize,"ADRC", adrc); // addr for copy
|
||||
patch_be32(p,lsize,"CTNC", cntc); // count for copy
|
||||
patch_be32(p,lsize,"CRDA", adrc); // addr for copy
|
||||
|
||||
patch_be32(p,lsize,"LENM", lenm); // len for map
|
||||
patch_be32(p,lsize,"ADRM", adrm); // addr for map
|
||||
patch_be32(p,lsize,"MNEL", lenm); // len for map
|
||||
patch_be32(p,lsize,"MRDA", adrm); // addr for map
|
||||
|
||||
#undef PAGE_SIZE
|
||||
#undef PAGE_MASK
|
||||
|
@ -1671,6 +1668,9 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
|||
|
||||
PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f)
|
||||
{
|
||||
e_machine = Elf32_Ehdr::EM_386;
|
||||
ei_class = Elf32_Ehdr::ELFCLASS32;
|
||||
ei_data = Elf32_Ehdr::ELFDATA2LSB;
|
||||
}
|
||||
|
||||
PackLinuxElf32x86::~PackLinuxElf32x86()
|
||||
|
@ -1712,8 +1712,7 @@ bool PackLinuxElf32x86::canPack()
|
|||
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
|
||||
|
||||
// now check the ELF header
|
||||
if (checkEhdr(ehdr, Elf32_Ehdr::EM_386,
|
||||
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) != 0)
|
||||
if (checkEhdr(ehdr) != 0)
|
||||
return false;
|
||||
|
||||
// additional requirements for linux/elf386
|
||||
|
@ -1810,6 +1809,9 @@ bool PackLinuxElf32x86::canPack()
|
|||
|
||||
PackLinuxElf32armLe::PackLinuxElf32armLe(InputFile *f) : super(f)
|
||||
{
|
||||
e_machine = Elf32_Ehdr::EM_ARM;
|
||||
ei_class = Elf32_Ehdr::ELFCLASS32;
|
||||
ei_data = Elf32_Ehdr::ELFDATA2LSB;
|
||||
}
|
||||
|
||||
PackLinuxElf32armLe::~PackLinuxElf32armLe()
|
||||
|
@ -1818,6 +1820,9 @@ PackLinuxElf32armLe::~PackLinuxElf32armLe()
|
|||
|
||||
PackLinuxElf32armBe::PackLinuxElf32armBe(InputFile *f) : super(f)
|
||||
{
|
||||
e_machine = Elf32_Ehdr::EM_ARM;
|
||||
ei_class = Elf32_Ehdr::ELFCLASS32;
|
||||
ei_data = Elf32_Ehdr::ELFDATA2MSB;
|
||||
}
|
||||
|
||||
PackLinuxElf32armBe::~PackLinuxElf32armBe()
|
||||
|
@ -1850,8 +1855,7 @@ bool PackLinuxElf32armLe::canPack()
|
|||
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
|
||||
|
||||
// now check the ELF header
|
||||
if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM,
|
||||
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) != 0)
|
||||
if (checkEhdr(ehdr) != 0)
|
||||
return false;
|
||||
|
||||
// additional requirements for linux/elfarm
|
||||
|
@ -1959,8 +1963,7 @@ bool PackLinuxElf32armBe::canPack()
|
|||
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;
|
||||
|
||||
// now check the ELF header
|
||||
if (checkEhdr(ehdr, Elf32_Ehdr::EM_ARM,
|
||||
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2MSB) != 0)
|
||||
if (checkEhdr(ehdr) != 0)
|
||||
return false;
|
||||
|
||||
// additional requirements for linux/elfarm
|
||||
|
@ -2075,8 +2078,8 @@ PackLinuxElf32::elf_find_dynamic(unsigned int const key) const
|
|||
{
|
||||
Elf32_Dyn const *dynp= dynseg;
|
||||
if (dynp)
|
||||
for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (dynp->d_tag == key) {
|
||||
unsigned const t= elf_get_offset_from_address(dynp->d_val);
|
||||
for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_native32(&dynp->d_tag)==key) {
|
||||
unsigned const t= elf_get_offset_from_address(get_native32(&dynp->d_val));
|
||||
if (t) {
|
||||
return t + file_image;
|
||||
}
|
||||
|
@ -2102,12 +2105,12 @@ unsigned PackLinuxElf32::elf_hash(char const *p)
|
|||
Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
|
||||
{
|
||||
if (hashtab && dynsym && dynstr) {
|
||||
unsigned const nbucket = hashtab[0];
|
||||
unsigned const nbucket = get_native32(&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= buckets[m]; 0!=si; si= chains[si]) {
|
||||
for (si= get_native32(&buckets[m]); 0!=si; si= get_native32(&chains[si])) {
|
||||
char const *const p= dynsym[si].st_name + dynstr;
|
||||
if (0==strcmp(name, p)) {
|
||||
return &dynsym[si];
|
||||
|
|
|
@ -62,8 +62,15 @@ protected:
|
|||
virtual void unpack(OutputFile *fo) = 0;
|
||||
|
||||
protected:
|
||||
char *file_image; // if ET_DYN investigation
|
||||
char const *dynstr; // from DT_STRTAB
|
||||
|
||||
unsigned sz_phdrs; // sizeof Phdr[]
|
||||
unsigned sz_elf_hdrs; // all Elf headers
|
||||
|
||||
unsigned short e_machine;
|
||||
unsigned char ei_class;
|
||||
unsigned char ei_data;
|
||||
};
|
||||
|
||||
class PackLinuxElf32 : public PackLinuxElf
|
||||
|
@ -73,11 +80,7 @@ public:
|
|||
PackLinuxElf32(InputFile *f);
|
||||
virtual ~PackLinuxElf32();
|
||||
protected:
|
||||
virtual int checkEhdr(
|
||||
Elf32_Ehdr const *ehdr,
|
||||
unsigned char e_machine,
|
||||
unsigned char ei_class,
|
||||
unsigned char ei_data) const;
|
||||
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
|
@ -112,12 +115,9 @@ protected:
|
|||
protected:
|
||||
Elf32_Ehdr ehdri; // from input file
|
||||
Elf32_Phdr *phdri; // for input file
|
||||
unsigned sz_phdrs; // sizeof Phdr[]
|
||||
|
||||
char *file_image; // if ET_DYN investigation
|
||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
||||
unsigned int const *hashtab; // from DT_HASH
|
||||
char const *dynstr; // from DT_STRTAB
|
||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||
|
||||
struct cprElfHdr1 {
|
||||
|
@ -154,11 +154,7 @@ public:
|
|||
/*virtual int buildLoader(const Filter *);*/
|
||||
|
||||
protected:
|
||||
virtual int checkEhdr(
|
||||
Elf64_Ehdr const *ehdr,
|
||||
unsigned char e_machine,
|
||||
unsigned char ei_class,
|
||||
unsigned char ei_data) const;
|
||||
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
|
|
Loading…
Reference in New Issue
Block a user