summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Beutner <gunnar@beutner.name>2021-04-22 09:16:17 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-23 23:35:36 +0200
commitf74b8a2d1f69b27a1200b3ee9625498aab1d6bbf (patch)
treee2032a046f549eea83771856e534033278dcfe4d
parent39d34fb1f15dc801cf6905cdef1d48442c7969e0 (diff)
downloadserenity-f74b8a2d1f69b27a1200b3ee9625498aab1d6bbf.zip
LibELF: Avoid calculating symbol hashes when we don't need them
-rw-r--r--Userland/Libraries/LibELF/DynamicLinker.cpp7
-rw-r--r--Userland/Libraries/LibELF/DynamicLoader.cpp2
-rw-r--r--Userland/Libraries/LibELF/DynamicObject.cpp25
-rw-r--r--Userland/Libraries/LibELF/DynamicObject.h25
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);