From d1adf5bc5e528d44e61c16a8ce379f1c25e7396b Mon Sep 17 00:00:00 2001 From: Valtteri Koskivuori Date: Mon, 18 Oct 2021 02:16:33 +0300 Subject: [PATCH] LibELF+Userland: Move a few functions to Elf::Image These were originally in `readelf`, but they became useful in `file` as well, so they are now available in Elf::Image with a slightly revised API. --- Userland/Libraries/LibELF/Image.cpp | 106 ++++++++++++++++++++++------ Userland/Libraries/LibELF/Image.h | 4 ++ Userland/Utilities/readelf.cpp | 54 ++------------ 3 files changed, 93 insertions(+), 71 deletions(-) diff --git a/Userland/Libraries/LibELF/Image.cpp b/Userland/Libraries/LibELF/Image.cpp index e8f30776dad..7bea64a6966 100644 --- a/Userland/Libraries/LibELF/Image.cpp +++ b/Userland/Libraries/LibELF/Image.cpp @@ -34,26 +34,6 @@ Image::~Image() { } -#if ELF_IMAGE_DEBUG -static const char* object_file_type_to_string(ElfW(Half) type) -{ - switch (type) { - case ET_NONE: - return "None"; - case ET_REL: - return "Relocatable"; - case ET_EXEC: - return "Executable"; - case ET_DYN: - return "Shared object"; - case ET_CORE: - return "Core"; - default: - return "(?)"; - } -} -#endif - StringView Image::section_index_to_string(unsigned index) const { VERIFY(m_valid); @@ -83,7 +63,7 @@ void Image::dump() const return; } - dbgln(" type: {}", object_file_type_to_string(header().e_type)); + dbgln(" type: {}", ELF::Image::object_file_type_to_string(header().e_type).value_or("(?)")); dbgln(" machine: {}", header().e_machine); dbgln(" entry: {:x}", header().e_entry); dbgln(" shoff: {}", header().e_shoff); @@ -283,6 +263,90 @@ Optional Image::lookup_section(const StringView& name) const return {}; } +Optional Image::object_file_type_to_string(ElfW(Half) type) +{ + switch (type) { + case ET_NONE: + return "None"sv; + case ET_REL: + return "Relocatable"sv; + case ET_EXEC: + return "Executable"sv; + case ET_DYN: + return "Shared object"sv; + case ET_CORE: + return "Core"sv; + default: + return {}; + } +} + +Optional Image::object_machine_type_to_string(ElfW(Half) type) +{ + switch (type) { + case ET_NONE: + return "None"sv; + case EM_M32: + return "AT&T WE 32100"sv; + case EM_SPARC: + return "SPARC"sv; + case EM_386: + return "Intel 80386"sv; + case EM_68K: + return "Motorola 68000"sv; + case EM_88K: + return "Motorola 88000"sv; + case EM_486: + return "Intel 80486"sv; + case EM_860: + return "Intel 80860"sv; + case EM_MIPS: + return "MIPS R3000 Big-Endian only"sv; + case EM_X86_64: + return "Advanced Micro Devices X86-64"sv; + default: + return {}; + } +} + +Optional Image::object_abi_type_to_string(Elf_Byte type) +{ + switch (type) { + case ELFOSABI_SYSV: + return "SYSV"sv; + case ELFOSABI_HPUX: + return "HP-UX"sv; + case ELFOSABI_NETBSD: + return "NetBSD"sv; + case ELFOSABI_LINUX: + return "Linux"sv; + case ELFOSABI_HURD: + return "GNU Hurd"sv; + case ELFOSABI_86OPEN: + return "86Open"sv; + case ELFOSABI_SOLARIS: + return "Solaris"sv; + case ELFOSABI_MONTEREY: + return "AIX"sv; + case ELFOSABI_IRIX: + return "IRIX"sv; + case ELFOSABI_FREEBSD: + return "FreeBSD"sv; + case ELFOSABI_TRU64: + return "Tru64"sv; + case ELFOSABI_MODESTO: + return "Novell Modesto"sv; + case ELFOSABI_OPENBSD: + return "OpenBSD"sv; + case ELFOSABI_ARM: + return "ARM"sv; + case ELFOSABI_STANDALONE: + return "Standalone"sv; + default: + return {}; + } +} + StringView Image::Symbol::raw_data() const { auto section = this->section(); diff --git a/Userland/Libraries/LibELF/Image.h b/Userland/Libraries/LibELF/Image.h index e2cea924228..fb4b06356ff 100644 --- a/Userland/Libraries/LibELF/Image.h +++ b/Userland/Libraries/LibELF/Image.h @@ -227,6 +227,10 @@ public: FlatPtr base_address() const { return (FlatPtr)m_buffer; } size_t size() const { return m_size; } + static Optional object_file_type_to_string(ElfW(Half) type); + static Optional object_machine_type_to_string(ElfW(Half) type); + static Optional object_abi_type_to_string(Elf_Byte type); + bool has_symbols() const { return symbol_count(); } #ifndef KERNEL Optional find_demangled_function(const StringView& name) const; diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp index 7313b2775c1..90a091c9120 100644 --- a/Userland/Utilities/readelf.cpp +++ b/Userland/Utilities/readelf.cpp @@ -19,52 +19,6 @@ #include #include -static const char* object_file_type_to_string(ElfW(Half) type) -{ - switch (type) { - case ET_NONE: - return "None"; - case ET_REL: - return "Relocatable"; - case ET_EXEC: - return "Executable"; - case ET_DYN: - return "Shared object"; - case ET_CORE: - return "Core"; - default: - return "(?)"; - } -} - -static const char* object_machine_type_to_string(ElfW(Half) type) -{ - switch (type) { - case ET_NONE: - return "None"; - case EM_M32: - return "AT&T WE 32100"; - case EM_SPARC: - return "SPARC"; - case EM_386: - return "Intel 80386"; - case EM_68K: - return "Motorola 68000"; - case EM_88K: - return "Motorola 88000"; - case EM_486: - return "Intel 80486"; - case EM_860: - return "Intel 80860"; - case EM_MIPS: - return "MIPS R3000 Big-Endian only"; - case EM_X86_64: - return "Advanced Micro Devices X86-64"; - default: - return "(?)"; - } -} - static const char* object_program_header_type_to_string(ElfW(Word) type) { switch (type) { @@ -414,8 +368,8 @@ int main(int argc, char** argv) } outln(); - outln(" Type: {} ({})", header.e_type, object_file_type_to_string(header.e_type)); - outln(" Machine: {} ({})", header.e_machine, object_machine_type_to_string(header.e_machine)); + outln(" Type: {} ({})", header.e_type, ELF::Image::object_file_type_to_string(header.e_type).value_or("(?)")); + outln(" Machine: {} ({})", header.e_machine, ELF::Image::object_machine_type_to_string(header.e_machine).value_or("(?)")); outln(" Version: {:#x}", header.e_version); outln(" Entry point address: {:#x}", header.e_entry); outln(" Start of program headers: {} (bytes into file)", header.e_phoff); @@ -463,7 +417,7 @@ int main(int argc, char** argv) if (display_program_headers) { if (!display_all) { - outln("ELF file type is {} ({})", header.e_type, object_file_type_to_string(header.e_type)); + outln("ELF file type is {} ({})", header.e_type, ELF::Image::object_file_type_to_string(header.e_type).value_or("(?)")); outln("Entry point {:#x}\n", header.e_entry); outln("There are {} program headers, starting at offset {}", header.e_phnum, header.e_phoff); outln(); @@ -586,7 +540,7 @@ int main(int argc, char** argv) if (display_unwind_info) { // TODO: Unwind info - outln("Decoding of unwind sections for machine type {} is not supported.", object_machine_type_to_string(header.e_machine)); + outln("Decoding of unwind sections for machine type {} is not supported.", ELF::Image::object_machine_type_to_string(header.e_machine).value_or("?")); outln(); }