diff options
Diffstat (limited to '')
| -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 | |||
| 58 | div_ceil.h | 58 | div_ceil.h |
| 59 | dynamic_library.cpp | 59 | dynamic_library.cpp |
| 60 | dynamic_library.h | 60 | dynamic_library.h |
| 61 | elf.h | ||
| 61 | error.cpp | 62 | error.cpp |
| 62 | error.h | 63 | error.h |
| 63 | expected.h | 64 | 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 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <array> | ||
| 7 | #include <cstddef> | ||
| 8 | |||
| 9 | #include "common_types.h" | ||
| 10 | |||
| 11 | namespace Common { | ||
| 12 | namespace ELF { | ||
| 13 | |||
| 14 | /* Type for a 16-bit quantity. */ | ||
| 15 | using Elf32_Half = u16; | ||
| 16 | using Elf64_Half = u16; | ||
| 17 | |||
| 18 | /* Types for signed and unsigned 32-bit quantities. */ | ||
| 19 | using Elf32_Word = u32; | ||
| 20 | using Elf32_Sword = s32; | ||
| 21 | using Elf64_Word = u32; | ||
| 22 | using Elf64_Sword = s32; | ||
| 23 | |||
| 24 | /* Types for signed and unsigned 64-bit quantities. */ | ||
| 25 | using Elf32_Xword = u64; | ||
| 26 | using Elf32_Sxword = s64; | ||
| 27 | using Elf64_Xword = u64; | ||
| 28 | using Elf64_Sxword = s64; | ||
| 29 | |||
| 30 | /* Type of addresses. */ | ||
| 31 | using Elf32_Addr = u32; | ||
| 32 | using Elf64_Addr = u64; | ||
| 33 | |||
| 34 | /* Type of file offsets. */ | ||
| 35 | using Elf32_Off = u32; | ||
| 36 | using Elf64_Off = u64; | ||
| 37 | |||
| 38 | /* Type for section indices, which are 16-bit quantities. */ | ||
| 39 | using Elf32_Section = u16; | ||
| 40 | using Elf64_Section = u16; | ||
| 41 | |||
| 42 | /* Type for version symbol information. */ | ||
| 43 | using Elf32_Versym = Elf32_Half; | ||
| 44 | using Elf64_Versym = Elf64_Half; | ||
| 45 | |||
| 46 | constexpr size_t ElfIdentSize = 16; | ||
| 47 | |||
| 48 | /* The ELF file header. This appears at the start of every ELF file. */ | ||
| 49 | |||
| 50 | struct Elf32_Ehdr { | ||
| 51 | std::array<u8, ElfIdentSize> e_ident; /* Magic number and other info */ | ||
| 52 | Elf32_Half e_type; /* Object file type */ | ||
| 53 | Elf32_Half e_machine; /* Architecture */ | ||
| 54 | Elf32_Word e_version; /* Object file version */ | ||
| 55 | Elf32_Addr e_entry; /* Entry point virtual address */ | ||
| 56 | Elf32_Off e_phoff; /* Program header table file offset */ | ||
| 57 | Elf32_Off e_shoff; /* Section header table file offset */ | ||
| 58 | Elf32_Word e_flags; /* Processor-specific flags */ | ||
| 59 | Elf32_Half e_ehsize; /* ELF header size in bytes */ | ||
| 60 | Elf32_Half e_phentsize; /* Program header table entry size */ | ||
| 61 | Elf32_Half e_phnum; /* Program header table entry count */ | ||
| 62 | Elf32_Half e_shentsize; /* Section header table entry size */ | ||
| 63 | Elf32_Half e_shnum; /* Section header table entry count */ | ||
| 64 | Elf32_Half e_shstrndx; /* Section header string table index */ | ||
| 65 | }; | ||
| 66 | |||
| 67 | struct Elf64_Ehdr { | ||
| 68 | std::array<u8, ElfIdentSize> e_ident; /* Magic number and other info */ | ||
| 69 | Elf64_Half e_type; /* Object file type */ | ||
| 70 | Elf64_Half e_machine; /* Architecture */ | ||
| 71 | Elf64_Word e_version; /* Object file version */ | ||
| 72 | Elf64_Addr e_entry; /* Entry point virtual address */ | ||
| 73 | Elf64_Off e_phoff; /* Program header table file offset */ | ||
| 74 | Elf64_Off e_shoff; /* Section header table file offset */ | ||
| 75 | Elf64_Word e_flags; /* Processor-specific flags */ | ||
| 76 | Elf64_Half e_ehsize; /* ELF header size in bytes */ | ||
| 77 | Elf64_Half e_phentsize; /* Program header table entry size */ | ||
| 78 | Elf64_Half e_phnum; /* Program header table entry count */ | ||
| 79 | Elf64_Half e_shentsize; /* Section header table entry size */ | ||
| 80 | Elf64_Half e_shnum; /* Section header table entry count */ | ||
| 81 | Elf64_Half e_shstrndx; /* Section header string table index */ | ||
| 82 | }; | ||
| 83 | |||
| 84 | constexpr u8 ElfClass32 = 1; /* 32-bit objects */ | ||
| 85 | constexpr u8 ElfClass64 = 2; /* 64-bit objects */ | ||
| 86 | constexpr u8 ElfData2Lsb = 1; /* 2's complement, little endian */ | ||
| 87 | constexpr u8 ElfVersionCurrent = 1; /* EV_CURRENT */ | ||
| 88 | constexpr u8 ElfOsAbiNone = 0; /* System V ABI */ | ||
| 89 | |||
| 90 | constexpr u16 ElfTypeNone = 0; /* No file type */ | ||
| 91 | constexpr u16 ElfTypeRel = 0; /* Relocatable file */ | ||
| 92 | constexpr u16 ElfTypeExec = 0; /* Executable file */ | ||
| 93 | constexpr u16 ElfTypeDyn = 0; /* Shared object file */ | ||
| 94 | |||
| 95 | constexpr u16 ElfMachineArm = 40; /* ARM */ | ||
| 96 | constexpr u16 ElfMachineAArch64 = 183; /* ARM AARCH64 */ | ||
| 97 | |||
| 98 | constexpr std::array<u8, ElfIdentSize> Elf32Ident{ | ||
| 99 | 0x7f, 'E', 'L', 'F', ElfClass32, ElfData2Lsb, ElfVersionCurrent, ElfOsAbiNone}; | ||
| 100 | |||
| 101 | constexpr std::array<u8, ElfIdentSize> Elf64Ident{ | ||
| 102 | 0x7f, 'E', 'L', 'F', ElfClass64, ElfData2Lsb, ElfVersionCurrent, ElfOsAbiNone}; | ||
| 103 | |||
| 104 | /* Section header. */ | ||
| 105 | |||
| 106 | struct Elf32_Shdr { | ||
| 107 | Elf32_Word sh_name; /* Section name (string tbl index) */ | ||
| 108 | Elf32_Word sh_type; /* Section type */ | ||
| 109 | Elf32_Word sh_flags; /* Section flags */ | ||
| 110 | Elf32_Addr sh_addr; /* Section virtual addr at execution */ | ||
| 111 | Elf32_Off sh_offset; /* Section file offset */ | ||
| 112 | Elf32_Word sh_size; /* Section size in bytes */ | ||
| 113 | Elf32_Word sh_link; /* Link to another section */ | ||
| 114 | Elf32_Word sh_info; /* Additional section information */ | ||
| 115 | Elf32_Word sh_addralign; /* Section alignment */ | ||
| 116 | Elf32_Word sh_entsize; /* Entry size if section holds table */ | ||
| 117 | }; | ||
| 118 | |||
| 119 | struct Elf64_Shdr { | ||
| 120 | Elf64_Word sh_name; /* Section name (string tbl index) */ | ||
| 121 | Elf64_Word sh_type; /* Section type */ | ||
| 122 | Elf64_Xword sh_flags; /* Section flags */ | ||
| 123 | Elf64_Addr sh_addr; /* Section virtual addr at execution */ | ||
| 124 | Elf64_Off sh_offset; /* Section file offset */ | ||
| 125 | Elf64_Xword sh_size; /* Section size in bytes */ | ||
| 126 | Elf64_Word sh_link; /* Link to another section */ | ||
| 127 | Elf64_Word sh_info; /* Additional section information */ | ||
| 128 | Elf64_Xword sh_addralign; /* Section alignment */ | ||
| 129 | Elf64_Xword sh_entsize; /* Entry size if section holds table */ | ||
| 130 | }; | ||
| 131 | |||
| 132 | constexpr u32 ElfShnUndef = 0; /* Undefined section */ | ||
| 133 | |||
| 134 | constexpr u32 ElfShtNull = 0; /* Section header table entry unused */ | ||
| 135 | constexpr u32 ElfShtProgBits = 1; /* Program data */ | ||
| 136 | constexpr u32 ElfShtSymtab = 2; /* Symbol table */ | ||
| 137 | constexpr u32 ElfShtStrtab = 3; /* String table */ | ||
| 138 | constexpr u32 ElfShtRela = 4; /* Relocation entries with addends */ | ||
| 139 | constexpr u32 ElfShtDynamic = 6; /* Dynamic linking information */ | ||
| 140 | constexpr u32 ElfShtNobits = 7; /* Program space with no data (bss) */ | ||
| 141 | constexpr u32 ElfShtRel = 9; /* Relocation entries, no addends */ | ||
| 142 | constexpr u32 ElfShtDynsym = 11; /* Dynamic linker symbol table */ | ||
| 143 | |||
| 144 | /* Symbol table entry. */ | ||
| 145 | |||
| 146 | struct Elf32_Sym { | ||
| 147 | Elf32_Word st_name; /* Symbol name (string tbl index) */ | ||
| 148 | Elf32_Addr st_value; /* Symbol value */ | ||
| 149 | Elf32_Word st_size; /* Symbol size */ | ||
| 150 | u8 st_info; /* Symbol type and binding */ | ||
| 151 | u8 st_other; /* Symbol visibility */ | ||
| 152 | Elf32_Section st_shndx; /* Section index */ | ||
| 153 | }; | ||
| 154 | |||
| 155 | struct Elf64_Sym { | ||
| 156 | Elf64_Word st_name; /* Symbol name (string tbl index) */ | ||
| 157 | u8 st_info; /* Symbol type and binding */ | ||
| 158 | u8 st_other; /* Symbol visibility */ | ||
| 159 | Elf64_Section st_shndx; /* Section index */ | ||
| 160 | Elf64_Addr st_value; /* Symbol value */ | ||
| 161 | Elf64_Xword st_size; /* Symbol size */ | ||
| 162 | }; | ||
| 163 | |||
| 164 | /* How to extract and insert information held in the st_info field. */ | ||
| 165 | |||
| 166 | static inline u8 ElfStBind(u8 st_info) { | ||
| 167 | return st_info >> 4; | ||
| 168 | } | ||
| 169 | static inline u8 ElfStType(u8 st_info) { | ||
| 170 | return st_info & 0xf; | ||
| 171 | } | ||
| 172 | static inline u8 ElfStInfo(u8 st_bind, u8 st_type) { | ||
| 173 | return static_cast<u8>((st_bind << 4) + (st_type & 0xf)); | ||
| 174 | } | ||
| 175 | |||
| 176 | constexpr u8 ElfBindLocal = 0; /* Local symbol */ | ||
| 177 | constexpr u8 ElfBindGlobal = 1; /* Global symbol */ | ||
| 178 | constexpr u8 ElfBindWeak = 2; /* Weak symbol */ | ||
| 179 | |||
| 180 | constexpr u8 ElfTypeUnspec = 0; /* Symbol type is unspecified */ | ||
| 181 | constexpr u8 ElfTypeObject = 1; /* Symbol is a data object */ | ||
| 182 | constexpr u8 ElfTypeFunc = 2; /* Symbol is a code object */ | ||
| 183 | |||
| 184 | static inline u8 ElfStVisibility(u8 st_other) { | ||
| 185 | return static_cast<u8>(st_other & 0x3); | ||
| 186 | } | ||
| 187 | |||
| 188 | constexpr u8 ElfVisibilityDefault = 0; /* Default symbol visibility rules */ | ||
| 189 | constexpr u8 ElfVisibilityInternal = 1; /* Processor specific hidden class */ | ||
| 190 | constexpr u8 ElfVisibilityHidden = 2; /* Sym unavailable in other modules */ | ||
| 191 | constexpr u8 ElfVisibilityProtected = 3; /* Not preemptible, not exported */ | ||
| 192 | |||
| 193 | /* Relocation table entry without addend (in section of type ShtRel). */ | ||
| 194 | |||
| 195 | struct Elf32_Rel { | ||
| 196 | Elf32_Addr r_offset; /* Address */ | ||
| 197 | Elf32_Word r_info; /* Relocation type and symbol index */ | ||
| 198 | }; | ||
| 199 | |||
| 200 | /* Relocation table entry with addend (in section of type ShtRela). */ | ||
| 201 | |||
| 202 | struct Elf32_Rela { | ||
| 203 | Elf32_Addr r_offset; /* Address */ | ||
| 204 | Elf32_Word r_info; /* Relocation type and symbol index */ | ||
| 205 | Elf32_Sword r_addend; /* Addend */ | ||
| 206 | }; | ||
| 207 | |||
| 208 | struct Elf64_Rela { | ||
| 209 | Elf64_Addr r_offset; /* Address */ | ||
| 210 | Elf64_Xword r_info; /* Relocation type and symbol index */ | ||
| 211 | Elf64_Sxword r_addend; /* Addend */ | ||
| 212 | }; | ||
| 213 | |||
| 214 | /* How to extract and insert information held in the r_info field. */ | ||
| 215 | |||
| 216 | static inline u32 Elf32RelSymIndex(Elf32_Word r_info) { | ||
| 217 | return r_info >> 8; | ||
| 218 | } | ||
| 219 | static inline u8 Elf32RelType(Elf32_Word r_info) { | ||
| 220 | return static_cast<u8>(r_info & 0xff); | ||
| 221 | } | ||
| 222 | static inline Elf32_Word Elf32RelInfo(u32 sym_index, u8 type) { | ||
| 223 | return (sym_index << 8) + type; | ||
| 224 | } | ||
| 225 | static inline u32 Elf64RelSymIndex(Elf64_Xword r_info) { | ||
| 226 | return static_cast<u32>(r_info >> 32); | ||
| 227 | } | ||
| 228 | static inline u32 Elf64RelType(Elf64_Xword r_info) { | ||
| 229 | return r_info & 0xffffffff; | ||
| 230 | } | ||
| 231 | static inline Elf64_Xword Elf64RelInfo(u32 sym_index, u32 type) { | ||
| 232 | return (static_cast<Elf64_Xword>(sym_index) << 32) + type; | ||
| 233 | } | ||
| 234 | |||
| 235 | constexpr u32 ElfArmCopy = 20; /* Copy symbol at runtime */ | ||
| 236 | constexpr u32 ElfArmGlobDat = 21; /* Create GOT entry */ | ||
| 237 | constexpr u32 ElfArmJumpSlot = 22; /* Create PLT entry */ | ||
| 238 | constexpr u32 ElfArmRelative = 23; /* Adjust by program base */ | ||
| 239 | |||
| 240 | constexpr u32 ElfAArch64Copy = 1024; /* Copy symbol at runtime */ | ||
| 241 | constexpr u32 ElfAArch64GlobDat = 1025; /* Create GOT entry */ | ||
| 242 | constexpr u32 ElfAArch64JumpSlot = 1026; /* Create PLT entry */ | ||
| 243 | constexpr u32 ElfAArch64Relative = 1027; /* Adjust by program base */ | ||
| 244 | |||
| 245 | /* Program segment header. */ | ||
| 246 | |||
| 247 | struct Elf32_Phdr { | ||
| 248 | Elf32_Word p_type; /* Segment type */ | ||
| 249 | Elf32_Off p_offset; /* Segment file offset */ | ||
| 250 | Elf32_Addr p_vaddr; /* Segment virtual address */ | ||
| 251 | Elf32_Addr p_paddr; /* Segment physical address */ | ||
| 252 | Elf32_Word p_filesz; /* Segment size in file */ | ||
| 253 | Elf32_Word p_memsz; /* Segment size in memory */ | ||
| 254 | Elf32_Word p_flags; /* Segment flags */ | ||
| 255 | Elf32_Word p_align; /* Segment alignment */ | ||
| 256 | }; | ||
| 257 | |||
| 258 | struct Elf64_Phdr { | ||
| 259 | Elf64_Word p_type; /* Segment type */ | ||
| 260 | Elf64_Word p_flags; /* Segment flags */ | ||
| 261 | Elf64_Off p_offset; /* Segment file offset */ | ||
| 262 | Elf64_Addr p_vaddr; /* Segment virtual address */ | ||
| 263 | Elf64_Addr p_paddr; /* Segment physical address */ | ||
| 264 | Elf64_Xword p_filesz; /* Segment size in file */ | ||
| 265 | Elf64_Xword p_memsz; /* Segment size in memory */ | ||
| 266 | Elf64_Xword p_align; /* Segment alignment */ | ||
| 267 | }; | ||
| 268 | |||
| 269 | /* Legal values for p_type (segment type). */ | ||
| 270 | |||
| 271 | constexpr u32 ElfPtNull = 0; /* Program header table entry unused */ | ||
| 272 | constexpr u32 ElfPtLoad = 1; /* Loadable program segment */ | ||
| 273 | constexpr u32 ElfPtDynamic = 2; /* Dynamic linking information */ | ||
| 274 | constexpr u32 ElfPtInterp = 3; /* Program interpreter */ | ||
| 275 | constexpr u32 ElfPtNote = 4; /* Auxiliary information */ | ||
| 276 | constexpr u32 ElfPtPhdr = 6; /* Entry for header table itself */ | ||
| 277 | constexpr u32 ElfPtTls = 7; /* Thread-local storage segment */ | ||
| 278 | |||
| 279 | /* Legal values for p_flags (segment flags). */ | ||
| 280 | |||
| 281 | constexpr u32 ElfPfExec = 0; /* Segment is executable */ | ||
| 282 | constexpr u32 ElfPfWrite = 1; /* Segment is writable */ | ||
| 283 | constexpr u32 ElfPfRead = 2; /* Segment is readable */ | ||
| 284 | |||
| 285 | /* Dynamic section entry. */ | ||
| 286 | |||
| 287 | struct Elf32_Dyn { | ||
| 288 | Elf32_Sword d_tag; /* Dynamic entry type */ | ||
| 289 | union { | ||
| 290 | Elf32_Word d_val; /* Integer value */ | ||
| 291 | Elf32_Addr d_ptr; /* Address value */ | ||
| 292 | } d_un; | ||
| 293 | }; | ||
| 294 | |||
| 295 | struct Elf64_Dyn { | ||
| 296 | Elf64_Sxword d_tag; /* Dynamic entry type */ | ||
| 297 | union { | ||
| 298 | Elf64_Xword d_val; /* Integer value */ | ||
| 299 | Elf64_Addr d_ptr; /* Address value */ | ||
| 300 | } d_un; | ||
| 301 | }; | ||
| 302 | |||
| 303 | /* Legal values for d_tag (dynamic entry type). */ | ||
| 304 | |||
| 305 | constexpr u32 ElfDtNull = 0; /* Marks end of dynamic section */ | ||
| 306 | constexpr u32 ElfDtNeeded = 1; /* Name of needed library */ | ||
| 307 | constexpr u32 ElfDtPltRelSz = 2; /* Size in bytes of PLT relocs */ | ||
| 308 | constexpr u32 ElfDtPltGot = 3; /* Processor defined value */ | ||
| 309 | constexpr u32 ElfDtHash = 4; /* Address of symbol hash table */ | ||
| 310 | constexpr u32 ElfDtStrtab = 5; /* Address of string table */ | ||
| 311 | constexpr u32 ElfDtSymtab = 6; /* Address of symbol table */ | ||
| 312 | constexpr u32 ElfDtRela = 7; /* Address of Rela relocs */ | ||
| 313 | constexpr u32 ElfDtRelasz = 8; /* Total size of Rela relocs */ | ||
| 314 | constexpr u32 ElfDtRelaent = 9; /* Size of one Rela reloc */ | ||
| 315 | constexpr u32 ElfDtStrsz = 10; /* Size of string table */ | ||
| 316 | constexpr u32 ElfDtSyment = 11; /* Size of one symbol table entry */ | ||
| 317 | constexpr u32 ElfDtInit = 12; /* Address of init function */ | ||
| 318 | constexpr u32 ElfDtFini = 13; /* Address of termination function */ | ||
| 319 | constexpr u32 ElfDtRel = 17; /* Address of Rel relocs */ | ||
| 320 | constexpr u32 ElfDtRelsz = 18; /* Total size of Rel relocs */ | ||
| 321 | constexpr u32 ElfDtRelent = 19; /* Size of one Rel reloc */ | ||
| 322 | constexpr u32 ElfDtPltRel = 20; /* Type of reloc in PLT */ | ||
| 323 | constexpr u32 ElfDtTextRel = 22; /* Reloc might modify .text */ | ||
| 324 | constexpr u32 ElfDtJmpRel = 23; /* Address of PLT relocs */ | ||
| 325 | constexpr u32 ElfDtBindNow = 24; /* Process relocations of object */ | ||
| 326 | constexpr u32 ElfDtInitArray = 25; /* Array with addresses of init fct */ | ||
| 327 | constexpr u32 ElfDtFiniArray = 26; /* Array with addresses of fini fct */ | ||
| 328 | constexpr u32 ElfDtInitArraySz = 27; /* Size in bytes of DT_INIT_ARRAY */ | ||
| 329 | constexpr u32 ElfDtFiniArraySz = 28; /* Size in bytes of DT_FINI_ARRAY */ | ||
| 330 | constexpr u32 ElfDtSymtabShndx = 34; /* Address of SYMTAB_SHNDX section */ | ||
| 331 | |||
| 332 | } // namespace ELF | ||
| 333 | } // 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 @@ | |||
| 3 | 3 | ||
| 4 | #include "common/bit_field.h" | 4 | #include "common/bit_field.h" |
| 5 | #include "common/common_funcs.h" | 5 | #include "common/common_funcs.h" |
| 6 | #include "common/elf.h" | ||
| 6 | #include "core/arm/symbols.h" | 7 | #include "core/arm/symbols.h" |
| 7 | #include "core/core.h" | 8 | #include "core/core.h" |
| 8 | #include "core/memory.h" | 9 | #include "core/memory.h" |
| 9 | 10 | ||
| 10 | namespace Core { | 11 | using namespace Common::ELF; |
| 11 | namespace { | ||
| 12 | |||
| 13 | constexpr u64 ELF_DYNAMIC_TAG_NULL = 0; | ||
| 14 | constexpr u64 ELF_DYNAMIC_TAG_STRTAB = 5; | ||
| 15 | constexpr u64 ELF_DYNAMIC_TAG_SYMTAB = 6; | ||
| 16 | constexpr u64 ELF_DYNAMIC_TAG_SYMENT = 11; | ||
| 17 | |||
| 18 | enum class ELFSymbolType : u8 { | ||
| 19 | None = 0, | ||
| 20 | Object = 1, | ||
| 21 | Function = 2, | ||
| 22 | Section = 3, | ||
| 23 | File = 4, | ||
| 24 | Common = 5, | ||
| 25 | TLS = 6, | ||
| 26 | }; | ||
| 27 | |||
| 28 | enum class ELFSymbolBinding : u8 { | ||
| 29 | Local = 0, | ||
| 30 | Global = 1, | ||
| 31 | Weak = 2, | ||
| 32 | }; | ||
| 33 | |||
| 34 | enum class ELFSymbolVisibility : u8 { | ||
| 35 | Default = 0, | ||
| 36 | Internal = 1, | ||
| 37 | Hidden = 2, | ||
| 38 | Protected = 3, | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct ELF64Symbol { | ||
| 42 | u32 name_index; | ||
| 43 | union { | ||
| 44 | u8 info; | ||
| 45 | |||
| 46 | BitField<0, 4, ELFSymbolType> type; | ||
| 47 | BitField<4, 4, ELFSymbolBinding> binding; | ||
| 48 | }; | ||
| 49 | ELFSymbolVisibility visibility; | ||
| 50 | u16 sh_index; | ||
| 51 | u64 value; | ||
| 52 | u64 size; | ||
| 53 | }; | ||
| 54 | static_assert(sizeof(ELF64Symbol) == 0x18, "ELF64Symbol has incorrect size."); | ||
| 55 | |||
| 56 | struct ELF32Symbol { | ||
| 57 | u32 name_index; | ||
| 58 | u32 value; | ||
| 59 | u32 size; | ||
| 60 | union { | ||
| 61 | u8 info; | ||
| 62 | |||
| 63 | BitField<0, 4, ELFSymbolType> type; | ||
| 64 | BitField<4, 4, ELFSymbolBinding> binding; | ||
| 65 | }; | ||
| 66 | ELFSymbolVisibility visibility; | ||
| 67 | u16 sh_index; | ||
| 68 | }; | ||
| 69 | static_assert(sizeof(ELF32Symbol) == 0x10, "ELF32Symbol has incorrect size."); | ||
| 70 | |||
| 71 | } // Anonymous namespace | ||
| 72 | 12 | ||
| 13 | namespace Core { | ||
| 73 | namespace Symbols { | 14 | namespace Symbols { |
| 74 | 15 | ||
| 75 | template <typename Word, typename ELFSymbol, typename ByteReader> | 16 | template <typename Word, typename ELFSymbol, typename ByteReader> |
| @@ -110,15 +51,15 @@ static Symbols GetSymbols(ByteReader ReadBytes) { | |||
| 110 | const Word value = ReadWord(dynamic_index + sizeof(Word)); | 51 | const Word value = ReadWord(dynamic_index + sizeof(Word)); |
| 111 | dynamic_index += 2 * sizeof(Word); | 52 | dynamic_index += 2 * sizeof(Word); |
| 112 | 53 | ||
| 113 | if (tag == ELF_DYNAMIC_TAG_NULL) { | 54 | if (tag == ElfDtNull) { |
| 114 | break; | 55 | break; |
| 115 | } | 56 | } |
| 116 | 57 | ||
| 117 | if (tag == ELF_DYNAMIC_TAG_STRTAB) { | 58 | if (tag == ElfDtStrtab) { |
| 118 | string_table_offset = value; | 59 | string_table_offset = value; |
| 119 | } else if (tag == ELF_DYNAMIC_TAG_SYMTAB) { | 60 | } else if (tag == ElfDtSymtab) { |
| 120 | symbol_table_offset = value; | 61 | symbol_table_offset = value; |
| 121 | } else if (tag == ELF_DYNAMIC_TAG_SYMENT) { | 62 | } else if (tag == ElfDtSyment) { |
| 122 | symbol_entry_size = value; | 63 | symbol_entry_size = value; |
| 123 | } | 64 | } |
| 124 | } | 65 | } |
| @@ -134,14 +75,14 @@ static Symbols GetSymbols(ByteReader ReadBytes) { | |||
| 134 | ELFSymbol symbol{}; | 75 | ELFSymbol symbol{}; |
| 135 | ReadBytes(&symbol, symbol_index, sizeof(ELFSymbol)); | 76 | ReadBytes(&symbol, symbol_index, sizeof(ELFSymbol)); |
| 136 | 77 | ||
| 137 | VAddr string_offset = string_table_offset + symbol.name_index; | 78 | VAddr string_offset = string_table_offset + symbol.st_name; |
| 138 | std::string name; | 79 | std::string name; |
| 139 | for (u8 c = Read8(string_offset); c != 0; c = Read8(++string_offset)) { | 80 | for (u8 c = Read8(string_offset); c != 0; c = Read8(++string_offset)) { |
| 140 | name += static_cast<char>(c); | 81 | name += static_cast<char>(c); |
| 141 | } | 82 | } |
| 142 | 83 | ||
| 143 | symbol_index += symbol_entry_size; | 84 | symbol_index += symbol_entry_size; |
| 144 | out[name] = std::make_pair(symbol.value, symbol.size); | 85 | out[name] = std::make_pair(symbol.st_value, symbol.st_size); |
| 145 | } | 86 | } |
| 146 | 87 | ||
| 147 | return out; | 88 | return out; |
| @@ -152,9 +93,9 @@ Symbols GetSymbols(VAddr base, Core::Memory::Memory& memory, bool is_64) { | |||
| 152 | [&](void* ptr, size_t offset, size_t size) { memory.ReadBlock(base + offset, ptr, size); }}; | 93 | [&](void* ptr, size_t offset, size_t size) { memory.ReadBlock(base + offset, ptr, size); }}; |
| 153 | 94 | ||
| 154 | if (is_64) { | 95 | if (is_64) { |
| 155 | return GetSymbols<u64, ELF64Symbol>(ReadBytes); | 96 | return GetSymbols<u64, Elf64_Sym>(ReadBytes); |
| 156 | } else { | 97 | } else { |
| 157 | return GetSymbols<u32, ELF32Symbol>(ReadBytes); | 98 | return GetSymbols<u32, Elf32_Sym>(ReadBytes); |
| 158 | } | 99 | } |
| 159 | } | 100 | } |
| 160 | 101 | ||
| @@ -164,9 +105,9 @@ Symbols GetSymbols(std::span<const u8> data, bool is_64) { | |||
| 164 | }}; | 105 | }}; |
| 165 | 106 | ||
| 166 | if (is_64) { | 107 | if (is_64) { |
| 167 | return GetSymbols<u64, ELF64Symbol>(ReadBytes); | 108 | return GetSymbols<u64, Elf64_Sym>(ReadBytes); |
| 168 | } else { | 109 | } else { |
| 169 | return GetSymbols<u32, ELF32Symbol>(ReadBytes); | 110 | return GetSymbols<u32, Elf32_Sym>(ReadBytes); |
| 170 | } | 111 | } |
| 171 | } | 112 | } |
| 172 | 113 | ||
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 @@ | |||
| 11 | #include "common/alignment.h" | 11 | #include "common/alignment.h" |
| 12 | #include "common/common_funcs.h" | 12 | #include "common/common_funcs.h" |
| 13 | #include "common/div_ceil.h" | 13 | #include "common/div_ceil.h" |
| 14 | #include "common/elf.h" | ||
| 14 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 15 | #include "core/hle/service/jit/jit_context.h" | 16 | #include "core/hle/service/jit/jit_context.h" |
| 16 | #include "core/memory.h" | 17 | #include "core/memory.h" |
| 17 | 18 | ||
| 19 | using namespace Common::ELF; | ||
| 20 | |||
| 18 | namespace Service::JIT { | 21 | namespace Service::JIT { |
| 19 | 22 | ||
| 20 | constexpr std::array<u8, 8> SVC0_ARM64 = { | 23 | constexpr std::array<u8, 8> SVC0_ARM64 = { |
| @@ -26,25 +29,6 @@ constexpr std::array HELPER_FUNCTIONS{ | |||
| 26 | "_stop", "_resolve", "_panic", "memcpy", "memmove", "memset", | 29 | "_stop", "_resolve", "_panic", "memcpy", "memmove", "memset", |
| 27 | }; | 30 | }; |
| 28 | 31 | ||
| 29 | struct Elf64_Dyn { | ||
| 30 | u64 d_tag; | ||
| 31 | u64 d_un; | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct Elf64_Rela { | ||
| 35 | u64 r_offset; | ||
| 36 | u64 r_info; | ||
| 37 | s64 r_addend; | ||
| 38 | }; | ||
| 39 | |||
| 40 | static constexpr u32 Elf64_RelaType(const Elf64_Rela* rela) { | ||
| 41 | return static_cast<u32>(rela->r_info); | ||
| 42 | } | ||
| 43 | |||
| 44 | constexpr int DT_RELA = 7; /* Address of Rela relocs */ | ||
| 45 | constexpr int DT_RELASZ = 8; /* Total size of Rela relocs */ | ||
| 46 | constexpr int R_AARCH64_RELATIVE = 1027; /* Adjust by program base. */ | ||
| 47 | |||
| 48 | constexpr size_t STACK_ALIGN = 16; | 32 | constexpr size_t STACK_ALIGN = 16; |
| 49 | 33 | ||
| 50 | class JITContextImpl; | 34 | class JITContextImpl; |
| @@ -206,17 +190,17 @@ public: | |||
| 206 | if (!dyn.d_tag) { | 190 | if (!dyn.d_tag) { |
| 207 | break; | 191 | break; |
| 208 | } | 192 | } |
| 209 | if (dyn.d_tag == DT_RELA) { | 193 | if (dyn.d_tag == ElfDtRela) { |
| 210 | rela_dyn = dyn.d_un; | 194 | rela_dyn = dyn.d_un.d_ptr; |
| 211 | } | 195 | } |
| 212 | if (dyn.d_tag == DT_RELASZ) { | 196 | if (dyn.d_tag == ElfDtRelasz) { |
| 213 | num_rela = dyn.d_un / sizeof(Elf64_Rela); | 197 | num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela); |
| 214 | } | 198 | } |
| 215 | } | 199 | } |
| 216 | 200 | ||
| 217 | for (size_t i = 0; i < num_rela; i++) { | 201 | for (size_t i = 0; i < num_rela; i++) { |
| 218 | const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))}; | 202 | const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))}; |
| 219 | if (Elf64_RelaType(&rela) != R_AARCH64_RELATIVE) { | 203 | if (Elf64RelType(rela.r_info) != ElfAArch64Relative) { |
| 220 | continue; | 204 | continue; |
| 221 | } | 205 | } |
| 222 | const VAddr contents{callbacks->MemoryRead64(rela.r_offset)}; | 206 | 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 @@ | |||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include "common/common_funcs.h" | 7 | #include "common/common_funcs.h" |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "common/elf.h" | ||
| 9 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 10 | #include "core/hle/kernel/code_set.h" | 11 | #include "core/hle/kernel/code_set.h" |
| 11 | #include "core/hle/kernel/k_page_table.h" | 12 | #include "core/hle/kernel/k_page_table.h" |
| @@ -13,159 +14,7 @@ | |||
| 13 | #include "core/loader/elf.h" | 14 | #include "core/loader/elf.h" |
| 14 | #include "core/memory.h" | 15 | #include "core/memory.h" |
| 15 | 16 | ||
| 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 17 | using namespace Common::ELF; |
| 17 | // ELF Header Constants | ||
| 18 | |||
| 19 | // File type | ||
| 20 | enum ElfType { | ||
| 21 | ET_NONE = 0, | ||
| 22 | ET_REL = 1, | ||
| 23 | ET_EXEC = 2, | ||
| 24 | ET_DYN = 3, | ||
| 25 | ET_CORE = 4, | ||
| 26 | ET_LOPROC = 0xFF00, | ||
| 27 | ET_HIPROC = 0xFFFF, | ||
| 28 | }; | ||
| 29 | |||
| 30 | // Machine/Architecture | ||
| 31 | enum ElfMachine { | ||
| 32 | EM_NONE = 0, | ||
| 33 | EM_M32 = 1, | ||
| 34 | EM_SPARC = 2, | ||
| 35 | EM_386 = 3, | ||
| 36 | EM_68K = 4, | ||
| 37 | EM_88K = 5, | ||
| 38 | EM_860 = 7, | ||
| 39 | EM_MIPS = 8 | ||
| 40 | }; | ||
| 41 | |||
| 42 | // File version | ||
| 43 | #define EV_NONE 0 | ||
| 44 | #define EV_CURRENT 1 | ||
| 45 | |||
| 46 | // Identification index | ||
| 47 | #define EI_MAG0 0 | ||
| 48 | #define EI_MAG1 1 | ||
| 49 | #define EI_MAG2 2 | ||
| 50 | #define EI_MAG3 3 | ||
| 51 | #define EI_CLASS 4 | ||
| 52 | #define EI_DATA 5 | ||
| 53 | #define EI_VERSION 6 | ||
| 54 | #define EI_PAD 7 | ||
| 55 | #define EI_NIDENT 16 | ||
| 56 | |||
| 57 | // Sections constants | ||
| 58 | |||
| 59 | // Section types | ||
| 60 | #define SHT_NULL 0 | ||
| 61 | #define SHT_PROGBITS 1 | ||
| 62 | #define SHT_SYMTAB 2 | ||
| 63 | #define SHT_STRTAB 3 | ||
| 64 | #define SHT_RELA 4 | ||
| 65 | #define SHT_HASH 5 | ||
| 66 | #define SHT_DYNAMIC 6 | ||
| 67 | #define SHT_NOTE 7 | ||
| 68 | #define SHT_NOBITS 8 | ||
| 69 | #define SHT_REL 9 | ||
| 70 | #define SHT_SHLIB 10 | ||
| 71 | #define SHT_DYNSYM 11 | ||
| 72 | #define SHT_LOPROC 0x70000000 | ||
| 73 | #define SHT_HIPROC 0x7FFFFFFF | ||
| 74 | #define SHT_LOUSER 0x80000000 | ||
| 75 | #define SHT_HIUSER 0xFFFFFFFF | ||
| 76 | |||
| 77 | // Section flags | ||
| 78 | enum ElfSectionFlags { | ||
| 79 | SHF_WRITE = 0x1, | ||
| 80 | SHF_ALLOC = 0x2, | ||
| 81 | SHF_EXECINSTR = 0x4, | ||
| 82 | SHF_MASKPROC = 0xF0000000, | ||
| 83 | }; | ||
| 84 | |||
| 85 | // Segment types | ||
| 86 | #define PT_NULL 0 | ||
| 87 | #define PT_LOAD 1 | ||
| 88 | #define PT_DYNAMIC 2 | ||
| 89 | #define PT_INTERP 3 | ||
| 90 | #define PT_NOTE 4 | ||
| 91 | #define PT_SHLIB 5 | ||
| 92 | #define PT_PHDR 6 | ||
| 93 | #define PT_LOPROC 0x70000000 | ||
| 94 | #define PT_HIPROC 0x7FFFFFFF | ||
| 95 | |||
| 96 | // Segment flags | ||
| 97 | #define PF_X 0x1 | ||
| 98 | #define PF_W 0x2 | ||
| 99 | #define PF_R 0x4 | ||
| 100 | #define PF_MASKPROC 0xF0000000 | ||
| 101 | |||
| 102 | typedef unsigned int Elf32_Addr; | ||
| 103 | typedef unsigned short Elf32_Half; | ||
| 104 | typedef unsigned int Elf32_Off; | ||
| 105 | typedef signed int Elf32_Sword; | ||
| 106 | typedef unsigned int Elf32_Word; | ||
| 107 | |||
| 108 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 109 | // ELF file header | ||
| 110 | |||
| 111 | struct Elf32_Ehdr { | ||
| 112 | unsigned char e_ident[EI_NIDENT]; | ||
| 113 | Elf32_Half e_type; | ||
| 114 | Elf32_Half e_machine; | ||
| 115 | Elf32_Word e_version; | ||
| 116 | Elf32_Addr e_entry; | ||
| 117 | Elf32_Off e_phoff; | ||
| 118 | Elf32_Off e_shoff; | ||
| 119 | Elf32_Word e_flags; | ||
| 120 | Elf32_Half e_ehsize; | ||
| 121 | Elf32_Half e_phentsize; | ||
| 122 | Elf32_Half e_phnum; | ||
| 123 | Elf32_Half e_shentsize; | ||
| 124 | Elf32_Half e_shnum; | ||
| 125 | Elf32_Half e_shstrndx; | ||
| 126 | }; | ||
| 127 | |||
| 128 | // Section header | ||
| 129 | struct Elf32_Shdr { | ||
| 130 | Elf32_Word sh_name; | ||
| 131 | Elf32_Word sh_type; | ||
| 132 | Elf32_Word sh_flags; | ||
| 133 | Elf32_Addr sh_addr; | ||
| 134 | Elf32_Off sh_offset; | ||
| 135 | Elf32_Word sh_size; | ||
| 136 | Elf32_Word sh_link; | ||
| 137 | Elf32_Word sh_info; | ||
| 138 | Elf32_Word sh_addralign; | ||
| 139 | Elf32_Word sh_entsize; | ||
| 140 | }; | ||
| 141 | |||
| 142 | // Segment header | ||
| 143 | struct Elf32_Phdr { | ||
| 144 | Elf32_Word p_type; | ||
| 145 | Elf32_Off p_offset; | ||
| 146 | Elf32_Addr p_vaddr; | ||
| 147 | Elf32_Addr p_paddr; | ||
| 148 | Elf32_Word p_filesz; | ||
| 149 | Elf32_Word p_memsz; | ||
| 150 | Elf32_Word p_flags; | ||
| 151 | Elf32_Word p_align; | ||
| 152 | }; | ||
| 153 | |||
| 154 | // Symbol table entry | ||
| 155 | struct Elf32_Sym { | ||
| 156 | Elf32_Word st_name; | ||
| 157 | Elf32_Addr st_value; | ||
| 158 | Elf32_Word st_size; | ||
| 159 | unsigned char st_info; | ||
| 160 | unsigned char st_other; | ||
| 161 | Elf32_Half st_shndx; | ||
| 162 | }; | ||
| 163 | |||
| 164 | // Relocation entries | ||
| 165 | struct Elf32_Rel { | ||
| 166 | Elf32_Addr r_offset; | ||
| 167 | Elf32_Word r_info; | ||
| 168 | }; | ||
| 169 | 18 | ||
| 170 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 19 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 171 | // ElfReader class | 20 | // ElfReader class |
| @@ -193,11 +42,11 @@ public: | |||
| 193 | } | 42 | } |
| 194 | 43 | ||
| 195 | // Quick accessors | 44 | // Quick accessors |
| 196 | ElfType GetType() const { | 45 | u16 GetType() const { |
| 197 | return (ElfType)(header->e_type); | 46 | return header->e_type; |
| 198 | } | 47 | } |
| 199 | ElfMachine GetMachine() const { | 48 | u16 GetMachine() const { |
| 200 | return (ElfMachine)(header->e_machine); | 49 | return header->e_machine; |
| 201 | } | 50 | } |
| 202 | VAddr GetEntryPoint() const { | 51 | VAddr GetEntryPoint() const { |
| 203 | return entryPoint; | 52 | return entryPoint; |
| @@ -220,13 +69,13 @@ public: | |||
| 220 | const u8* GetSectionDataPtr(int section) const { | 69 | const u8* GetSectionDataPtr(int section) const { |
| 221 | if (section < 0 || section >= header->e_shnum) | 70 | if (section < 0 || section >= header->e_shnum) |
| 222 | return nullptr; | 71 | return nullptr; |
| 223 | if (sections[section].sh_type != SHT_NOBITS) | 72 | if (sections[section].sh_type != ElfShtNobits) |
| 224 | return GetPtr(sections[section].sh_offset); | 73 | return GetPtr(sections[section].sh_offset); |
| 225 | else | 74 | else |
| 226 | return nullptr; | 75 | return nullptr; |
| 227 | } | 76 | } |
| 228 | bool IsCodeSection(int section) const { | 77 | bool IsCodeSection(int section) const { |
| 229 | return sections[section].sh_type == SHT_PROGBITS; | 78 | return sections[section].sh_type == ElfShtProgBits; |
| 230 | } | 79 | } |
| 231 | const u8* GetSegmentPtr(int segment) { | 80 | const u8* GetSegmentPtr(int segment) { |
| 232 | return GetPtr(segments[segment].p_offset); | 81 | return GetPtr(segments[segment].p_offset); |
| @@ -256,7 +105,7 @@ ElfReader::ElfReader(void* ptr) { | |||
| 256 | } | 105 | } |
| 257 | 106 | ||
| 258 | const char* ElfReader::GetSectionName(int section) const { | 107 | const char* ElfReader::GetSectionName(int section) const { |
| 259 | if (sections[section].sh_type == SHT_NULL) | 108 | if (sections[section].sh_type == ElfShtNull) |
| 260 | return nullptr; | 109 | return nullptr; |
| 261 | 110 | ||
| 262 | int name_offset = sections[section].sh_name; | 111 | int name_offset = sections[section].sh_name; |
| @@ -272,7 +121,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { | |||
| 272 | LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); | 121 | LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); |
| 273 | 122 | ||
| 274 | // Should we relocate? | 123 | // Should we relocate? |
| 275 | relocate = (header->e_type != ET_EXEC); | 124 | relocate = (header->e_type != ElfTypeExec); |
| 276 | 125 | ||
| 277 | if (relocate) { | 126 | if (relocate) { |
| 278 | LOG_DEBUG(Loader, "Relocatable module"); | 127 | LOG_DEBUG(Loader, "Relocatable module"); |
| @@ -288,7 +137,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { | |||
| 288 | u64 total_image_size = 0; | 137 | u64 total_image_size = 0; |
| 289 | for (unsigned int i = 0; i < header->e_phnum; ++i) { | 138 | for (unsigned int i = 0; i < header->e_phnum; ++i) { |
| 290 | const Elf32_Phdr* p = &segments[i]; | 139 | const Elf32_Phdr* p = &segments[i]; |
| 291 | if (p->p_type == PT_LOAD) { | 140 | if (p->p_type == ElfPtLoad) { |
| 292 | total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF; | 141 | total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF; |
| 293 | } | 142 | } |
| 294 | } | 143 | } |
| @@ -303,14 +152,14 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { | |||
| 303 | LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, | 152 | LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, |
| 304 | p->p_vaddr, p->p_filesz, p->p_memsz); | 153 | p->p_vaddr, p->p_filesz, p->p_memsz); |
| 305 | 154 | ||
| 306 | if (p->p_type == PT_LOAD) { | 155 | if (p->p_type == ElfPtLoad) { |
| 307 | Kernel::CodeSet::Segment* codeset_segment; | 156 | Kernel::CodeSet::Segment* codeset_segment; |
| 308 | u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); | 157 | u32 permission_flags = p->p_flags & (ElfPfRead | ElfPfWrite | ElfPfExec); |
| 309 | if (permission_flags == (PF_R | PF_X)) { | 158 | if (permission_flags == (ElfPfRead | ElfPfExec)) { |
| 310 | codeset_segment = &codeset.CodeSegment(); | 159 | codeset_segment = &codeset.CodeSegment(); |
| 311 | } else if (permission_flags == (PF_R)) { | 160 | } else if (permission_flags == (ElfPfRead)) { |
| 312 | codeset_segment = &codeset.RODataSegment(); | 161 | codeset_segment = &codeset.RODataSegment(); |
| 313 | } else if (permission_flags == (PF_R | PF_W)) { | 162 | } else if (permission_flags == (ElfPfRead | ElfPfWrite)) { |
| 314 | codeset_segment = &codeset.DataSegment(); | 163 | codeset_segment = &codeset.DataSegment(); |
| 315 | } else { | 164 | } else { |
| 316 | LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, | 165 | LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, |