Fixed some ElfLinker endian issues.

This commit is contained in:
Markus F.X.J. Oberhumer 2006-11-18 17:43:29 +01:00
parent 9eca502026
commit d9e8c953b1
10 changed files with 127 additions and 10 deletions

View File

@ -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;
}

View File

@ -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 };

View File

@ -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)
{
}

View File

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

View File

@ -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;

View File

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

View File

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

View File

@ -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;

View File

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

View File

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