pe32.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #ifndef GRUB_EFI_PE32_HEADER
  19. #define GRUB_EFI_PE32_HEADER 1
  20. #include <grub/types.h>
  21. #include <grub/efi/memory.h>
  22. /* The MSDOS compatibility stub. This was copied from the output of
  23. objcopy, and it is not necessary to care about what this means. */
  24. #define GRUB_PE32_MSDOS_STUB \
  25. { \
  26. 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
  27. 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
  28. 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
  29. 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
  30. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
  31. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
  32. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
  33. 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
  34. 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
  35. 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
  36. 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
  37. 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
  38. 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
  39. 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
  40. 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
  41. 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
  42. }
  43. #define GRUB_PE32_MSDOS_STUB_SIZE 0x80
  44. #define GRUB_PE32_MAGIC 0x5a4d
  45. struct grub_msdos_image_header
  46. {
  47. /* This is always 'MZ'. (GRUB_PE32_MAGIC) */
  48. grub_uint16_t msdos_magic;
  49. grub_uint16_t reserved[29];
  50. /* The file offset of the PE image header. */
  51. grub_uint32_t pe_image_header_offset;
  52. };
  53. /* According to the spec, the minimal alignment is 512 bytes...
  54. But some examples (such as EFI drivers in the Intel
  55. Sample Implementation) use 32 bytes (0x20) instead, and it seems
  56. to be working.
  57. However, there is firmware showing up in the field now with
  58. page alignment constraints to guarantee that page protection
  59. bits take effect. Because currently existing GRUB code can not
  60. properly distinguish between in-memory and in-file layout, let's
  61. bump all alignment to GRUB_EFI_PAGE_SIZE. */
  62. #define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE
  63. #define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT
  64. struct grub_pe32_coff_header
  65. {
  66. grub_uint16_t machine;
  67. grub_uint16_t num_sections;
  68. grub_uint32_t time;
  69. grub_uint32_t symtab_offset;
  70. grub_uint32_t num_symbols;
  71. grub_uint16_t optional_header_size;
  72. grub_uint16_t characteristics;
  73. };
  74. #define GRUB_PE32_MACHINE_I386 0x14c
  75. #define GRUB_PE32_MACHINE_IA64 0x200
  76. #define GRUB_PE32_MACHINE_X86_64 0x8664
  77. #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
  78. #define GRUB_PE32_MACHINE_ARM64 0xAA64
  79. #define GRUB_PE32_MACHINE_LOONGARCH32 0x6232
  80. #define GRUB_PE32_MACHINE_LOONGARCH64 0x6264
  81. #define GRUB_PE32_MACHINE_RISCV32 0x5032
  82. #define GRUB_PE32_MACHINE_RISCV64 0x5064
  83. #define GRUB_PE32_RELOCS_STRIPPED 0x0001
  84. #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002
  85. #define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004
  86. #define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008
  87. #define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010
  88. #define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020
  89. #define GRUB_PE32_16BIT_MACHINE 0x0040
  90. #define GRUB_PE32_BYTES_REVERSED_LO 0x0080
  91. #define GRUB_PE32_32BIT_MACHINE 0x0100
  92. #define GRUB_PE32_DEBUG_STRIPPED 0x0200
  93. #define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
  94. #define GRUB_PE32_SYSTEM 0x1000
  95. #define GRUB_PE32_DLL 0x2000
  96. #define GRUB_PE32_UP_SYSTEM_ONLY 0x4000
  97. #define GRUB_PE32_BYTES_REVERSED_HI 0x8000
  98. struct grub_pe32_data_directory
  99. {
  100. grub_uint32_t rva;
  101. grub_uint32_t size;
  102. };
  103. struct grub_pe32_optional_header
  104. {
  105. grub_uint16_t magic;
  106. grub_uint8_t major_linker_version;
  107. grub_uint8_t minor_linker_version;
  108. grub_uint32_t code_size;
  109. grub_uint32_t data_size;
  110. grub_uint32_t bss_size;
  111. grub_uint32_t entry_addr;
  112. grub_uint32_t code_base;
  113. grub_uint32_t data_base;
  114. grub_uint32_t image_base;
  115. grub_uint32_t section_alignment;
  116. grub_uint32_t file_alignment;
  117. grub_uint16_t major_os_version;
  118. grub_uint16_t minor_os_version;
  119. grub_uint16_t major_image_version;
  120. grub_uint16_t minor_image_version;
  121. grub_uint16_t major_subsystem_version;
  122. grub_uint16_t minor_subsystem_version;
  123. grub_uint32_t reserved;
  124. grub_uint32_t image_size;
  125. grub_uint32_t header_size;
  126. grub_uint32_t checksum;
  127. grub_uint16_t subsystem;
  128. grub_uint16_t dll_characteristics;
  129. grub_uint32_t stack_reserve_size;
  130. grub_uint32_t stack_commit_size;
  131. grub_uint32_t heap_reserve_size;
  132. grub_uint32_t heap_commit_size;
  133. grub_uint32_t loader_flags;
  134. grub_uint32_t num_data_directories;
  135. /* Data directories. */
  136. struct grub_pe32_data_directory export_table;
  137. struct grub_pe32_data_directory import_table;
  138. struct grub_pe32_data_directory resource_table;
  139. struct grub_pe32_data_directory exception_table;
  140. struct grub_pe32_data_directory certificate_table;
  141. struct grub_pe32_data_directory base_relocation_table;
  142. struct grub_pe32_data_directory debug;
  143. struct grub_pe32_data_directory architecture;
  144. struct grub_pe32_data_directory global_ptr;
  145. struct grub_pe32_data_directory tls_table;
  146. struct grub_pe32_data_directory load_config_table;
  147. struct grub_pe32_data_directory bound_import;
  148. struct grub_pe32_data_directory iat;
  149. struct grub_pe32_data_directory delay_import_descriptor;
  150. struct grub_pe32_data_directory com_runtime_header;
  151. struct grub_pe32_data_directory reserved_entry;
  152. };
  153. struct grub_pe64_optional_header
  154. {
  155. grub_uint16_t magic;
  156. grub_uint8_t major_linker_version;
  157. grub_uint8_t minor_linker_version;
  158. grub_uint32_t code_size;
  159. grub_uint32_t data_size;
  160. grub_uint32_t bss_size;
  161. grub_uint32_t entry_addr;
  162. grub_uint32_t code_base;
  163. grub_uint64_t image_base;
  164. grub_uint32_t section_alignment;
  165. grub_uint32_t file_alignment;
  166. grub_uint16_t major_os_version;
  167. grub_uint16_t minor_os_version;
  168. grub_uint16_t major_image_version;
  169. grub_uint16_t minor_image_version;
  170. grub_uint16_t major_subsystem_version;
  171. grub_uint16_t minor_subsystem_version;
  172. grub_uint32_t reserved;
  173. grub_uint32_t image_size;
  174. grub_uint32_t header_size;
  175. grub_uint32_t checksum;
  176. grub_uint16_t subsystem;
  177. grub_uint16_t dll_characteristics;
  178. grub_uint64_t stack_reserve_size;
  179. grub_uint64_t stack_commit_size;
  180. grub_uint64_t heap_reserve_size;
  181. grub_uint64_t heap_commit_size;
  182. grub_uint32_t loader_flags;
  183. grub_uint32_t num_data_directories;
  184. /* Data directories. */
  185. struct grub_pe32_data_directory export_table;
  186. struct grub_pe32_data_directory import_table;
  187. struct grub_pe32_data_directory resource_table;
  188. struct grub_pe32_data_directory exception_table;
  189. struct grub_pe32_data_directory certificate_table;
  190. struct grub_pe32_data_directory base_relocation_table;
  191. struct grub_pe32_data_directory debug;
  192. struct grub_pe32_data_directory architecture;
  193. struct grub_pe32_data_directory global_ptr;
  194. struct grub_pe32_data_directory tls_table;
  195. struct grub_pe32_data_directory load_config_table;
  196. struct grub_pe32_data_directory bound_import;
  197. struct grub_pe32_data_directory iat;
  198. struct grub_pe32_data_directory delay_import_descriptor;
  199. struct grub_pe32_data_directory com_runtime_header;
  200. struct grub_pe32_data_directory reserved_entry;
  201. };
  202. #define GRUB_PE32_PE32_MAGIC 0x10b
  203. #define GRUB_PE32_PE64_MAGIC 0x20b
  204. #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
  205. #define GRUB_PE32_NX_COMPAT 0x0100
  206. #define GRUB_PE32_NUM_DATA_DIRECTORIES 16
  207. struct grub_pe32_section_table
  208. {
  209. char name[8];
  210. grub_uint32_t virtual_size;
  211. grub_uint32_t virtual_address;
  212. grub_uint32_t raw_data_size;
  213. grub_uint32_t raw_data_offset;
  214. grub_uint32_t relocations_offset;
  215. grub_uint32_t line_numbers_offset;
  216. grub_uint16_t num_relocations;
  217. grub_uint16_t num_line_numbers;
  218. grub_uint32_t characteristics;
  219. };
  220. #define GRUB_PE32_SCN_CNT_CODE 0x00000020
  221. #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
  222. #define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
  223. #define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
  224. #define GRUB_PE32_SCN_MEM_READ 0x40000000
  225. #define GRUB_PE32_SCN_MEM_WRITE 0x80000000
  226. #define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
  227. #define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
  228. #define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000
  229. #define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000
  230. #define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
  231. #define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
  232. #define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
  233. #define GRUB_PE32_SCN_ALIGN_SHIFT 20
  234. #define GRUB_PE32_SCN_ALIGN_MASK 7
  235. #define GRUB_PE32_SIGNATURE_SIZE 4
  236. #if GRUB_TARGET_SIZEOF_VOID_P == 8
  237. #define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
  238. #else
  239. #define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
  240. #endif
  241. struct grub_pe_image_header
  242. {
  243. /* This is always PE\0\0. */
  244. char signature[GRUB_PE32_SIGNATURE_SIZE];
  245. /* The COFF file header. */
  246. struct grub_pe32_coff_header coff_header;
  247. #if GRUB_TARGET_SIZEOF_VOID_P == 8
  248. /* The Optional header. */
  249. struct grub_pe64_optional_header optional_header;
  250. #else
  251. /* The Optional header. */
  252. struct grub_pe32_optional_header optional_header;
  253. #endif
  254. };
  255. struct grub_pe32_fixup_block
  256. {
  257. grub_uint32_t page_rva;
  258. grub_uint32_t block_size;
  259. grub_uint16_t entries[0];
  260. };
  261. #define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
  262. #define GRUB_PE32_REL_BASED_ABSOLUTE 0
  263. #define GRUB_PE32_REL_BASED_HIGH 1
  264. #define GRUB_PE32_REL_BASED_LOW 2
  265. #define GRUB_PE32_REL_BASED_HIGHLOW 3
  266. #define GRUB_PE32_REL_BASED_HIGHADJ 4
  267. #define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
  268. #define GRUB_PE32_REL_BASED_ARM_MOV32A 5
  269. #define GRUB_PE32_REL_BASED_RISCV_HI20 5
  270. #define GRUB_PE32_REL_BASED_SECTION 6
  271. #define GRUB_PE32_REL_BASED_REL 7
  272. #define GRUB_PE32_REL_BASED_ARM_MOV32T 7
  273. #define GRUB_PE32_REL_BASED_RISCV_LOW12I 7
  274. #define GRUB_PE32_REL_BASED_RISCV_LOW12S 8
  275. #define GRUB_PE32_REL_BASED_LOONGARCH32_MARK_LA 8
  276. #define GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA 8
  277. #define GRUB_PE32_REL_BASED_IA64_IMM64 9
  278. #define GRUB_PE32_REL_BASED_DIR64 10
  279. #define GRUB_PE32_REL_BASED_HIGH3ADJ 11
  280. struct grub_pe32_symbol
  281. {
  282. union
  283. {
  284. char short_name[8];
  285. grub_uint32_t long_name[2];
  286. };
  287. grub_uint32_t value;
  288. grub_uint16_t section;
  289. grub_uint16_t type;
  290. grub_uint8_t storage_class;
  291. grub_uint8_t num_aux;
  292. } GRUB_PACKED;
  293. #define GRUB_PE32_SYM_CLASS_EXTERNAL 2
  294. #define GRUB_PE32_SYM_CLASS_STATIC 3
  295. #define GRUB_PE32_SYM_CLASS_FILE 0x67
  296. #define GRUB_PE32_DT_FUNCTION 0x20
  297. struct grub_pe32_reloc
  298. {
  299. grub_uint32_t offset;
  300. grub_uint32_t symtab_index;
  301. grub_uint16_t type;
  302. } GRUB_PACKED;
  303. #define GRUB_PE32_REL_I386_DIR32 0x6
  304. #define GRUB_PE32_REL_I386_REL32 0x14
  305. #endif /* ! GRUB_EFI_PE32_HEADER */