mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 15:37:43 +00:00
LibELF: Use StringView instead of "const char*" in dynamic linker code
There's no reason to use C strings more than absolutely necessary.
This commit is contained in:
parent
2c3f284b06
commit
0c0127dc3f
6 changed files with 36 additions and 41 deletions
|
@ -65,11 +65,11 @@ bool g_allowed_to_check_environment_variables { false };
|
|||
bool g_do_breakpoint_trap_before_entry { false };
|
||||
}
|
||||
|
||||
Optional<DynamicObject::SymbolLookupResult> DynamicLinker::lookup_global_symbol(const char* symbol_name)
|
||||
Optional<DynamicObject::SymbolLookupResult> DynamicLinker::lookup_global_symbol(const StringView& symbol)
|
||||
{
|
||||
Optional<DynamicObject::SymbolLookupResult> weak_result;
|
||||
for (auto& lib : g_global_objects) {
|
||||
auto res = lib->lookup_symbol(symbol_name);
|
||||
auto res = lib->lookup_symbol(symbol);
|
||||
if (!res.has_value())
|
||||
continue;
|
||||
if (res.value().bind == STB_GLOBAL)
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace ELF {
|
|||
|
||||
class DynamicLinker {
|
||||
public:
|
||||
static Optional<DynamicObject::SymbolLookupResult> lookup_global_symbol(const char* symbol);
|
||||
static Optional<DynamicObject::SymbolLookupResult> lookup_global_symbol(const StringView& symbol);
|
||||
[[noreturn]] static void linker_main(String&& main_program_name, int fd, bool is_secure, int argc, char** argv, char** envp);
|
||||
|
||||
private:
|
||||
|
|
|
@ -140,7 +140,7 @@ bool DynamicLoader::validate()
|
|||
return true;
|
||||
}
|
||||
|
||||
void* DynamicLoader::symbol_for_name(const char* name)
|
||||
void* DynamicLoader::symbol_for_name(const StringView& name)
|
||||
{
|
||||
auto symbol = m_dynamic_object->hash_section().lookup_symbol(name);
|
||||
|
||||
|
@ -445,10 +445,8 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si
|
|||
// We do not support these
|
||||
// TODO: Can we tell gcc not to generate the piece of code that uses these?
|
||||
// (--disable-tm-clone-registry flag in gcc conifugraion?)
|
||||
if (!strcmp(symbol.name(), "__deregister_frame_info") || !strcmp(symbol.name(), "_ITM_registerTMCloneTable")
|
||||
|| !strcmp(symbol.name(), "_ITM_deregisterTMCloneTable") || !strcmp(symbol.name(), "__register_frame_info")) {
|
||||
if (symbol.name().is_one_of("__deregister_frame_info", "_ITM_registerTMCloneTable", "_ITM_deregisterTMCloneTable", "__register_frame_info"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (symbol.bind() == STB_WEAK)
|
||||
return RelocationResult::ResolveLater;
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
// Stage 3 of loading: lazy relocations and initializers
|
||||
RefPtr<DynamicObject> load_stage_3(unsigned flags, size_t total_tls_size);
|
||||
// Intended for use by dlsym or other internal methods
|
||||
void* symbol_for_name(const char*);
|
||||
void* symbol_for_name(const StringView&);
|
||||
|
||||
void dump();
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <LibELF/DynamicLinker.h>
|
||||
#include <LibELF/DynamicObject.h>
|
||||
#include <LibELF/exec_elf.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace ELF {
|
||||
|
@ -71,7 +70,7 @@ void DynamicObject::dump() const
|
|||
});
|
||||
|
||||
if (m_has_soname)
|
||||
builder.appendf("DT_SONAME: %s\n", soname()); // FIXME: Valdidate that this string is null terminated?
|
||||
builder.appendff("DT_SONAME: {}\n", soname()); // FIXME: Valdidate that this string is null terminated?
|
||||
|
||||
dbgln_if(DYNAMIC_LOAD_DEBUG, "Dynamic section at address {} contains {} entries:", m_dynamic_address.as_ptr(), num_dynamic_sections);
|
||||
dbgln_if(DYNAMIC_LOAD_DEBUG, "{}", builder.string_view());
|
||||
|
@ -249,17 +248,16 @@ const DynamicObject::RelocationSection DynamicObject::plt_relocation_section() c
|
|||
return RelocationSection(Section(*this, m_plt_relocation_offset_location, m_size_of_plt_relocation_entry_list, m_size_of_relocation_entry, "DT_JMPREL"));
|
||||
}
|
||||
|
||||
u32 DynamicObject::HashSection::calculate_elf_hash(const char* name) const
|
||||
u32 DynamicObject::HashSection::calculate_elf_hash(const StringView& name) const
|
||||
{
|
||||
// SYSV ELF hash algorithm
|
||||
// Note that the GNU HASH algorithm has less collisions
|
||||
|
||||
uint32_t hash = 0;
|
||||
|
||||
while (*name != '\0') {
|
||||
for (auto ch : name) {
|
||||
hash = hash << 4;
|
||||
hash += *name;
|
||||
name++;
|
||||
hash += ch;
|
||||
|
||||
const uint32_t top_nibble_of_hash = hash & 0xF0000000U;
|
||||
hash ^= top_nibble_of_hash >> 24;
|
||||
|
@ -269,24 +267,23 @@ u32 DynamicObject::HashSection::calculate_elf_hash(const char* name) const
|
|||
return hash;
|
||||
}
|
||||
|
||||
u32 DynamicObject::HashSection::calculate_gnu_hash(const char* name) const
|
||||
u32 DynamicObject::HashSection::calculate_gnu_hash(const StringView& name) const
|
||||
{
|
||||
// GNU ELF hash algorithm
|
||||
u32 hash = 5381;
|
||||
|
||||
for (; *name != '\0'; ++name) {
|
||||
hash = hash * 33 + *name;
|
||||
}
|
||||
for (auto ch : name)
|
||||
hash = hash * 33 + ch;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
const DynamicObject::Symbol DynamicObject::HashSection::lookup_symbol(const char* name) const
|
||||
auto DynamicObject::HashSection::lookup_symbol(const StringView& name) const -> Symbol
|
||||
{
|
||||
return (this->*(m_lookup_function))(name);
|
||||
}
|
||||
|
||||
const DynamicObject::Symbol DynamicObject::HashSection::lookup_elf_symbol(const char* name) const
|
||||
const DynamicObject::Symbol DynamicObject::HashSection::lookup_elf_symbol(const StringView& name) const
|
||||
{
|
||||
u32 hash_value = calculate_elf_hash(name);
|
||||
|
||||
|
@ -305,7 +302,7 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_elf_symbol(const
|
|||
|
||||
for (u32 i = buckets[hash_value % num_buckets]; i; i = chains[i]) {
|
||||
auto symbol = m_dynamic.symbol(i);
|
||||
if (strcmp(name, symbol.name()) == 0) {
|
||||
if (name == symbol.name()) {
|
||||
dbgln_if(DYNAMIC_LOAD_DEBUG, "Returning SYSV dynamic symbol with index {} for {}: {}", i, symbol.name(), symbol.address().as_ptr());
|
||||
return symbol;
|
||||
}
|
||||
|
@ -313,7 +310,7 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_elf_symbol(const
|
|||
return Symbol::create_undefined(m_dynamic);
|
||||
}
|
||||
|
||||
const DynamicObject::Symbol DynamicObject::HashSection::lookup_gnu_symbol(const char* name) const
|
||||
const DynamicObject::Symbol DynamicObject::HashSection::lookup_gnu_symbol(const StringView& name) const
|
||||
{
|
||||
// Algorithm reference: https://ent-voy.blogspot.com/2011/02/
|
||||
// TODO: Handle 64bit bloomwords for ELF_CLASS64
|
||||
|
@ -350,7 +347,7 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_gnu_symbol(const
|
|||
for (hash1 &= ~1;; ++current_sym) {
|
||||
hash2 = *(current_chain++);
|
||||
const auto symbol = m_dynamic.symbol(current_sym);
|
||||
if ((hash1 == (hash2 & ~1)) && strcmp(name, symbol.name()) == 0) {
|
||||
if ((hash1 == (hash2 & ~1)) && name == symbol.name()) {
|
||||
dbgln_if(DYNAMIC_LOAD_DEBUG, "Returning GNU dynamic symbol with index {} for {}: {}", current_sym, symbol.name(), symbol.address().as_ptr());
|
||||
return symbol;
|
||||
}
|
||||
|
@ -362,9 +359,9 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_gnu_symbol(const
|
|||
return Symbol::create_undefined(m_dynamic);
|
||||
}
|
||||
|
||||
const char* DynamicObject::symbol_string_table_string(Elf32_Word index) const
|
||||
StringView DynamicObject::symbol_string_table_string(Elf32_Word index) const
|
||||
{
|
||||
return (const char*)base_address().offset(m_string_table_offset + index).as_ptr();
|
||||
return StringView { (const char*)base_address().offset(m_string_table_offset + index).as_ptr() };
|
||||
}
|
||||
|
||||
DynamicObject::InitializationFunction DynamicObject::init_section_function() const
|
||||
|
@ -465,7 +462,7 @@ static const char* name_for_dtag(Elf32_Sword d_tag)
|
|||
}
|
||||
}
|
||||
|
||||
Optional<DynamicObject::SymbolLookupResult> DynamicObject::lookup_symbol(const char* name) const
|
||||
Optional<DynamicObject::SymbolLookupResult> DynamicObject::lookup_symbol(const StringView& name) const
|
||||
{
|
||||
auto res = hash_section().lookup_symbol(name);
|
||||
if (res.is_undefined())
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
|
||||
~Symbol() { }
|
||||
|
||||
const char* name() const { return m_dynamic.symbol_string_table_string(m_sym.st_name); }
|
||||
StringView name() const { return m_dynamic.symbol_string_table_string(m_sym.st_name); }
|
||||
unsigned section_index() const { return m_sym.st_shndx; }
|
||||
unsigned value() const { return m_sym.st_value; }
|
||||
unsigned size() const { return m_sym.st_size; }
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
|
||||
class Section {
|
||||
public:
|
||||
Section(const DynamicObject& dynamic, unsigned section_offset, unsigned section_size_bytes, unsigned entry_size, const char* name)
|
||||
Section(const DynamicObject& dynamic, unsigned section_offset, unsigned section_size_bytes, unsigned entry_size, const StringView& name)
|
||||
: m_dynamic(dynamic)
|
||||
, m_section_offset(section_offset)
|
||||
, m_section_size_bytes(section_size_bytes)
|
||||
|
@ -132,7 +132,7 @@ public:
|
|||
}
|
||||
~Section() { }
|
||||
|
||||
const char* name() const { return m_name; }
|
||||
StringView name() const { return m_name; }
|
||||
unsigned offset() const { return m_section_offset; }
|
||||
unsigned size() const { return m_section_size_bytes; }
|
||||
unsigned entry_size() const { return m_entry_size; }
|
||||
|
@ -152,7 +152,7 @@ public:
|
|||
unsigned m_section_offset;
|
||||
unsigned m_section_size_bytes;
|
||||
unsigned m_entry_size;
|
||||
const char* m_name { nullptr };
|
||||
StringView m_name;
|
||||
};
|
||||
|
||||
class RelocationSection : public Section {
|
||||
|
@ -220,17 +220,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
const Symbol lookup_symbol(const char*) const;
|
||||
Symbol lookup_symbol(const StringView& name) const;
|
||||
|
||||
private:
|
||||
u32 calculate_elf_hash(const char* name) const;
|
||||
u32 calculate_gnu_hash(const char* name) const;
|
||||
u32 calculate_elf_hash(const StringView& name) const;
|
||||
u32 calculate_gnu_hash(const StringView& name) const;
|
||||
|
||||
const DynamicObject::Symbol lookup_elf_symbol(const char* name) const;
|
||||
const DynamicObject::Symbol lookup_gnu_symbol(const char* name) const;
|
||||
const DynamicObject::Symbol lookup_elf_symbol(const StringView& name) const;
|
||||
const DynamicObject::Symbol lookup_gnu_symbol(const StringView& name) const;
|
||||
|
||||
typedef const DynamicObject::Symbol (HashSection::*LookupFunction)(const char*) const;
|
||||
LookupFunction m_lookup_function;
|
||||
typedef const DynamicObject::Symbol (HashSection::*LookupFunction)(const StringView&) const;
|
||||
LookupFunction m_lookup_function {};
|
||||
};
|
||||
|
||||
unsigned symbol_count() const { return m_symbol_count; }
|
||||
|
@ -263,7 +263,7 @@ public:
|
|||
VirtualAddress plt_got_base_address() const { return m_base_address.offset(m_procedure_linkage_table_offset.value()); }
|
||||
VirtualAddress base_address() const { return m_base_address; }
|
||||
|
||||
const char* soname() const { return m_has_soname ? symbol_string_table_string(m_soname_index) : nullptr; }
|
||||
StringView soname() const { return m_has_soname ? symbol_string_table_string(m_soname_index) : StringView {}; }
|
||||
|
||||
Optional<FlatPtr> tls_offset() const { return m_tls_offset; }
|
||||
Optional<FlatPtr> tls_size() const { return m_tls_size; }
|
||||
|
@ -282,7 +282,7 @@ public:
|
|||
unsigned bind { STB_LOCAL };
|
||||
const ELF::DynamicObject* dynamic_object { nullptr }; // The object in which the symbol is defined
|
||||
};
|
||||
Optional<SymbolLookupResult> lookup_symbol(const char* name) const;
|
||||
Optional<SymbolLookupResult> lookup_symbol(const StringView& name) const;
|
||||
|
||||
// Will be called from _fixup_plt_entry, as part of the PLT trampoline
|
||||
Elf32_Addr patch_plt_entry(u32 relocation_offset);
|
||||
|
@ -294,7 +294,7 @@ public:
|
|||
private:
|
||||
explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
|
||||
|
||||
const char* symbol_string_table_string(Elf32_Word) const;
|
||||
StringView symbol_string_table_string(Elf32_Word) const;
|
||||
void parse();
|
||||
|
||||
template<typename F>
|
||||
|
@ -390,7 +390,7 @@ inline void DynamicObject::for_each_needed_library(F func) const
|
|||
if (entry.tag() != DT_NEEDED)
|
||||
return IterationDecision::Continue;
|
||||
Elf32_Word offset = entry.val();
|
||||
const char* name = (const char*)(m_base_address.offset(m_string_table_offset).offset(offset)).as_ptr();
|
||||
StringView name { (const char*)(m_base_address.offset(m_string_table_offset).offset(offset)).as_ptr() };
|
||||
if (func(StringView(name)) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
return IterationDecision::Continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue