elf.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #pragma once
  2. #include <vector>
  3. #include <stdint.h>
  4. #include <kernel/interrupt.hpp>
  5. #include <kernel/process.hpp>
  6. #include <kernel/vfs.hpp>
  7. #include <kernel/vfs/dentry.hpp>
  8. namespace types::elf {
  9. using elf32_addr_t = uint32_t;
  10. using elf32_off_t = uint32_t;
  11. using elf64_addr_t = uint64_t;
  12. using elf64_off_t = uint64_t;
  13. constexpr elf32_addr_t ELF32_STACK_BOTTOM = 0xbffff000;
  14. constexpr elf32_off_t ELF32_STACK_SIZE = 8 * 1024 * 1024;
  15. constexpr elf32_addr_t ELF32_STACK_TOP = ELF32_STACK_BOTTOM - ELF32_STACK_SIZE;
  16. constexpr int ELF_LOAD_FAIL_NORETURN = 0x114514;
  17. struct PACKED elf32_header {
  18. // 0x7f, "ELF"
  19. char magic[4];
  20. enum : uint8_t {
  21. FORMAT_32 = 1,
  22. FORMAT_64 = 2,
  23. } format;
  24. enum : uint8_t {
  25. ENDIAN_LITTLE = 1,
  26. ENDIAN_BIG = 2,
  27. } endian;
  28. // should be 1
  29. uint8_t _version1;
  30. enum : uint8_t {
  31. ABI_SYSTEM_V = 0x00,
  32. // TODO:
  33. ABI_LINUX = 0x03,
  34. } abi;
  35. uint8_t abi_version;
  36. uint8_t _reserved[7];
  37. enum : uint16_t {
  38. ET_NONE = 0x00,
  39. ET_REL = 0x01,
  40. ET_EXEC = 0x02,
  41. ET_DYN = 0x03,
  42. ET_CORE = 0x04,
  43. ET_LOOS = 0xfe00,
  44. ET_HIOS = 0xfeff,
  45. ET_LOPROC = 0xff00,
  46. ET_HIPROC = 0xffff,
  47. } type;
  48. enum : uint16_t {
  49. ARCH_NONE = 0x00,
  50. ARCH_X86 = 0x03,
  51. ARCH_ARM = 0x28,
  52. ARCH_IA64 = 0x32,
  53. ARCH_X86_64 = 0x3e,
  54. ARCH_ARM64 = 0xb7,
  55. ARCH_RISCV = 0xf3,
  56. } arch;
  57. // should be 1
  58. uint32_t _version2;
  59. // entry address
  60. elf32_addr_t entry;
  61. // program header table offset
  62. elf32_off_t phoff;
  63. // section header table offset
  64. elf32_off_t shoff;
  65. // architecture dependent flags
  66. uint32_t flags;
  67. // elf header size
  68. uint16_t ehsize;
  69. // program header table entry size
  70. uint16_t phentsize;
  71. // program header table entries number
  72. uint16_t phnum;
  73. // section header table entry size
  74. uint16_t shentsize;
  75. // section header table entries number
  76. uint16_t shnum;
  77. // section header table entry index that contains section names
  78. uint16_t shstrndx;
  79. };
  80. struct PACKED elf32_program_header_entry {
  81. enum : uint32_t {
  82. PT_NULL = 0x00,
  83. PT_LOAD = 0x01,
  84. PT_DYNAMIC = 0x02,
  85. PT_INTERP = 0x03,
  86. PT_NOTE = 0x04,
  87. PT_SHLIB = 0x05,
  88. PT_PHDR = 0x06,
  89. PT_TLS = 0x07,
  90. PT_LOOS = 0x60000000,
  91. PT_HIOS = 0x6fffffff,
  92. PT_LIPROC = 0x70000000,
  93. PT_HIPROC = 0x7fffffff,
  94. } type;
  95. elf32_off_t offset;
  96. elf32_addr_t vaddr;
  97. elf32_addr_t paddr;
  98. elf32_off_t filesz;
  99. elf32_off_t memsz;
  100. // segment dependent
  101. enum : uint32_t {
  102. PF_X = 0x1,
  103. PF_W = 0x2,
  104. PF_R = 0x4,
  105. } flags;
  106. // 0 and 1 for no alignment, otherwise power of 2
  107. uint32_t align;
  108. };
  109. struct PACKED elf32_section_header_entry {
  110. elf32_off_t sh_name;
  111. enum : uint32_t {
  112. SHT_NULL = 0x00,
  113. SHT_PROGBITS = 0x01,
  114. SHT_RELA = 0x04,
  115. SHT_DYNAMIC = 0x06,
  116. SHT_NOTE = 0x07,
  117. SHT_NOBITS = 0x08,
  118. SHT_REL = 0x09,
  119. SHT_DYNSYM = 0x0b,
  120. SHT_INIT_ARRAY = 0x0e,
  121. SHT_FINI_ARRAY = 0x0f,
  122. SHT_PREINIT_ARRAY = 0x0f,
  123. } sh_type;
  124. enum : uint32_t {
  125. SHF_WRITE = 0x01,
  126. SHF_ALLOC = 0x02,
  127. SHF_EXECINSTR = 0x04,
  128. } sh_flags;
  129. elf32_addr_t sh_addr;
  130. elf32_off_t sh_offset;
  131. elf32_off_t sh_size;
  132. uint32_t sh_link;
  133. uint32_t sh_info;
  134. elf32_off_t sh_addralign;
  135. elf32_off_t sh_entsize;
  136. };
  137. struct elf32_load_data {
  138. struct dentry* exec_dent; // Owned
  139. const char* const* argv;
  140. size_t argv_count;
  141. const char* const* envp;
  142. size_t envp_count;
  143. uintptr_t ip;
  144. uintptr_t sp;
  145. };
  146. // TODO: environment variables
  147. int elf32_load(elf32_load_data& data);
  148. struct PACKED elf64_header {
  149. // 0x7f, "ELF"
  150. char magic[4];
  151. enum : uint8_t {
  152. FORMAT_32 = 1,
  153. FORMAT_64 = 2,
  154. } format;
  155. enum : uint8_t {
  156. ENDIAN_LITTLE = 1,
  157. ENDIAN_BIG = 2,
  158. } endian;
  159. // should be 1
  160. uint8_t _version1;
  161. enum : uint8_t {
  162. ABI_SYSTEM_V = 0x00,
  163. // TODO:
  164. ABI_LINUX = 0x03,
  165. } abi;
  166. uint8_t abi_version;
  167. uint8_t _reserved[7];
  168. enum : uint16_t {
  169. ET_NONE = 0x00,
  170. ET_REL = 0x01,
  171. ET_EXEC = 0x02,
  172. ET_DYN = 0x03,
  173. ET_CORE = 0x04,
  174. ET_LOOS = 0xfe00,
  175. ET_HIOS = 0xfeff,
  176. ET_LOPROC = 0xff00,
  177. ET_HIPROC = 0xffff,
  178. } type;
  179. enum : uint16_t {
  180. ARCH_NONE = 0x00,
  181. ARCH_X86 = 0x03,
  182. ARCH_ARM = 0x28,
  183. ARCH_IA64 = 0x32,
  184. ARCH_X86_64 = 0x3e,
  185. ARCH_ARM64 = 0xb7,
  186. ARCH_RISCV = 0xf3,
  187. } arch;
  188. // should be 1
  189. uint32_t _version2;
  190. // entry address
  191. elf64_addr_t entry;
  192. // program header table offset
  193. elf64_off_t phoff;
  194. // section header table offset
  195. elf64_off_t shoff;
  196. // architecture dependent flags
  197. uint32_t flags;
  198. // elf header size
  199. uint16_t ehsize;
  200. // program header table entry size
  201. uint16_t phentsize;
  202. // program header table entries number
  203. uint16_t phnum;
  204. // section header table entry size
  205. uint16_t shentsize;
  206. // section header table entries number
  207. uint16_t shnum;
  208. // section header table entry index that contains section names
  209. uint16_t shstrndx;
  210. };
  211. struct PACKED elf64_program_header_entry {
  212. enum : uint32_t {
  213. PT_NULL = 0x00,
  214. PT_LOAD = 0x01,
  215. PT_DYNAMIC = 0x02,
  216. PT_INTERP = 0x03,
  217. PT_NOTE = 0x04,
  218. PT_SHLIB = 0x05,
  219. PT_PHDR = 0x06,
  220. PT_TLS = 0x07,
  221. PT_LOOS = 0x60000000,
  222. PT_HIOS = 0x6fffffff,
  223. PT_LIPROC = 0x70000000,
  224. PT_HIPROC = 0x7fffffff,
  225. } type;
  226. // segment dependent
  227. enum : uint32_t {
  228. PF_X = 0x1,
  229. PF_W = 0x2,
  230. PF_R = 0x4,
  231. } flags;
  232. elf64_off_t offset;
  233. elf64_addr_t vaddr;
  234. elf64_addr_t paddr;
  235. elf64_off_t filesz;
  236. elf64_off_t memsz;
  237. // 0 and 1 for no alignment, otherwise power of 2
  238. uint64_t align;
  239. };
  240. struct PACKED elf64_section_header_entry {
  241. uint32_t sh_name;
  242. enum : uint32_t {
  243. SHT_NULL = 0x00,
  244. SHT_PROGBITS = 0x01,
  245. SHT_RELA = 0x04,
  246. SHT_DYNAMIC = 0x06,
  247. SHT_NOTE = 0x07,
  248. SHT_NOBITS = 0x08,
  249. SHT_REL = 0x09,
  250. SHT_DYNSYM = 0x0b,
  251. SHT_INIT_ARRAY = 0x0e,
  252. SHT_FINI_ARRAY = 0x0f,
  253. SHT_PREINIT_ARRAY = 0x0f,
  254. } sh_type;
  255. enum : uint64_t {
  256. SHF_WRITE = 0x01,
  257. SHF_ALLOC = 0x02,
  258. SHF_EXECINSTR = 0x04,
  259. } sh_flags;
  260. elf64_addr_t sh_addr;
  261. elf64_off_t sh_offset;
  262. elf64_off_t sh_size;
  263. uint32_t sh_link;
  264. uint32_t sh_info;
  265. elf64_off_t sh_addralign;
  266. elf64_off_t sh_entsize;
  267. };
  268. struct elf64_load_data {
  269. fs::dentry_pointer exec_dent;
  270. std::vector<std::string> argv;
  271. std::vector<std::string> envp;
  272. unsigned long ip;
  273. unsigned long sp;
  274. };
  275. } // namespace types::elf