Explorar o código

LibELF: Use StringView instead of "const char*" in dynamic linker code

There's no reason to use C strings more than absolutely necessary.
Andreas Kling %!s(int64=4) %!d(string=hai) anos
pai
achega
0c0127dc3f

+ 2 - 2
Userland/Libraries/LibELF/DynamicLinker.cpp

@@ -65,11 +65,11 @@ 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 char* symbol_name)
+Optional<DynamicObject::SymbolLookupResult> DynamicLinker::lookup_global_symbol(const StringView& symbol)
 {
 {
     Optional<DynamicObject::SymbolLookupResult> weak_result;
     Optional<DynamicObject::SymbolLookupResult> weak_result;
     for (auto& lib : g_global_objects) {
     for (auto& lib : g_global_objects) {
-        auto res = lib->lookup_symbol(symbol_name);
+        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)

+ 1 - 1
Userland/Libraries/LibELF/DynamicLinker.h

@@ -34,7 +34,7 @@ namespace ELF {
 
 
 class DynamicLinker {
 class DynamicLinker {
 public:
 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);
     [[noreturn]] static void linker_main(String&& main_program_name, int fd, bool is_secure, int argc, char** argv, char** envp);
 
 
 private:
 private:

+ 2 - 4
Userland/Libraries/LibELF/DynamicLoader.cpp

@@ -140,7 +140,7 @@ bool DynamicLoader::validate()
     return true;
     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);
     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
             // We do not support these
             // TODO: Can we tell gcc not to generate the piece of code that uses these?
             // TODO: Can we tell gcc not to generate the piece of code that uses these?
             // (--disable-tm-clone-registry flag in gcc conifugraion?)
             // (--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;
                 break;
-            }
 
 
             if (symbol.bind() == STB_WEAK)
             if (symbol.bind() == STB_WEAK)
                 return RelocationResult::ResolveLater;
                 return RelocationResult::ResolveLater;

+ 1 - 1
Userland/Libraries/LibELF/DynamicLoader.h

@@ -60,7 +60,7 @@ public:
     // Stage 3 of loading: lazy relocations and initializers
     // Stage 3 of loading: lazy relocations and initializers
     RefPtr<DynamicObject> load_stage_3(unsigned flags, size_t total_tls_size);
     RefPtr<DynamicObject> load_stage_3(unsigned flags, size_t total_tls_size);
     // Intended for use by dlsym or other internal methods
     // Intended for use by dlsym or other internal methods
-    void* symbol_for_name(const char*);
+    void* symbol_for_name(const StringView&);
 
 
     void dump();
     void dump();
 
 

+ 15 - 18
Userland/Libraries/LibELF/DynamicObject.cpp

@@ -31,7 +31,6 @@
 #include <LibELF/DynamicLinker.h>
 #include <LibELF/DynamicLinker.h>
 #include <LibELF/DynamicObject.h>
 #include <LibELF/DynamicObject.h>
 #include <LibELF/exec_elf.h>
 #include <LibELF/exec_elf.h>
-#include <stdio.h>
 #include <string.h>
 #include <string.h>
 
 
 namespace ELF {
 namespace ELF {
@@ -71,7 +70,7 @@ void DynamicObject::dump() const
     });
     });
 
 
     if (m_has_soname)
     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, "Dynamic section at address {} contains {} entries:", m_dynamic_address.as_ptr(), num_dynamic_sections);
     dbgln_if(DYNAMIC_LOAD_DEBUG, "{}", builder.string_view());
     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"));
     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
     // SYSV ELF hash algorithm
     // Note that the GNU HASH algorithm has less collisions
     // Note that the GNU HASH algorithm has less collisions
 
 
     uint32_t hash = 0;
     uint32_t hash = 0;
 
 
-    while (*name != '\0') {
+    for (auto ch : name) {
         hash = hash << 4;
         hash = hash << 4;
-        hash += *name;
-        name++;
+        hash += ch;
 
 
         const uint32_t top_nibble_of_hash = hash & 0xF0000000U;
         const uint32_t top_nibble_of_hash = hash & 0xF0000000U;
         hash ^= top_nibble_of_hash >> 24;
         hash ^= top_nibble_of_hash >> 24;
@@ -269,24 +267,23 @@ u32 DynamicObject::HashSection::calculate_elf_hash(const char* name) const
     return hash;
     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
     // GNU ELF hash algorithm
     u32 hash = 5381;
     u32 hash = 5381;
 
 
-    for (; *name != '\0'; ++name) {
-        hash = hash * 33 + *name;
-    }
+    for (auto ch : name)
+        hash = hash * 33 + ch;
 
 
     return hash;
     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);
     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);
     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]) {
     for (u32 i = buckets[hash_value % num_buckets]; i; i = chains[i]) {
         auto symbol = m_dynamic.symbol(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());
             dbgln_if(DYNAMIC_LOAD_DEBUG, "Returning SYSV dynamic symbol with index {} for {}: {}", i, symbol.name(), symbol.address().as_ptr());
             return symbol;
             return symbol;
         }
         }
@@ -313,7 +310,7 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_elf_symbol(const
     return Symbol::create_undefined(m_dynamic);
     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/
     // Algorithm reference: https://ent-voy.blogspot.com/2011/02/
     // TODO: Handle 64bit bloomwords for ELF_CLASS64
     // 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) {
     for (hash1 &= ~1;; ++current_sym) {
         hash2 = *(current_chain++);
         hash2 = *(current_chain++);
         const auto symbol = m_dynamic.symbol(current_sym);
         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());
             dbgln_if(DYNAMIC_LOAD_DEBUG, "Returning GNU dynamic symbol with index {} for {}: {}", current_sym, symbol.name(), symbol.address().as_ptr());
             return symbol;
             return symbol;
         }
         }
@@ -362,9 +359,9 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_gnu_symbol(const
     return Symbol::create_undefined(m_dynamic);
     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
 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);
     auto res = hash_section().lookup_symbol(name);
     if (res.is_undefined())
     if (res.is_undefined())

+ 15 - 15
Userland/Libraries/LibELF/DynamicObject.h

@@ -93,7 +93,7 @@ public:
 
 
         ~Symbol() { }
         ~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 section_index() const { return m_sym.st_shndx; }
         unsigned value() const { return m_sym.st_value; }
         unsigned value() const { return m_sym.st_value; }
         unsigned size() const { return m_sym.st_size; }
         unsigned size() const { return m_sym.st_size; }
@@ -122,7 +122,7 @@ public:
 
 
     class Section {
     class Section {
     public:
     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_dynamic(dynamic)
             , m_section_offset(section_offset)
             , m_section_offset(section_offset)
             , m_section_size_bytes(section_size_bytes)
             , m_section_size_bytes(section_size_bytes)
@@ -132,7 +132,7 @@ public:
         }
         }
         ~Section() { }
         ~Section() { }
 
 
-        const char* name() const { return m_name; }
+        StringView name() const { return m_name; }
         unsigned offset() const { return m_section_offset; }
         unsigned offset() const { return m_section_offset; }
         unsigned size() const { return m_section_size_bytes; }
         unsigned size() const { return m_section_size_bytes; }
         unsigned entry_size() const { return m_entry_size; }
         unsigned entry_size() const { return m_entry_size; }
@@ -152,7 +152,7 @@ public:
         unsigned m_section_offset;
         unsigned m_section_offset;
         unsigned m_section_size_bytes;
         unsigned m_section_size_bytes;
         unsigned m_entry_size;
         unsigned m_entry_size;
-        const char* m_name { nullptr };
+        StringView m_name;
     };
     };
 
 
     class RelocationSection : public Section {
     class RelocationSection : public Section {
@@ -220,17 +220,17 @@ public:
             }
             }
         }
         }
 
 
-        const Symbol lookup_symbol(const char*) const;
+        Symbol lookup_symbol(const StringView& name) const;
 
 
     private:
     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; }
     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 plt_got_base_address() const { return m_base_address.offset(m_procedure_linkage_table_offset.value()); }
     VirtualAddress base_address() const { return m_base_address; }
     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_offset() const { return m_tls_offset; }
     Optional<FlatPtr> tls_size() const { return m_tls_size; }
     Optional<FlatPtr> tls_size() const { return m_tls_size; }
@@ -282,7 +282,7 @@ public:
         unsigned bind { STB_LOCAL };
         unsigned bind { STB_LOCAL };
         const ELF::DynamicObject* dynamic_object { nullptr }; // The object in which the symbol is defined
         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
     // Will be called from _fixup_plt_entry, as part of the PLT trampoline
     Elf32_Addr patch_plt_entry(u32 relocation_offset);
     Elf32_Addr patch_plt_entry(u32 relocation_offset);
@@ -294,7 +294,7 @@ public:
 private:
 private:
     explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
     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();
     void parse();
 
 
     template<typename F>
     template<typename F>
@@ -390,7 +390,7 @@ inline void DynamicObject::for_each_needed_library(F func) const
         if (entry.tag() != DT_NEEDED)
         if (entry.tag() != DT_NEEDED)
             return IterationDecision::Continue;
             return IterationDecision::Continue;
         Elf32_Word offset = entry.val();
         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)
         if (func(StringView(name)) == IterationDecision::Break)
             return IterationDecision::Break;
             return IterationDecision::Break;
         return IterationDecision::Continue;
         return IterationDecision::Continue;