summaryrefslogtreecommitdiff
path: root/src/core/loader/elf.h
diff options
context:
space:
mode:
authorGravatar bunnei2014-06-16 23:05:10 -0400
committerGravatar bunnei2014-06-16 23:43:32 -0400
commit1da361c7ab55e1dbe6709a738e228bfab5a5bb78 (patch)
tree487be34416c624106a01edf8b075866fb2cb9d33 /src/core/loader/elf.h
parentLoader: Added support for booting NCCH executables. (diff)
downloadyuzu-1da361c7ab55e1dbe6709a738e228bfab5a5bb78.tar.gz
yuzu-1da361c7ab55e1dbe6709a738e228bfab5a5bb78.tar.xz
yuzu-1da361c7ab55e1dbe6709a738e228bfab5a5bb78.zip
Elf: Renamed modules to be consistent with new loader naming, fixed tabs -> spaces.
Diffstat (limited to 'src/core/loader/elf.h')
-rw-r--r--src/core/loader/elf.h331
1 files changed, 331 insertions, 0 deletions
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h
new file mode 100644
index 000000000..2e6b80982
--- /dev/null
+++ b/src/core/loader/elf.h
@@ -0,0 +1,331 @@
1// Copyright 2013 Dolphin Emulator Project / Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common.h"
8
9// ELF Header Constants
10
11// File type
12enum ElfType {
13 ET_NONE = 0,
14 ET_REL = 1,
15 ET_EXEC = 2,
16 ET_DYN = 3,
17 ET_CORE = 4,
18 ET_LOPROC = 0xFF00,
19 ET_HIPROC = 0xFFFF,
20};
21
22// Machine/Architecture
23enum ElfMachine {
24 EM_NONE = 0,
25 EM_M32 = 1,
26 EM_SPARC = 2,
27 EM_386 = 3,
28 EM_68K = 4,
29 EM_88K = 5,
30 EM_860 = 7,
31 EM_MIPS = 8
32};
33
34// File version
35#define EV_NONE 0
36#define EV_CURRENT 1
37
38// Identification index
39#define EI_MAG0 0
40#define EI_MAG1 1
41#define EI_MAG2 2
42#define EI_MAG3 3
43#define EI_CLASS 4
44#define EI_DATA 5
45#define EI_VERSION 6
46#define EI_PAD 7
47#define EI_NIDENT 16
48
49// Magic number
50#define ELFMAG0 0x7F
51#define ELFMAG1 'E'
52#define ELFMAG2 'L'
53#define ELFMAG3 'F'
54
55// File class
56#define ELFCLASSNONE 0
57#define ELFCLASS32 1
58#define ELFCLASS64 2
59
60// Encoding
61#define ELFDATANONE 0
62#define ELFDATA2LSB 1
63#define ELFDATA2MSB 2
64
65// Sections constants
66
67// Section indexes
68#define SHN_UNDEF 0
69#define SHN_LORESERVE 0xFF00
70#define SHN_LOPROC 0xFF00
71#define SHN_HIPROC 0xFF1F
72#define SHN_ABS 0xFFF1
73#define SHN_COMMON 0xFFF2
74#define SHN_HIRESERVE 0xFFFF
75
76// Section types
77#define SHT_NULL 0
78#define SHT_PROGBITS 1
79#define SHT_SYMTAB 2
80#define SHT_STRTAB 3
81#define SHT_RELA 4
82#define SHT_HASH 5
83#define SHT_DYNAMIC 6
84#define SHT_NOTE 7
85#define SHT_NOBITS 8
86#define SHT_REL 9
87#define SHT_SHLIB 10
88#define SHT_DYNSYM 11
89#define SHT_LOPROC 0x70000000
90#define SHT_HIPROC 0x7FFFFFFF
91#define SHT_LOUSER 0x80000000
92#define SHT_HIUSER 0xFFFFFFFF
93
94// Custom section types
95#define SHT_PSPREL 0x700000a0
96
97// Section flags
98enum ElfSectionFlags
99{
100 SHF_WRITE = 0x1,
101 SHF_ALLOC = 0x2,
102 SHF_EXECINSTR = 0x4,
103 SHF_MASKPROC = 0xF0000000,
104};
105
106// Symbol binding
107#define STB_LOCAL 0
108#define STB_GLOBAL 1
109#define STB_WEAK 2
110#define STB_LOPROC 13
111#define STB_HIPROC 15
112
113// Symbol types
114#define STT_NOTYPE 0
115#define STT_OBJECT 1
116#define STT_FUNC 2
117#define STT_SECTION 3
118#define STT_FILE 4
119#define STT_LOPROC 13
120#define STT_HIPROC 15
121
122// Undefined name
123#define STN_UNDEF 0
124
125// Relocation types
126#define R_386_NONE 0
127#define R_386_32 1
128#define R_386_PC32 2
129#define R_386_GOT32 3
130#define R_386_PLT32 4
131#define R_386_COPY 5
132#define R_386_GLOB_DAT 6
133#define R_386_JMP_SLOT 7
134#define R_386_RELATIVE 8
135#define R_386_GOTOFF 9
136#define R_386_GOTPC 10
137
138// Segment types
139#define PT_NULL 0
140#define PT_LOAD 1
141#define PT_DYNAMIC 2
142#define PT_INTERP 3
143#define PT_NOTE 4
144#define PT_SHLIB 5
145#define PT_PHDR 6
146#define PT_LOPROC 0x70000000
147#define PT_HIPROC 0x7FFFFFFF
148
149// Segment flags
150#define PF_X 1
151#define PF_W 2
152#define PF_R 4
153
154// Dynamic Array Tags
155#define DT_NULL 0
156#define DT_NEEDED 1
157#define DT_PLTRELSZ 2
158#define DT_PLTGOT 3
159#define DT_HASH 4
160#define DT_STRTAB 5
161#define DT_SYMTAB 6
162#define DT_RELA 7
163#define DT_RELASZ 8
164#define DT_RELAENT 9
165#define DT_STRSZ 10
166#define DT_SYMENT 11
167#define DT_INIT 12
168#define DT_FINI 13
169#define DT_SONAME 14
170#define DT_RPATH 15
171#define DT_SYMBOLIC 16
172#define DT_REL 17
173#define DT_RELSZ 18
174#define DT_RELENT 19
175#define DT_PLTREL 20
176#define DT_DEBUG 21
177#define DT_TEXTREL 22
178#define DT_JMPREL 23
179#define DT_LOPROC 0x70000000
180#define DT_HIPROC 0x7FFFFFFF
181
182typedef unsigned int Elf32_Addr;
183typedef unsigned short Elf32_Half;
184typedef unsigned int Elf32_Off;
185typedef signed int Elf32_Sword;
186typedef unsigned int Elf32_Word;
187
188// ELF file header
189struct Elf32_Ehdr {
190 unsigned char e_ident[EI_NIDENT];
191 Elf32_Half e_type;
192 Elf32_Half e_machine;
193 Elf32_Word e_version;
194 Elf32_Addr e_entry;
195 Elf32_Off e_phoff;
196 Elf32_Off e_shoff;
197 Elf32_Word e_flags;
198 Elf32_Half e_ehsize;
199 Elf32_Half e_phentsize;
200 Elf32_Half e_phnum;
201 Elf32_Half e_shentsize;
202 Elf32_Half e_shnum;
203 Elf32_Half e_shstrndx;
204};
205
206// Section header
207struct Elf32_Shdr {
208 Elf32_Word sh_name;
209 Elf32_Word sh_type;
210 Elf32_Word sh_flags;
211 Elf32_Addr sh_addr;
212 Elf32_Off sh_offset;
213 Elf32_Word sh_size;
214 Elf32_Word sh_link;
215 Elf32_Word sh_info;
216 Elf32_Word sh_addralign;
217 Elf32_Word sh_entsize;
218};
219
220// Segment header
221struct Elf32_Phdr {
222 Elf32_Word p_type;
223 Elf32_Off p_offset;
224 Elf32_Addr p_vaddr;
225 Elf32_Addr p_paddr;
226 Elf32_Word p_filesz;
227 Elf32_Word p_memsz;
228 Elf32_Word p_flags;
229 Elf32_Word p_align;
230};
231
232// Symbol table entry
233struct Elf32_Sym {
234 Elf32_Word st_name;
235 Elf32_Addr st_value;
236 Elf32_Word st_size;
237 unsigned char st_info;
238 unsigned char st_other;
239 Elf32_Half st_shndx;
240};
241
242#define ELF32_ST_BIND(i) ((i)>>4)
243#define ELF32_ST_TYPE(i) ((i)&0xf)
244#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
245
246// Relocation entries
247struct Elf32_Rel {
248 Elf32_Addr r_offset;
249 Elf32_Word r_info;
250};
251
252struct Elf32_Rela {
253 Elf32_Addr r_offset;
254 Elf32_Word r_info;
255 Elf32_Sword r_addend;
256};
257
258#define ELF32_R_SYM(i) ((i)>>8)
259#define ELF32_R_TYPE(i) ((unsigned char)(i))
260#define ELF32_R_INFO(s,t) (((s)<<8 )+(unsigned char)(t))
261
262struct Elf32_Dyn {
263 Elf32_Sword d_tag;
264 union {
265 Elf32_Word d_val;
266 Elf32_Addr d_ptr;
267 } d_un;
268};
269
270enum KnownElfTypes {
271 KNOWNELF_PSP = 0,
272 KNOWNELF_DS = 1,
273 KNOWNELF_GBA = 2,
274 KNOWNELF_GC = 3,
275};
276
277typedef int SectionID;
278
279class ElfReader {
280private:
281 char *base;
282 u32 *base32;
283
284 Elf32_Ehdr *header;
285 Elf32_Phdr *segments;
286 Elf32_Shdr *sections;
287
288 u32 *sectionAddrs;
289 bool bRelocate;
290 u32 entryPoint;
291
292public:
293 ElfReader(void *ptr);
294 ~ElfReader() { }
295
296 u32 Read32(int off) const { return base32[off >> 2]; }
297
298 // Quick accessors
299 ElfType GetType() const { return (ElfType)(header->e_type); }
300 ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
301 u32 GetEntryPoint() const { return entryPoint; }
302 u32 GetFlags() const { return (u32)(header->e_flags); }
303 bool LoadInto(u32 vaddr);
304 bool LoadSymbols();
305
306 int GetNumSegments() const { return (int)(header->e_phnum); }
307 int GetNumSections() const { return (int)(header->e_shnum); }
308 const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
309 const char *GetSectionName(int section) const;
310 const u8 *GetSectionDataPtr(int section) const {
311 if (section < 0 || section >= header->e_shnum)
312 return nullptr;
313 if (sections[section].sh_type != SHT_NOBITS)
314 return GetPtr(sections[section].sh_offset);
315 else
316 return nullptr;
317 }
318 bool IsCodeSection(int section) const {
319 return sections[section].sh_type == SHT_PROGBITS;
320 }
321 const u8 *GetSegmentPtr(int segment) {
322 return GetPtr(segments[segment].p_offset);
323 }
324 u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
325 int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
326 SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
327
328 bool DidRelocate() {
329 return bRelocate;
330 }
331};