mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
DynamicLoader: Don't use LibELF to do the initial relocations
Using LibELF to do the initial relocations doesn't work when building SerenityOS with Clang. We seem to be accessing a global symbol that hasn't been relocated yet somewhere along the path to ELF::DynamicObject::create().
This commit is contained in:
parent
c351b4ad0d
commit
4591c00328
Notes:
sideshowbarker
2024-07-18 10:15:09 +09:00
Author: https://github.com/gunnarbeutner Commit: https://github.com/SerenityOS/serenity/commit/4591c003287 Pull-request: https://github.com/SerenityOS/serenity/pull/8487
1 changed files with 25 additions and 7 deletions
|
@ -46,17 +46,35 @@ static void perform_self_relocations(auxv_t* auxvp)
|
|||
if (!dynamic_section_addr)
|
||||
exit(1);
|
||||
|
||||
auto dynamic_object = ELF::DynamicObject::create({}, (VirtualAddress(base_address)), (VirtualAddress(dynamic_section_addr)));
|
||||
FlatPtr relocation_section_addr = 0;
|
||||
size_t relocation_table_size = 0;
|
||||
size_t relocation_count = 0;
|
||||
auto* dyns = reinterpret_cast<const ElfW(Dyn)*>(dynamic_section_addr);
|
||||
for (unsigned i = 0;; ++i) {
|
||||
auto& dyn = dyns[i];
|
||||
if (dyn.d_tag == DT_NULL)
|
||||
break;
|
||||
if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELA)
|
||||
relocation_section_addr = base_address + dyn.d_un.d_ptr;
|
||||
else if (dyn.d_tag == DT_RELCOUNT || dyn.d_tag == DT_RELACOUNT)
|
||||
relocation_count = dyn.d_un.d_val;
|
||||
else if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
|
||||
relocation_table_size = dyn.d_un.d_val;
|
||||
}
|
||||
if (!relocation_section_addr || !relocation_table_size || !relocation_count)
|
||||
exit(1);
|
||||
|
||||
dynamic_object->relocation_section().for_each_relocation([base_address](auto& reloc) {
|
||||
auto relocation_entry_size = relocation_table_size / relocation_count;
|
||||
for (unsigned i = 0; i < relocation_count; ++i) {
|
||||
size_t offset_in_section = i * relocation_entry_size;
|
||||
auto* relocation = (ElfW(Rela)*)(relocation_section_addr + offset_in_section);
|
||||
#if ARCH(I386)
|
||||
VERIFY(reloc.type() == R_386_RELATIVE);
|
||||
VERIFY(ELF32_R_TYPE(relocation->r_info) == R_386_RELATIVE);
|
||||
#else
|
||||
VERIFY(reloc.type() == R_X86_64_RELATIVE);
|
||||
VERIFY(ELF64_R_TYPE(relocation->r_info) == R_X86_64_RELATIVE);
|
||||
#endif
|
||||
|
||||
*(FlatPtr*)reloc.address().as_ptr() += base_address;
|
||||
});
|
||||
*(FlatPtr*)(base_address + relocation->r_offset) += base_address;
|
||||
}
|
||||
}
|
||||
|
||||
static void display_help()
|
||||
|
|
Loading…
Reference in a new issue