Explorar o código

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.
Valtteri Koskivuori %!s(int64=3) %!d(string=hai) anos
pai
achega
d1adf5bc5e

+ 85 - 21
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::Section> Image::lookup_section(const StringView& name) const
     return {};
 }
 
+Optional<StringView> 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<StringView> 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<StringView> 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();

+ 4 - 0
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<StringView> object_file_type_to_string(ElfW(Half) type);
+    static Optional<StringView> object_machine_type_to_string(ElfW(Half) type);
+    static Optional<StringView> object_abi_type_to_string(Elf_Byte type);
+
     bool has_symbols() const { return symbol_count(); }
 #ifndef KERNEL
     Optional<Symbol> find_demangled_function(const StringView& name) const;

+ 4 - 50
Userland/Utilities/readelf.cpp

@@ -19,52 +19,6 @@
 #include <stdio.h>
 #include <unistd.h>
 
-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();
     }