diff options
author | Gunnar Beutner <gunnar@beutner.name> | 2021-04-22 09:16:17 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-23 23:35:36 +0200 |
commit | f74b8a2d1f69b27a1200b3ee9625498aab1d6bbf (patch) | |
tree | e2032a046f549eea83771856e534033278dcfe4d | |
parent | 39d34fb1f15dc801cf6905cdef1d48442c7969e0 (diff) | |
download | serenity-f74b8a2d1f69b27a1200b3ee9625498aab1d6bbf.zip |
LibELF: Avoid calculating symbol hashes when we don't need them
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLinker.cpp | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicObject.cpp | 25 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicObject.h | 25 |
4 files changed, 44 insertions, 15 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index bd862e6011..004f8fd738 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -45,15 +45,14 @@ bool g_allowed_to_check_environment_variables { false }; bool g_do_breakpoint_trap_before_entry { false }; } -Optional<DynamicObject::SymbolLookupResult> DynamicLinker::lookup_global_symbol(const StringView& symbol) +Optional<DynamicObject::SymbolLookupResult> DynamicLinker::lookup_global_symbol(const StringView& name) { Optional<DynamicObject::SymbolLookupResult> weak_result; - auto gnu_hash = compute_gnu_hash(symbol); - auto sysv_hash = compute_sysv_hash(symbol); + auto symbol = DynamicObject::HashSymbol { name }; for (auto& lib : g_global_objects) { - auto res = lib->lookup_symbol(symbol, gnu_hash, sysv_hash); + auto res = lib->lookup_symbol(symbol); if (!res.has_value()) continue; if (res.value().bind == STB_GLOBAL) diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index d211617dfa..29c233aa2b 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -125,7 +125,7 @@ bool DynamicLoader::validate() void* DynamicLoader::symbol_for_name(const StringView& name) { - auto result = m_dynamic_object->hash_section().lookup_symbol(name, compute_gnu_hash(name), compute_sysv_hash(name)); + auto result = m_dynamic_object->hash_section().lookup_symbol(name); if (!result.has_value()) return nullptr; auto symbol = result.value(); diff --git a/Userland/Libraries/LibELF/DynamicObject.cpp b/Userland/Libraries/LibELF/DynamicObject.cpp index 7c5b2957cf..2cd474770c 100644 --- a/Userland/Libraries/LibELF/DynamicObject.cpp +++ b/Userland/Libraries/LibELF/DynamicObject.cpp @@ -428,18 +428,18 @@ static const char* name_for_dtag(Elf32_Sword d_tag) auto DynamicObject::lookup_symbol(const StringView& name) const -> Optional<SymbolLookupResult> { - return lookup_symbol(name, compute_gnu_hash(name), compute_sysv_hash(name)); + return lookup_symbol(HashSymbol { name }); } -auto DynamicObject::lookup_symbol(const StringView& name, u32 gnu_hash, u32 sysv_hash) const -> Optional<SymbolLookupResult> +auto DynamicObject::lookup_symbol(const HashSymbol& symbol) const -> Optional<SymbolLookupResult> { - auto result = hash_section().lookup_symbol(name, gnu_hash, sysv_hash); + auto result = hash_section().lookup_symbol(symbol); if (!result.has_value()) return {}; - auto symbol = result.value(); - if (symbol.is_undefined()) + auto symbol_result = result.value(); + if (symbol_result.is_undefined()) return {}; - return SymbolLookupResult { symbol.value(), symbol.address(), symbol.bind(), this }; + return SymbolLookupResult { symbol_result.value(), symbol_result.address(), symbol_result.bind(), this }; } NonnullRefPtr<DynamicObject> DynamicObject::create(const String& filename, VirtualAddress base_address, VirtualAddress dynamic_section_address) @@ -469,4 +469,17 @@ VirtualAddress DynamicObject::patch_plt_entry(u32 relocation_offset) return symbol_location; } +u32 DynamicObject::HashSymbol::gnu_hash() const +{ + if (!m_gnu_hash.has_value()) + m_gnu_hash = compute_gnu_hash(m_name); + return m_gnu_hash.value(); +} + +u32 DynamicObject::HashSymbol::sysv_hash() const +{ + if (!m_sysv_hash.has_value()) + m_sysv_hash = compute_sysv_hash(m_name); + return m_sysv_hash.value(); +} } // end namespace ELF diff --git a/Userland/Libraries/LibELF/DynamicObject.h b/Userland/Libraries/LibELF/DynamicObject.h index 90e0f91f13..b2289eacbd 100644 --- a/Userland/Libraries/LibELF/DynamicObject.h +++ b/Userland/Libraries/LibELF/DynamicObject.h @@ -162,6 +162,23 @@ public: GNU }; + class HashSymbol { + public: + HashSymbol(const StringView& name) + : m_name(name) + { + } + + StringView name() const { return m_name; } + u32 gnu_hash() const; + u32 sysv_hash() const; + + private: + StringView m_name; + mutable Optional<u32> m_gnu_hash; + mutable Optional<u32> m_sysv_hash; + }; + class HashSection : public Section { public: HashSection(const Section& section, HashType hash_type) @@ -170,11 +187,11 @@ public: { } - Optional<Symbol> lookup_symbol(const StringView& name, u32 gnu_hash, u32 sysv_hash) const + Optional<Symbol> lookup_symbol(const HashSymbol& symbol) const { if (m_hash_type == HashType::SYSV) - return lookup_sysv_symbol(name, sysv_hash); - return lookup_gnu_symbol(name, gnu_hash); + return lookup_sysv_symbol(symbol.name(), symbol.sysv_hash()); + return lookup_gnu_symbol(symbol.name(), symbol.gnu_hash()); } private: @@ -253,7 +270,7 @@ public: }; Optional<SymbolLookupResult> lookup_symbol(const StringView& name) const; - Optional<SymbolLookupResult> lookup_symbol(const StringView& name, u32 gnu_hash, u32 sysv_hash) const; + Optional<SymbolLookupResult> lookup_symbol(const HashSymbol& symbol) const; // Will be called from _fixup_plt_entry, as part of the PLT trampoline VirtualAddress patch_plt_entry(u32 relocation_offset); |