elf.h 7.9 KB

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