elf.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #pragma once
  2. #include <errno.h>
  3. #include <kernel/interrupt.h>
  4. #include <kernel/process.hpp>
  5. #include <kernel/vfs.hpp>
  6. #include <stdint.h>
  7. namespace types::elf {
  8. using elf32_addr_t = uint32_t;
  9. using elf32_off_t = uint32_t;
  10. using elf_addr_t = elf32_addr_t;
  11. using elf_off_t = elf32_off_t;
  12. constexpr elf32_addr_t ELF_STACK_BOTTOM = 0xbffff000;
  13. constexpr elf32_off_t ELF_STACK_SIZE = 8 * 1024 * 1024;
  14. constexpr elf32_addr_t ELF_STACK_TOP = ELF_STACK_BOTTOM - ELF_STACK_SIZE;
  15. struct PACKED elf32_header {
  16. // 0x7f, "ELF"
  17. char magic[4];
  18. enum : uint8_t {
  19. FORMAT_32 = 1,
  20. FORMAT_64 = 2,
  21. } format;
  22. enum : uint8_t {
  23. ENDIAN_LITTLE = 1,
  24. ENDIAN_BIG = 2,
  25. } endian;
  26. // should be 1
  27. uint8_t _version1;
  28. enum : uint8_t {
  29. ABI_SYSTEM_V = 0x00,
  30. // TODO:
  31. ABI_LINUX = 0x03,
  32. } abi;
  33. uint8_t abi_version;
  34. uint8_t _reserved[7];
  35. enum : uint16_t {
  36. ET_NONE = 0x00,
  37. ET_REL = 0x01,
  38. ET_EXEC = 0x02,
  39. ET_DYN = 0x03,
  40. ET_CORE = 0x04,
  41. ET_LOOS = 0xfe00,
  42. ET_HIOS = 0xfeff,
  43. ET_LOPROC = 0xff00,
  44. ET_HIPROC = 0xffff,
  45. } type;
  46. enum : uint16_t {
  47. ARCH_NONE = 0x00,
  48. ARCH_X86 = 0x03,
  49. ARCH_ARM = 0x28,
  50. ARCH_IA64 = 0x32,
  51. ARCH_X86_64 = 0x3e,
  52. ARCH_ARM64 = 0xb7,
  53. ARCH_RISCV = 0xf3,
  54. } arch;
  55. // should be 1
  56. uint32_t _version2;
  57. // entry address
  58. elf32_addr_t entry;
  59. // program header table offset
  60. elf32_off_t phoff;
  61. // section header table offset
  62. elf32_off_t shoff;
  63. // architecture dependent flags
  64. uint32_t flags;
  65. // elf header size
  66. uint16_t ehsize;
  67. // program header table entry size
  68. uint16_t phentsize;
  69. // program header table entries number
  70. uint16_t phnum;
  71. // section header table entry size
  72. uint16_t shentsize;
  73. // section header table entries number
  74. uint16_t shnum;
  75. // section header table entry index that contains section names
  76. uint16_t shstrndx;
  77. };
  78. struct PACKED elf32_program_header_entry {
  79. enum : uint32_t {
  80. PT_NULL = 0x00,
  81. PT_LOAD = 0x01,
  82. PT_DYNAMIC = 0x02,
  83. PT_INTERP = 0x03,
  84. PT_NOTE = 0x04,
  85. PT_SHLIB = 0x05,
  86. PT_PHDR = 0x06,
  87. PT_TLS = 0x07,
  88. PT_LOOS = 0x60000000,
  89. PT_HIOS = 0x6fffffff,
  90. PT_LIPROC = 0x70000000,
  91. PT_HIPROC = 0x7fffffff,
  92. } type;
  93. elf32_off_t offset;
  94. elf32_addr_t vaddr;
  95. elf32_addr_t paddr;
  96. elf32_off_t filesz;
  97. elf32_off_t memsz;
  98. // segment dependent
  99. uint32_t flags;
  100. // 0 and 1 for no alignment, otherwise power of 2
  101. uint32_t align;
  102. };
  103. struct PACKED elf32_section_header_entry {
  104. elf32_off_t sh_name;
  105. enum : uint32_t {
  106. SHT_NULL = 0x00,
  107. SHT_PROGBITS = 0x01,
  108. SHT_RELA = 0x04,
  109. SHT_DYNAMIC = 0x06,
  110. SHT_NOTE = 0x07,
  111. SHT_NOBITS = 0x08,
  112. SHT_REL = 0x09,
  113. SHT_DYNSYM = 0x0b,
  114. SHT_INIT_ARRAY = 0x0e,
  115. SHT_FINI_ARRAY = 0x0f,
  116. SHT_PREINIT_ARRAY = 0x0f,
  117. } sh_type;
  118. enum : uint32_t {
  119. SHF_WRITE = 0x01,
  120. SHF_ALLOC = 0x02,
  121. SHF_EXECINSTR = 0x04,
  122. } sh_flags;
  123. elf32_addr_t sh_addr;
  124. elf32_off_t sh_offset;
  125. uint32_t sh_size;
  126. char _[16];
  127. };
  128. struct elf32_load_data {
  129. const fs::dentry* exec_dent;
  130. const char* const* argv;
  131. const char* const* envp;
  132. int errcode;
  133. void* eip;
  134. uint32_t* sp;
  135. bool system;
  136. };
  137. // TODO: environment variables
  138. int elf32_load(elf32_load_data* data);
  139. } // namespace types::elf