summaryrefslogtreecommitdiff
path: root/src/core/loader/elf.cpp
diff options
context:
space:
mode:
authorGravatar Emmanuel Gil Peyrot2015-01-07 01:30:32 +0000
committerGravatar Emmanuel Gil Peyrot2015-01-15 22:23:08 +0100
commitdf0d66c7cf518638112843b0bf0a8d7950b9041c (patch)
treeefc5136c95e8cf154b0ae13974d60e6412483f3a /src/core/loader/elf.cpp
parentLoader: Clean up the 3DSX AppLoader. (diff)
downloadyuzu-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.cpp73
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
20enum ElfType { 20enum 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
31enum ElfMachine { 31enum 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
84enum ElfSectionFlags 78enum 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
103typedef unsigned int Elf32_Addr; 97typedef unsigned int Elf32_Addr;
104typedef unsigned short Elf32_Half; 98typedef unsigned short Elf32_Half;
105typedef unsigned int Elf32_Off; 99typedef unsigned int Elf32_Off;
106typedef signed int Elf32_Sword; 100typedef signed int Elf32_Sword;
107typedef unsigned int Elf32_Word; 101typedef unsigned int Elf32_Word;
108 102
109//////////////////////////////////////////////////////////////////////////////////////////////////// 103////////////////////////////////////////////////////////////////////////////////////////////////////
110// ELF file header 104// ELF file header
@@ -188,7 +182,6 @@ private:
188 182
189public: 183public:
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
230ElfReader::ElfReader(void *ptr) { 223ElfReader::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
256bool ElfReader::LoadInto(u32 vaddr) { 249void 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
290SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { 282SectionID 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);