summaryrefslogtreecommitdiff
path: root/src/core/loader/elf.cpp
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-09-21 11:29:48 -0700
committerGravatar GitHub2016-09-21 11:29:48 -0700
commitd5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a (patch)
tree8a22ca73ff838f3f0090b29a548ae81087fc90ed /src/core/loader/elf.cpp
parentREADME: Specify master branch for Travis CI badge (diff)
parentFix Travis clang-format check (diff)
downloadyuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.gz
yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.xz
yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.zip
Merge pull request #2086 from linkmauve/clang-format
Add clang-format as part of our {commit,travis}-time checks
Diffstat (limited to 'src/core/loader/elf.cpp')
-rw-r--r--src/core/loader/elf.cpp233
1 files changed, 127 insertions, 106 deletions
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 69df94324..8eb5200ab 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -3,14 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring> 5#include <cstring>
6#include <string>
7#include <memory> 6#include <memory>
8 7#include <string>
9#include "common/common_types.h" 8#include "common/common_types.h"
10#include "common/file_util.h" 9#include "common/file_util.h"
11#include "common/logging/log.h" 10#include "common/logging/log.h"
12#include "common/symbols.h" 11#include "common/symbols.h"
13
14#include "core/hle/kernel/process.h" 12#include "core/hle/kernel/process.h"
15#include "core/hle/kernel/resource_limit.h" 13#include "core/hle/kernel/resource_limit.h"
16#include "core/loader/elf.h" 14#include "core/loader/elf.h"
@@ -24,112 +22,111 @@ using Kernel::CodeSet;
24 22
25// File type 23// File type
26enum ElfType { 24enum ElfType {
27 ET_NONE = 0, 25 ET_NONE = 0,
28 ET_REL = 1, 26 ET_REL = 1,
29 ET_EXEC = 2, 27 ET_EXEC = 2,
30 ET_DYN = 3, 28 ET_DYN = 3,
31 ET_CORE = 4, 29 ET_CORE = 4,
32 ET_LOPROC = 0xFF00, 30 ET_LOPROC = 0xFF00,
33 ET_HIPROC = 0xFFFF, 31 ET_HIPROC = 0xFFFF,
34}; 32};
35 33
36// Machine/Architecture 34// Machine/Architecture
37enum ElfMachine { 35enum ElfMachine {
38 EM_NONE = 0, 36 EM_NONE = 0,
39 EM_M32 = 1, 37 EM_M32 = 1,
40 EM_SPARC = 2, 38 EM_SPARC = 2,
41 EM_386 = 3, 39 EM_386 = 3,
42 EM_68K = 4, 40 EM_68K = 4,
43 EM_88K = 5, 41 EM_88K = 5,
44 EM_860 = 7, 42 EM_860 = 7,
45 EM_MIPS = 8 43 EM_MIPS = 8
46}; 44};
47 45
48// File version 46// File version
49#define EV_NONE 0 47#define EV_NONE 0
50#define EV_CURRENT 1 48#define EV_CURRENT 1
51 49
52// Identification index 50// Identification index
53#define EI_MAG0 0 51#define EI_MAG0 0
54#define EI_MAG1 1 52#define EI_MAG1 1
55#define EI_MAG2 2 53#define EI_MAG2 2
56#define EI_MAG3 3 54#define EI_MAG3 3
57#define EI_CLASS 4 55#define EI_CLASS 4
58#define EI_DATA 5 56#define EI_DATA 5
59#define EI_VERSION 6 57#define EI_VERSION 6
60#define EI_PAD 7 58#define EI_PAD 7
61#define EI_NIDENT 16 59#define EI_NIDENT 16
62 60
63// Sections constants 61// Sections constants
64 62
65// Section types 63// Section types
66#define SHT_NULL 0 64#define SHT_NULL 0
67#define SHT_PROGBITS 1 65#define SHT_PROGBITS 1
68#define SHT_SYMTAB 2 66#define SHT_SYMTAB 2
69#define SHT_STRTAB 3 67#define SHT_STRTAB 3
70#define SHT_RELA 4 68#define SHT_RELA 4
71#define SHT_HASH 5 69#define SHT_HASH 5
72#define SHT_DYNAMIC 6 70#define SHT_DYNAMIC 6
73#define SHT_NOTE 7 71#define SHT_NOTE 7
74#define SHT_NOBITS 8 72#define SHT_NOBITS 8
75#define SHT_REL 9 73#define SHT_REL 9
76#define SHT_SHLIB 10 74#define SHT_SHLIB 10
77#define SHT_DYNSYM 11 75#define SHT_DYNSYM 11
78#define SHT_LOPROC 0x70000000 76#define SHT_LOPROC 0x70000000
79#define SHT_HIPROC 0x7FFFFFFF 77#define SHT_HIPROC 0x7FFFFFFF
80#define SHT_LOUSER 0x80000000 78#define SHT_LOUSER 0x80000000
81#define SHT_HIUSER 0xFFFFFFFF 79#define SHT_HIUSER 0xFFFFFFFF
82 80
83// Section flags 81// Section flags
84enum ElfSectionFlags 82enum ElfSectionFlags {
85{ 83 SHF_WRITE = 0x1,
86 SHF_WRITE = 0x1, 84 SHF_ALLOC = 0x2,
87 SHF_ALLOC = 0x2,
88 SHF_EXECINSTR = 0x4, 85 SHF_EXECINSTR = 0x4,
89 SHF_MASKPROC = 0xF0000000, 86 SHF_MASKPROC = 0xF0000000,
90}; 87};
91 88
92// Segment types 89// Segment types
93#define PT_NULL 0 90#define PT_NULL 0
94#define PT_LOAD 1 91#define PT_LOAD 1
95#define PT_DYNAMIC 2 92#define PT_DYNAMIC 2
96#define PT_INTERP 3 93#define PT_INTERP 3
97#define PT_NOTE 4 94#define PT_NOTE 4
98#define PT_SHLIB 5 95#define PT_SHLIB 5
99#define PT_PHDR 6 96#define PT_PHDR 6
100#define PT_LOPROC 0x70000000 97#define PT_LOPROC 0x70000000
101#define PT_HIPROC 0x7FFFFFFF 98#define PT_HIPROC 0x7FFFFFFF
102 99
103// Segment flags 100// Segment flags
104#define PF_X 0x1 101#define PF_X 0x1
105#define PF_W 0x2 102#define PF_W 0x2
106#define PF_R 0x4 103#define PF_R 0x4
107#define PF_MASKPROC 0xF0000000 104#define PF_MASKPROC 0xF0000000
108 105
109typedef unsigned int Elf32_Addr; 106typedef unsigned int Elf32_Addr;
110typedef unsigned short Elf32_Half; 107typedef unsigned short Elf32_Half;
111typedef unsigned int Elf32_Off; 108typedef unsigned int Elf32_Off;
112typedef signed int Elf32_Sword; 109typedef signed int Elf32_Sword;
113typedef unsigned int Elf32_Word; 110typedef unsigned int Elf32_Word;
114 111
115//////////////////////////////////////////////////////////////////////////////////////////////////// 112////////////////////////////////////////////////////////////////////////////////////////////////////
116// ELF file header 113// ELF file header
117 114
118struct Elf32_Ehdr { 115struct Elf32_Ehdr {
119 unsigned char e_ident[EI_NIDENT]; 116 unsigned char e_ident[EI_NIDENT];
120 Elf32_Half e_type; 117 Elf32_Half e_type;
121 Elf32_Half e_machine; 118 Elf32_Half e_machine;
122 Elf32_Word e_version; 119 Elf32_Word e_version;
123 Elf32_Addr e_entry; 120 Elf32_Addr e_entry;
124 Elf32_Off e_phoff; 121 Elf32_Off e_phoff;
125 Elf32_Off e_shoff; 122 Elf32_Off e_shoff;
126 Elf32_Word e_flags; 123 Elf32_Word e_flags;
127 Elf32_Half e_ehsize; 124 Elf32_Half e_ehsize;
128 Elf32_Half e_phentsize; 125 Elf32_Half e_phentsize;
129 Elf32_Half e_phnum; 126 Elf32_Half e_phnum;
130 Elf32_Half e_shentsize; 127 Elf32_Half e_shentsize;
131 Elf32_Half e_shnum; 128 Elf32_Half e_shnum;
132 Elf32_Half e_shstrndx; 129 Elf32_Half e_shstrndx;
133}; 130};
134 131
135// Section header 132// Section header
@@ -138,7 +135,7 @@ struct Elf32_Shdr {
138 Elf32_Word sh_type; 135 Elf32_Word sh_type;
139 Elf32_Word sh_flags; 136 Elf32_Word sh_flags;
140 Elf32_Addr sh_addr; 137 Elf32_Addr sh_addr;
141 Elf32_Off sh_offset; 138 Elf32_Off sh_offset;
142 Elf32_Word sh_size; 139 Elf32_Word sh_size;
143 Elf32_Word sh_link; 140 Elf32_Word sh_link;
144 Elf32_Word sh_info; 141 Elf32_Word sh_info;
@@ -149,7 +146,7 @@ struct Elf32_Shdr {
149// Segment header 146// Segment header
150struct Elf32_Phdr { 147struct Elf32_Phdr {
151 Elf32_Word p_type; 148 Elf32_Word p_type;
152 Elf32_Off p_offset; 149 Elf32_Off p_offset;
153 Elf32_Addr p_vaddr; 150 Elf32_Addr p_vaddr;
154 Elf32_Addr p_paddr; 151 Elf32_Addr p_paddr;
155 Elf32_Word p_filesz; 152 Elf32_Word p_filesz;
@@ -160,12 +157,12 @@ struct Elf32_Phdr {
160 157
161// Symbol table entry 158// Symbol table entry
162struct Elf32_Sym { 159struct Elf32_Sym {
163 Elf32_Word st_name; 160 Elf32_Word st_name;
164 Elf32_Addr st_value; 161 Elf32_Addr st_value;
165 Elf32_Word st_size; 162 Elf32_Word st_size;
166 unsigned char st_info; 163 unsigned char st_info;
167 unsigned char st_other; 164 unsigned char st_other;
168 Elf32_Half st_shndx; 165 Elf32_Half st_shndx;
169}; 166};
170 167
171// Relocation entries 168// Relocation entries
@@ -181,35 +178,51 @@ typedef int SectionID;
181 178
182class ElfReader { 179class ElfReader {
183private: 180private:
184 char *base; 181 char* base;
185 u32 *base32; 182 u32* base32;
186 183
187 Elf32_Ehdr *header; 184 Elf32_Ehdr* header;
188 Elf32_Phdr *segments; 185 Elf32_Phdr* segments;
189 Elf32_Shdr *sections; 186 Elf32_Shdr* sections;
190 187
191 u32 *sectionAddrs; 188 u32* sectionAddrs;
192 bool relocate; 189 bool relocate;
193 u32 entryPoint; 190 u32 entryPoint;
194 191
195public: 192public:
196 ElfReader(void *ptr); 193 ElfReader(void* ptr);
197 194
198 u32 Read32(int off) const { return base32[off >> 2]; } 195 u32 Read32(int off) const {
196 return base32[off >> 2];
197 }
199 198
200 // Quick accessors 199 // Quick accessors
201 ElfType GetType() const { return (ElfType)(header->e_type); } 200 ElfType GetType() const {
202 ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } 201 return (ElfType)(header->e_type);
203 u32 GetEntryPoint() const { return entryPoint; } 202 }
204 u32 GetFlags() const { return (u32)(header->e_flags); } 203 ElfMachine GetMachine() const {
204 return (ElfMachine)(header->e_machine);
205 }
206 u32 GetEntryPoint() const {
207 return entryPoint;
208 }
209 u32 GetFlags() const {
210 return (u32)(header->e_flags);
211 }
205 SharedPtr<CodeSet> LoadInto(u32 vaddr); 212 SharedPtr<CodeSet> LoadInto(u32 vaddr);
206 bool LoadSymbols(); 213 bool LoadSymbols();
207 214
208 int GetNumSegments() const { return (int)(header->e_phnum); } 215 int GetNumSegments() const {
209 int GetNumSections() const { return (int)(header->e_shnum); } 216 return (int)(header->e_phnum);
210 const u8 *GetPtr(int offset) const { return (u8*)base + offset; } 217 }
211 const char *GetSectionName(int section) const; 218 int GetNumSections() const {
212 const u8 *GetSectionDataPtr(int section) const { 219 return (int)(header->e_shnum);
220 }
221 const u8* GetPtr(int offset) const {
222 return (u8*)base + offset;
223 }
224 const char* GetSectionName(int section) const;
225 const u8* GetSectionDataPtr(int section) const {
213 if (section < 0 || section >= header->e_shnum) 226 if (section < 0 || section >= header->e_shnum)
214 return nullptr; 227 return nullptr;
215 if (sections[section].sh_type != SHT_NOBITS) 228 if (sections[section].sh_type != SHT_NOBITS)
@@ -220,19 +233,23 @@ public:
220 bool IsCodeSection(int section) const { 233 bool IsCodeSection(int section) const {
221 return sections[section].sh_type == SHT_PROGBITS; 234 return sections[section].sh_type == SHT_PROGBITS;
222 } 235 }
223 const u8 *GetSegmentPtr(int segment) { 236 const u8* GetSegmentPtr(int segment) {
224 return GetPtr(segments[segment].p_offset); 237 return GetPtr(segments[segment].p_offset);
225 } 238 }
226 u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; } 239 u32 GetSectionAddr(SectionID section) const {
227 unsigned int GetSectionSize(SectionID section) const { return sections[section].sh_size; } 240 return sectionAddrs[section];
228 SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found 241 }
242 unsigned int GetSectionSize(SectionID section) const {
243 return sections[section].sh_size;
244 }
245 SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found
229 246
230 bool DidRelocate() const { 247 bool DidRelocate() const {
231 return relocate; 248 return relocate;
232 } 249 }
233}; 250};
234 251
235ElfReader::ElfReader(void *ptr) { 252ElfReader::ElfReader(void* ptr) {
236 base = (char*)ptr; 253 base = (char*)ptr;
237 base32 = (u32*)ptr; 254 base32 = (u32*)ptr;
238 header = (Elf32_Ehdr*)ptr; 255 header = (Elf32_Ehdr*)ptr;
@@ -245,7 +262,7 @@ ElfReader::ElfReader(void *ptr) {
245 LoadSymbols(); 262 LoadSymbols();
246} 263}
247 264
248const char *ElfReader::GetSectionName(int section) const { 265const char* ElfReader::GetSectionName(int section) const {
249 if (sections[section].sh_type == SHT_NULL) 266 if (sections[section].sh_type == SHT_NULL)
250 return nullptr; 267 return nullptr;
251 268
@@ -303,12 +320,15 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
303 } else if (permission_flags == (PF_R | PF_W)) { 320 } else if (permission_flags == (PF_R | PF_W)) {
304 codeset_segment = &codeset->data; 321 codeset_segment = &codeset->data;
305 } else { 322 } else {
306 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, p->p_flags); 323 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i,
324 p->p_flags);
307 continue; 325 continue;
308 } 326 }
309 327
310 if (codeset_segment->size != 0) { 328 if (codeset_segment->size != 0) {
311 LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra segment (id %i)", i); 329 LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra "
330 "segment (id %i)",
331 i);
312 continue; 332 continue;
313 } 333 }
314 334
@@ -332,9 +352,9 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
332 return codeset; 352 return codeset;
333} 353}
334 354
335SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { 355SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const {
336 for (int i = firstSection; i < header->e_shnum; i++) { 356 for (int i = firstSection; i < header->e_shnum; i++) {
337 const char *secname = GetSectionName(i); 357 const char* secname = GetSectionName(i);
338 358
339 if (secname != nullptr && strcmp(name, secname) == 0) 359 if (secname != nullptr && strcmp(name, secname) == 0)
340 return i; 360 return i;
@@ -347,9 +367,9 @@ bool ElfReader::LoadSymbols() {
347 SectionID sec = GetSectionByName(".symtab"); 367 SectionID sec = GetSectionByName(".symtab");
348 if (sec != -1) { 368 if (sec != -1) {
349 int stringSection = sections[sec].sh_link; 369 int stringSection = sections[sec].sh_link;
350 const char *stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection)); 370 const char* stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection));
351 371
352 //We have a symbol table! 372 // We have a symbol table!
353 const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec)); 373 const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec));
354 unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); 374 unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
355 for (unsigned sym = 0; sym < numSymbols; sym++) { 375 for (unsigned sym = 0; sym < numSymbols; sym++) {
@@ -359,7 +379,7 @@ bool ElfReader::LoadSymbols() {
359 379
360 int type = symtab[sym].st_info & 0xF; 380 int type = symtab[sym].st_info & 0xF;
361 381
362 const char *name = stringBase + symtab[sym].st_name; 382 const char* name = stringBase + symtab[sym].st_name;
363 383
364 Symbols::Add(symtab[sym].st_value, name, size, type); 384 Symbols::Add(symtab[sym].st_value, name, size, type);
365 385
@@ -411,7 +431,8 @@ ResultStatus AppLoader_ELF::Load() {
411 Kernel::g_current_process->address_mappings = default_address_mappings; 431 Kernel::g_current_process->address_mappings = default_address_mappings;
412 432
413 // Attach the default resource limit (APPLICATION) to the process 433 // Attach the default resource limit (APPLICATION) to the process
414 Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 434 Kernel::g_current_process->resource_limit =
435 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
415 436
416 Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); 437 Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE);
417 438