am de0fb393: Restore protection flags for ifunc during relocs.
* commit 'de0fb393ae8136a5958fe17eee0c6285e2f7f91a': Restore protection flags for ifunc during relocs.
This commit is contained in:
commit
ab6ca484bd
@ -1999,9 +1999,32 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
|
||||
DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// We got a definition.
|
||||
} else { // We got a definition.
|
||||
#if !defined(__LP64__)
|
||||
// When relocating dso with text_relocation .text segment is
|
||||
// not executable. We need to restore elf flags before resolving
|
||||
// STT_GNU_IFUNC symbol.
|
||||
bool protect_segments = has_text_relocations &&
|
||||
lsi == this &&
|
||||
ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC;
|
||||
if (protect_segments) {
|
||||
if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
|
||||
DL_ERR("can't protect segments for \"%s\": %s",
|
||||
get_realpath(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sym_addr = lsi->resolve_symbol_address(s);
|
||||
#if !defined(__LP64__)
|
||||
if (protect_segments) {
|
||||
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
|
||||
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
|
||||
get_realpath(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count_relocation(kRelocSymbol);
|
||||
}
|
||||
@ -2038,7 +2061,32 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
|
||||
TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
|
||||
reinterpret_cast<void*>(reloc),
|
||||
reinterpret_cast<void*>(load_bias + addend));
|
||||
*reinterpret_cast<ElfW(Addr)*>(reloc) = call_ifunc_resolver(load_bias + addend);
|
||||
{
|
||||
#if !defined(__LP64__)
|
||||
// When relocating dso with text_relocation .text segment is
|
||||
// not executable. We need to restore elf flags for this
|
||||
// particular call.
|
||||
if (has_text_relocations) {
|
||||
if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
|
||||
DL_ERR("can't protect segments for \"%s\": %s",
|
||||
get_realpath(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ElfW(Addr) ifunc_addr = call_ifunc_resolver(load_bias + addend);
|
||||
#if !defined(__LP64__)
|
||||
// Unprotect it afterwards...
|
||||
if (has_text_relocations) {
|
||||
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
|
||||
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
|
||||
get_realpath(), strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
Loading…
x
Reference in New Issue
Block a user