Sfoglia il codice sorgente

LibELF: Save the negative TLS offset in m_tls_offset

This makes it unnecessary to track the symbol size which just isn't
available for unexported symbols (e.g. for 'static __thread').
Gunnar Beutner 4 anni fa
parent
commit
5f6ee4c539

+ 1 - 1
Userland/Libraries/LibELF/DynamicLinker.cpp

@@ -91,8 +91,8 @@ static Result<NonnullRefPtr<DynamicLoader>, DlErrorMessage> map_library(const St
 
     s_loaders.set(get_library_name(filename), *loader);
 
+    s_current_tls_offset -= loader->tls_size_of_current_object();
     loader->set_tls_offset(s_current_tls_offset);
-    s_current_tls_offset += loader->tls_size_of_current_object();
 
     return loader;
 }

+ 4 - 5
Userland/Libraries/LibELF/DynamicLoader.cpp

@@ -490,7 +490,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO
             break;
         auto* dynamic_object_of_symbol = res.value().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(), res.value().size);
+        *patch_ptr = negative_offset_from_tls_block_end(res.value().value, dynamic_object_of_symbol->tls_offset().value());
         break;
     }
 #ifndef __LP64__
@@ -519,10 +519,9 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO
     return RelocationResult::Success;
 }
 
-ssize_t DynamicLoader::negative_offset_from_tls_block_end(size_t value_of_symbol, size_t tls_offset, size_t symbol_size) const
+ssize_t DynamicLoader::negative_offset_from_tls_block_end(size_t value_of_symbol, ssize_t tls_offset) const
 {
-    VERIFY(symbol_size > 0);
-    ssize_t offset = -static_cast<ssize_t>(value_of_symbol + tls_offset + symbol_size);
+    ssize_t offset = static_cast<ssize_t>(tls_offset + value_of_symbol);
     // At offset 0 there's the thread's ThreadSpecificData structure, we don't want to collide with it.
     VERIFY(offset < 0);
     return offset;
@@ -549,7 +548,7 @@ void DynamicLoader::copy_initial_tls_data_into(ByteBuffer& buffer) const
         if (symbol.type() != STT_TLS)
             return IterationDecision::Continue;
 
-        ssize_t negative_offset = negative_offset_from_tls_block_end(symbol.value(), m_tls_offset, symbol.size());
+        ssize_t negative_offset = negative_offset_from_tls_block_end(symbol.value(), m_tls_offset);
         VERIFY(symbol.size() != 0);
         VERIFY(buffer.size() + negative_offset + symbol.size() <= buffer.size());
         memcpy(buffer.data() + buffer.size() + negative_offset, tls_data + symbol.value(), symbol.size());

+ 2 - 2
Userland/Libraries/LibELF/DynamicLoader.h

@@ -131,7 +131,7 @@ private:
     };
     RelocationResult do_relocation(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 symbol_size) const;
+    ssize_t negative_offset_from_tls_block_end(size_t value_of_symbol, ssize_t tls_offset) const;
 
     String m_filename;
     String m_program_interpreter;
@@ -151,7 +151,7 @@ private:
 
     VirtualAddress m_dynamic_section_address;
 
-    size_t m_tls_offset { 0 };
+    ssize_t m_tls_offset { 0 };
     size_t m_tls_size_of_current_object { 0 };
 
     Vector<DynamicObject::Relocation> m_unresolved_relocations;

+ 1 - 0
Userland/Libraries/LibELF/DynamicObject.h

@@ -195,6 +195,7 @@ public:
                 return m_dynamic.base_address().offset(offset());
             return VirtualAddress { offset() };
         }
+        [[nodiscard]] DynamicObject const& dynamic_object() const { return m_dynamic; }
 
     private:
         const DynamicObject& m_dynamic;