1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:18:13 +00:00

LibELF: Support relocating weak symbols against global libraries

A strong symbol anywhere in an executable must override any
weak symbol used in any library. This means that the weak symbol
must be overridden by a strong symbol even if the strong symbol
is in a dependent library. This means we need to perform relocations
twice, and resolve weak symbols globally before attempting to resolve
them locally. Consequentially we need to defer performing any
initialisations until after we have performed the second round of
relocations.
This commit is contained in:
William Marlow 2021-01-02 00:48:19 +00:00 committed by Andreas Kling
parent 3e815ad5b1
commit 05345fc07d
4 changed files with 189 additions and 148 deletions

View file

@ -207,9 +207,25 @@ static void load_elf(const String& name)
g_global_objects.append(*dynamic_object);
VERBOSE("load_elf: done %s\n", name.characters());
if (name == "libc.so") {
initialize_libc(*dynamic_object);
}
static NonnullRefPtr<DynamicLoader> commit_elf(const String& name)
{
auto loader = g_loaders.get(name).value();
for (const auto& needed_name : get_dependencies(name)) {
String library_name = get_library_name(needed_name);
if (g_loaders.contains(library_name)) {
commit_elf(library_name);
}
}
auto object = loader->load_stage_3(RTLD_GLOBAL | RTLD_LAZY, g_total_tls_size);
ASSERT(object);
if (name == "libc.so") {
initialize_libc(*object);
}
g_loaders.remove(name);
return loader;
}
void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_program_fd, int argc, char** argv, char** envp)
@ -226,7 +242,7 @@ void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_progra
allocate_tls();
load_elf(main_program_name);
auto main_program_lib = g_loaders.get(main_program_name).value();
auto main_program_lib = commit_elf(main_program_name);
FlatPtr entry_point = reinterpret_cast<FlatPtr>(main_program_lib->image().entry().as_ptr());
if (main_program_lib->is_dynamic())