diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-07-04 00:05:59 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-04 01:07:28 +0200 |
commit | 251eaad8f0136cf7d24f7e1b174008c37349c76e (patch) | |
tree | 053c4892d9e0d2c570d7623a00cedf6a75328091 | |
parent | 5f6ee4c539b4ca93b1266b542e83d629e6b9d26c (diff) | |
download | serenity-251eaad8f0136cf7d24f7e1b174008c37349c76e.zip |
LibELF: Fix relocation support for 'static __thread' variables
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.cpp | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 53fa8fab0e..f802395aa9 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -482,15 +482,21 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO case R_X86_64_TPOFF64: { #endif auto symbol = relocation.symbol(); - // For some reason, LibC has a R_386_TLS_TPOFF that refers to the undefined symbol.. huh - if (relocation.symbol_index() == 0) - break; - auto res = lookup_symbol(symbol); - if (!res.has_value()) - break; - auto* dynamic_object_of_symbol = res.value().dynamic_object; + FlatPtr symbol_value; + DynamicObject const* dynamic_object_of_symbol; + if (relocation.symbol_index() != 0) { + auto res = lookup_symbol(symbol); + if (!res.has_value()) + break; + symbol_value = res.value().value; + dynamic_object_of_symbol = res.value().dynamic_object; + } else { + symbol_value = 0; + dynamic_object_of_symbol = &relocation.dynamic_object(); + } VERIFY(dynamic_object_of_symbol); - *patch_ptr = negative_offset_from_tls_block_end(res.value().value, dynamic_object_of_symbol->tls_offset().value()); + size_t addend = relocation.addend_used() ? relocation.addend() : *patch_ptr; + *patch_ptr = negative_offset_from_tls_block_end(symbol_value + addend, dynamic_object_of_symbol->tls_offset().value()); break; } #ifndef __LP64__ |