diff options
| author | 2015-01-07 01:30:32 +0000 | |
|---|---|---|
| committer | 2015-01-15 22:23:08 +0100 | |
| commit | df0d66c7cf518638112843b0bf0a8d7950b9041c (patch) | |
| tree | efc5136c95e8cf154b0ae13974d60e6412483f3a /src/core/loader/elf.cpp | |
| parent | Loader: Clean up the 3DSX AppLoader. (diff) | |
| download | yuzu-df0d66c7cf518638112843b0bf0a8d7950b9041c.tar.gz yuzu-df0d66c7cf518638112843b0bf0a8d7950b9041c.tar.xz yuzu-df0d66c7cf518638112843b0bf0a8d7950b9041c.zip | |
Loader: Clean up the ELF AppLoader.
Diffstat (limited to 'src/core/loader/elf.cpp')
| -rw-r--r-- | src/core/loader/elf.cpp | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index d1c3aea72..e7e5df408 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -18,25 +18,25 @@ | |||
| 18 | 18 | ||
| 19 | // File type | 19 | // File type |
| 20 | enum ElfType { | 20 | enum ElfType { |
| 21 | ET_NONE = 0, | 21 | ET_NONE = 0, |
| 22 | ET_REL = 1, | 22 | ET_REL = 1, |
| 23 | ET_EXEC = 2, | 23 | ET_EXEC = 2, |
| 24 | ET_DYN = 3, | 24 | ET_DYN = 3, |
| 25 | ET_CORE = 4, | 25 | ET_CORE = 4, |
| 26 | ET_LOPROC = 0xFF00, | 26 | ET_LOPROC = 0xFF00, |
| 27 | ET_HIPROC = 0xFFFF, | 27 | ET_HIPROC = 0xFFFF, |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | // Machine/Architecture | 30 | // Machine/Architecture |
| 31 | enum ElfMachine { | 31 | enum ElfMachine { |
| 32 | EM_NONE = 0, | 32 | EM_NONE = 0, |
| 33 | EM_M32 = 1, | 33 | EM_M32 = 1, |
| 34 | EM_SPARC = 2, | 34 | EM_SPARC = 2, |
| 35 | EM_386 = 3, | 35 | EM_386 = 3, |
| 36 | EM_68K = 4, | 36 | EM_68K = 4, |
| 37 | EM_88K = 5, | 37 | EM_88K = 5, |
| 38 | EM_860 = 7, | 38 | EM_860 = 7, |
| 39 | EM_MIPS = 8 | 39 | EM_MIPS = 8 |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | // File version | 42 | // File version |
| @@ -54,12 +54,6 @@ enum ElfMachine { | |||
| 54 | #define EI_PAD 7 | 54 | #define EI_PAD 7 |
| 55 | #define EI_NIDENT 16 | 55 | #define EI_NIDENT 16 |
| 56 | 56 | ||
| 57 | // Magic number | ||
| 58 | #define ELFMAG0 0x7F | ||
| 59 | #define ELFMAG1 'E' | ||
| 60 | #define ELFMAG2 'L' | ||
| 61 | #define ELFMAG3 'F' | ||
| 62 | |||
| 63 | // Sections constants | 57 | // Sections constants |
| 64 | 58 | ||
| 65 | // Section types | 59 | // Section types |
| @@ -83,10 +77,10 @@ enum ElfMachine { | |||
| 83 | // Section flags | 77 | // Section flags |
| 84 | enum ElfSectionFlags | 78 | enum ElfSectionFlags |
| 85 | { | 79 | { |
| 86 | SHF_WRITE = 0x1, | 80 | SHF_WRITE = 0x1, |
| 87 | SHF_ALLOC = 0x2, | 81 | SHF_ALLOC = 0x2, |
| 88 | SHF_EXECINSTR = 0x4, | 82 | SHF_EXECINSTR = 0x4, |
| 89 | SHF_MASKPROC = 0xF0000000, | 83 | SHF_MASKPROC = 0xF0000000, |
| 90 | }; | 84 | }; |
| 91 | 85 | ||
| 92 | // Segment types | 86 | // Segment types |
| @@ -100,11 +94,11 @@ enum ElfSectionFlags | |||
| 100 | #define PT_LOPROC 0x70000000 | 94 | #define PT_LOPROC 0x70000000 |
| 101 | #define PT_HIPROC 0x7FFFFFFF | 95 | #define PT_HIPROC 0x7FFFFFFF |
| 102 | 96 | ||
| 103 | typedef unsigned int Elf32_Addr; | 97 | typedef unsigned int Elf32_Addr; |
| 104 | typedef unsigned short Elf32_Half; | 98 | typedef unsigned short Elf32_Half; |
| 105 | typedef unsigned int Elf32_Off; | 99 | typedef unsigned int Elf32_Off; |
| 106 | typedef signed int Elf32_Sword; | 100 | typedef signed int Elf32_Sword; |
| 107 | typedef unsigned int Elf32_Word; | 101 | typedef unsigned int Elf32_Word; |
| 108 | 102 | ||
| 109 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 103 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 110 | // ELF file header | 104 | // ELF file header |
| @@ -188,7 +182,6 @@ private: | |||
| 188 | 182 | ||
| 189 | public: | 183 | public: |
| 190 | ElfReader(void *ptr); | 184 | ElfReader(void *ptr); |
| 191 | ~ElfReader() { } | ||
| 192 | 185 | ||
| 193 | u32 Read32(int off) const { return base32[off >> 2]; } | 186 | u32 Read32(int off) const { return base32[off >> 2]; } |
| 194 | 187 | ||
| @@ -197,7 +190,7 @@ public: | |||
| 197 | ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } | 190 | ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } |
| 198 | u32 GetEntryPoint() const { return entryPoint; } | 191 | u32 GetEntryPoint() const { return entryPoint; } |
| 199 | u32 GetFlags() const { return (u32)(header->e_flags); } | 192 | u32 GetFlags() const { return (u32)(header->e_flags); } |
| 200 | bool LoadInto(u32 vaddr); | 193 | void LoadInto(u32 vaddr); |
| 201 | bool LoadSymbols(); | 194 | bool LoadSymbols(); |
| 202 | 195 | ||
| 203 | int GetNumSegments() const { return (int)(header->e_phnum); } | 196 | int GetNumSegments() const { return (int)(header->e_phnum); } |
| @@ -229,11 +222,11 @@ public: | |||
| 229 | 222 | ||
| 230 | ElfReader::ElfReader(void *ptr) { | 223 | ElfReader::ElfReader(void *ptr) { |
| 231 | base = (char*)ptr; | 224 | base = (char*)ptr; |
| 232 | base32 = (u32 *)ptr; | 225 | base32 = (u32*)ptr; |
| 233 | header = (Elf32_Ehdr*)ptr; | 226 | header = (Elf32_Ehdr*)ptr; |
| 234 | 227 | ||
| 235 | segments = (Elf32_Phdr *)(base + header->e_phoff); | 228 | segments = (Elf32_Phdr*)(base + header->e_phoff); |
| 236 | sections = (Elf32_Shdr *)(base + header->e_shoff); | 229 | sections = (Elf32_Shdr*)(base + header->e_shoff); |
| 237 | 230 | ||
| 238 | entryPoint = header->e_entry; | 231 | entryPoint = header->e_entry; |
| 239 | 232 | ||
| @@ -245,7 +238,7 @@ const char *ElfReader::GetSectionName(int section) const { | |||
| 245 | return nullptr; | 238 | return nullptr; |
| 246 | 239 | ||
| 247 | int name_offset = sections[section].sh_name; | 240 | int name_offset = sections[section].sh_name; |
| 248 | char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx); | 241 | const char* ptr = (char*)GetSectionDataPtr(header->e_shstrndx); |
| 249 | 242 | ||
| 250 | if (ptr) | 243 | if (ptr) |
| 251 | return ptr + name_offset; | 244 | return ptr + name_offset; |
| @@ -253,7 +246,7 @@ const char *ElfReader::GetSectionName(int section) const { | |||
| 253 | return nullptr; | 246 | return nullptr; |
| 254 | } | 247 | } |
| 255 | 248 | ||
| 256 | bool ElfReader::LoadInto(u32 vaddr) { | 249 | void ElfReader::LoadInto(u32 vaddr) { |
| 257 | LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); | 250 | LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); |
| 258 | 251 | ||
| 259 | // Should we relocate? | 252 | // Should we relocate? |
| @@ -271,20 +264,19 @@ bool ElfReader::LoadInto(u32 vaddr) { | |||
| 271 | u32 segment_addr[32]; | 264 | u32 segment_addr[32]; |
| 272 | u32 base_addr = relocate ? vaddr : 0; | 265 | u32 base_addr = relocate ? vaddr : 0; |
| 273 | 266 | ||
| 274 | for (int i = 0; i < header->e_phnum; i++) { | 267 | for (unsigned i = 0; i < header->e_phnum; i++) { |
| 275 | Elf32_Phdr *p = segments + i; | 268 | Elf32_Phdr* p = segments + i; |
| 276 | LOG_DEBUG(Loader, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, | 269 | LOG_DEBUG(Loader, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, |
| 277 | p->p_filesz, p->p_memsz); | 270 | p->p_filesz, p->p_memsz); |
| 278 | 271 | ||
| 279 | if (p->p_type == PT_LOAD) { | 272 | if (p->p_type == PT_LOAD) { |
| 280 | segment_addr[i] = base_addr + p->p_vaddr; | 273 | segment_addr[i] = base_addr + p->p_vaddr; |
| 281 | memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz); | 274 | memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz); |
| 282 | LOG_DEBUG(Loader, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], | 275 | LOG_DEBUG(Loader, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], |
| 283 | p->p_memsz); | 276 | p->p_memsz); |
| 284 | } | 277 | } |
| 285 | } | 278 | } |
| 286 | LOG_DEBUG(Loader, "Done loading."); | 279 | LOG_DEBUG(Loader, "Done loading."); |
| 287 | return true; | ||
| 288 | } | 280 | } |
| 289 | 281 | ||
| 290 | SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { | 282 | SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { |
| @@ -305,9 +297,9 @@ bool ElfReader::LoadSymbols() { | |||
| 305 | const char *stringBase = (const char *)GetSectionDataPtr(stringSection); | 297 | const char *stringBase = (const char *)GetSectionDataPtr(stringSection); |
| 306 | 298 | ||
| 307 | //We have a symbol table! | 299 | //We have a symbol table! |
| 308 | Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); | 300 | Elf32_Sym* symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); |
| 309 | int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); | 301 | int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); |
| 310 | for (int sym = 0; sym < numSymbols; sym++) { | 302 | for (unsigned sym = 0; sym < numSymbols; sym++) { |
| 311 | int size = symtab[sym].st_size; | 303 | int size = symtab[sym].st_size; |
| 312 | if (size == 0) | 304 | if (size == 0) |
| 313 | continue; | 305 | continue; |
| @@ -354,7 +346,8 @@ ResultStatus AppLoader_ELF::Load() { | |||
| 354 | 346 | ||
| 355 | u32 size = static_cast<u32>(file->GetSize()); | 347 | u32 size = static_cast<u32>(file->GetSize()); |
| 356 | std::unique_ptr<u8[]> buffer(new u8[size]); | 348 | std::unique_ptr<u8[]> buffer(new u8[size]); |
| 357 | file->ReadBytes(&buffer[0], size); | 349 | if (file->ReadBytes(&buffer[0], size) != size) |
| 350 | return ResultStatus::Error; | ||
| 358 | 351 | ||
| 359 | ElfReader elf_reader(&buffer[0]); | 352 | ElfReader elf_reader(&buffer[0]); |
| 360 | elf_reader.LoadInto(0x00100000); | 353 | elf_reader.LoadInto(0x00100000); |