ElfLinker::init() allows symbols and relocations (but not Sections) to be empty

modified:   linker.cpp
	modified:   linker.h
This commit is contained in:
John Reiser 2022-05-04 13:29:36 -07:00 committed by Markus F.X.J. Oberhumer
parent 7a232cb330
commit 2721ef0636
2 changed files with 22 additions and 17 deletions

View File

@ -120,7 +120,8 @@ ElfLinker::~ElfLinker() {
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;
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) {
// decompress pre-compressed stub-loader
@ -156,30 +157,34 @@ void ElfLinker::init(const void *pdata_v, int plen) {
}
input[inputlen] = 0; // NUL terminate
output = new upx_byte[inputlen ? inputlen : 0x4000];
output = new upx_byte[inputlen ? (inputlen + pxtra) : 0x4000];
outputlen = 0;
// FIXME: bad compare when either symbols or relocs are absent
if ((int) strlen("Sections:\n"
"SYMBOL TABLE:\n"
"RELOCATION RECORDS FOR ") < inputlen) {
char const *const eof = (char const *)&input[inputlen];
int pos = find(input, inputlen, "Sections:\n", 10);
assert(pos != -1);
char *psections = (char *) input + pos;
char *const psections = (char *) input + pos;
char *psymbols = strstr(psections, "SYMBOL TABLE:\n");
assert(psymbols != nullptr);
char *const psymbols = strstr(psections, "SYMBOL TABLE:\n");
//assert(psymbols != nullptr);
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR ");
assert(prelocs != nullptr);
char *const prelocs = strstr((psymbols ? psymbols : psections), "RELOCATION RECORDS FOR ");
//assert(prelocs != nullptr);
preprocessSections(psections, psymbols);
preprocessSymbols(psymbols, prelocs);
preprocessRelocations(prelocs, (char *) input + inputlen);
preprocessSections(psections, (psymbols ? psymbols : (prelocs ? prelocs : eof)));
if (psymbols)
preprocessSymbols(psymbols, (prelocs ? prelocs : eof));
if (prelocs)
preprocessRelocations(prelocs, eof);
addLoader("*UND*");
}
}
void ElfLinker::preprocessSections(char *start, char *end) {
void ElfLinker::preprocessSections(char *start, char const *end) {
char *nextl;
for (nsections = 0; start < end; start = 1 + nextl) {
nextl = strchr(start, '\n');
@ -201,7 +206,7 @@ void ElfLinker::preprocessSections(char *start, char *end) {
addSection("*UND*", nullptr, 0, 0);
}
void ElfLinker::preprocessSymbols(char *start, char *end) {
void ElfLinker::preprocessSymbols(char *start, char const *end) {
char *nextl;
for (nsymbols = 0; start < end; start = 1 + nextl) {
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;
char *nextl;
for (nrelocations = 0; start < end; start = 1 + nextl) {

View File

@ -64,9 +64,9 @@ protected:
bool reloc_done = false;
protected:
void preprocessSections(char *start, char *end);
void preprocessSymbols(char *start, char *end);
void preprocessRelocations(char *start, char *end);
void preprocessSections(char *start, char const *end);
void preprocessSymbols(char *start, char const *end);
void preprocessRelocations(char *start, char const *end);
Section *findSection(const char *name, bool fatal = true) const;
Symbol *findSymbol(const char *name, bool fatal = true) const;
@ -78,7 +78,7 @@ public:
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 int addLoader(const char *sname);
void addLoader(const char *s, va_list ap);