From 9eca502026ffddbba936528c9be36b16606b6da1 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sat, 18 Nov 2006 14:37:22 +0100 Subject: [PATCH 1/3] Make upx build with gcc-2.95 again. --- src/conf.h | 1 + src/linker.cpp | 31 +++++++++++++++++++++++++++++++ src/linker.h | 9 +++++++++ src/main.cpp | 12 ++++++++++++ src/p_ps1.cpp | 25 +------------------------ 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/conf.h b/src/conf.h index 8e98d177..ecbbfcdc 100644 --- a/src/conf.h +++ b/src/conf.h @@ -470,6 +470,7 @@ struct upx_callback_t template struct OptVar { + typedef T Type; static const T default_value_c = default_value; static const T min_value_c = min_value; static const T max_value_c = max_value; diff --git a/src/linker.cpp b/src/linker.cpp index ea738d84..155da926 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -695,6 +695,37 @@ void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location, } +void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, + unsigned value, const char *type) +{ +#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15)) +#define MIPS_LO(a) ((a) & 0xffff) +#define MIPS_PC16(a) ((a) >> 2) +#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2) + + if (strcmp(type, "R_MIPS_HI16") == 0) + set_le16(location, get_le16(location) + MIPS_HI(value)); + else if (strcmp(type, "R_MIPS_LO16") == 0) + set_le16(location, get_le16(location) + MIPS_LO(value)); + else if (strcmp(type, "R_MIPS_PC16") == 0) + { + value -= rel->section->offset + rel->offset; + set_le16(location, get_le16(location) + MIPS_PC16(value)); + } + else if (strcmp(type, "R_MIPS_26") == 0) + set_le32(location, get_le32(location) + MIPS_PC26(value)); + else if (strcmp(type, "R_MIPS_32") == 0) + set_le32(location, get_le32(location) + value); + else + super::relocate1(rel, location, value, type); + +#undef MIPS_HI +#undef MIPS_LO +#undef MIPS_PC16 +#undef MIPS_PC26 +} + + void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location, unsigned value, const char *type) { diff --git a/src/linker.h b/src/linker.h index c9144993..e96cfb83 100644 --- a/src/linker.h +++ b/src/linker.h @@ -180,6 +180,15 @@ protected: }; +class ElfLinkerMipsLE : public ElfLinker +{ + typedef ElfLinker super; +protected: + virtual void relocate1(const Relocation *, upx_byte *location, + unsigned value, const char *type); +}; + + class ElfLinkerPpc32 : public ElfLinker { typedef ElfLinker super; diff --git a/src/main.cpp b/src/main.cpp index b30fea5a..006aeec3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -442,6 +442,7 @@ done: return r; } +#if 1 && (ACC_CC_GNUC >= 0x030300) template int getoptvar(OptVar *var, const char *arg_fatal) { @@ -451,6 +452,17 @@ int getoptvar(OptVar *var, const char *arg_ *var = v; return r; } +#else +template +int getoptvar(T *var, const char *arg_fatal) +{ + typename T::Type v = T::default_value_c; + int r = getoptvar(&v, T::min_value_c, T::max_value_c, arg_fatal); + if (r == 0) + *var = v; + return r; +} +#endif static int do_option(int optc, const char *arg) diff --git a/src/p_ps1.cpp b/src/p_ps1.cpp index 3c03dfce..b209bc52 100644 --- a/src/p_ps1.cpp +++ b/src/p_ps1.cpp @@ -61,6 +61,7 @@ static const #define MIPS_PC16(a) ((a) >> 2) #define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2) + /************************************************************************* // ps1 exe looks like this: // 1.
2048 bytes @@ -110,30 +111,6 @@ const int *PackPs1::getFilters() const Linker* PackPs1::newLinker() const { - class ElfLinkerMipsLE : public ElfLinker - { - typedef ElfLinker super; - - virtual void relocate1(const Relocation *rel, upx_byte *location, - unsigned value, const char *type) - { - if (strcmp(type, "R_MIPS_HI16") == 0) - set_le16(location, get_le16(location) + MIPS_HI(value)); - else if (strcmp(type, "R_MIPS_LO16") == 0) - set_le16(location, get_le16(location) + MIPS_LO(value)); - else if (strcmp(type, "R_MIPS_PC16") == 0) - { - value -= rel->section->offset + rel->offset; - set_le16(location, get_le16(location) + MIPS_PC16(value)); - } - else if (strcmp(type, "R_MIPS_26") == 0) - set_le32(location, get_le32(location) + MIPS_PC26(value)); - else if (strcmp(type, "R_MIPS_32") == 0) - set_le32(location, get_le32(location) + value); - else - super::relocate1(rel, location, value, type); - } - }; return new ElfLinkerMipsLE; } From d9e8c953b192e80fd8003726f0c67f5f880775f0 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sat, 18 Nov 2006 17:43:29 +0100 Subject: [PATCH 2/3] Fixed some ElfLinker endian issues. --- src/bele.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++ src/bele_policy.h | 3 +++ src/linker.cpp | 2 +- src/linker.h | 9 ++++++++ src/main.cpp | 4 ++++ src/p_lx_exc.cpp | 4 +++- src/p_vmlinz.cpp | 4 +++- src/packer.cpp | 4 ++-- src/packer_c.cpp | 8 +++---- src/util.cpp | 43 ++++++++++++++++++++++++++++++++++++ 10 files changed, 127 insertions(+), 10 deletions(-) diff --git a/src/bele.h b/src/bele.h index 40da8aa9..1d8958f1 100644 --- a/src/bele.h +++ b/src/bele.h @@ -246,6 +246,58 @@ inline acc_int64l_t get_le64_signed(const void *p) } +/************************************************************************* +// swab (bswap) +**************************************************************************/ + +inline unsigned acc_swab16(unsigned v) +{ + return ((v & 0x00ff) << 8) | + ((v & 0xff00) >> 8); +} + +inline unsigned acc_swab32(unsigned v) +{ + return ((v & 0x000000ff) << 24) | + ((v & 0x0000ff00) << 8) | + ((v & 0x00ff0000) >> 8) | + ((v & 0xff000000) >> 24); +} + + +inline unsigned acc_swab16p(const acc_uint16e_t *p) +{ + return acc_swab16(*p); +} + +inline unsigned acc_swap32p(const acc_uint32e_t *p) +{ + return acc_swab32(*p); +} + + +inline void acc_swab16s(acc_uint16e_t *p) +{ + *p = acc_swab16(*p); +} + +inline void acc_swab32s(acc_uint32e_t *p) +{ + *p = acc_swab32(*p); +} + + +inline void acc_ua_swab16s(void *p) +{ + set_be16(p, get_le16(p)); +} + +inline void acc_ua_swab32s(void *p) +{ + set_be32(p, get_le32(p)); +} + + /************************************************************************* // classes for portable unaligned access // @@ -496,12 +548,16 @@ namespace N_BELE_CTP { #define BELE_CTP 1 #include "bele_policy.h" #undef BELE_CTP +extern const BEPolicy be_policy; +extern const LEPolicy le_policy; } namespace N_BELE_RTP { #define BELE_RTP 1 #include "bele_policy.h" #undef BELE_RTP +extern const BEPolicy be_policy; +extern const LEPolicy le_policy; } diff --git a/src/bele_policy.h b/src/bele_policy.h index 97ee620f..b7375e9e 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -53,6 +53,7 @@ #if defined(BELE_RTP) struct AbstractPolicy { + AbstractPolicy() {} virtual inline ~AbstractPolicy() {} V bool isBE() C = 0; V bool isLE() C = 0; @@ -90,6 +91,7 @@ struct BEPolicy : public AbstractPolicy #endif { + BEPolicy() {} #if defined(BELE_CTP) typedef N_BELE_RTP::BEPolicy RTP_Policy; enum { isBE = 1, isLE = 0 }; @@ -164,6 +166,7 @@ struct LEPolicy : public AbstractPolicy #endif { + LEPolicy() {} #if defined(BELE_CTP) typedef N_BELE_RTP::LEPolicy RTP_Policy; enum { isBE = 0, isLE = 1 }; diff --git a/src/linker.cpp b/src/linker.cpp index 155da926..4fae5d78 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -108,7 +108,7 @@ ElfLinker::ElfLinker() : nsections(0), nsections_capacity(0), nsymbols(0), nsymbols_capacity(0), nrelocations(0), nrelocations_capacity(0), - reloc_done(false) + reloc_done(false), bele_policy(&N_BELE_RTP::le_policy) { } diff --git a/src/linker.h b/src/linker.h index e96cfb83..2b539cf7 100644 --- a/src/linker.h +++ b/src/linker.h @@ -61,7 +61,10 @@ protected: unsigned nrelocations_capacity; bool reloc_done; +public: + const N_BELE_RTP::AbstractPolicy *bele_policy; +protected: void preprocessSections(char *start, const char *end); void preprocessSymbols(char *start, const char *end); void preprocessRelocations(char *start, const char *end); @@ -155,6 +158,8 @@ protected: class ElfLinkerArmBE : public ElfLinker { typedef ElfLinker super; +public: + ElfLinkerArmBE() { bele_policy = &N_BELE_RTP::be_policy; } protected: virtual void relocate1(const Relocation *, upx_byte *location, unsigned value, const char *type); @@ -173,6 +178,8 @@ protected: class ElfLinkerM68k : public ElfLinker { typedef ElfLinker super; +public: + ElfLinkerM68k() { bele_policy = &N_BELE_RTP::be_policy; } protected: virtual void alignCode(unsigned len); virtual void relocate1(const Relocation *, upx_byte *location, @@ -192,6 +199,8 @@ protected: class ElfLinkerPpc32 : public ElfLinker { typedef ElfLinker super; +public: + ElfLinkerPpc32() { bele_policy = &N_BELE_RTP::be_policy; } protected: virtual void relocate1(const Relocation *, upx_byte *location, unsigned value, const char *type); diff --git a/src/main.cpp b/src/main.cpp index 006aeec3..c8abbbbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1273,6 +1273,10 @@ void upx_sanity_check(void) #if !defined(WITH_GUI) +#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__) +extern "C" { extern long _stksize; long _stksize = 256 * 1024L; } +#endif + int __acc_cdecl_main main(int argc, char *argv[]) { int i; diff --git a/src/p_lx_exc.cpp b/src/p_lx_exc.cpp index 11103e4f..1232ab47 100644 --- a/src/p_lx_exc.cpp +++ b/src/p_lx_exc.cpp @@ -374,10 +374,12 @@ PackLinuxI386::buildLinuxLoader( addLoader("FOLDEXEC", NULL); if (ph.method == M_LZMA) { const lzma_compress_result_t *res = &ph.compress_result.result_lzma; - unsigned const properties = // lc, lp, pb, dummy + acc_uint32e_t properties = // lc, lp, pb, dummy (res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16); + if (linker->bele_policy->isBE()) // big endian - bswap32 + acc_swab32s(&properties); linker->defineSymbol("lzma_properties", properties); // -2 for properties linker->defineSymbol("lzma_c_len", ph.c_len - 2); diff --git a/src/p_vmlinz.cpp b/src/p_vmlinz.cpp index 3d5fd7c5..34b8f105 100644 --- a/src/p_vmlinz.cpp +++ b/src/p_vmlinz.cpp @@ -411,10 +411,12 @@ void PackBvmlinuzI386::pack(OutputFile *fo) if (ph.method == M_LZMA) { const lzma_compress_result_t *res = &ph.compress_result.result_lzma; - unsigned const properties = // lc, lp, pb, dummy + acc_uint32e_t properties = // lc, lp, pb, dummy (res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16); + if (linker->bele_policy->isBE()) // big endian - bswap32 + acc_swab32s(&properties); linker->defineSymbol("lzma_properties", properties); // -2 for properties linker->defineSymbol("lzma_c_len", ph.c_len - 2); diff --git a/src/packer.cpp b/src/packer.cpp index e1b9da5b..6ed5e624 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -879,7 +879,7 @@ upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum, } pc += oc; if (bswap) - set_be32(image+pc,get_le32(image+pc)); + acc_ua_swab32s(image + pc); } *fix++ = 0; return fix; @@ -920,7 +920,7 @@ unsigned Packer::unoptimizeReloc32(upx_byte **in, upx_byte *image, } *relocs++ = jc; if (bswap && image) - set_be32(image+jc,get_le32(image+jc)); + acc_ua_swab32s(image + jc); } //fprintf(stderr,"relocnum=%x\n",relocn); *in = p+1; diff --git a/src/packer_c.cpp b/src/packer_c.cpp index 640c0501..87513c67 100644 --- a/src/packer_c.cpp +++ b/src/packer_c.cpp @@ -253,14 +253,12 @@ void Packer::defineDecompressorSymbols() { const lzma_compress_result_t *res = &ph.compress_result.result_lzma; // FIXME - this is for i386 only - unsigned properties = // lc, lp, pb, dummy + acc_uint32e_t properties = // lc, lp, pb, dummy (res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16); - // big endian - bswap32 - if (getFormat() >= 128) - set_be32(&properties, properties); - + if (linker->bele_policy->isBE()) // big endian - bswap32 + acc_swab32s(&properties); linker->defineSymbol("lzma_properties", properties); // -2 for properties linker->defineSymbol("lzma_c_len", ph.c_len - 2); diff --git a/src/util.cpp b/src/util.cpp index 1655eed4..1e7ef702 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -43,6 +43,21 @@ #include "miniacc.h" +/************************************************************************* +// bele.h +**************************************************************************/ + +namespace N_BELE_CTP { +const BEPolicy be_policy; +const LEPolicy le_policy; +} + +namespace N_BELE_RTP { +const BEPolicy be_policy; +const LEPolicy le_policy; +} + + /************************************************************************* // qsort() util **************************************************************************/ @@ -54,6 +69,13 @@ int __acc_cdecl_qsort be16_compare(const void *e1, const void *e2) return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); } +int __acc_cdecl_qsort be24_compare(const void *e1, const void *e2) +{ + const unsigned d1 = get_be24(e1); + const unsigned d2 = get_be24(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + int __acc_cdecl_qsort be32_compare(const void *e1, const void *e2) { const unsigned d1 = get_be32(e1); @@ -75,6 +97,13 @@ int __acc_cdecl_qsort le16_compare(const void *e1, const void *e2) return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); } +int __acc_cdecl_qsort le24_compare(const void *e1, const void *e2) +{ + const unsigned d1 = get_le24(e1); + const unsigned d2 = get_le24(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + int __acc_cdecl_qsort le32_compare(const void *e1, const void *e2) { const unsigned d1 = get_le32(e1); @@ -97,6 +126,13 @@ int __acc_cdecl_qsort be16_compare_signed(const void *e1, const void *e2) return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); } +int __acc_cdecl_qsort be24_compare_signed(const void *e1, const void *e2) +{ + const int d1 = get_be24_signed(e1); + const int d2 = get_be24_signed(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + int __acc_cdecl_qsort be32_compare_signed(const void *e1, const void *e2) { const int d1 = get_be32_signed(e1); @@ -118,6 +154,13 @@ int __acc_cdecl_qsort le16_compare_signed(const void *e1, const void *e2) return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); } +int __acc_cdecl_qsort le24_compare_signed(const void *e1, const void *e2) +{ + const int d1 = get_le24_signed(e1); + const int d2 = get_le24_signed(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + int __acc_cdecl_qsort le32_compare_signed(const void *e1, const void *e2) { const int d1 = get_le32_signed(e1); From d822b4a62af0aa4d0790e542453ed27212e22243 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sat, 18 Nov 2006 18:25:11 +0100 Subject: [PATCH 3/3] Store shentsize in target byte-order. --- src/p_lx_elf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index e043f040..10d714cc 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -1049,7 +1049,7 @@ PackLinuxElf32::generateElfHdr( h2->ehdr.e_shoff = 0; assert(get_native16(&h2->ehdr.e_ehsize) == sizeof(Elf32_Ehdr)); assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf32_Phdr)); - h2->ehdr.e_shentsize = sizeof(Elf32_Shdr); + set_native16(&h2->ehdr.e_shentsize, sizeof(Elf32_Shdr)); h2->ehdr.e_shnum = 0; h2->ehdr.e_shstrndx = 0; @@ -1099,7 +1099,7 @@ PackOpenBSDElf32x86::generateElfHdr( h3->ehdr.e_shoff = 0; assert(get_native16(&h3->ehdr.e_ehsize) == sizeof(Elf32_Ehdr)); assert(get_native16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr)); - h3->ehdr.e_shentsize = sizeof(Elf32_Shdr); + set_native16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr)); h3->ehdr.e_shnum = 0; h3->ehdr.e_shstrndx = 0; @@ -1161,7 +1161,7 @@ PackLinuxElf64::generateElfHdr( h2->ehdr.e_shoff = 0; assert(get_native16(&h2->ehdr.e_ehsize) == sizeof(Elf64_Ehdr)); assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf64_Phdr)); - h2->ehdr.e_shentsize = sizeof(Elf64_Shdr); + set_native16(&h2->ehdr.e_shentsize, sizeof(Elf64_Shdr)); h2->ehdr.e_shnum = 0; h2->ehdr.e_shstrndx = 0;