diff options
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.cpp | 23 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.h | 7 |
2 files changed, 20 insertions, 10 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 376d497e0c..a483dc7801 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -211,7 +211,7 @@ bool DynamicLoader::load_stage_2(unsigned flags, size_t total_tls_size) void DynamicLoader::do_main_relocations(size_t total_tls_size) { auto do_single_relocation = [&](const ELF::DynamicObject::Relocation& relocation) { - switch (do_relocation(total_tls_size, relocation)) { + switch (do_relocation(total_tls_size, relocation, ShouldInitializeWeak::No)) { case RelocationResult::Failed: dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name()); VERIFY_NOT_REACHED(); @@ -267,7 +267,7 @@ void DynamicLoader::load_stage_4() void DynamicLoader::do_lazy_relocations(size_t total_tls_size) { for (const auto& relocation : m_unresolved_relocations) { - if (auto res = do_relocation(total_tls_size, relocation); res != RelocationResult::Success) { + if (auto res = do_relocation(total_tls_size, relocation, ShouldInitializeWeak::Yes); res != RelocationResult::Success) { dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name()); VERIFY_NOT_REACHED(); } @@ -424,7 +424,7 @@ void DynamicLoader::load_program_headers() // FIXME: Initialize the values in the TLS section. Currently, it is zeroed. } -DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_size, const ELF::DynamicObject::Relocation& relocation) +DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_size, const ELF::DynamicObject::Relocation& relocation, ShouldInitializeWeak should_initialize_weak) { FlatPtr* patch_ptr = nullptr; if (is_dynamic()) @@ -462,14 +462,19 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si case R_386_GLOB_DAT: { auto symbol = relocation.symbol(); auto res = lookup_symbol(symbol); + VirtualAddress symbol_location; if (!res.has_value()) { - if (symbol.bind() == STB_WEAK) - return RelocationResult::ResolveLater; + if (symbol.bind() == STB_WEAK) { + if (should_initialize_weak == ShouldInitializeWeak::No) + return RelocationResult::ResolveLater; + } else { + // Symbol not found + return RelocationResult::Failed; + } - // Symbol not found - return RelocationResult::Failed; - } - auto symbol_location = res.value().address; + symbol_location = VirtualAddress { (FlatPtr)0 }; + } else + symbol_location = res.value().address; VERIFY(symbol_location != m_dynamic_object->base_address()); *patch_ptr = symbol_location.get(); break; diff --git a/Userland/Libraries/LibELF/DynamicLoader.h b/Userland/Libraries/LibELF/DynamicLoader.h index 25c95902a1..6bb2ec8f7e 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.h +++ b/Userland/Libraries/LibELF/DynamicLoader.h @@ -54,6 +54,11 @@ private: size_t m_size; }; +enum class ShouldInitializeWeak { + Yes, + No +}; + class DynamicLoader : public RefCounted<DynamicLoader> { public: static RefPtr<DynamicLoader> try_create(int fd, String filename); @@ -145,7 +150,7 @@ private: Success = 1, ResolveLater = 2, }; - RelocationResult do_relocation(size_t total_tls_size, const DynamicObject::Relocation&); + RelocationResult do_relocation(size_t total_tls_size, const DynamicObject::Relocation&, ShouldInitializeWeak should_initialize_weak); size_t calculate_tls_size() const; String m_filename; |