diff options
Diffstat (limited to 'src/core/arm/symbols.cpp')
| -rw-r--r-- | src/core/arm/symbols.cpp | 85 |
1 files changed, 13 insertions, 72 deletions
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 | ||