mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
Bug 628232 part 1 - Use the init symbol from elfhack injected code as an entry point instead of hardcoding 0. r=tglek,a=sdwilsh
This commit is contained in:
parent
a59a2243d8
commit
a46608b3ad
@ -123,22 +123,45 @@ public:
|
||||
if (elf->getMachine() != parent.getMachine())
|
||||
throw std::runtime_error("architecture of object for injected code doesn't match");
|
||||
|
||||
ElfSymtab_Section *symtab = NULL;
|
||||
|
||||
// Get all executable sections from the injected code object.
|
||||
// Most of the time, there will only be one for the init function,
|
||||
// but on e.g. x86, there is a separate section for
|
||||
// __i686.get_pc_thunk.$reg
|
||||
for (ElfSection *text = elf->getSection(1); text != NULL;
|
||||
text = text->getNext()) {
|
||||
if ((text->getType() == SHT_PROGBITS) &&
|
||||
(text->getFlags() & SHF_EXECINSTR)) {
|
||||
code.push_back(text);
|
||||
// Find the symbol table at the same time.
|
||||
for (ElfSection *section = elf->getSection(1); section != NULL;
|
||||
section = section->getNext()) {
|
||||
if ((section->getType() == SHT_PROGBITS) &&
|
||||
(section->getFlags() & SHF_EXECINSTR)) {
|
||||
code.push_back(section);
|
||||
// We need to align this section depending on the greater
|
||||
// alignment required by code sections.
|
||||
if (shdr.sh_addralign < text->getAddrAlign())
|
||||
shdr.sh_addralign = text->getAddrAlign();
|
||||
if (shdr.sh_addralign < section->getAddrAlign())
|
||||
shdr.sh_addralign = section->getAddrAlign();
|
||||
} else if (section->getType() == SHT_SYMTAB) {
|
||||
symtab = (ElfSymtab_Section *) section;
|
||||
}
|
||||
}
|
||||
assert(code.size() != 0);
|
||||
if (symtab == NULL)
|
||||
throw std::runtime_error("Couldn't find a symbol table for the injected code");
|
||||
|
||||
// Find the init symbol
|
||||
entry_point = -1;
|
||||
int shndx = 0;
|
||||
ElfStrtab_Section *strtab = (ElfStrtab_Section *)symtab->getLink();
|
||||
for (std::vector<Elf_Sym>::iterator sym = symtab->syms.begin();
|
||||
sym != symtab->syms.end(); sym++) {
|
||||
const char *name = strtab->getStr(sym->st_name);
|
||||
if (strcmp(name, "init") == 0) {
|
||||
entry_point = sym->st_value;
|
||||
shndx = sym->st_shndx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry_point == -1)
|
||||
throw std::runtime_error("Couldn't find an 'init' symbol in the injected code");
|
||||
|
||||
// Adjust code sections offsets according to their size
|
||||
std::vector<ElfSection *>::iterator c = code.begin();
|
||||
@ -155,6 +178,8 @@ public:
|
||||
for (c = code.begin(); c != code.end(); c++) {
|
||||
memcpy(buf, (*c)->getData(), (*c)->getSize());
|
||||
buf += (*c)->getSize();
|
||||
if ((*c)->getIndex() < shndx)
|
||||
entry_point += (*c)->getSize();
|
||||
}
|
||||
name = elfhack_text;
|
||||
}
|
||||
@ -188,6 +213,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int getEntryPoint() {
|
||||
return entry_point;
|
||||
}
|
||||
private:
|
||||
void apply_pc32_relocation(ElfSection *the_code, char *base, Elf_Rel *r, unsigned int addr)
|
||||
{
|
||||
@ -291,6 +319,7 @@ private:
|
||||
Elf *elf, &parent;
|
||||
std::vector<ElfSection *> code;
|
||||
ElfSection *init;
|
||||
int entry_point;
|
||||
};
|
||||
|
||||
template <typename Rel_Type>
|
||||
@ -353,7 +382,7 @@ int do_relocation_section(Elf *elf, unsigned int rel_type)
|
||||
|
||||
section->rels.assign(new_rels.begin(), new_rels.end());
|
||||
section->shrink(new_rels.size() * section->getEntSize());
|
||||
ElfLocation *init = new ElfLocation(relhackcode, 0);
|
||||
ElfLocation *init = new ElfLocation(relhackcode, relhackcode->getEntryPoint());
|
||||
dyn->setValueForType(DT_INIT, init);
|
||||
// TODO: adjust the value according to the remaining number of relative relocations
|
||||
if (dyn->getValueForType(Rel_Type::d_tag_count))
|
||||
|
Loading…
x
Reference in New Issue
Block a user