1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 00:37:35 +00:00

LibELF: Avoid calculating symbol hashes when we don't need them

This commit is contained in:
Gunnar Beutner 2021-04-22 09:16:17 +02:00 committed by Andreas Kling
parent 39d34fb1f1
commit f74b8a2d1f
4 changed files with 44 additions and 15 deletions

View file

@ -45,15 +45,14 @@ bool g_allowed_to_check_environment_variables { false };
bool g_do_breakpoint_trap_before_entry { 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; Optional<DynamicObject::SymbolLookupResult> weak_result;
auto gnu_hash = compute_gnu_hash(symbol); auto symbol = DynamicObject::HashSymbol { name };
auto sysv_hash = compute_sysv_hash(symbol);
for (auto& lib : g_global_objects) { 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()) if (!res.has_value())
continue; continue;
if (res.value().bind == STB_GLOBAL) if (res.value().bind == STB_GLOBAL)

View file

@ -125,7 +125,7 @@ bool DynamicLoader::validate()
void* DynamicLoader::symbol_for_name(const StringView& name) 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()) if (!result.has_value())
return nullptr; return nullptr;
auto symbol = result.value(); auto symbol = result.value();

View file

@ -428,18 +428,18 @@ static const char* name_for_dtag(Elf32_Sword d_tag)
auto DynamicObject::lookup_symbol(const StringView& name) const -> Optional<SymbolLookupResult> 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()) if (!result.has_value())
return {}; return {};
auto symbol = result.value(); auto symbol_result = result.value();
if (symbol.is_undefined()) if (symbol_result.is_undefined())
return {}; 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) 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; 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 } // end namespace ELF

View file

@ -162,6 +162,23 @@ public:
GNU 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 { class HashSection : public Section {
public: public:
HashSection(const Section& section, HashType hash_type) 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) if (m_hash_type == HashType::SYSV)
return lookup_sysv_symbol(name, sysv_hash); return lookup_sysv_symbol(symbol.name(), symbol.sysv_hash());
return lookup_gnu_symbol(name, gnu_hash); return lookup_gnu_symbol(symbol.name(), symbol.gnu_hash());
} }
private: private:
@ -253,7 +270,7 @@ public:
}; };
Optional<SymbolLookupResult> lookup_symbol(const StringView& name) const; 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 // Will be called from _fixup_plt_entry, as part of the PLT trampoline
VirtualAddress patch_plt_entry(u32 relocation_offset); VirtualAddress patch_plt_entry(u32 relocation_offset);