2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
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.
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.
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/>.
19 #ifndef GRUB_EFI_PE32_HEADER
20 #define GRUB_EFI_PE32_HEADER 1
22 #include <grub/types.h>
24 /* The MSDOS compatibility stub. This was copied from the output of
25 objcopy, and it is not necessary to care about what this means. */
26 #define GRUB_PE32_MSDOS_STUB \
28 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
29 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
30 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
31 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
35 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
36 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
37 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
38 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
39 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
40 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
41 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
42 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
43 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
46 #define GRUB_PE32_MSDOS_STUB_SIZE 0x80
48 #define GRUB_PE32_MAGIC 0x5a4d
50 /* According to the spec, the minimal alignment is 512 bytes...
51 But some examples (such as EFI drivers in the Intel
52 Sample Implementation) use 32 bytes (0x20) instead, and it seems
53 to be working. For now, GRUB uses 512 bytes for safety. */
54 #define GRUB_PE32_SECTION_ALIGNMENT 0x200
55 #define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT
57 struct grub_pe32_coff_header
59 grub_uint16_t machine;
60 grub_uint16_t num_sections;
62 grub_uint32_t symtab_offset;
63 grub_uint32_t num_symbols;
64 grub_uint16_t optional_header_size;
65 grub_uint16_t characteristics;
68 #define GRUB_PE32_MACHINE_I386 0x14c
69 #define GRUB_PE32_MACHINE_IA64 0x200
70 #define GRUB_PE32_MACHINE_X86_64 0x8664
71 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
72 #define GRUB_PE32_MACHINE_ARM64 0xAA64
74 #define GRUB_PE32_RELOCS_STRIPPED 0x0001
75 #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002
76 #define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004
77 #define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008
78 #define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010
79 #define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020
80 #define GRUB_PE32_16BIT_MACHINE 0x0040
81 #define GRUB_PE32_BYTES_REVERSED_LO 0x0080
82 #define GRUB_PE32_32BIT_MACHINE 0x0100
83 #define GRUB_PE32_DEBUG_STRIPPED 0x0200
84 #define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
85 #define GRUB_PE32_SYSTEM 0x1000
86 #define GRUB_PE32_DLL 0x2000
87 #define GRUB_PE32_UP_SYSTEM_ONLY 0x4000
88 #define GRUB_PE32_BYTES_REVERSED_HI 0x8000
90 struct grub_pe32_data_directory
96 struct grub_pe32_optional_header
99 grub_uint8_t major_linker_version;
100 grub_uint8_t minor_linker_version;
101 grub_uint32_t code_size;
102 grub_uint32_t data_size;
103 grub_uint32_t bss_size;
104 grub_uint32_t entry_addr;
105 grub_uint32_t code_base;
107 grub_uint32_t data_base;
108 grub_uint32_t image_base;
110 grub_uint32_t section_alignment;
111 grub_uint32_t file_alignment;
112 grub_uint16_t major_os_version;
113 grub_uint16_t minor_os_version;
114 grub_uint16_t major_image_version;
115 grub_uint16_t minor_image_version;
116 grub_uint16_t major_subsystem_version;
117 grub_uint16_t minor_subsystem_version;
118 grub_uint32_t reserved;
119 grub_uint32_t image_size;
120 grub_uint32_t header_size;
121 grub_uint32_t checksum;
122 grub_uint16_t subsystem;
123 grub_uint16_t dll_characteristics;
125 grub_uint32_t stack_reserve_size;
126 grub_uint32_t stack_commit_size;
127 grub_uint32_t heap_reserve_size;
128 grub_uint32_t heap_commit_size;
130 grub_uint32_t loader_flags;
131 grub_uint32_t num_data_directories;
133 /* Data directories. */
134 struct grub_pe32_data_directory export_table;
135 struct grub_pe32_data_directory import_table;
136 struct grub_pe32_data_directory resource_table;
137 struct grub_pe32_data_directory exception_table;
138 struct grub_pe32_data_directory certificate_table;
139 struct grub_pe32_data_directory base_relocation_table;
140 struct grub_pe32_data_directory debug;
141 struct grub_pe32_data_directory architecture;
142 struct grub_pe32_data_directory global_ptr;
143 struct grub_pe32_data_directory tls_table;
144 struct grub_pe32_data_directory load_config_table;
145 struct grub_pe32_data_directory bound_import;
146 struct grub_pe32_data_directory iat;
147 struct grub_pe32_data_directory delay_import_descriptor;
148 struct grub_pe32_data_directory com_runtime_header;
149 struct grub_pe32_data_directory reserved_entry;
152 struct grub_pe64_optional_header
155 grub_uint8_t major_linker_version;
156 grub_uint8_t minor_linker_version;
157 grub_uint32_t code_size;
158 grub_uint32_t data_size;
159 grub_uint32_t bss_size;
160 grub_uint32_t entry_addr;
161 grub_uint32_t code_base;
163 grub_uint64_t image_base;
165 grub_uint32_t section_alignment;
166 grub_uint32_t file_alignment;
167 grub_uint16_t major_os_version;
168 grub_uint16_t minor_os_version;
169 grub_uint16_t major_image_version;
170 grub_uint16_t minor_image_version;
171 grub_uint16_t major_subsystem_version;
172 grub_uint16_t minor_subsystem_version;
173 grub_uint32_t reserved;
174 grub_uint32_t image_size;
175 grub_uint32_t header_size;
176 grub_uint32_t checksum;
177 grub_uint16_t subsystem;
178 grub_uint16_t dll_characteristics;
180 grub_uint64_t stack_reserve_size;
181 grub_uint64_t stack_commit_size;
182 grub_uint64_t heap_reserve_size;
183 grub_uint64_t heap_commit_size;
185 grub_uint32_t loader_flags;
186 grub_uint32_t num_data_directories;
188 /* Data directories. */
189 struct grub_pe32_data_directory export_table;
190 struct grub_pe32_data_directory import_table;
191 struct grub_pe32_data_directory resource_table;
192 struct grub_pe32_data_directory exception_table;
193 struct grub_pe32_data_directory certificate_table;
194 struct grub_pe32_data_directory base_relocation_table;
195 struct grub_pe32_data_directory debug;
196 struct grub_pe32_data_directory architecture;
197 struct grub_pe32_data_directory global_ptr;
198 struct grub_pe32_data_directory tls_table;
199 struct grub_pe32_data_directory load_config_table;
200 struct grub_pe32_data_directory bound_import;
201 struct grub_pe32_data_directory iat;
202 struct grub_pe32_data_directory delay_import_descriptor;
203 struct grub_pe32_data_directory com_runtime_header;
204 struct grub_pe32_data_directory reserved_entry;
207 #define GRUB_PE32_PE32_MAGIC 0x10b
208 #define GRUB_PE32_PE64_MAGIC 0x20b
210 #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
212 #define GRUB_PE32_NUM_DATA_DIRECTORIES 16
214 struct grub_pe32_section_table
217 grub_uint32_t virtual_size;
218 grub_uint32_t virtual_address;
219 grub_uint32_t raw_data_size;
220 grub_uint32_t raw_data_offset;
221 grub_uint32_t relocations_offset;
222 grub_uint32_t line_numbers_offset;
223 grub_uint16_t num_relocations;
224 grub_uint16_t num_line_numbers;
225 grub_uint32_t characteristics;
228 #define GRUB_PE32_SCN_CNT_CODE 0x00000020
229 #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
230 #define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
231 #define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
232 #define GRUB_PE32_SCN_MEM_READ 0x40000000
233 #define GRUB_PE32_SCN_MEM_WRITE 0x80000000
235 #define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
236 #define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
237 #define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000
238 #define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000
239 #define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
240 #define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
241 #define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
243 #define GRUB_PE32_SCN_ALIGN_SHIFT 20
244 #define GRUB_PE32_SCN_ALIGN_MASK 7
246 #define GRUB_PE32_SIGNATURE_SIZE 4
248 struct grub_pe32_header
250 /* This should be filled in with GRUB_PE32_MSDOS_STUB. */
251 grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
253 /* This is always PE\0\0. */
254 char signature[GRUB_PE32_SIGNATURE_SIZE];
256 /* The COFF file header. */
257 struct grub_pe32_coff_header coff_header;
259 #if GRUB_TARGET_SIZEOF_VOID_P == 8
260 /* The Optional header. */
261 struct grub_pe64_optional_header optional_header;
263 /* The Optional header. */
264 struct grub_pe32_optional_header optional_header;
268 struct grub_pe32_fixup_block
270 grub_uint32_t page_rva;
271 grub_uint32_t block_size;
272 grub_uint16_t entries[0];
275 #define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
277 #define GRUB_PE32_REL_BASED_ABSOLUTE 0
278 #define GRUB_PE32_REL_BASED_HIGH 1
279 #define GRUB_PE32_REL_BASED_LOW 2
280 #define GRUB_PE32_REL_BASED_HIGHLOW 3
281 #define GRUB_PE32_REL_BASED_HIGHADJ 4
282 #define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
283 #define GRUB_PE32_REL_BASED_ARM_MOV32A 5
284 #define GRUB_PE32_REL_BASED_SECTION 6
285 #define GRUB_PE32_REL_BASED_REL 7
286 #define GRUB_PE32_REL_BASED_ARM_MOV32T 7
287 #define GRUB_PE32_REL_BASED_IA64_IMM64 9
288 #define GRUB_PE32_REL_BASED_DIR64 10
289 #define GRUB_PE32_REL_BASED_HIGH3ADJ 11
291 struct grub_pe32_symbol
296 grub_uint32_t long_name[2];
300 grub_uint16_t section;
302 grub_uint8_t storage_class;
303 grub_uint8_t num_aux;
306 #define GRUB_PE32_SYM_CLASS_EXTERNAL 2
307 #define GRUB_PE32_SYM_CLASS_STATIC 3
308 #define GRUB_PE32_SYM_CLASS_FILE 0x67
310 #define GRUB_PE32_DT_FUNCTION 0x20
312 struct grub_pe32_reloc
314 grub_uint32_t offset;
315 grub_uint32_t symtab_index;
319 #define GRUB_PE32_REL_I386_DIR32 0x6
320 #define GRUB_PE32_REL_I386_REL32 0x14
322 #endif /* ! GRUB_EFI_PE32_HEADER */