Bug 1385783 - Don't assume both elfhack sections are next to each other. r?froydnj
--- a/build/unix/elfhack/elfhack.cpp
+++ b/build/unix/elfhack/elfhack.cpp
@@ -84,18 +84,20 @@ public:
shdr.sh_size = rels.size() * shdr.sh_entsize;
}
private:
std::vector<Elf_RelHack> rels;
};
class ElfRelHackCode_Section: public ElfSection {
public:
- ElfRelHackCode_Section(Elf_Shdr &s, Elf &e, unsigned int init, unsigned int mprotect_cb)
- : ElfSection(s, nullptr, nullptr), parent(e), init(init), mprotect_cb(mprotect_cb) {
+ ElfRelHackCode_Section(Elf_Shdr &s, Elf &e, ElfRelHack_Section &relhack_section,
+ unsigned int init, unsigned int mprotect_cb)
+ : ElfSection(s, nullptr, nullptr), parent(e), relhack_section(relhack_section),
+ init(init), mprotect_cb(mprotect_cb) {
std::string file(rundir);
file += "/inject/";
switch (parent.getMachine()) {
case EM_386:
file += "x86";
break;
case EM_X86_64:
file += "x86_64";
@@ -349,17 +351,17 @@ private:
// TODO: various checks on the sections
ElfSymtab_Section *symtab = (ElfSymtab_Section *)rel->getLink();
for (typename std::vector<Rel_Type>::iterator r = rel->rels.begin(); r != rel->rels.end(); r++) {
// TODO: various checks on the symbol
const char *name = symtab->syms[ELF32_R_SYM(r->r_info)].name;
unsigned int addr;
if (symtab->syms[ELF32_R_SYM(r->r_info)].value.getSection() == nullptr) {
if (strcmp(name, "relhack") == 0) {
- addr = getNext()->getAddr();
+ addr = relhack_section.getAddr();
} else if (strcmp(name, "elf_header") == 0) {
// TODO: change this ungly hack to something better
ElfSection *ehdr = parent.getSection(1)->getPrevious()->getPrevious();
addr = ehdr->getAddr();
} else if (strcmp(name, "original_init") == 0) {
addr = init;
} else if (relro && strcmp(name, "mprotect_cb") == 0) {
addr = mprotect_cb;
@@ -412,16 +414,17 @@ private:
break;
default:
throw std::runtime_error("Unsupported relocation type");
}
}
}
Elf *elf, &parent;
+ ElfRelHack_Section &relhack_section;
std::vector<ElfSection *> code;
unsigned int init;
unsigned int mprotect_cb;
int entry_point;
ElfSegment *relro;
unsigned int align;
};
@@ -745,17 +748,17 @@ int do_relocation_section(Elf *elf, unsi
fprintf(stderr, "Couldn't find .bss. Skipping\n");
return -1;
}
}
section->rels.assign(new_rels.begin(), new_rels.end());
section->shrink(new_rels.size() * section->getEntSize());
- ElfRelHackCode_Section *relhackcode = new ElfRelHackCode_Section(relhackcode_section, *elf, original_init, mprotect_cb);
+ ElfRelHackCode_Section *relhackcode = new ElfRelHackCode_Section(relhackcode_section, *elf, *relhack, original_init, mprotect_cb);
relhackcode->insertBefore(section);
relhack->insertAfter(relhackcode);
if (section->getOffset() + section->getSize() >= old_end) {
fprintf(stderr, "No gain. Skipping\n");
return -1;
}
// Adjust PT_LOAD segments