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] 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);