diff options
| -rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/common/elf.h | 333 | ||||
| -rw-r--r-- | src/core/arm/symbols.cpp | 85 | ||||
| -rw-r--r-- | src/core/hle/service/jit/jit_context.cpp | 32 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 183 | 
5 files changed, 371 insertions, 263 deletions
| diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index adf70eb8b..73bf626d4 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -58,6 +58,7 @@ add_library(common STATIC      div_ceil.h      dynamic_library.cpp      dynamic_library.h +    elf.h      error.cpp      error.h      expected.h diff --git a/src/common/elf.h b/src/common/elf.h new file mode 100644 index 000000000..14a5e9597 --- /dev/null +++ b/src/common/elf.h @@ -0,0 +1,333 @@ +// SPDX-FileCopyrightText: 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <array> +#include <cstddef> + +#include "common_types.h" + +namespace Common { +namespace ELF { + +/* Type for a 16-bit quantity.  */ +using Elf32_Half = u16; +using Elf64_Half = u16; + +/* Types for signed and unsigned 32-bit quantities.  */ +using Elf32_Word = u32; +using Elf32_Sword = s32; +using Elf64_Word = u32; +using Elf64_Sword = s32; + +/* Types for signed and unsigned 64-bit quantities.  */ +using Elf32_Xword = u64; +using Elf32_Sxword = s64; +using Elf64_Xword = u64; +using Elf64_Sxword = s64; + +/* Type of addresses.  */ +using Elf32_Addr = u32; +using Elf64_Addr = u64; + +/* Type of file offsets.  */ +using Elf32_Off = u32; +using Elf64_Off = u64; + +/* Type for section indices, which are 16-bit quantities.  */ +using Elf32_Section = u16; +using Elf64_Section = u16; + +/* Type for version symbol information.  */ +using Elf32_Versym = Elf32_Half; +using Elf64_Versym = Elf64_Half; + +constexpr size_t ElfIdentSize = 16; + +/* The ELF file header.  This appears at the start of every ELF file.  */ + +struct Elf32_Ehdr { +    std::array<u8, ElfIdentSize> e_ident; /* Magic number and other info */ +    Elf32_Half e_type;                    /* Object file type */ +    Elf32_Half e_machine;                 /* Architecture */ +    Elf32_Word e_version;                 /* Object file version */ +    Elf32_Addr e_entry;                   /* Entry point virtual address */ +    Elf32_Off e_phoff;                    /* Program header table file offset */ +    Elf32_Off e_shoff;                    /* Section header table file offset */ +    Elf32_Word e_flags;                   /* Processor-specific flags */ +    Elf32_Half e_ehsize;                  /* ELF header size in bytes */ +    Elf32_Half e_phentsize;               /* Program header table entry size */ +    Elf32_Half e_phnum;                   /* Program header table entry count */ +    Elf32_Half e_shentsize;               /* Section header table entry size */ +    Elf32_Half e_shnum;                   /* Section header table entry count */ +    Elf32_Half e_shstrndx;                /* Section header string table index */ +}; + +struct Elf64_Ehdr { +    std::array<u8, ElfIdentSize> e_ident; /* Magic number and other info */ +    Elf64_Half e_type;                    /* Object file type */ +    Elf64_Half e_machine;                 /* Architecture */ +    Elf64_Word e_version;                 /* Object file version */ +    Elf64_Addr e_entry;                   /* Entry point virtual address */ +    Elf64_Off e_phoff;                    /* Program header table file offset */ +    Elf64_Off e_shoff;                    /* Section header table file offset */ +    Elf64_Word e_flags;                   /* Processor-specific flags */ +    Elf64_Half e_ehsize;                  /* ELF header size in bytes */ +    Elf64_Half e_phentsize;               /* Program header table entry size */ +    Elf64_Half e_phnum;                   /* Program header table entry count */ +    Elf64_Half e_shentsize;               /* Section header table entry size */ +    Elf64_Half e_shnum;                   /* Section header table entry count */ +    Elf64_Half e_shstrndx;                /* Section header string table index */ +}; + +constexpr u8 ElfClass32 = 1;        /* 32-bit objects */ +constexpr u8 ElfClass64 = 2;        /* 64-bit objects */ +constexpr u8 ElfData2Lsb = 1;       /* 2's complement, little endian */ +constexpr u8 ElfVersionCurrent = 1; /* EV_CURRENT */ +constexpr u8 ElfOsAbiNone = 0;      /* System V ABI */ + +constexpr u16 ElfTypeNone = 0; /* No file type */ +constexpr u16 ElfTypeRel = 0;  /* Relocatable file */ +constexpr u16 ElfTypeExec = 0; /* Executable file */ +constexpr u16 ElfTypeDyn = 0;  /* Shared object file */ + +constexpr u16 ElfMachineArm = 40;      /* ARM */ +constexpr u16 ElfMachineAArch64 = 183; /* ARM AARCH64 */ + +constexpr std::array<u8, ElfIdentSize> Elf32Ident{ +    0x7f, 'E', 'L', 'F', ElfClass32, ElfData2Lsb, ElfVersionCurrent, ElfOsAbiNone}; + +constexpr std::array<u8, ElfIdentSize> Elf64Ident{ +    0x7f, 'E', 'L', 'F', ElfClass64, ElfData2Lsb, ElfVersionCurrent, ElfOsAbiNone}; + +/* Section header.  */ + +struct Elf32_Shdr { +    Elf32_Word sh_name;      /* Section name (string tbl index) */ +    Elf32_Word sh_type;      /* Section type */ +    Elf32_Word sh_flags;     /* Section flags */ +    Elf32_Addr sh_addr;      /* Section virtual addr at execution */ +    Elf32_Off sh_offset;     /* Section file offset */ +    Elf32_Word sh_size;      /* Section size in bytes */ +    Elf32_Word sh_link;      /* Link to another section */ +    Elf32_Word sh_info;      /* Additional section information */ +    Elf32_Word sh_addralign; /* Section alignment */ +    Elf32_Word sh_entsize;   /* Entry size if section holds table */ +}; + +struct Elf64_Shdr { +    Elf64_Word sh_name;       /* Section name (string tbl index) */ +    Elf64_Word sh_type;       /* Section type */ +    Elf64_Xword sh_flags;     /* Section flags */ +    Elf64_Addr sh_addr;       /* Section virtual addr at execution */ +    Elf64_Off sh_offset;      /* Section file offset */ +    Elf64_Xword sh_size;      /* Section size in bytes */ +    Elf64_Word sh_link;       /* Link to another section */ +    Elf64_Word sh_info;       /* Additional section information */ +    Elf64_Xword sh_addralign; /* Section alignment */ +    Elf64_Xword sh_entsize;   /* Entry size if section holds table */ +}; + +constexpr u32 ElfShnUndef = 0; /* Undefined section */ + +constexpr u32 ElfShtNull = 0;     /* Section header table entry unused */ +constexpr u32 ElfShtProgBits = 1; /* Program data */ +constexpr u32 ElfShtSymtab = 2;   /* Symbol table */ +constexpr u32 ElfShtStrtab = 3;   /* String table */ +constexpr u32 ElfShtRela = 4;     /* Relocation entries with addends */ +constexpr u32 ElfShtDynamic = 6;  /* Dynamic linking information */ +constexpr u32 ElfShtNobits = 7;   /* Program space with no data (bss) */ +constexpr u32 ElfShtRel = 9;      /* Relocation entries, no addends */ +constexpr u32 ElfShtDynsym = 11;  /* Dynamic linker symbol table */ + +/* Symbol table entry.  */ + +struct Elf32_Sym { +    Elf32_Word st_name;     /* Symbol name (string tbl index) */ +    Elf32_Addr st_value;    /* Symbol value */ +    Elf32_Word st_size;     /* Symbol size */ +    u8 st_info;             /* Symbol type and binding */ +    u8 st_other;            /* Symbol visibility */ +    Elf32_Section st_shndx; /* Section index */ +}; + +struct Elf64_Sym { +    Elf64_Word st_name;     /* Symbol name (string tbl index) */ +    u8 st_info;             /* Symbol type and binding */ +    u8 st_other;            /* Symbol visibility */ +    Elf64_Section st_shndx; /* Section index */ +    Elf64_Addr st_value;    /* Symbol value */ +    Elf64_Xword st_size;    /* Symbol size */ +}; + +/* How to extract and insert information held in the st_info field.  */ + +static inline u8 ElfStBind(u8 st_info) { +    return st_info >> 4; +} +static inline u8 ElfStType(u8 st_info) { +    return st_info & 0xf; +} +static inline u8 ElfStInfo(u8 st_bind, u8 st_type) { +    return static_cast<u8>((st_bind << 4) + (st_type & 0xf)); +} + +constexpr u8 ElfBindLocal = 0;  /* Local symbol */ +constexpr u8 ElfBindGlobal = 1; /* Global symbol */ +constexpr u8 ElfBindWeak = 2;   /* Weak symbol */ + +constexpr u8 ElfTypeUnspec = 0; /* Symbol type is unspecified */ +constexpr u8 ElfTypeObject = 1; /* Symbol is a data object */ +constexpr u8 ElfTypeFunc = 2;   /* Symbol is a code object */ + +static inline u8 ElfStVisibility(u8 st_other) { +    return static_cast<u8>(st_other & 0x3); +} + +constexpr u8 ElfVisibilityDefault = 0;   /* Default symbol visibility rules */ +constexpr u8 ElfVisibilityInternal = 1;  /* Processor specific hidden class */ +constexpr u8 ElfVisibilityHidden = 2;    /* Sym unavailable in other modules */ +constexpr u8 ElfVisibilityProtected = 3; /* Not preemptible, not exported */ + +/* Relocation table entry without addend (in section of type ShtRel).  */ + +struct Elf32_Rel { +    Elf32_Addr r_offset; /* Address */ +    Elf32_Word r_info;   /* Relocation type and symbol index */ +}; + +/* Relocation table entry with addend (in section of type ShtRela).  */ + +struct Elf32_Rela { +    Elf32_Addr r_offset;  /* Address */ +    Elf32_Word r_info;    /* Relocation type and symbol index */ +    Elf32_Sword r_addend; /* Addend */ +}; + +struct Elf64_Rela { +    Elf64_Addr r_offset;   /* Address */ +    Elf64_Xword r_info;    /* Relocation type and symbol index */ +    Elf64_Sxword r_addend; /* Addend */ +}; + +/* How to extract and insert information held in the r_info field.  */ + +static inline u32 Elf32RelSymIndex(Elf32_Word r_info) { +    return r_info >> 8; +} +static inline u8 Elf32RelType(Elf32_Word r_info) { +    return static_cast<u8>(r_info & 0xff); +} +static inline Elf32_Word Elf32RelInfo(u32 sym_index, u8 type) { +    return (sym_index << 8) + type; +} +static inline u32 Elf64RelSymIndex(Elf64_Xword r_info) { +    return static_cast<u32>(r_info >> 32); +} +static inline u32 Elf64RelType(Elf64_Xword r_info) { +    return r_info & 0xffffffff; +} +static inline Elf64_Xword Elf64RelInfo(u32 sym_index, u32 type) { +    return (static_cast<Elf64_Xword>(sym_index) << 32) + type; +} + +constexpr u32 ElfArmCopy = 20;     /* Copy symbol at runtime */ +constexpr u32 ElfArmGlobDat = 21;  /* Create GOT entry */ +constexpr u32 ElfArmJumpSlot = 22; /* Create PLT entry */ +constexpr u32 ElfArmRelative = 23; /* Adjust by program base */ + +constexpr u32 ElfAArch64Copy = 1024;     /* Copy symbol at runtime */ +constexpr u32 ElfAArch64GlobDat = 1025;  /* Create GOT entry */ +constexpr u32 ElfAArch64JumpSlot = 1026; /* Create PLT entry */ +constexpr u32 ElfAArch64Relative = 1027; /* Adjust by program base */ + +/* Program segment header.  */ + +struct Elf32_Phdr { +    Elf32_Word p_type;   /* Segment type */ +    Elf32_Off p_offset;  /* Segment file offset */ +    Elf32_Addr p_vaddr;  /* Segment virtual address */ +    Elf32_Addr p_paddr;  /* Segment physical address */ +    Elf32_Word p_filesz; /* Segment size in file */ +    Elf32_Word p_memsz;  /* Segment size in memory */ +    Elf32_Word p_flags;  /* Segment flags */ +    Elf32_Word p_align;  /* Segment alignment */ +}; + +struct Elf64_Phdr { +    Elf64_Word p_type;    /* Segment type */ +    Elf64_Word p_flags;   /* Segment flags */ +    Elf64_Off p_offset;   /* Segment file offset */ +    Elf64_Addr p_vaddr;   /* Segment virtual address */ +    Elf64_Addr p_paddr;   /* Segment physical address */ +    Elf64_Xword p_filesz; /* Segment size in file */ +    Elf64_Xword p_memsz;  /* Segment size in memory */ +    Elf64_Xword p_align;  /* Segment alignment */ +}; + +/* Legal values for p_type (segment type).  */ + +constexpr u32 ElfPtNull = 0;    /* Program header table entry unused */ +constexpr u32 ElfPtLoad = 1;    /* Loadable program segment */ +constexpr u32 ElfPtDynamic = 2; /* Dynamic linking information */ +constexpr u32 ElfPtInterp = 3;  /* Program interpreter */ +constexpr u32 ElfPtNote = 4;    /* Auxiliary information */ +constexpr u32 ElfPtPhdr = 6;    /* Entry for header table itself */ +constexpr u32 ElfPtTls = 7;     /* Thread-local storage segment */ + +/* Legal values for p_flags (segment flags).  */ + +constexpr u32 ElfPfExec = 0;  /* Segment is executable */ +constexpr u32 ElfPfWrite = 1; /* Segment is writable */ +constexpr u32 ElfPfRead = 2;  /* Segment is readable */ + +/* Dynamic section entry.  */ + +struct Elf32_Dyn { +    Elf32_Sword d_tag; /* Dynamic entry type */ +    union { +        Elf32_Word d_val; /* Integer value */ +        Elf32_Addr d_ptr; /* Address value */ +    } d_un; +}; + +struct Elf64_Dyn { +    Elf64_Sxword d_tag; /* Dynamic entry type */ +    union { +        Elf64_Xword d_val; /* Integer value */ +        Elf64_Addr d_ptr;  /* Address value */ +    } d_un; +}; + +/* Legal values for d_tag (dynamic entry type).  */ + +constexpr u32 ElfDtNull = 0;         /* Marks end of dynamic section */ +constexpr u32 ElfDtNeeded = 1;       /* Name of needed library */ +constexpr u32 ElfDtPltRelSz = 2;     /* Size in bytes of PLT relocs */ +constexpr u32 ElfDtPltGot = 3;       /* Processor defined value */ +constexpr u32 ElfDtHash = 4;         /* Address of symbol hash table */ +constexpr u32 ElfDtStrtab = 5;       /* Address of string table */ +constexpr u32 ElfDtSymtab = 6;       /* Address of symbol table */ +constexpr u32 ElfDtRela = 7;         /* Address of Rela relocs */ +constexpr u32 ElfDtRelasz = 8;       /* Total size of Rela relocs */ +constexpr u32 ElfDtRelaent = 9;      /* Size of one Rela reloc */ +constexpr u32 ElfDtStrsz = 10;       /* Size of string table */ +constexpr u32 ElfDtSyment = 11;      /* Size of one symbol table entry */ +constexpr u32 ElfDtInit = 12;        /* Address of init function */ +constexpr u32 ElfDtFini = 13;        /* Address of termination function */ +constexpr u32 ElfDtRel = 17;         /* Address of Rel relocs */ +constexpr u32 ElfDtRelsz = 18;       /* Total size of Rel relocs */ +constexpr u32 ElfDtRelent = 19;      /* Size of one Rel reloc */ +constexpr u32 ElfDtPltRel = 20;      /* Type of reloc in PLT */ +constexpr u32 ElfDtTextRel = 22;     /* Reloc might modify .text */ +constexpr u32 ElfDtJmpRel = 23;      /* Address of PLT relocs */ +constexpr u32 ElfDtBindNow = 24;     /* Process relocations of object */ +constexpr u32 ElfDtInitArray = 25;   /* Array with addresses of init fct */ +constexpr u32 ElfDtFiniArray = 26;   /* Array with addresses of fini fct */ +constexpr u32 ElfDtInitArraySz = 27; /* Size in bytes of DT_INIT_ARRAY */ +constexpr u32 ElfDtFiniArraySz = 28; /* Size in bytes of DT_FINI_ARRAY */ +constexpr u32 ElfDtSymtabShndx = 34; /* Address of SYMTAB_SHNDX section */ + +} // namespace ELF +} // namespace Common diff --git a/src/core/arm/symbols.cpp b/src/core/arm/symbols.cpp index 4aa1a1ee1..0259c7ea2 100644 --- a/src/core/arm/symbols.cpp +++ b/src/core/arm/symbols.cpp @@ -3,73 +3,14 @@  #include "common/bit_field.h"  #include "common/common_funcs.h" +#include "common/elf.h"  #include "core/arm/symbols.h"  #include "core/core.h"  #include "core/memory.h" -namespace Core { -namespace { - -constexpr u64 ELF_DYNAMIC_TAG_NULL = 0; -constexpr u64 ELF_DYNAMIC_TAG_STRTAB = 5; -constexpr u64 ELF_DYNAMIC_TAG_SYMTAB = 6; -constexpr u64 ELF_DYNAMIC_TAG_SYMENT = 11; - -enum class ELFSymbolType : u8 { -    None = 0, -    Object = 1, -    Function = 2, -    Section = 3, -    File = 4, -    Common = 5, -    TLS = 6, -}; - -enum class ELFSymbolBinding : u8 { -    Local = 0, -    Global = 1, -    Weak = 2, -}; - -enum class ELFSymbolVisibility : u8 { -    Default = 0, -    Internal = 1, -    Hidden = 2, -    Protected = 3, -}; - -struct ELF64Symbol { -    u32 name_index; -    union { -        u8 info; - -        BitField<0, 4, ELFSymbolType> type; -        BitField<4, 4, ELFSymbolBinding> binding; -    }; -    ELFSymbolVisibility visibility; -    u16 sh_index; -    u64 value; -    u64 size; -}; -static_assert(sizeof(ELF64Symbol) == 0x18, "ELF64Symbol has incorrect size."); - -struct ELF32Symbol { -    u32 name_index; -    u32 value; -    u32 size; -    union { -        u8 info; - -        BitField<0, 4, ELFSymbolType> type; -        BitField<4, 4, ELFSymbolBinding> binding; -    }; -    ELFSymbolVisibility visibility; -    u16 sh_index; -}; -static_assert(sizeof(ELF32Symbol) == 0x10, "ELF32Symbol has incorrect size."); - -} // Anonymous namespace +using namespace Common::ELF; +namespace Core {  namespace Symbols {  template <typename Word, typename ELFSymbol, typename ByteReader> @@ -110,15 +51,15 @@ static Symbols GetSymbols(ByteReader ReadBytes) {          const Word value = ReadWord(dynamic_index + sizeof(Word));          dynamic_index += 2 * sizeof(Word); -        if (tag == ELF_DYNAMIC_TAG_NULL) { +        if (tag == ElfDtNull) {              break;          } -        if (tag == ELF_DYNAMIC_TAG_STRTAB) { +        if (tag == ElfDtStrtab) {              string_table_offset = value; -        } else if (tag == ELF_DYNAMIC_TAG_SYMTAB) { +        } else if (tag == ElfDtSymtab) {              symbol_table_offset = value; -        } else if (tag == ELF_DYNAMIC_TAG_SYMENT) { +        } else if (tag == ElfDtSyment) {              symbol_entry_size = value;          }      } @@ -134,14 +75,14 @@ static Symbols GetSymbols(ByteReader ReadBytes) {          ELFSymbol symbol{};          ReadBytes(&symbol, symbol_index, sizeof(ELFSymbol)); -        VAddr string_offset = string_table_offset + symbol.name_index; +        VAddr string_offset = string_table_offset + symbol.st_name;          std::string name;          for (u8 c = Read8(string_offset); c != 0; c = Read8(++string_offset)) {              name += static_cast<char>(c);          }          symbol_index += symbol_entry_size; -        out[name] = std::make_pair(symbol.value, symbol.size); +        out[name] = std::make_pair(symbol.st_value, symbol.st_size);      }      return out; @@ -152,9 +93,9 @@ Symbols GetSymbols(VAddr base, Core::Memory::Memory& memory, bool is_64) {          [&](void* ptr, size_t offset, size_t size) { memory.ReadBlock(base + offset, ptr, size); }};      if (is_64) { -        return GetSymbols<u64, ELF64Symbol>(ReadBytes); +        return GetSymbols<u64, Elf64_Sym>(ReadBytes);      } else { -        return GetSymbols<u32, ELF32Symbol>(ReadBytes); +        return GetSymbols<u32, Elf32_Sym>(ReadBytes);      }  } @@ -164,9 +105,9 @@ Symbols GetSymbols(std::span<const u8> data, bool is_64) {      }};      if (is_64) { -        return GetSymbols<u64, ELF64Symbol>(ReadBytes); +        return GetSymbols<u64, Elf64_Sym>(ReadBytes);      } else { -        return GetSymbols<u32, ELF32Symbol>(ReadBytes); +        return GetSymbols<u32, Elf32_Sym>(ReadBytes);      }  } diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 19bd85b6c..4ed3f02e2 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -11,10 +11,13 @@  #include "common/alignment.h"  #include "common/common_funcs.h"  #include "common/div_ceil.h" +#include "common/elf.h"  #include "common/logging/log.h"  #include "core/hle/service/jit/jit_context.h"  #include "core/memory.h" +using namespace Common::ELF; +  namespace Service::JIT {  constexpr std::array<u8, 8> SVC0_ARM64 = { @@ -26,25 +29,6 @@ constexpr std::array HELPER_FUNCTIONS{      "_stop", "_resolve", "_panic", "memcpy", "memmove", "memset",  }; -struct Elf64_Dyn { -    u64 d_tag; -    u64 d_un; -}; - -struct Elf64_Rela { -    u64 r_offset; -    u64 r_info; -    s64 r_addend; -}; - -static constexpr u32 Elf64_RelaType(const Elf64_Rela* rela) { -    return static_cast<u32>(rela->r_info); -} - -constexpr int DT_RELA = 7;               /* Address of Rela relocs */ -constexpr int DT_RELASZ = 8;             /* Total size of Rela relocs */ -constexpr int R_AARCH64_RELATIVE = 1027; /* Adjust by program base.  */ -  constexpr size_t STACK_ALIGN = 16;  class JITContextImpl; @@ -206,17 +190,17 @@ public:              if (!dyn.d_tag) {                  break;              } -            if (dyn.d_tag == DT_RELA) { -                rela_dyn = dyn.d_un; +            if (dyn.d_tag == ElfDtRela) { +                rela_dyn = dyn.d_un.d_ptr;              } -            if (dyn.d_tag == DT_RELASZ) { -                num_rela = dyn.d_un / sizeof(Elf64_Rela); +            if (dyn.d_tag == ElfDtRelasz) { +                num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela);              }          }          for (size_t i = 0; i < num_rela; i++) {              const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))}; -            if (Elf64_RelaType(&rela) != R_AARCH64_RELATIVE) { +            if (Elf64RelType(rela.r_info) != ElfAArch64Relative) {                  continue;              }              const VAddr contents{callbacks->MemoryRead64(rela.r_offset)}; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index cf5933699..dfb10c34f 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -6,6 +6,7 @@  #include <memory>  #include "common/common_funcs.h"  #include "common/common_types.h" +#include "common/elf.h"  #include "common/logging/log.h"  #include "core/hle/kernel/code_set.h"  #include "core/hle/kernel/k_page_table.h" @@ -13,159 +14,7 @@  #include "core/loader/elf.h"  #include "core/memory.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ELF Header Constants - -// File type -enum ElfType { -    ET_NONE = 0, -    ET_REL = 1, -    ET_EXEC = 2, -    ET_DYN = 3, -    ET_CORE = 4, -    ET_LOPROC = 0xFF00, -    ET_HIPROC = 0xFFFF, -}; - -// Machine/Architecture -enum ElfMachine { -    EM_NONE = 0, -    EM_M32 = 1, -    EM_SPARC = 2, -    EM_386 = 3, -    EM_68K = 4, -    EM_88K = 5, -    EM_860 = 7, -    EM_MIPS = 8 -}; - -// File version -#define EV_NONE 0 -#define EV_CURRENT 1 - -// Identification index -#define EI_MAG0 0 -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_PAD 7 -#define EI_NIDENT 16 - -// Sections constants - -// Section types -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7FFFFFFF -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xFFFFFFFF - -// Section flags -enum ElfSectionFlags { -    SHF_WRITE = 0x1, -    SHF_ALLOC = 0x2, -    SHF_EXECINSTR = 0x4, -    SHF_MASKPROC = 0xF0000000, -}; - -// Segment types -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7FFFFFFF - -// Segment flags -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 -#define PF_MASKPROC 0xF0000000 - -typedef unsigned int Elf32_Addr; -typedef unsigned short Elf32_Half; -typedef unsigned int Elf32_Off; -typedef signed int Elf32_Sword; -typedef unsigned int Elf32_Word; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ELF file header - -struct Elf32_Ehdr { -    unsigned char e_ident[EI_NIDENT]; -    Elf32_Half e_type; -    Elf32_Half e_machine; -    Elf32_Word e_version; -    Elf32_Addr e_entry; -    Elf32_Off e_phoff; -    Elf32_Off e_shoff; -    Elf32_Word e_flags; -    Elf32_Half e_ehsize; -    Elf32_Half e_phentsize; -    Elf32_Half e_phnum; -    Elf32_Half e_shentsize; -    Elf32_Half e_shnum; -    Elf32_Half e_shstrndx; -}; - -// Section header -struct Elf32_Shdr { -    Elf32_Word sh_name; -    Elf32_Word sh_type; -    Elf32_Word sh_flags; -    Elf32_Addr sh_addr; -    Elf32_Off sh_offset; -    Elf32_Word sh_size; -    Elf32_Word sh_link; -    Elf32_Word sh_info; -    Elf32_Word sh_addralign; -    Elf32_Word sh_entsize; -}; - -// Segment header -struct Elf32_Phdr { -    Elf32_Word p_type; -    Elf32_Off p_offset; -    Elf32_Addr p_vaddr; -    Elf32_Addr p_paddr; -    Elf32_Word p_filesz; -    Elf32_Word p_memsz; -    Elf32_Word p_flags; -    Elf32_Word p_align; -}; - -// Symbol table entry -struct Elf32_Sym { -    Elf32_Word st_name; -    Elf32_Addr st_value; -    Elf32_Word st_size; -    unsigned char st_info; -    unsigned char st_other; -    Elf32_Half st_shndx; -}; - -// Relocation entries -struct Elf32_Rel { -    Elf32_Addr r_offset; -    Elf32_Word r_info; -}; +using namespace Common::ELF;  ////////////////////////////////////////////////////////////////////////////////////////////////////  // ElfReader class @@ -193,11 +42,11 @@ public:      }      // Quick accessors -    ElfType GetType() const { -        return (ElfType)(header->e_type); +    u16 GetType() const { +        return header->e_type;      } -    ElfMachine GetMachine() const { -        return (ElfMachine)(header->e_machine); +    u16 GetMachine() const { +        return header->e_machine;      }      VAddr GetEntryPoint() const {          return entryPoint; @@ -220,13 +69,13 @@ public:      const u8* GetSectionDataPtr(int section) const {          if (section < 0 || section >= header->e_shnum)              return nullptr; -        if (sections[section].sh_type != SHT_NOBITS) +        if (sections[section].sh_type != ElfShtNobits)              return GetPtr(sections[section].sh_offset);          else              return nullptr;      }      bool IsCodeSection(int section) const { -        return sections[section].sh_type == SHT_PROGBITS; +        return sections[section].sh_type == ElfShtProgBits;      }      const u8* GetSegmentPtr(int segment) {          return GetPtr(segments[segment].p_offset); @@ -256,7 +105,7 @@ ElfReader::ElfReader(void* ptr) {  }  const char* ElfReader::GetSectionName(int section) const { -    if (sections[section].sh_type == SHT_NULL) +    if (sections[section].sh_type == ElfShtNull)          return nullptr;      int name_offset = sections[section].sh_name; @@ -272,7 +121,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {      LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx);      // Should we relocate? -    relocate = (header->e_type != ET_EXEC); +    relocate = (header->e_type != ElfTypeExec);      if (relocate) {          LOG_DEBUG(Loader, "Relocatable module"); @@ -288,7 +137,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {      u64 total_image_size = 0;      for (unsigned int i = 0; i < header->e_phnum; ++i) {          const Elf32_Phdr* p = &segments[i]; -        if (p->p_type == PT_LOAD) { +        if (p->p_type == ElfPtLoad) {              total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF;          }      } @@ -303,14 +152,14 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {          LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type,                    p->p_vaddr, p->p_filesz, p->p_memsz); -        if (p->p_type == PT_LOAD) { +        if (p->p_type == ElfPtLoad) {              Kernel::CodeSet::Segment* codeset_segment; -            u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); -            if (permission_flags == (PF_R | PF_X)) { +            u32 permission_flags = p->p_flags & (ElfPfRead | ElfPfWrite | ElfPfExec); +            if (permission_flags == (ElfPfRead | ElfPfExec)) {                  codeset_segment = &codeset.CodeSegment(); -            } else if (permission_flags == (PF_R)) { +            } else if (permission_flags == (ElfPfRead)) {                  codeset_segment = &codeset.RODataSegment(); -            } else if (permission_flags == (PF_R | PF_W)) { +            } else if (permission_flags == (ElfPfRead | ElfPfWrite)) {                  codeset_segment = &codeset.DataSegment();              } else {                  LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, | 
