ElfLinker::init() allows symbols and relocations (but not Sections) to be empty
modified: linker.cpp modified: linker.h
This commit is contained in:
committed by
Markus F.X.J. Oberhumer
parent
7a232cb330
commit
2721ef0636
+18
-13
@@ -120,7 +120,8 @@ ElfLinker::~ElfLinker() {
|
|||||||
free(relocations);
|
free(relocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::init(const void *pdata_v, int plen) {
|
void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra)
|
||||||
|
{
|
||||||
const upx_byte *pdata = (const upx_byte *) pdata_v;
|
const upx_byte *pdata = (const upx_byte *) pdata_v;
|
||||||
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) {
|
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) {
|
||||||
// decompress pre-compressed stub-loader
|
// decompress pre-compressed stub-loader
|
||||||
@@ -156,30 +157,34 @@ void ElfLinker::init(const void *pdata_v, int plen) {
|
|||||||
}
|
}
|
||||||
input[inputlen] = 0; // NUL terminate
|
input[inputlen] = 0; // NUL terminate
|
||||||
|
|
||||||
output = new upx_byte[inputlen ? inputlen : 0x4000];
|
output = new upx_byte[inputlen ? (inputlen + pxtra) : 0x4000];
|
||||||
outputlen = 0;
|
outputlen = 0;
|
||||||
|
|
||||||
|
// FIXME: bad compare when either symbols or relocs are absent
|
||||||
if ((int) strlen("Sections:\n"
|
if ((int) strlen("Sections:\n"
|
||||||
"SYMBOL TABLE:\n"
|
"SYMBOL TABLE:\n"
|
||||||
"RELOCATION RECORDS FOR ") < inputlen) {
|
"RELOCATION RECORDS FOR ") < inputlen) {
|
||||||
|
char const *const eof = (char const *)&input[inputlen];
|
||||||
int pos = find(input, inputlen, "Sections:\n", 10);
|
int pos = find(input, inputlen, "Sections:\n", 10);
|
||||||
assert(pos != -1);
|
assert(pos != -1);
|
||||||
char *psections = (char *) input + pos;
|
char *const psections = (char *) input + pos;
|
||||||
|
|
||||||
char *psymbols = strstr(psections, "SYMBOL TABLE:\n");
|
char *const psymbols = strstr(psections, "SYMBOL TABLE:\n");
|
||||||
assert(psymbols != nullptr);
|
//assert(psymbols != nullptr);
|
||||||
|
|
||||||
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR ");
|
char *const prelocs = strstr((psymbols ? psymbols : psections), "RELOCATION RECORDS FOR ");
|
||||||
assert(prelocs != nullptr);
|
//assert(prelocs != nullptr);
|
||||||
|
|
||||||
preprocessSections(psections, psymbols);
|
preprocessSections(psections, (psymbols ? psymbols : (prelocs ? prelocs : eof)));
|
||||||
preprocessSymbols(psymbols, prelocs);
|
if (psymbols)
|
||||||
preprocessRelocations(prelocs, (char *) input + inputlen);
|
preprocessSymbols(psymbols, (prelocs ? prelocs : eof));
|
||||||
|
if (prelocs)
|
||||||
|
preprocessRelocations(prelocs, eof);
|
||||||
addLoader("*UND*");
|
addLoader("*UND*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::preprocessSections(char *start, char *end) {
|
void ElfLinker::preprocessSections(char *start, char const *end) {
|
||||||
char *nextl;
|
char *nextl;
|
||||||
for (nsections = 0; start < end; start = 1 + nextl) {
|
for (nsections = 0; start < end; start = 1 + nextl) {
|
||||||
nextl = strchr(start, '\n');
|
nextl = strchr(start, '\n');
|
||||||
@@ -201,7 +206,7 @@ void ElfLinker::preprocessSections(char *start, char *end) {
|
|||||||
addSection("*UND*", nullptr, 0, 0);
|
addSection("*UND*", nullptr, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::preprocessSymbols(char *start, char *end) {
|
void ElfLinker::preprocessSymbols(char *start, char const *end) {
|
||||||
char *nextl;
|
char *nextl;
|
||||||
for (nsymbols = 0; start < end; start = 1 + nextl) {
|
for (nsymbols = 0; start < end; start = 1 + nextl) {
|
||||||
nextl = strchr(start, '\n');
|
nextl = strchr(start, '\n');
|
||||||
@@ -237,7 +242,7 @@ void ElfLinker::preprocessSymbols(char *start, char *end) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::preprocessRelocations(char *start, char *end) {
|
void ElfLinker::preprocessRelocations(char *start, char const *end) {
|
||||||
Section *section = nullptr;
|
Section *section = nullptr;
|
||||||
char *nextl;
|
char *nextl;
|
||||||
for (nrelocations = 0; start < end; start = 1 + nextl) {
|
for (nrelocations = 0; start < end; start = 1 + nextl) {
|
||||||
|
|||||||
+4
-4
@@ -64,9 +64,9 @@ protected:
|
|||||||
bool reloc_done = false;
|
bool reloc_done = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void preprocessSections(char *start, char *end);
|
void preprocessSections(char *start, char const *end);
|
||||||
void preprocessSymbols(char *start, char *end);
|
void preprocessSymbols(char *start, char const *end);
|
||||||
void preprocessRelocations(char *start, char *end);
|
void preprocessRelocations(char *start, char const *end);
|
||||||
Section *findSection(const char *name, bool fatal = true) const;
|
Section *findSection(const char *name, bool fatal = true) const;
|
||||||
Symbol *findSymbol(const char *name, bool fatal = true) const;
|
Symbol *findSymbol(const char *name, bool fatal = true) const;
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ public:
|
|||||||
ElfLinker();
|
ElfLinker();
|
||||||
virtual ~ElfLinker();
|
virtual ~ElfLinker();
|
||||||
|
|
||||||
virtual void init(const void *pdata, int plen);
|
virtual void init(const void *pdata, int plen, unsigned pxtra = 0);
|
||||||
// virtual void setLoaderAlignOffset(int phase);
|
// virtual void setLoaderAlignOffset(int phase);
|
||||||
virtual int addLoader(const char *sname);
|
virtual int addLoader(const char *sname);
|
||||||
void addLoader(const char *s, va_list ap);
|
void addLoader(const char *s, va_list ap);
|
||||||
|
|||||||
Reference in New Issue
Block a user