f79c36c026e0a518b3f9edaca36251d6d4943757
[grub.git] / include / grub / efi / pe32.h
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
19 #ifndef GRUB_EFI_PE32_HEADER
20 #define GRUB_EFI_PE32_HEADER    1
21
22 #include <grub/types.h>
23
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 \
27   { \
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  \
44   }
45
46 #define GRUB_PE32_MSDOS_STUB_SIZE       0x80
47
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
54
55 struct grub_pe32_coff_header
56 {
57   grub_uint16_t machine;
58   grub_uint16_t num_sections;
59   grub_uint32_t time;
60   grub_uint32_t symtab_offset;
61   grub_uint32_t num_symbols;
62   grub_uint16_t optional_header_size;
63   grub_uint16_t characteristics;
64 };
65
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
71
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
87
88 struct grub_pe32_data_directory
89 {
90   grub_uint32_t rva;
91   grub_uint32_t size;
92 };
93
94 struct grub_pe32_optional_header
95 {
96   grub_uint16_t magic;
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;
104
105   grub_uint32_t data_base;
106   grub_uint32_t image_base;
107
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;
122
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;
127
128   grub_uint32_t loader_flags;
129   grub_uint32_t num_data_directories;
130
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;
148 };
149
150 struct grub_pe64_optional_header
151 {
152   grub_uint16_t magic;
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;
160
161   grub_uint64_t image_base;
162
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;
177
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
183   grub_uint32_t loader_flags;
184   grub_uint32_t num_data_directories;
185
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;
203 };
204
205 #define GRUB_PE32_PE32_MAGIC    0x10b
206 #define GRUB_PE32_PE64_MAGIC    0x20b
207
208 #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION     10
209
210 #define GRUB_PE32_NUM_DATA_DIRECTORIES  16
211
212 struct grub_pe32_section_table
213 {
214   char name[8];
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;
224 };
225
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
232
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
240
241 #define GRUB_PE32_SCN_ALIGN_SHIFT               20
242 #define GRUB_PE32_SCN_ALIGN_MASK                7
243
244 #define GRUB_PE32_SIGNATURE_SIZE 4
245
246 struct grub_pe32_header
247 {
248   /* This should be filled in with GRUB_PE32_MSDOS_STUB.  */
249   grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
250
251   /* This is always PE\0\0.  */
252   char signature[GRUB_PE32_SIGNATURE_SIZE];
253
254   /* The COFF file header.  */
255   struct grub_pe32_coff_header coff_header;
256
257 #if GRUB_TARGET_SIZEOF_VOID_P == 8
258   /* The Optional header.  */
259   struct grub_pe64_optional_header optional_header;
260 #else
261   /* The Optional header.  */
262   struct grub_pe32_optional_header optional_header;
263 #endif
264 };
265
266 struct grub_pe32_fixup_block
267 {
268   grub_uint32_t page_rva;
269   grub_uint32_t block_size;
270   grub_uint16_t entries[0];
271 };
272
273 #define GRUB_PE32_FIXUP_ENTRY(type, offset)     (((type) << 12) | (offset))
274
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
288
289 struct grub_pe32_symbol
290 {
291   union
292   {
293     char short_name[8];
294     grub_uint32_t long_name[2];
295   };
296
297   grub_uint32_t value;
298   grub_uint16_t section;
299   grub_uint16_t type;
300   grub_uint8_t storage_class;
301   grub_uint8_t num_aux;
302 } GRUB_PACKED;
303
304 #define GRUB_PE32_SYM_CLASS_EXTERNAL    2
305 #define GRUB_PE32_SYM_CLASS_STATIC      3
306 #define GRUB_PE32_SYM_CLASS_FILE        0x67
307
308 #define GRUB_PE32_DT_FUNCTION           0x20
309
310 struct grub_pe32_reloc
311 {
312   grub_uint32_t offset;
313   grub_uint32_t symtab_index;
314   grub_uint16_t type;
315 } GRUB_PACKED;
316
317 #define GRUB_PE32_REL_I386_DIR32        0x6
318 #define GRUB_PE32_REL_I386_REL32        0x14
319
320 #endif /* ! GRUB_EFI_PE32_HEADER */