diff options
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.cpp | 11 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.h | 3 |
2 files changed, 11 insertions, 3 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 8a8fc78732..fc3f3c361b 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -460,10 +460,9 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si auto res = lookup_symbol(symbol); if (!res.has_value()) break; - u32 symbol_value = res.value().value; auto* dynamic_object_of_symbol = res.value().dynamic_object; VERIFY(dynamic_object_of_symbol); - *patch_ptr = dynamic_object_of_symbol->tls_offset().value() + symbol_value - total_tls_size; + *patch_ptr = negative_offset_from_tls_block_end(res.value().value, dynamic_object_of_symbol->tls_offset().value(), total_tls_size); break; } case R_386_JMP_SLOT: { @@ -488,6 +487,14 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si return RelocationResult::Success; } +ssize_t DynamicLoader::negative_offset_from_tls_block_end(size_t value_of_symbol, size_t tls_offset, size_t total_tls_size) const +{ + auto negative_offset = static_cast<ssize_t>(tls_offset + value_of_symbol - total_tls_size); + // Offset has to be strictly negative. Otherwise we'd collide with the thread's ThreadSpecificData structure. + VERIFY(negative_offset < 0); + return negative_offset; +} + // Defined in <arch>/plt_trampoline.S extern "C" void _plt_trampoline(void) __attribute__((visibility("hidden"))); diff --git a/Userland/Libraries/LibELF/DynamicLoader.h b/Userland/Libraries/LibELF/DynamicLoader.h index e39db15416..6c3b136477 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.h +++ b/Userland/Libraries/LibELF/DynamicLoader.h @@ -130,6 +130,7 @@ private: }; RelocationResult do_relocation(size_t total_tls_size, const DynamicObject::Relocation&, ShouldInitializeWeak should_initialize_weak); size_t calculate_tls_size() const; + ssize_t negative_offset_from_tls_block_end(size_t value_of_symbol, size_t tls_offset, size_t total_tls_size) const; String m_filename; String m_program_interpreter; @@ -150,7 +151,7 @@ private: VirtualAddress m_dynamic_section_address; size_t m_tls_offset { 0 }; - size_t m_tls_size { 0 }; + size_t m_tls_size { 0 }; // TLS size of the current object Vector<DynamicObject::Relocation> m_unresolved_relocations; |