Some linker.cpp cleanups.
This commit is contained in:
+152
-117
@@ -34,6 +34,16 @@ static int hex(unsigned char c)
|
|||||||
return (c & 0xf) + (c > '9' ? 9 : 0);
|
return (c & 0xf) + (c > '9' ? 9 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool update_capacity(unsigned size, unsigned *capacity)
|
||||||
|
{
|
||||||
|
if (size < *capacity)
|
||||||
|
return false;
|
||||||
|
if (*capacity == 0)
|
||||||
|
*capacity = 16;
|
||||||
|
while (size >= *capacity)
|
||||||
|
*capacity *= 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -65,8 +75,8 @@ ElfLinker::Symbol::~Symbol()
|
|||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElfLinker::Relocation::Relocation(Section *s, unsigned o, const char *t,
|
ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t,
|
||||||
Symbol *v, unsigned a) :
|
const Symbol *v, unsigned a) :
|
||||||
section(s), offset(o), type(t), value(v), add(a)
|
section(s), offset(o), type(t), value(v), add(a)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -175,7 +185,7 @@ void ElfLinker::preprocessRelocations(char *start, const char *end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ElfLinker::Section *ElfLinker::findSection(const char *name)
|
ElfLinker::Section *ElfLinker::findSection(const char *name) const
|
||||||
{
|
{
|
||||||
for (unsigned ic = 0; ic < nsections; ic++)
|
for (unsigned ic = 0; ic < nsections; ic++)
|
||||||
if (strcmp(sections[ic]->name, name) == 0)
|
if (strcmp(sections[ic]->name, name) == 0)
|
||||||
@@ -186,45 +196,51 @@ ElfLinker::Section *ElfLinker::findSection(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name)
|
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name) /*const*/
|
||||||
{
|
{
|
||||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||||
if (strcmp(symbols[ic]->name, name) == 0)
|
if (strcmp(symbols[ic]->name, name) == 0)
|
||||||
return symbols[ic];
|
return symbols[ic];
|
||||||
|
|
||||||
if ('*'==name[0]) { // *ABS*
|
// FIXME: this should be a const method !
|
||||||
addSymbol(name, name, 0);
|
if ('*' == name[0]) // *ABS*
|
||||||
return symbols[nsymbols -1];
|
return addSymbol(name, name, 0);
|
||||||
}
|
|
||||||
printf("unknown symbol %s\n", name);
|
printf("unknown symbol %s\n", name);
|
||||||
abort();
|
abort();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::addSymbol(const char *name, const char *section,
|
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||||
unsigned offset)
|
unsigned offset)
|
||||||
{
|
{
|
||||||
symbols = static_cast<Symbol **>(realloc(symbols, (nsymbols + 1)
|
if (update_capacity(nsymbols, &nsymbols_capacity))
|
||||||
* sizeof(Symbol *)));
|
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||||
assert(symbols);
|
assert(symbols != NULL);
|
||||||
symbols[nsymbols++] = new Symbol(name, findSection(section), offset);
|
Symbol *sym = new Symbol(name, findSection(section), offset);
|
||||||
|
symbols[nsymbols++] = sym;
|
||||||
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::addRelocation(const char *section, unsigned off,
|
ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned off,
|
||||||
const char *type, const char *symbol,
|
const char *type, const char *symbol,
|
||||||
unsigned add)
|
unsigned add)
|
||||||
{
|
{
|
||||||
relocations = static_cast<Relocation **>(realloc(relocations,
|
if (update_capacity(nrelocations, &nrelocations_capacity))
|
||||||
(nrelocations + 1)
|
relocations = static_cast<Relocation **>(realloc(relocations, (nrelocations_capacity) * sizeof(Relocation *)));
|
||||||
* sizeof(Relocation *)));
|
assert(relocations != NULL);
|
||||||
assert(relocations);
|
Relocation *rel = new Relocation(findSection(section), off,
|
||||||
relocations[nrelocations++] = new Relocation(findSection(section), off,
|
|
||||||
type, findSymbol(symbol), add);
|
type, findSymbol(symbol), add);
|
||||||
|
relocations[nrelocations++] = rel;
|
||||||
|
return rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElfLinker::ElfLinker() :
|
ElfLinker::ElfLinker() :
|
||||||
frozen(false), input(NULL), output(NULL), head(NULL), tail(NULL),
|
frozen(false), input(NULL), output(NULL), head(NULL), tail(NULL),
|
||||||
sections(NULL), symbols(NULL), relocations(NULL)
|
sections(NULL), symbols(NULL), relocations(NULL),
|
||||||
|
nsections(0), nsections_capacity(0),
|
||||||
|
nsymbols(0), nsymbols_capacity(0),
|
||||||
|
nrelocations(0), nrelocations_capacity(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +261,7 @@ ElfLinker::~ElfLinker()
|
|||||||
free(relocations);
|
free(relocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::init(const void *pdata, int plen, int)
|
void ElfLinker::init(const void *pdata, int plen)
|
||||||
{
|
{
|
||||||
upx_byte *i = new upx_byte[plen + 1];
|
upx_byte *i = new upx_byte[plen + 1];
|
||||||
memcpy(i, pdata, plen);
|
memcpy(i, pdata, plen);
|
||||||
@@ -341,10 +357,12 @@ int ElfLinker::addSection(const char *sname)
|
|||||||
void ElfLinker::addSection(const char *sname, const void *sdata, int slen, int align)
|
void ElfLinker::addSection(const char *sname, const void *sdata, int slen, int align)
|
||||||
{
|
{
|
||||||
assert(!frozen);
|
assert(!frozen);
|
||||||
sections = static_cast<Section **>(realloc(sections, (nsections + 1)
|
if (update_capacity(nsections, &nsections_capacity))
|
||||||
* sizeof(Section *)));
|
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
|
||||||
assert(sections);
|
assert(sections);
|
||||||
sections[nsections++] = new Section(sname, sdata, slen, align);
|
Section *sec = new Section(sname, sdata, slen, align);
|
||||||
|
sections[nsections++] = sec;
|
||||||
|
//return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::freeze()
|
void ElfLinker::freeze()
|
||||||
@@ -444,61 +462,19 @@ void ElfLinker::align(unsigned len)
|
|||||||
alignWithByte(len, 0);
|
alignWithByte(len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::relocate1(Relocation *rel, upx_byte *,
|
void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
||||||
unsigned, const char *)
|
unsigned, const char *)
|
||||||
{
|
{
|
||||||
printf("unknown relocation type '%s\n", rel->type);
|
printf("unknown relocation type '%s\n", rel->type);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinkerX86::align(unsigned len)
|
|
||||||
{
|
|
||||||
alignWithByte(len, 0x90);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElfLinkerAMD64::align(unsigned len)
|
/*************************************************************************
|
||||||
{
|
// ElfLinker arch subclasses
|
||||||
alignWithByte(len, 0x90);
|
**************************************************************************/
|
||||||
}
|
|
||||||
|
|
||||||
void ElfLinkerPpc32::align(unsigned len)
|
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
{
|
|
||||||
alignWithByte(len, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElfLinkerX86::relocate1(Relocation *rel, upx_byte *location,
|
|
||||||
unsigned value, const char *type)
|
|
||||||
{
|
|
||||||
if (strncmp(type, "R_386_", 6))
|
|
||||||
return super::relocate1(rel, location, value, type);
|
|
||||||
type += 6;
|
|
||||||
|
|
||||||
if (strncmp(type, "PC", 2) == 0)
|
|
||||||
{
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
type += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, "8") == 0)
|
|
||||||
{
|
|
||||||
int displ = (signed char) *location + (int) value;
|
|
||||||
if (displ < -127 || displ > 128)
|
|
||||||
{
|
|
||||||
printf("target out of range (%d) in reloc %s:%x\n",
|
|
||||||
displ, rel->section->name, rel->offset);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
*location += value;
|
|
||||||
}
|
|
||||||
else if (strcmp(type, "16") == 0)
|
|
||||||
set_le16(location, get_le16(location) + value);
|
|
||||||
else if (strcmp(type, "32") == 0)
|
|
||||||
set_le32(location, get_le32(location) + value);
|
|
||||||
else
|
|
||||||
super::relocate1(rel, location, value, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElfLinkerAMD64::relocate1(Relocation *rel, upx_byte *location,
|
|
||||||
unsigned value, const char *type)
|
unsigned value, const char *type)
|
||||||
{
|
{
|
||||||
if (strncmp(type, "R_X86_64_", 9))
|
if (strncmp(type, "R_X86_64_", 9))
|
||||||
@@ -530,7 +506,89 @@ void ElfLinkerAMD64::relocate1(Relocation *rel, upx_byte *location,
|
|||||||
super::relocate1(rel, location, value, type);
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinkerPpc32::relocate1(Relocation *rel, upx_byte *location,
|
|
||||||
|
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_be24(1+ location, get_be24(1+ location) + value / 4);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||||
|
{
|
||||||
|
set_be32(location, get_be32(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
value += ((get_be16(location) & 0x7ff) << 12);
|
||||||
|
value += (get_be16(location + 2) & 0x7ff) << 1;
|
||||||
|
|
||||||
|
set_be16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||||
|
set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||||
|
|
||||||
|
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||||
|
//set_be32(location, get_be32(location) + value / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_le24(location, get_le24(location) + value / 4);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||||
|
{
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
value += ((get_le16(location) & 0x7ff) << 12);
|
||||||
|
value += (get_le16(location + 2) & 0x7ff) << 1;
|
||||||
|
|
||||||
|
set_le16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||||
|
set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||||
|
|
||||||
|
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||||
|
//set_le32(location, get_le32(location) + value / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_68K_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
}
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
|
*location += value;
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_be16(location, get_be16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
|
set_be32(location, get_be32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
unsigned value, const char *type)
|
unsigned value, const char *type)
|
||||||
{
|
{
|
||||||
if (strncmp(type, "R_PPC_", 6))
|
if (strncmp(type, "R_PPC_", 6))
|
||||||
@@ -568,58 +626,35 @@ void ElfLinkerPpc32::relocate1(Relocation *rel, upx_byte *location,
|
|||||||
super::relocate1(rel, location, value, type);
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinkerArmLE::relocate1(Relocation *rel, upx_byte *location,
|
|
||||||
|
void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
unsigned value, const char *type)
|
unsigned value, const char *type)
|
||||||
{
|
{
|
||||||
if (strcmp(type, "R_ARM_PC24") == 0)
|
if (strncmp(type, "R_386_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
{
|
{
|
||||||
value -= rel->section->offset + rel->offset;
|
value -= rel->section->offset + rel->offset;
|
||||||
set_le24(location, get_le24(location) + value / 4);
|
type += 2;
|
||||||
}
|
}
|
||||||
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
{
|
{
|
||||||
|
int displ = (signed char) *location + (int) value;
|
||||||
|
if (displ < -127 || displ > 128)
|
||||||
|
{
|
||||||
|
printf("target out of range (%d) in reloc %s:%x\n",
|
||||||
|
displ, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*location += value;
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
set_le32(location, get_le32(location) + value);
|
set_le32(location, get_le32(location) + value);
|
||||||
}
|
|
||||||
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
|
||||||
{
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
value += ((get_le16(location) & 0x7ff) << 12);
|
|
||||||
value += (get_le16(location + 2) & 0x7ff) << 1;
|
|
||||||
|
|
||||||
set_le16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
|
||||||
set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
|
||||||
|
|
||||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
|
||||||
//set_le32(location, get_le32(location) + value / 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
super::relocate1(rel, location, value, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElfLinkerArmBE::relocate1(Relocation *rel, upx_byte *location,
|
|
||||||
unsigned value, const char *type)
|
|
||||||
{
|
|
||||||
if (strcmp(type, "R_ARM_PC24") == 0)
|
|
||||||
{
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
set_be24(1+ location, get_be24(1+ location) + value / 4);
|
|
||||||
}
|
|
||||||
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
|
||||||
{
|
|
||||||
set_be32(location, get_be32(location) + value);
|
|
||||||
}
|
|
||||||
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
|
||||||
{
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
value += ((get_be16(location) & 0x7ff) << 12);
|
|
||||||
value += (get_be16(location + 2) & 0x7ff) << 1;
|
|
||||||
|
|
||||||
set_be16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
|
||||||
set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
|
||||||
|
|
||||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
|
||||||
//set_be32(location, get_be32(location) + value / 4);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
super::relocate1(rel, location, value, type);
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-48
@@ -37,12 +37,12 @@
|
|||||||
class ElfLinker : private nocopy
|
class ElfLinker : private nocopy
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool frozen; // FIXME: can we remove this ?
|
|
||||||
|
|
||||||
struct Section;
|
struct Section;
|
||||||
struct Symbol;
|
struct Symbol;
|
||||||
struct Relocation;
|
struct Relocation;
|
||||||
|
|
||||||
|
bool frozen; // FIXME: can we remove this ?
|
||||||
|
|
||||||
upx_byte *input;
|
upx_byte *input;
|
||||||
int inputlen;
|
int inputlen;
|
||||||
upx_byte *output;
|
upx_byte *output;
|
||||||
@@ -56,24 +56,27 @@ protected:
|
|||||||
Relocation **relocations;
|
Relocation **relocations;
|
||||||
|
|
||||||
unsigned nsections;
|
unsigned nsections;
|
||||||
|
unsigned nsections_capacity;
|
||||||
unsigned nsymbols;
|
unsigned nsymbols;
|
||||||
|
unsigned nsymbols_capacity;
|
||||||
unsigned nrelocations;
|
unsigned nrelocations;
|
||||||
|
unsigned nrelocations_capacity;
|
||||||
|
|
||||||
void preprocessSections(char *start, const char *end);
|
void preprocessSections(char *start, const char *end);
|
||||||
void preprocessSymbols(char *start, const char *end);
|
void preprocessSymbols(char *start, const char *end);
|
||||||
void preprocessRelocations(char *start, const char *end);
|
void preprocessRelocations(char *start, const char *end);
|
||||||
Section *findSection(const char *name);
|
Section *findSection(const char *name) const;
|
||||||
Symbol *findSymbol(const char *name);
|
Symbol *findSymbol(const char *name) /*const*/;
|
||||||
|
|
||||||
void addSymbol(const char *name, const char *section, unsigned offset);
|
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||||
void addRelocation(const char *section, unsigned off, const char *type,
|
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||||
const char *symbol, unsigned add);
|
const char *symbol, unsigned add);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ElfLinker();
|
ElfLinker();
|
||||||
virtual ~ElfLinker();
|
virtual ~ElfLinker();
|
||||||
|
|
||||||
virtual void init(const void *pdata, int plen, int);
|
virtual void init(const void *pdata, int plen);
|
||||||
virtual void setLoaderAlignOffset(int phase);
|
virtual void setLoaderAlignOffset(int phase);
|
||||||
virtual int addSection(const char *sname);
|
virtual int addSection(const char *sname);
|
||||||
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
|
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
|
||||||
@@ -86,7 +89,7 @@ public:
|
|||||||
|
|
||||||
void alignWithByte(unsigned len, upx_byte b);
|
void alignWithByte(unsigned len, upx_byte b);
|
||||||
virtual void align(unsigned len);
|
virtual void align(unsigned len);
|
||||||
virtual void relocate1(Relocation *, upx_byte *location,
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
unsigned value, const char *type);
|
unsigned value, const char *type);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,56 +122,27 @@ struct ElfLinker::Symbol : private nocopy
|
|||||||
|
|
||||||
struct ElfLinker::Relocation : private nocopy
|
struct ElfLinker::Relocation : private nocopy
|
||||||
{
|
{
|
||||||
Section *section;
|
const Section *section;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
const char *type;
|
const char *type;
|
||||||
Symbol *value;
|
const Symbol *value;
|
||||||
unsigned add; // used in .rela relocations
|
unsigned add; // used in .rela relocations
|
||||||
|
|
||||||
Relocation(Section *s, unsigned o, const char *t,
|
Relocation(const Section *s, unsigned o, const char *t,
|
||||||
Symbol *v, unsigned a);
|
const Symbol *v, unsigned a);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ElfLinkerX86 : public ElfLinker
|
/*************************************************************************
|
||||||
{
|
// ElfLinker arch subclasses
|
||||||
typedef ElfLinker super;
|
**************************************************************************/
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void align(unsigned len);
|
|
||||||
virtual void relocate1(Relocation *, upx_byte *location,
|
|
||||||
unsigned value, const char *type);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ElfLinkerAMD64 : public ElfLinker
|
class ElfLinkerAMD64 : public ElfLinker
|
||||||
{
|
{
|
||||||
typedef ElfLinker super;
|
typedef ElfLinker super;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void align(unsigned len);
|
virtual void align(unsigned len) { alignWithByte(len, 0x90); }
|
||||||
virtual void relocate1(Relocation *, upx_byte *location,
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
unsigned value, const char *type);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ElfLinkerPpc32 : public ElfLinker
|
|
||||||
{
|
|
||||||
typedef ElfLinker super;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void align(unsigned len);
|
|
||||||
virtual void relocate1(Relocation *, upx_byte *location,
|
|
||||||
unsigned value, const char *type);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ElfLinkerArmLE : public ElfLinker
|
|
||||||
{
|
|
||||||
typedef ElfLinker super;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void relocate1(Relocation *, upx_byte *location,
|
|
||||||
unsigned value, const char *type);
|
unsigned value, const char *type);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,13 +150,50 @@ protected:
|
|||||||
class ElfLinkerArmBE : public ElfLinker
|
class ElfLinkerArmBE : public ElfLinker
|
||||||
{
|
{
|
||||||
typedef ElfLinker super;
|
typedef ElfLinker super;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void relocate1(Relocation *, upx_byte *location,
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
unsigned value, const char *type);
|
unsigned value, const char *type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerArmLE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerM68k : 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;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerX86 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void align(unsigned len) { alignWithByte(len, 0x90); }
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,33 +78,6 @@ const int *PackTos::getFilters() const
|
|||||||
|
|
||||||
Linker* PackTos::newLinker() const
|
Linker* PackTos::newLinker() const
|
||||||
{
|
{
|
||||||
class ElfLinkerM68k : public ElfLinker
|
|
||||||
{
|
|
||||||
typedef ElfLinker super;
|
|
||||||
|
|
||||||
virtual void relocate1(Relocation *rel, upx_byte *location,
|
|
||||||
unsigned value, const char *type)
|
|
||||||
{
|
|
||||||
if (strncmp(type, "R_68K_", 6))
|
|
||||||
return super::relocate1(rel, location, value, type);
|
|
||||||
type += 6;
|
|
||||||
|
|
||||||
if (strncmp(type, "PC", 2) == 0)
|
|
||||||
{
|
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
type += 2;
|
|
||||||
}
|
|
||||||
if (strcmp(type, "8") == 0)
|
|
||||||
*location += value;
|
|
||||||
else if (strcmp(type, "16") == 0)
|
|
||||||
set_be16(location, get_be16(location) + value);
|
|
||||||
else if (strcmp(type, "32") == 0)
|
|
||||||
set_be32(location, get_be32(location) + value);
|
|
||||||
else
|
|
||||||
super::relocate1(rel, location, value, type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return new ElfLinkerM68k;
|
return new ElfLinkerM68k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -545,7 +545,7 @@ int PackW32Pe::buildLoader(const Filter *ft)
|
|||||||
tmp_tlsindex = 0;
|
tmp_tlsindex = 0;
|
||||||
|
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader, sizeof(nrv_loader), -1, 2);
|
initLoader(nrv_loader, sizeof(nrv_loader), 2);
|
||||||
addLoader(isdll ? "PEISDLL1" : "",
|
addLoader(isdll ? "PEISDLL1" : "",
|
||||||
"PEMAIN01",
|
"PEMAIN01",
|
||||||
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
||||||
|
|||||||
+2
-8
@@ -1046,17 +1046,11 @@ char const *Packer::getIdentstr(unsigned *size, int small) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Packer::initLoader(const void *pdata, int plen, int pinfo, int small)
|
void Packer::initLoader(const void *pdata, int plen, int small)
|
||||||
{
|
{
|
||||||
if (pinfo < 0)
|
|
||||||
{
|
|
||||||
pinfo = get_le16((const unsigned char *)pdata + plen - 2);
|
|
||||||
pinfo = (pinfo + 3) &~ 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete linker;
|
delete linker;
|
||||||
linker = newLinker();
|
linker = newLinker();
|
||||||
linker->init(pdata, plen, pinfo);
|
linker->init(pdata, plen);
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
char const * const ident = getIdentstr(&size, small);
|
char const * const ident = getIdentstr(&size, small);
|
||||||
|
|||||||
+1
-1
@@ -210,7 +210,7 @@ protected:
|
|||||||
virtual upx_byte *getLoader() const;
|
virtual upx_byte *getLoader() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual int getLoaderSize() const;
|
||||||
virtual const char *getIdentstr(unsigned *size, int small=-1) const;
|
virtual const char *getIdentstr(unsigned *size, int small=-1) const;
|
||||||
virtual void initLoader(const void *pdata, int plen, int pinfo=-1, int small=-1);
|
virtual void initLoader(const void *pdata, int plen, int small=-1);
|
||||||
#if 1 && (ACC_CC_GNUC >= 0x040100)
|
#if 1 && (ACC_CC_GNUC >= 0x040100)
|
||||||
virtual void __acc_cdecl_va addLoader(const char *s, ...) __attribute__((__sentinel__));
|
virtual void __acc_cdecl_va addLoader(const char *s, ...) __attribute__((__sentinel__));
|
||||||
#else
|
#else
|
||||||
|
|||||||
+2
-2
@@ -153,8 +153,8 @@ define tc.default.embed_objinfo
|
|||||||
$(call tc,m-objcopy) --strip-unneeded $2
|
$(call tc,m-objcopy) --strip-unneeded $2
|
||||||
$(call tc,m-objcopy) -R .text -R .data -R .bss $2
|
$(call tc,m-objcopy) -R .text -R .data -R .bss $2
|
||||||
$(call tc,m-objcopy) -R .comment -R .note -R .reginfo $2
|
$(call tc,m-objcopy) -R .comment -R .note -R .reginfo $2
|
||||||
$(call tc,m-objdump) -trwh $2 > $2.dump
|
$(call tc,m-objdump) -trwh $2 | sed -e 's/[ ]*$$//' > $2.dump
|
||||||
sed -e 's/[ ]*$$//' < $2.dump >> $2
|
cat $2.dump >> $2
|
||||||
endef
|
endef
|
||||||
|
|
||||||
# some common settings for $(tc_list)
|
# some common settings for $(tc_list)
|
||||||
|
|||||||
Reference in New Issue
Block a user