Add IFUNC support for arm64 and IRELATIVE reloc

There are number of changes in the way IFUNC related relocations are done:
 1. IRELATIVE relocations are now supported for x86/x86_64 and arm64.
 2. IFUNC relocations are now relying on static linker to generate
    them in correct order - this removes necessety of additional
    relocation pass for ifuncs.
 3. Related to 2: rela?.dyn relocations are preformed before .plt ones.
 4. Ifunc are resolved on symbol lookup this approach allowed to avoid
    mprotect(PROT_WRITE) call on r-x program segments.

Bug: 17399706
Bug: 17177284
Change-Id: I414dd3e82bd47cc03442c5dfc7c279949aec51ed
This commit is contained in:
Dmitriy Ivanov
2014-09-11 15:16:03 -07:00
parent c71483c0b3
commit 9aea164457
10 changed files with 95 additions and 134 deletions

View File

@@ -118,7 +118,7 @@ void* dlsym(void* handle, const char* symbol) {
unsigned bind = ELF_ST_BIND(sym->st_info);
if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
return reinterpret_cast<void*>(sym->st_value + found->load_bias);
return reinterpret_cast<void*>(found->resolve_symbol_address(sym));
}
__bionic_format_dlerror("symbol found but not global", symbol);
@@ -148,7 +148,7 @@ int dladdr(const void* addr, Dl_info* info) {
ElfW(Sym)* sym = dladdr_find_symbol(si, addr);
if (sym != nullptr) {
info->dli_sname = si->strtab + sym->st_name;
info->dli_saddr = reinterpret_cast<void*>(si->load_bias + sym->st_value);
info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
}
return 1;