diff options
author | Gunnar Beutner <gunnar@beutner.name> | 2021-04-19 11:39:31 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-19 12:00:40 +0200 |
commit | 1dab5ca5fd9f2d730f773d628f88dad1be70a637 (patch) | |
tree | 7a0653da44e6c6a51bba0c0d0bbab7148059abee /Userland/Libraries/LibELF | |
parent | 97d7450571caaec13c18a57da38f5b8c2eb24c09 (diff) | |
download | serenity-1dab5ca5fd9f2d730f773d628f88dad1be70a637.zip |
LibELF: Fix support for relocating weak symbols
Having unresolved weak symbols is allowed and we should initialize
them to zero.
Diffstat (limited to 'Userland/Libraries/LibELF')
-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; |