diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index adf70eb8ba..73bf626d4c 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 0000000000..14a5e9597b
--- /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 4aa1a1ee17..0259c7ea27 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"
 
+using namespace Common::ELF;
+
 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
-
 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 19bd85b6c2..4ed3f02e2e 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 cf5933699c..dfb10c34f0 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,