diff options
author | Andrew Kaster <andrewdkaster@gmail.com> | 2020-04-11 12:24:07 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-11 22:41:05 +0200 |
commit | 21b5909dc6c912809f0ff2fd4798f0d613b36c14 (patch) | |
tree | 6de075abe62c33671da24790120d3f1232060e82 /Libraries/LibELF | |
parent | 6b0f47683c78b0b9482efb7c95e42bb9a2bcaf7f (diff) | |
download | serenity-21b5909dc6c912809f0ff2fd4798f0d613b36c14.zip |
LibELF: Move ELF classes into namespace ELF
This is for consistency with other namespace changes that were made
a while back to the other libraries :)
Diffstat (limited to 'Libraries/LibELF')
-rw-r--r-- | Libraries/LibELF/DynamicLoader.cpp (renamed from Libraries/LibELF/ELFDynamicLoader.cpp) | 48 | ||||
-rw-r--r-- | Libraries/LibELF/DynamicLoader.h (renamed from Libraries/LibELF/ELFDynamicLoader.h) | 24 | ||||
-rw-r--r-- | Libraries/LibELF/DynamicObject.cpp (renamed from Libraries/LibELF/ELFDynamicObject.cpp) | 48 | ||||
-rw-r--r-- | Libraries/LibELF/DynamicObject.h (renamed from Libraries/LibELF/ELFDynamicObject.h) | 28 | ||||
-rw-r--r-- | Libraries/LibELF/Image.cpp (renamed from Libraries/LibELF/ELFImage.cpp) | 62 | ||||
-rw-r--r-- | Libraries/LibELF/Image.h (renamed from Libraries/LibELF/ELFImage.h) | 36 | ||||
-rw-r--r-- | Libraries/LibELF/Loader.cpp (renamed from Libraries/LibELF/ELFLoader.cpp) | 30 | ||||
-rw-r--r-- | Libraries/LibELF/Loader.h (renamed from Libraries/LibELF/ELFLoader.h) | 22 |
8 files changed, 165 insertions, 133 deletions
diff --git a/Libraries/LibELF/ELFDynamicLoader.cpp b/Libraries/LibELF/DynamicLoader.cpp index 836972237e..78e94644bc 100644 --- a/Libraries/LibELF/ELFDynamicLoader.cpp +++ b/Libraries/LibELF/DynamicLoader.cpp @@ -25,7 +25,7 @@ */ #include <AK/StringBuilder.h> -#include <LibELF/ELFDynamicLoader.h> +#include <LibELF/DynamicLoader.h> #include <assert.h> #include <dlfcn.h> @@ -45,14 +45,16 @@ } while (0) #endif +namespace ELF { + static bool s_always_bind_now = false; -NonnullRefPtr<ELFDynamicLoader> ELFDynamicLoader::construct(const char* filename, int fd, size_t size) +NonnullRefPtr<DynamicLoader> DynamicLoader::construct(const char* filename, int fd, size_t size) { - return adopt(*new ELFDynamicLoader(filename, fd, size)); + return adopt(*new DynamicLoader(filename, fd, size)); } -ELFDynamicLoader::ELFDynamicLoader(const char* filename, int fd, size_t size) +DynamicLoader::DynamicLoader(const char* filename, int fd, size_t size) : m_filename(filename) , m_file_size(size) , m_image_fd(fd) @@ -65,13 +67,13 @@ ELFDynamicLoader::ELFDynamicLoader(const char* filename, int fd, size_t size) } } -ELFDynamicLoader::~ELFDynamicLoader() +DynamicLoader::~DynamicLoader() { if (MAP_FAILED != m_file_mapping) munmap(m_file_mapping, m_file_size); } -void* ELFDynamicLoader::symbol_for_name(const char* name) +void* DynamicLoader::symbol_for_name(const char* name) { auto symbol = m_dynamic_object->hash_section().lookup_symbol(name); @@ -81,9 +83,9 @@ void* ELFDynamicLoader::symbol_for_name(const char* name) return m_dynamic_object->base_address().offset(symbol.value()).as_ptr(); } -bool ELFDynamicLoader::load_from_image(unsigned flags) +bool DynamicLoader::load_from_image(unsigned flags) { - ELFImage elf_image((u8*)m_file_mapping, m_file_size); + Image elf_image((u8*)m_file_mapping, m_file_size); m_valid = elf_image.is_valid() && elf_image.is_dynamic(); @@ -101,12 +103,12 @@ bool ELFDynamicLoader::load_from_image(unsigned flags) munmap(m_file_mapping, m_file_size); m_file_mapping = MAP_FAILED; - m_dynamic_object = AK::make<ELFDynamicObject>(m_text_segment_load_address, m_dynamic_section_address); + m_dynamic_object = AK::make<DynamicObject>(m_text_segment_load_address, m_dynamic_section_address); return load_stage_2(flags); } -bool ELFDynamicLoader::load_stage_2(unsigned flags) +bool DynamicLoader::load_stage_2(unsigned flags) { ASSERT(flags & RTLD_GLOBAL); ASSERT(flags & RTLD_LAZY); @@ -143,7 +145,7 @@ bool ELFDynamicLoader::load_stage_2(unsigned flags) return true; } -void ELFDynamicLoader::load_program_headers(const ELFImage& elf_image) +void DynamicLoader::load_program_headers(const Image& elf_image) { Vector<ProgramHeaderRegion> program_headers; @@ -152,7 +154,7 @@ void ELFDynamicLoader::load_program_headers(const ELFImage& elf_image) ProgramHeaderRegion* tls_region_ptr = nullptr; VirtualAddress dynamic_region_desired_vaddr; - elf_image.for_each_program_header([&](const ELFImage::ProgramHeader& program_header) { + elf_image.for_each_program_header([&](const Image::ProgramHeader& program_header) { ProgramHeaderRegion new_region; new_region.set_program_header(program_header.raw_header()); program_headers.append(move(new_region)); @@ -200,7 +202,7 @@ void ELFDynamicLoader::load_program_headers(const ELFImage& elf_image) } } -void ELFDynamicLoader::do_relocations() +void DynamicLoader::do_relocations() { u32 load_base_address = m_dynamic_object->base_address().get(); @@ -208,7 +210,7 @@ void ELFDynamicLoader::do_relocations() auto main_relocation_section = m_dynamic_object->relocation_section(); - main_relocation_section.for_each_relocation([&](const ELFDynamicObject::Relocation& relocation) { + main_relocation_section.for_each_relocation([&](const DynamicObject::Relocation& relocation) { VERBOSE("====== RELOCATION %d: offset 0x%08X, type %d, symidx %08X\n", relocation.offset_in_section() / main_relocation_section.entry_size(), relocation.offset(), relocation.type(), relocation.symbol_index()); u32* patch_ptr = (u32*)(load_base_address + relocation.offset()); switch (relocation.type()) { @@ -260,7 +262,7 @@ void ELFDynamicLoader::do_relocations() default: // Raise the alarm! Someone needs to implement this relocation type dbgprintf("Found a new exciting relocation type %d\n", relocation.type()); - printf("ELFDynamicLoader: Found unknown relocation type %d\n", relocation.type()); + printf("DynamicLoader: Found unknown relocation type %d\n", relocation.type()); ASSERT_NOT_REACHED(); break; } @@ -268,7 +270,7 @@ void ELFDynamicLoader::do_relocations() }); // Handle PLT Global offset table relocations. - m_dynamic_object->plt_relocation_section().for_each_relocation([&](const ELFDynamicObject::Relocation& relocation) { + m_dynamic_object->plt_relocation_section().for_each_relocation([&](const DynamicObject::Relocation& relocation) { // FIXME: Or BIND_NOW flag passed in? if (m_dynamic_object->must_bind_now() || s_always_bind_now) { // Eagerly BIND_NOW the PLT entries, doing all the symbol looking goodness @@ -294,7 +296,7 @@ void ELFDynamicLoader::do_relocations() // Defined in <arch>/plt_trampoline.S extern "C" void _plt_trampoline(void) __attribute__((visibility("hidden"))); -void ELFDynamicLoader::setup_plt_trampoline() +void DynamicLoader::setup_plt_trampoline() { VirtualAddress got_address = m_dynamic_object->plt_got_base_address(); @@ -308,13 +310,13 @@ void ELFDynamicLoader::setup_plt_trampoline() } // Called from our ASM routine _plt_trampoline -extern "C" Elf32_Addr _fixup_plt_entry(ELFDynamicLoader* object, u32 relocation_offset) +extern "C" Elf32_Addr _fixup_plt_entry(DynamicLoader* object, u32 relocation_offset) { return object->patch_plt_entry(relocation_offset); } // offset is in PLT relocation table -Elf32_Addr ELFDynamicLoader::patch_plt_entry(u32 relocation_offset) +Elf32_Addr DynamicLoader::patch_plt_entry(u32 relocation_offset) { auto relocation = m_dynamic_object->plt_relocation_section().relocation_at_offset(relocation_offset); @@ -325,14 +327,14 @@ Elf32_Addr ELFDynamicLoader::patch_plt_entry(u32 relocation_offset) u8* relocation_address = relocation.address().as_ptr(); u32 symbol_location = sym.address().get(); - VERBOSE("ELFDynamicLoader: Jump slot relocation: putting %s (%p) into PLT at %p\n", sym.name(), symbol_location, relocation_address); + VERBOSE("DynamicLoader: Jump slot relocation: putting %s (%p) into PLT at %p\n", sym.name(), symbol_location, relocation_address); *(u32*)relocation_address = symbol_location; return symbol_location; } -void ELFDynamicLoader::call_object_init_functions() +void DynamicLoader::call_object_init_functions() { typedef void (*InitFunc)(); auto init_function = (InitFunc)(m_dynamic_object->init_section().address().as_ptr()); @@ -359,7 +361,7 @@ void ELFDynamicLoader::call_object_init_functions() } } -u32 ELFDynamicLoader::ProgramHeaderRegion::mmap_prot() const +u32 DynamicLoader::ProgramHeaderRegion::mmap_prot() const { int prot = 0; prot |= is_executable() ? PROT_EXEC : 0; @@ -367,3 +369,5 @@ u32 ELFDynamicLoader::ProgramHeaderRegion::mmap_prot() const prot |= is_writable() ? PROT_WRITE : 0; return prot; } + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFDynamicLoader.h b/Libraries/LibELF/DynamicLoader.h index c3932714d4..94174fb9fc 100644 --- a/Libraries/LibELF/ELFDynamicLoader.h +++ b/Libraries/LibELF/DynamicLoader.h @@ -30,22 +30,24 @@ #include <AK/OwnPtr.h> #include <AK/RefCounted.h> #include <AK/String.h> -#include <LibELF/ELFDynamicObject.h> -#include <LibELF/ELFImage.h> +#include <LibELF/DynamicObject.h> +#include <LibELF/Image.h> #include <LibELF/exec_elf.h> #include <sys/mman.h> +namespace ELF { + #define ALIGN_ROUND_UP(x, align) ((((size_t)(x)) + align - 1) & (~(align - 1))) -class ELFDynamicLoader : public RefCounted<ELFDynamicLoader> { +class DynamicLoader : public RefCounted<DynamicLoader> { public: - static NonnullRefPtr<ELFDynamicLoader> construct(const char* filename, int fd, size_t file_size); + static NonnullRefPtr<DynamicLoader> construct(const char* filename, int fd, size_t file_size); - ~ELFDynamicLoader(); + ~DynamicLoader(); bool is_valid() const { return m_valid; } - // Load a full ELF image from file into the current process and create an ELFDynamicObject + // Load a full ELF image from file into the current process and create an DynamicObject // from the SHT_DYNAMIC in the file. bool load_from_image(unsigned flags); @@ -89,11 +91,11 @@ private: Elf32_Phdr m_program_header; // Explictly a copy of the PHDR in the image }; - explicit ELFDynamicLoader(const char* filename, int fd, size_t file_size); - explicit ELFDynamicLoader(Elf32_Dyn* dynamic_location, Elf32_Addr load_address); + explicit DynamicLoader(const char* filename, int fd, size_t file_size); + explicit DynamicLoader(Elf32_Dyn* dynamic_location, Elf32_Addr load_address); // Stage 1 - void load_program_headers(const ELFImage& elf_image); + void load_program_headers(const Image& elf_image); // Stage 2 void do_relocations(); @@ -106,7 +108,7 @@ private: void* m_file_mapping { nullptr }; bool m_valid { true }; - OwnPtr<ELFDynamicObject> m_dynamic_object; + OwnPtr<DynamicObject> m_dynamic_object; VirtualAddress m_text_segment_load_address; size_t m_text_segment_size; @@ -114,3 +116,5 @@ private: VirtualAddress m_tls_segment_address; VirtualAddress m_dynamic_section_address; }; + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFDynamicObject.cpp b/Libraries/LibELF/DynamicObject.cpp index 385de9e3be..e1fc93be88 100644 --- a/Libraries/LibELF/ELFDynamicObject.cpp +++ b/Libraries/LibELF/DynamicObject.cpp @@ -26,31 +26,33 @@ #include <AK/String.h> #include <AK/StringBuilder.h> -#include <LibELF/ELFDynamicObject.h> +#include <LibELF/DynamicObject.h> #include <LibELF/exec_elf.h> #include <stdio.h> #include <string.h> +namespace ELF { + static const char* name_for_dtag(Elf32_Sword d_tag); -ELFDynamicObject::ELFDynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_addresss) +DynamicObject::DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_addresss) : m_base_address(base_address) , m_dynamic_address(dynamic_section_addresss) { parse(); } -ELFDynamicObject::~ELFDynamicObject() +DynamicObject::~DynamicObject() { } -void ELFDynamicObject::dump() const +void DynamicObject::dump() const { StringBuilder builder; builder.append("\nd_tag tag_name value\n"); size_t num_dynamic_sections = 0; - for_each_dynamic_entry([&](const ELFDynamicObject::DynamicEntry& entry) { + for_each_dynamic_entry([&](const DynamicObject::DynamicEntry& entry) { String name_field = String::format("(%s)", name_for_dtag(entry.tag())); builder.appendf("0x%08X %-17s0x%X\n", entry.tag(), name_field.characters(), entry.val()); num_dynamic_sections++; @@ -61,7 +63,7 @@ void ELFDynamicObject::dump() const dbgprintf(builder.to_string().characters()); } -void ELFDynamicObject::parse() +void DynamicObject::parse() { for_each_dynamic_entry([&](const DynamicEntry& entry) { switch (entry.tag()) { @@ -134,8 +136,8 @@ void ELFDynamicObject::parse() m_dt_flags |= DF_TEXTREL; // This tag seems to exist for legacy reasons only? break; default: - dbgprintf("ELFDynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag())); - printf("ELFDynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag())); + dbgprintf("DynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag())); + printf("DynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag())); ASSERT_NOT_REACHED(); // FIXME: Maybe just break out here and return false? break; } @@ -147,7 +149,7 @@ void ELFDynamicObject::parse() m_symbol_count = num_hash_chains; } -const ELFDynamicObject::Relocation ELFDynamicObject::RelocationSection::relocation(unsigned index) const +const DynamicObject::Relocation DynamicObject::RelocationSection::relocation(unsigned index) const { ASSERT(index < entry_count()); unsigned offset_in_section = index * entry_size(); @@ -155,56 +157,56 @@ const ELFDynamicObject::Relocation ELFDynamicObject::RelocationSection::relocati return Relocation(m_dynamic, *relocation_address, offset_in_section); } -const ELFDynamicObject::Relocation ELFDynamicObject::RelocationSection::relocation_at_offset(unsigned offset) const +const DynamicObject::Relocation DynamicObject::RelocationSection::relocation_at_offset(unsigned offset) const { ASSERT(offset <= (m_section_size_bytes - m_entry_size)); auto relocation_address = (Elf32_Rel*)address().offset(offset).as_ptr(); return Relocation(m_dynamic, *relocation_address, offset); } -const ELFDynamicObject::Symbol ELFDynamicObject::symbol(unsigned index) const +const DynamicObject::Symbol DynamicObject::symbol(unsigned index) const { auto symbol_section = Section(*this, m_symbol_table_offset, (m_symbol_count * m_size_of_symbol_table_entry), m_size_of_symbol_table_entry, "DT_SYMTAB"); auto symbol_entry = (Elf32_Sym*)symbol_section.address().offset(index * symbol_section.entry_size()).as_ptr(); return Symbol(*this, index, *symbol_entry); } -const ELFDynamicObject::Section ELFDynamicObject::init_section() const +const DynamicObject::Section DynamicObject::init_section() const { return Section(*this, m_init_offset, sizeof(void (*)()), sizeof(void (*)()), "DT_INIT"); } -const ELFDynamicObject::Section ELFDynamicObject::fini_section() const +const DynamicObject::Section DynamicObject::fini_section() const { return Section(*this, m_fini_offset, sizeof(void (*)()), sizeof(void (*)()), "DT_FINI"); } -const ELFDynamicObject::Section ELFDynamicObject::init_array_section() const +const DynamicObject::Section DynamicObject::init_array_section() const { return Section(*this, m_init_array_offset, m_init_array_size, sizeof(void (*)()), "DT_INIT_ARRAY"); } -const ELFDynamicObject::Section ELFDynamicObject::fini_array_section() const +const DynamicObject::Section DynamicObject::fini_array_section() const { return Section(*this, m_fini_array_offset, m_fini_array_size, sizeof(void (*)()), "DT_FINI_ARRAY"); } -const ELFDynamicObject::HashSection ELFDynamicObject::hash_section() const +const DynamicObject::HashSection DynamicObject::hash_section() const { return HashSection(Section(*this, m_hash_table_offset, 0, 0, "DT_HASH"), HashType::SYSV); } -const ELFDynamicObject::RelocationSection ELFDynamicObject::relocation_section() const +const DynamicObject::RelocationSection DynamicObject::relocation_section() const { return RelocationSection(Section(*this, m_relocation_table_offset, m_size_of_relocation_table, m_size_of_relocation_entry, "DT_REL")); } -const ELFDynamicObject::RelocationSection ELFDynamicObject::plt_relocation_section() const +const DynamicObject::RelocationSection DynamicObject::plt_relocation_section() const { return RelocationSection(Section(*this, m_plt_relocation_offset_location, m_size_of_plt_relocation_entry_list, m_size_of_relocation_entry, "DT_JMPREL")); } -u32 ELFDynamicObject::HashSection::calculate_elf_hash(const char* name) const +u32 DynamicObject::HashSection::calculate_elf_hash(const char* name) const { // SYSV ELF hash algorithm // Note that the GNU HASH algorithm has less collisions @@ -226,13 +228,13 @@ u32 ELFDynamicObject::HashSection::calculate_elf_hash(const char* name) const return hash; } -u32 ELFDynamicObject::HashSection::calculate_gnu_hash(const char*) const +u32 DynamicObject::HashSection::calculate_gnu_hash(const char*) const { // FIXME: Implement the GNU hash algorithm ASSERT_NOT_REACHED(); } -const ELFDynamicObject::Symbol ELFDynamicObject::HashSection::lookup_symbol(const char* name) const +const DynamicObject::Symbol DynamicObject::HashSection::lookup_symbol(const char* name) const { // FIXME: If we enable gnu hash in the compiler, we should use that here instead // The algo is way better with less collisions @@ -262,7 +264,7 @@ const ELFDynamicObject::Symbol ELFDynamicObject::HashSection::lookup_symbol(cons return m_dynamic.the_undefined_symbol(); } -const char* ELFDynamicObject::symbol_string_table_string(Elf32_Word index) const +const char* DynamicObject::symbol_string_table_string(Elf32_Word index) const { return (const char*)base_address().offset(m_string_table_offset + index).as_ptr(); } @@ -358,3 +360,5 @@ static const char* name_for_dtag(Elf32_Sword d_tag) return "??"; } } + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFDynamicObject.h b/Libraries/LibELF/DynamicObject.h index 8618d721d0..d37869e4f9 100644 --- a/Libraries/LibELF/ELFDynamicObject.h +++ b/Libraries/LibELF/DynamicObject.h @@ -30,10 +30,12 @@ #include <LibBareMetal/Memory/VirtualAddress.h> #include <LibELF/exec_elf.h> -class ELFDynamicObject { +namespace ELF { + +class DynamicObject { public: - explicit ELFDynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address); - ~ELFDynamicObject(); + explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address); + ~DynamicObject(); void dump() const; class DynamicEntry; @@ -62,7 +64,7 @@ public: class Symbol { public: - Symbol(const ELFDynamicObject& dynamic, unsigned index, const Elf32_Sym& sym) + Symbol(const DynamicObject& dynamic, unsigned index, const Elf32_Sym& sym) : m_dynamic(dynamic) , m_sym(sym) , m_index(index) @@ -82,14 +84,14 @@ public: VirtualAddress address() const { return m_dynamic.base_address().offset(value()); } private: - const ELFDynamicObject& m_dynamic; + const DynamicObject& m_dynamic; const Elf32_Sym& m_sym; const unsigned m_index; }; class Section { public: - Section(const ELFDynamicObject& 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 char* name) : m_dynamic(dynamic) , m_section_offset(section_offset) , m_section_size_bytes(section_size_bytes) @@ -109,7 +111,7 @@ public: protected: friend class RelocationSection; friend class HashSection; - const ELFDynamicObject& m_dynamic; + const DynamicObject& m_dynamic; unsigned m_section_offset; unsigned m_section_size_bytes; unsigned m_entry_size; @@ -131,7 +133,7 @@ public: class Relocation { public: - Relocation(const ELFDynamicObject& dynamic, const Elf32_Rel& rel, unsigned offset_in_section) + Relocation(const DynamicObject& dynamic, const Elf32_Rel& rel, unsigned offset_in_section) : m_dynamic(dynamic) , m_rel(rel) , m_offset_in_section(offset_in_section) @@ -148,7 +150,7 @@ public: VirtualAddress address() const { return m_dynamic.base_address().offset(offset()); } private: - const ELFDynamicObject& m_dynamic; + const DynamicObject& m_dynamic; const Elf32_Rel& m_rel; const unsigned m_offset_in_section; }; @@ -261,7 +263,7 @@ private: }; template<typename F> -inline void ELFDynamicObject::RelocationSection::for_each_relocation(F func) const +inline void DynamicObject::RelocationSection::for_each_relocation(F func) const { for (unsigned i = 0; i < relocation_count(); ++i) { if (func(relocation(i)) == IterationDecision::Break) @@ -270,7 +272,7 @@ inline void ELFDynamicObject::RelocationSection::for_each_relocation(F func) con } template<typename F> -inline void ELFDynamicObject::for_each_symbol(F func) const +inline void DynamicObject::for_each_symbol(F func) const { for (unsigned i = 0; i < symbol_count(); ++i) { if (func(symbol(i)) == IterationDecision::Break) @@ -279,7 +281,7 @@ inline void ELFDynamicObject::for_each_symbol(F func) const } template<typename F> -inline void ELFDynamicObject::for_each_dynamic_entry(F func) const +inline void DynamicObject::for_each_dynamic_entry(F func) const { auto* dyns = reinterpret_cast<const Elf32_Dyn*>(m_dynamic_address.as_ptr()); for (unsigned i = 0;; ++i) { @@ -290,3 +292,5 @@ inline void ELFDynamicObject::for_each_dynamic_entry(F func) const break; } } + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFImage.cpp b/Libraries/LibELF/Image.cpp index 6ae75963fd..c265e3a9b8 100644 --- a/Libraries/LibELF/ELFImage.cpp +++ b/Libraries/LibELF/Image.cpp @@ -27,16 +27,18 @@ #include <AK/Memory.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> -#include <LibELF/ELFImage.h> +#include <LibELF/Image.h> -ELFImage::ELFImage(const u8* buffer, size_t size) +namespace ELF { + +Image::Image(const u8* buffer, size_t size) : m_buffer(buffer) , m_size(size) { m_valid = parse(); } -ELFImage::~ELFImage() +Image::~Image() { } @@ -58,7 +60,7 @@ static const char* object_file_type_to_string(Elf32_Half type) } } -StringView ELFImage::section_index_to_string(unsigned index) const +StringView Image::section_index_to_string(unsigned index) const { if (index == SHN_UNDEF) return "Undefined"; @@ -67,14 +69,14 @@ StringView ELFImage::section_index_to_string(unsigned index) const return section(index).name(); } -unsigned ELFImage::symbol_count() const +unsigned Image::symbol_count() const { return section(m_symbol_table_section_index).entry_count(); } -void ELFImage::dump() const +void Image::dump() const { - dbgprintf("ELFImage{%p} {\n", this); + dbgprintf("Image{%p} {\n", this); dbgprintf(" is_valid: %u\n", is_valid()); if (!is_valid()) { @@ -124,20 +126,20 @@ void ELFImage::dump() const dbgprintf("}\n"); } -unsigned ELFImage::section_count() const +unsigned Image::section_count() const { return header().e_shnum; } -unsigned ELFImage::program_header_count() const +unsigned Image::program_header_count() const { return header().e_phnum; } -bool ELFImage::parse() +bool Image::parse() { if (!validate_elf_header(header(), m_size)) { - dbgputstr("ELFImage::parse(): ELF Header not valid\n"); + dbgputstr("Image::parse(): ELF Header not valid\n"); return false; } @@ -163,14 +165,14 @@ bool ELFImage::parse() return true; } -StringView ELFImage::table_string(unsigned table_index, unsigned offset) const +StringView Image::table_string(unsigned table_index, unsigned offset) const { auto& sh = section_header(table_index); if (sh.sh_type != SHT_STRTAB) return nullptr; size_t computed_offset = sh.sh_offset + offset; if (computed_offset >= m_size) { - dbgprintf("SHENANIGANS! ELFImage::table_string() computed offset outside image.\n"); + dbgprintf("SHENANIGANS! Image::table_string() computed offset outside image.\n"); return {}; } size_t max_length = m_size - computed_offset; @@ -178,65 +180,65 @@ StringView ELFImage::table_string(unsigned table_index, unsigned offset) const return { raw_data(sh.sh_offset + offset), length }; } -StringView ELFImage::section_header_table_string(unsigned offset) const +StringView Image::section_header_table_string(unsigned offset) const { return table_string(header().e_shstrndx, offset); } -StringView ELFImage::table_string(unsigned offset) const +StringView Image::table_string(unsigned offset) const { return table_string(m_string_table_section_index, offset); } -const char* ELFImage::raw_data(unsigned offset) const +const char* Image::raw_data(unsigned offset) const { return reinterpret_cast<const char*>(m_buffer) + offset; } -const Elf32_Ehdr& ELFImage::header() const +const Elf32_Ehdr& Image::header() const { return *reinterpret_cast<const Elf32_Ehdr*>(raw_data(0)); } -const Elf32_Phdr& ELFImage::program_header_internal(unsigned index) const +const Elf32_Phdr& Image::program_header_internal(unsigned index) const { ASSERT(index < header().e_phnum); return *reinterpret_cast<const Elf32_Phdr*>(raw_data(header().e_phoff + (index * sizeof(Elf32_Phdr)))); } -const Elf32_Shdr& ELFImage::section_header(unsigned index) const +const Elf32_Shdr& Image::section_header(unsigned index) const { ASSERT(index < header().e_shnum); return *reinterpret_cast<const Elf32_Shdr*>(raw_data(header().e_shoff + (index * header().e_shentsize))); } -const ELFImage::Symbol ELFImage::symbol(unsigned index) const +const Image::Symbol Image::symbol(unsigned index) const { ASSERT(index < symbol_count()); auto* raw_syms = reinterpret_cast<const Elf32_Sym*>(raw_data(section(m_symbol_table_section_index).offset())); return Symbol(*this, index, raw_syms[index]); } -const ELFImage::Section ELFImage::section(unsigned index) const +const Image::Section Image::section(unsigned index) const { ASSERT(index < section_count()); return Section(*this, index); } -const ELFImage::ProgramHeader ELFImage::program_header(unsigned index) const +const Image::ProgramHeader Image::program_header(unsigned index) const { ASSERT(index < program_header_count()); return ProgramHeader(*this, index); } -const ELFImage::Relocation ELFImage::RelocationSection::relocation(unsigned index) const +const Image::Relocation Image::RelocationSection::relocation(unsigned index) const { ASSERT(index < relocation_count()); auto* rels = reinterpret_cast<const Elf32_Rel*>(m_image.raw_data(offset())); return Relocation(m_image, rels[index]); } -const ELFImage::RelocationSection ELFImage::Section::relocations() const +const Image::RelocationSection Image::Section::relocations() const { StringBuilder builder; builder.append(".rel"); @@ -246,20 +248,20 @@ const ELFImage::RelocationSection ELFImage::Section::relocations() const if (relocation_section.type() != SHT_REL) return static_cast<const RelocationSection>(m_image.section(0)); -#ifdef ELFIMAGE_DEBUG +#ifdef Image_DEBUG dbgprintf("Found relocations for %s in %s\n", name(), relocation_section.name()); #endif return static_cast<const RelocationSection>(relocation_section); } -const ELFImage::Section ELFImage::lookup_section(const String& name) const +const Image::Section Image::lookup_section(const String& name) const { if (auto it = m_sections.find(name); it != m_sections.end()) return section((*it).value); return section(0); } -bool ELFImage::validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_size) +bool Image::validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_size) { if (!IS_ELF(elf_header)) { dbgputstr("File is not an ELF file.\n"); @@ -358,7 +360,7 @@ bool ELFImage::validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_siz return true; } -bool ELFImage::validate_program_headers(const Elf32_Ehdr& elf_header, size_t file_size, u8* buffer, size_t buffer_size, String& interpreter_path) +bool Image::validate_program_headers(const Elf32_Ehdr& elf_header, size_t file_size, u8* buffer, size_t buffer_size, String& interpreter_path) { // Can we actually parse all the program headers in the given buffer? size_t end_of_last_program_header = elf_header.e_phoff + (elf_header.e_phnum * elf_header.e_phentsize); @@ -414,8 +416,10 @@ bool ELFImage::validate_program_headers(const Elf32_Ehdr& elf_header, size_t fil return true; } -StringView ELFImage::Symbol::raw_data() const +StringView Image::Symbol::raw_data() const { auto& section = this->section(); return { section.raw_data() + (value() - section.address()), size() }; } + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFImage.h b/Libraries/LibELF/Image.h index 61f912079d..7d0df2813a 100644 --- a/Libraries/LibELF/ELFImage.h +++ b/Libraries/LibELF/Image.h @@ -32,10 +32,12 @@ #include <LibBareMetal/Memory/VirtualAddress.h> #include <LibELF/exec_elf.h> -class ELFImage { +namespace ELF { + +class Image { public: - explicit ELFImage(const u8*, size_t); - ~ELFImage(); + explicit Image(const u8*, size_t); + ~Image(); void dump() const; bool is_valid() const { return m_valid; } bool parse(); @@ -56,7 +58,7 @@ public: class Symbol { public: - Symbol(const ELFImage& image, unsigned index, const Elf32_Sym& sym) + Symbol(const Image& image, unsigned index, const Elf32_Sym& sym) : m_image(image) , m_sym(sym) , m_index(index) @@ -76,14 +78,14 @@ public: StringView raw_data() const; private: - const ELFImage& m_image; + const Image& m_image; const Elf32_Sym& m_sym; const unsigned m_index; }; class ProgramHeader { public: - ProgramHeader(const ELFImage& image, unsigned program_header_index) + ProgramHeader(const Image& image, unsigned program_header_index) : m_image(image) , m_program_header(image.program_header_internal(program_header_index)) , m_program_header_index(program_header_index) @@ -106,14 +108,14 @@ public: Elf32_Phdr raw_header() const { return m_program_header; } private: - const ELFImage& m_image; + const Image& m_image; const Elf32_Phdr& m_program_header; unsigned m_program_header_index { 0 }; }; class Section { public: - Section(const ELFImage& image, unsigned sectionIndex) + Section(const Image& image, unsigned sectionIndex) : m_image(image) , m_section_header(image.section_header(sectionIndex)) , m_section_index(sectionIndex) @@ -137,7 +139,7 @@ public: protected: friend class RelocationSection; - const ELFImage& m_image; + const Image& m_image; const Elf32_Shdr& m_section_header; unsigned m_section_index; }; @@ -156,7 +158,7 @@ public: class Relocation { public: - Relocation(const ELFImage& image, const Elf32_Rel& rel) + Relocation(const Image& image, const Elf32_Rel& rel) : m_image(image) , m_rel(rel) { @@ -170,7 +172,7 @@ public: const Symbol symbol() const { return m_image.symbol(symbol_index()); } private: - const ELFImage& m_image; + const Image& m_image; const Elf32_Rel& m_rel; }; @@ -224,7 +226,7 @@ private: }; template<typename F> -inline void ELFImage::for_each_section(F func) const +inline void Image::for_each_section(F func) const { auto section_count = this->section_count(); for (unsigned i = 0; i < section_count; ++i) @@ -232,7 +234,7 @@ inline void ELFImage::for_each_section(F func) const } template<typename F> -inline void ELFImage::for_each_section_of_type(unsigned type, F func) const +inline void Image::for_each_section_of_type(unsigned type, F func) const { auto section_count = this->section_count(); for (unsigned i = 0; i < section_count; ++i) { @@ -245,7 +247,7 @@ inline void ELFImage::for_each_section_of_type(unsigned type, F func) const } template<typename F> -inline void ELFImage::RelocationSection::for_each_relocation(F func) const +inline void Image::RelocationSection::for_each_relocation(F func) const { auto relocation_count = this->relocation_count(); for (unsigned i = 0; i < relocation_count; ++i) { @@ -255,7 +257,7 @@ inline void ELFImage::RelocationSection::for_each_relocation(F func) const } template<typename F> -inline void ELFImage::for_each_symbol(F func) const +inline void Image::for_each_symbol(F func) const { auto symbol_count = this->symbol_count(); for (unsigned i = 0; i < symbol_count; ++i) { @@ -265,9 +267,11 @@ inline void ELFImage::for_each_symbol(F func) const } template<typename F> -inline void ELFImage::for_each_program_header(F func) const +inline void Image::for_each_program_header(F func) const { auto program_header_count = this->program_header_count(); for (unsigned i = 0; i < program_header_count; ++i) func(program_header(i)); } + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFLoader.cpp b/Libraries/LibELF/Loader.cpp index 27c5cd0bed..39a50a9fb2 100644 --- a/Libraries/LibELF/ELFLoader.cpp +++ b/Libraries/LibELF/Loader.cpp @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "ELFLoader.h" +#include "Loader.h" #include <AK/Demangle.h> #include <AK/Memory.h> #include <AK/QuickSort.h> @@ -36,21 +36,23 @@ # define do_memcpy memcpy #endif -//#define ELFLOADER_DEBUG +//#define Loader_DEBUG -ELFLoader::ELFLoader(const u8* buffer, size_t size) +namespace ELF { + +Loader::Loader(const u8* buffer, size_t size) : m_image(buffer, size) { m_symbol_count = m_image.symbol_count(); } -ELFLoader::~ELFLoader() +Loader::~Loader() { } -bool ELFLoader::load() +bool Loader::load() { -#ifdef ELFLOADER_DEBUG +#ifdef Loader_DEBUG m_image.dump(); #endif if (!m_image.is_valid()) @@ -62,10 +64,10 @@ bool ELFLoader::load() return true; } -bool ELFLoader::layout() +bool Loader::layout() { bool failed = false; - m_image.for_each_program_header([&](const ELFImage::ProgramHeader& program_header) { + m_image.for_each_program_header([&](const Image::ProgramHeader& program_header) { if (program_header.type() == PT_TLS) { #ifdef KERNEL auto* tls_image = tls_section_hook(program_header.size_in_memory(), program_header.alignment()); @@ -84,7 +86,7 @@ bool ELFLoader::layout() } if (program_header.type() != PT_LOAD) return; -#ifdef ELFLOADER_DEBUG +#ifdef Loader_DEBUG kprintf("PH: V%p %u r:%u w:%u\n", program_header.vaddr().get(), program_header.size_in_memory(), program_header.is_readable(), program_header.is_writable()); #endif #ifdef KERNEL @@ -134,10 +136,10 @@ bool ELFLoader::layout() return !failed; } -char* ELFLoader::symbol_ptr(const char* name) +char* Loader::symbol_ptr(const char* name) { char* found_ptr = nullptr; - m_image.for_each_symbol([&](const ELFImage::Symbol symbol) { + m_image.for_each_symbol([&](const Image::Symbol symbol) { if (symbol.type() != STT_FUNC) return IterationDecision::Continue; if (symbol.name() == name) @@ -152,7 +154,7 @@ char* ELFLoader::symbol_ptr(const char* name) } #ifndef KERNEL -Optional<ELFImage::Symbol> ELFLoader::find_symbol(u32 address, u32* out_offset) const +Optional<Image::Symbol> Loader::find_symbol(u32 address, u32* out_offset) const { if (!m_symbol_count) return {}; @@ -201,7 +203,7 @@ Optional<ELFImage::Symbol> ELFLoader::find_symbol(u32 address, u32* out_offset) } #endif -String ELFLoader::symbolicate(u32 address, u32* out_offset) const +String Loader::symbolicate(u32 address, u32* out_offset) const { if (!m_symbol_count) { if (out_offset) @@ -266,3 +268,5 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const *out_offset = 0; return "??"; } + +} // end namespace ELF diff --git a/Libraries/LibELF/ELFLoader.h b/Libraries/LibELF/Loader.h index 49fe5ad414..394ceeafab 100644 --- a/Libraries/LibELF/ELFLoader.h +++ b/Libraries/LibELF/Loader.h @@ -31,7 +31,7 @@ #include <AK/OwnPtr.h> #include <AK/StringView.h> #include <AK/Vector.h> -#include <LibELF/ELFImage.h> +#include <LibELF/Image.h> #ifdef KERNEL # include <LibBareMetal/Memory/VirtualAddress.h> @@ -40,10 +40,12 @@ class Region; } #endif -class ELFLoader { +namespace ELF { + +class Loader { public: - explicit ELFLoader(const u8*, size_t); - ~ELFLoader(); + explicit Loader(const u8*, size_t); + ~Loader(); bool load(); #if defined(KERNEL) @@ -57,13 +59,13 @@ public: bool has_symbols() const { return m_symbol_count; } String symbolicate(u32 address, u32* offset = nullptr) const; - Optional<ELFImage::Symbol> find_symbol(u32 address, u32* offset = nullptr) const; + Optional<Image::Symbol> find_symbol(u32 address, u32* offset = nullptr) const; private: bool layout(); bool perform_relocations(); - void* lookup(const ELFImage::Symbol&); - char* area_for_section(const ELFImage::Section&); + void* lookup(const ELF::Image::Symbol&); + char* area_for_section(const ELF::Image::Section&); char* area_for_section_name(const char*); struct PtrAndSize { @@ -77,7 +79,7 @@ private: char* ptr { nullptr }; unsigned size { 0 }; }; - ELFImage m_image; + Image m_image; size_t m_symbol_count { 0 }; @@ -86,7 +88,7 @@ private: StringView name; #ifndef KERNEL String demangled_name; - Optional<ELFImage::Symbol> symbol; + Optional<Image::Symbol> symbol; #endif }; #ifdef KERNEL @@ -95,3 +97,5 @@ private: mutable Vector<SortedSymbol> m_sorted_symbols; #endif }; + +} // end namespace ELF |