1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:57:35 +00:00

DynamicLoader: Add RELA support for self-relocations

GCC doesn't seem to rely on those to work, but Clang does.
This commit is contained in:
Gunnar Beutner 2021-07-13 14:11:12 +02:00 committed by Andreas Kling
parent 42eb06f045
commit 2fc002f778

View file

@ -49,11 +49,14 @@ static void perform_self_relocations(auxv_t* auxvp)
FlatPtr relocation_section_addr = 0; FlatPtr relocation_section_addr = 0;
size_t relocation_table_size = 0; size_t relocation_table_size = 0;
size_t relocation_count = 0; size_t relocation_count = 0;
bool use_addend = false;
auto* dyns = reinterpret_cast<const ElfW(Dyn)*>(dynamic_section_addr); auto* dyns = reinterpret_cast<const ElfW(Dyn)*>(dynamic_section_addr);
for (unsigned i = 0;; ++i) { for (unsigned i = 0;; ++i) {
auto& dyn = dyns[i]; auto& dyn = dyns[i];
if (dyn.d_tag == DT_NULL) if (dyn.d_tag == DT_NULL)
break; break;
if (dyn.d_tag == DT_RELA)
use_addend = true;
if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELA) if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELA)
relocation_section_addr = base_address + dyn.d_un.d_ptr; relocation_section_addr = base_address + dyn.d_un.d_ptr;
else if (dyn.d_tag == DT_RELCOUNT || dyn.d_tag == DT_RELACOUNT) else if (dyn.d_tag == DT_RELCOUNT || dyn.d_tag == DT_RELACOUNT)
@ -73,7 +76,10 @@ static void perform_self_relocations(auxv_t* auxvp)
#else #else
VERIFY(ELF64_R_TYPE(relocation->r_info) == R_X86_64_RELATIVE); VERIFY(ELF64_R_TYPE(relocation->r_info) == R_X86_64_RELATIVE);
#endif #endif
*(FlatPtr*)(base_address + relocation->r_offset) += base_address; if (use_addend)
*(FlatPtr*)(base_address + relocation->r_offset) = base_address + relocation->r_addend;
else
*(FlatPtr*)(base_address + relocation->r_offset) += base_address;
} }
} }