summaryrefslogtreecommitdiff
path: root/src/core/loader/elf.h
diff options
context:
space:
mode:
authorGravatar bunnei2014-06-18 18:58:09 -0400
committerGravatar bunnei2014-06-24 19:29:58 -0400
commit7889cafc76ac99b8509fa3cd1558a09f8a7e5f91 (patch)
treee6ffea9ec1c334bfca13404c47a2191fd281554c /src/core/loader/elf.h
parentNCCH: Changed decompression to load .code directly into memory rather than an... (diff)
downloadyuzu-7889cafc76ac99b8509fa3cd1558a09f8a7e5f91.tar.gz
yuzu-7889cafc76ac99b8509fa3cd1558a09f8a7e5f91.tar.xz
yuzu-7889cafc76ac99b8509fa3cd1558a09f8a7e5f91.zip
Loader: Implemented AppLoader interface for abstracting application loading.
- Various cleanups/refactorings to Loader, ELF, and NCCH modules. - Added AppLoader interface to ELF and NCCH. - Updated Qt/GLFW frontends to check AppLoader ResultStatus. NCCH: Removed extra qualification typos. Loader: Removed unnecessary #include's. NCCH: Improved readability of memcmp statements. NCCH: Added missing space. Elf: Removed unnecessary usage of unique_ptr. Loader: Removed unnecessary usage of unique_ptr.
Diffstat (limited to 'src/core/loader/elf.h')
-rw-r--r--src/core/loader/elf.h230
1 files changed, 16 insertions, 214 deletions
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h
index 24d2f91be..3fb010113 100644
--- a/src/core/loader/elf.h
+++ b/src/core/loader/elf.h
@@ -5,226 +5,28 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/loader/loader.h"
8 9
9// ELF Header Constants 10////////////////////////////////////////////////////////////////////////////////////////////////////
10 11// Loader namespace
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// Sections constants
56
57// Section types
58#define SHT_NULL 0
59#define SHT_PROGBITS 1
60#define SHT_SYMTAB 2
61#define SHT_STRTAB 3
62#define SHT_RELA 4
63#define SHT_HASH 5
64#define SHT_DYNAMIC 6
65#define SHT_NOTE 7
66#define SHT_NOBITS 8
67#define SHT_REL 9
68#define SHT_SHLIB 10
69#define SHT_DYNSYM 11
70#define SHT_LOPROC 0x70000000
71#define SHT_HIPROC 0x7FFFFFFF
72#define SHT_LOUSER 0x80000000
73#define SHT_HIUSER 0xFFFFFFFF
74
75// Section flags
76enum ElfSectionFlags
77{
78 SHF_WRITE = 0x1,
79 SHF_ALLOC = 0x2,
80 SHF_EXECINSTR = 0x4,
81 SHF_MASKPROC = 0xF0000000,
82};
83
84// Segment types
85#define PT_NULL 0
86#define PT_LOAD 1
87#define PT_DYNAMIC 2
88#define PT_INTERP 3
89#define PT_NOTE 4
90#define PT_SHLIB 5
91#define PT_PHDR 6
92#define PT_LOPROC 0x70000000
93#define PT_HIPROC 0x7FFFFFFF
94
95typedef unsigned int Elf32_Addr;
96typedef unsigned short Elf32_Half;
97typedef unsigned int Elf32_Off;
98typedef signed int Elf32_Sword;
99typedef unsigned int Elf32_Word;
100
101// ELF file header
102struct Elf32_Ehdr {
103 unsigned char e_ident[EI_NIDENT];
104 Elf32_Half e_type;
105 Elf32_Half e_machine;
106 Elf32_Word e_version;
107 Elf32_Addr e_entry;
108 Elf32_Off e_phoff;
109 Elf32_Off e_shoff;
110 Elf32_Word e_flags;
111 Elf32_Half e_ehsize;
112 Elf32_Half e_phentsize;
113 Elf32_Half e_phnum;
114 Elf32_Half e_shentsize;
115 Elf32_Half e_shnum;
116 Elf32_Half e_shstrndx;
117};
118
119// Section header
120struct Elf32_Shdr {
121 Elf32_Word sh_name;
122 Elf32_Word sh_type;
123 Elf32_Word sh_flags;
124 Elf32_Addr sh_addr;
125 Elf32_Off sh_offset;
126 Elf32_Word sh_size;
127 Elf32_Word sh_link;
128 Elf32_Word sh_info;
129 Elf32_Word sh_addralign;
130 Elf32_Word sh_entsize;
131};
132
133// Segment header
134struct Elf32_Phdr {
135 Elf32_Word p_type;
136 Elf32_Off p_offset;
137 Elf32_Addr p_vaddr;
138 Elf32_Addr p_paddr;
139 Elf32_Word p_filesz;
140 Elf32_Word p_memsz;
141 Elf32_Word p_flags;
142 Elf32_Word p_align;
143};
144
145// Symbol table entry
146struct Elf32_Sym {
147 Elf32_Word st_name;
148 Elf32_Addr st_value;
149 Elf32_Word st_size;
150 unsigned char st_info;
151 unsigned char st_other;
152 Elf32_Half st_shndx;
153};
154
155// Relocation entries
156struct Elf32_Rel {
157 Elf32_Addr r_offset;
158 Elf32_Word r_info;
159};
160
161typedef int SectionID;
162
163class ElfReader {
164private:
165 char *base;
166 u32 *base32;
167
168 Elf32_Ehdr *header;
169 Elf32_Phdr *segments;
170 Elf32_Shdr *sections;
171 12
172 u32 *sectionAddrs; 13namespace Loader {
173 bool bRelocate;
174 u32 entryPoint;
175 14
15/// Loads an ELF/AXF file
16class AppLoader_ELF : public AppLoader {
176public: 17public:
177 ElfReader(void *ptr); 18 AppLoader_ELF(std::string& filename);
178 ~ElfReader() { } 19 ~AppLoader_ELF();
179 20
180 u32 Read32(int off) const { return base32[off >> 2]; } 21 /**
22 * Load the bootable file
23 * @return ResultStatus result of function
24 */
25 const ResultStatus Load();
181 26
182 // Quick accessors 27private:
183 ElfType GetType() const { return (ElfType)(header->e_type); } 28 std::string filename;
184 ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } 29 bool is_loaded;
185 u32 GetEntryPoint() const { return entryPoint; }
186 u32 GetFlags() const { return (u32)(header->e_flags); }
187 bool LoadInto(u32 vaddr);
188 bool LoadSymbols();
189
190 int GetNumSegments() const { return (int)(header->e_phnum); }
191 int GetNumSections() const { return (int)(header->e_shnum); }
192 const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
193 const char *GetSectionName(int section) const;
194 const u8 *GetSectionDataPtr(int section) const {
195 if (section < 0 || section >= header->e_shnum)
196 return nullptr;
197 if (sections[section].sh_type != SHT_NOBITS)
198 return GetPtr(sections[section].sh_offset);
199 else
200 return nullptr;
201 }
202 bool IsCodeSection(int section) const {
203 return sections[section].sh_type == SHT_PROGBITS;
204 }
205 const u8 *GetSegmentPtr(int segment) {
206 return GetPtr(segments[segment].p_offset);
207 }
208 u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
209 int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
210 SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
211
212 bool DidRelocate() {
213 return bRelocate;
214 }
215}; 30};
216 31
217////////////////////////////////////////////////////////////////////////////////////////////////////
218// Loader namespace
219
220namespace Loader {
221
222/**
223 * Loads an ELF file
224 * @param filename String filename of ELF file
225 * @param error_string Pointer to string to put error message if an error has occurred
226 * @return True on success, otherwise false
227 */
228bool Load_ELF(std::string& filename, std::string* error_string);
229
230} // namespace Loader 32} // namespace Loader