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 /* According to the spec, the minimal alignment is 512 bytes...
49 But some examples (such as EFI drivers in the Intel
50 Sample Implementation) use 32 bytes (0x20) instead, and it seems
51 to be working. For now, GRUB uses 512 bytes for safety. */
52 #define GRUB_PE32_SECTION_ALIGNMENT 0x200
53 #define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT
55 struct grub_pe32_coff_header
57 grub_uint16_t machine;
58 grub_uint16_t num_sections;
60 grub_uint32_t symtab_offset;
61 grub_uint32_t num_symbols;
62 grub_uint16_t optional_header_size;
63 grub_uint16_t characteristics;
66 #define GRUB_PE32_MACHINE_I386 0x14c
67 #define GRUB_PE32_MACHINE_IA64 0x200
68 #define GRUB_PE32_MACHINE_X86_64 0x8664
69 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
70 #define GRUB_PE32_MACHINE_ARM64 0xAA64
72 #define GRUB_PE32_RELOCS_STRIPPED 0x0001
73 #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002
74 #define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004
75 #define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008
76 #define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010
77 #define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020
78 #define GRUB_PE32_16BIT_MACHINE 0x0040
79 #define GRUB_PE32_BYTES_REVERSED_LO 0x0080
80 #define GRUB_PE32_32BIT_MACHINE 0x0100
81 #define GRUB_PE32_DEBUG_STRIPPED 0x0200
82 #define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
83 #define GRUB_PE32_SYSTEM 0x1000
84 #define GRUB_PE32_DLL 0x2000
85 #define GRUB_PE32_UP_SYSTEM_ONLY 0x4000
86 #define GRUB_PE32_BYTES_REVERSED_HI 0x8000
88 struct grub_pe32_data_directory
94 struct grub_pe32_optional_header
97 grub_uint8_t major_linker_version;
98 grub_uint8_t minor_linker_version;
99 grub_uint32_t code_size;
100 grub_uint32_t data_size;
101 grub_uint32_t bss_size;
102 grub_uint32_t entry_addr;
103 grub_uint32_t code_base;
105 grub_uint32_t data_base;
106 grub_uint32_t image_base;
108 grub_uint32_t section_alignment;
109 grub_uint32_t file_alignment;
110 grub_uint16_t major_os_version;
111 grub_uint16_t minor_os_version;
112 grub_uint16_t major_image_version;
113 grub_uint16_t minor_image_version;
114 grub_uint16_t major_subsystem_version;
115 grub_uint16_t minor_subsystem_version;
116 grub_uint32_t reserved;
117 grub_uint32_t image_size;
118 grub_uint32_t header_size;
119 grub_uint32_t checksum;
120 grub_uint16_t subsystem;
121 grub_uint16_t dll_characteristics;
123 grub_uint32_t stack_reserve_size;
124 grub_uint32_t stack_commit_size;
125 grub_uint32_t heap_reserve_size;
126 grub_uint32_t heap_commit_size;
128 grub_uint32_t loader_flags;
129 grub_uint32_t num_data_directories;
131 /* Data directories. */
132 struct grub_pe32_data_directory export_table;
133 struct grub_pe32_data_directory import_table;
134 struct grub_pe32_data_directory resource_table;
135 struct grub_pe32_data_directory exception_table;
136 struct grub_pe32_data_directory certificate_table;
137 struct grub_pe32_data_directory base_relocation_table;
138 struct grub_pe32_data_directory debug;
139 struct grub_pe32_data_directory architecture;
140 struct grub_pe32_data_directory global_ptr;
141 struct grub_pe32_data_directory tls_table;
142 struct grub_pe32_data_directory load_config_table;
143 struct grub_pe32_data_directory bound_import;
144 struct grub_pe32_data_directory iat;
145 struct grub_pe32_data_directory delay_import_descriptor;
146 struct grub_pe32_data_directory com_runtime_header;
147 struct grub_pe32_data_directory reserved_entry;
150 struct grub_pe64_optional_header
153 grub_uint8_t major_linker_version;
154 grub_uint8_t minor_linker_version;
155 grub_uint32_t code_size;
156 grub_uint32_t data_size;
157 grub_uint32_t bss_size;
158 grub_uint32_t entry_addr;
159 grub_uint32_t code_base;
161 grub_uint64_t image_base;
163 grub_uint32_t section_alignment;
164 grub_uint32_t file_alignment;
165 grub_uint16_t major_os_version;
166 grub_uint16_t minor_os_version;
167 grub_uint16_t major_image_version;
168 grub_uint16_t minor_image_version;
169 grub_uint16_t major_subsystem_version;
170 grub_uint16_t minor_subsystem_version;
171 grub_uint32_t reserved;
172 grub_uint32_t image_size;
173 grub_uint32_t header_size;
174 grub_uint32_t checksum;
175 grub_uint16_t subsystem;
176 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;
183 grub_uint32_t loader_flags;
184 grub_uint32_t num_data_directories;
186 /* Data directories. */
187 struct grub_pe32_data_directory export_table;
188 struct grub_pe32_data_directory import_table;
189 struct grub_pe32_data_directory resource_table;
190 struct grub_pe32_data_directory exception_table;
191 struct grub_pe32_data_directory certificate_table;
192 struct grub_pe32_data_directory base_relocation_table;
193 struct grub_pe32_data_directory debug;
194 struct grub_pe32_data_directory architecture;
195 struct grub_pe32_data_directory global_ptr;
196 struct grub_pe32_data_directory tls_table;
197 struct grub_pe32_data_directory load_config_table;
198 struct grub_pe32_data_directory bound_import;
199 struct grub_pe32_data_directory iat;
200 struct grub_pe32_data_directory delay_import_descriptor;
201 struct grub_pe32_data_directory com_runtime_header;
202 struct grub_pe32_data_directory reserved_entry;
205 #define GRUB_PE32_PE32_MAGIC 0x10b
206 #define GRUB_PE32_PE64_MAGIC 0x20b
208 #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
210 #define GRUB_PE32_NUM_DATA_DIRECTORIES 16
212 struct grub_pe32_section_table
215 grub_uint32_t virtual_size;
216 grub_uint32_t virtual_address;
217 grub_uint32_t raw_data_size;
218 grub_uint32_t raw_data_offset;
219 grub_uint32_t relocations_offset;
220 grub_uint32_t line_numbers_offset;
221 grub_uint16_t num_relocations;
222 grub_uint16_t num_line_numbers;
223 grub_uint32_t characteristics;
226 #define GRUB_PE32_SCN_CNT_CODE 0x00000020
227 #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
228 #define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
229 #define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
230 #define GRUB_PE32_SCN_MEM_READ 0x40000000
231 #define GRUB_PE32_SCN_MEM_WRITE 0x80000000
233 #define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
234 #define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
235 #define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000
236 #define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000
237 #define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
238 #define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
239 #define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
241 #define GRUB_PE32_SCN_ALIGN_SHIFT 20
242 #define GRUB_PE32_SCN_ALIGN_MASK 7
244 #define GRUB_PE32_SIGNATURE_SIZE 4
246 struct grub_pe32_header
248 /* This should be filled in with GRUB_PE32_MSDOS_STUB. */
249 grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
251 /* This is always PE\0\0. */
252 char signature[GRUB_PE32_SIGNATURE_SIZE];
254 /* The COFF file header. */
255 struct grub_pe32_coff_header coff_header;
257 #if GRUB_TARGET_SIZEOF_VOID_P == 8
258 /* The Optional header. */
259 struct grub_pe64_optional_header optional_header;
261 /* The Optional header. */
262 struct grub_pe32_optional_header optional_header;
266 struct grub_pe32_fixup_block
268 grub_uint32_t page_rva;
269 grub_uint32_t block_size;
270 grub_uint16_t entries[0];
273 #define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
275 #define GRUB_PE32_REL_BASED_ABSOLUTE 0
276 #define GRUB_PE32_REL_BASED_HIGH 1
277 #define GRUB_PE32_REL_BASED_LOW 2
278 #define GRUB_PE32_REL_BASED_HIGHLOW 3
279 #define GRUB_PE32_REL_BASED_HIGHADJ 4
280 #define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
281 #define GRUB_PE32_REL_BASED_ARM_MOV32A 5
282 #define GRUB_PE32_REL_BASED_SECTION 6
283 #define GRUB_PE32_REL_BASED_REL 7
284 #define GRUB_PE32_REL_BASED_ARM_MOV32T 7
285 #define GRUB_PE32_REL_BASED_IA64_IMM64 9
286 #define GRUB_PE32_REL_BASED_DIR64 10
287 #define GRUB_PE32_REL_BASED_HIGH3ADJ 11
289 struct grub_pe32_symbol
294 grub_uint32_t long_name[2];
298 grub_uint16_t section;
300 grub_uint8_t storage_class;
301 grub_uint8_t num_aux;
304 #define GRUB_PE32_SYM_CLASS_EXTERNAL 2
305 #define GRUB_PE32_SYM_CLASS_STATIC 3
306 #define GRUB_PE32_SYM_CLASS_FILE 0x67
308 #define GRUB_PE32_DT_FUNCTION 0x20
310 struct grub_pe32_reloc
312 grub_uint32_t offset;
313 grub_uint32_t symtab_index;
317 #define GRUB_PE32_REL_I386_DIR32 0x6
318 #define GRUB_PE32_REL_I386_REL32 0x14
320 #endif /* ! GRUB_EFI_PE32_HEADER */