1319780Sdim//===-- llvm/BinaryFormat/COFF.h --------------------------------*- C++ -*-===//
2319780Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6319780Sdim//
7319780Sdim//===----------------------------------------------------------------------===//
8319780Sdim//
9319780Sdim// This file contains an definitions used in Windows COFF Files.
10319780Sdim//
11319780Sdim// Structures and enums defined within this file where created using
12319780Sdim// information from Microsoft's publicly available PE/COFF format document:
13319780Sdim//
14319780Sdim// Microsoft Portable Executable and Common Object File Format Specification
15319780Sdim// Revision 8.1 - February 15, 2008
16319780Sdim//
17319780Sdim// As of 5/2/2010, hosted by Microsoft at:
18319780Sdim// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
19319780Sdim//
20319780Sdim//===----------------------------------------------------------------------===//
21319780Sdim
22319780Sdim#ifndef LLVM_BINARYFORMAT_COFF_H
23319780Sdim#define LLVM_BINARYFORMAT_COFF_H
24319780Sdim
25319780Sdim#include "llvm/Support/DataTypes.h"
26319780Sdim#include <cassert>
27319780Sdim#include <cstring>
28319780Sdim
29319780Sdimnamespace llvm {
30319780Sdimnamespace COFF {
31319780Sdim
32319780Sdim// The maximum number of sections that a COFF object can have (inclusive).
33319780Sdimconst int32_t MaxNumberOfSections16 = 65279;
34319780Sdim
35319780Sdim// The PE signature bytes that follows the DOS stub header.
36319780Sdimstatic const char PEMagic[] = {'P', 'E', '\0', '\0'};
37319780Sdim
38319780Sdimstatic const char BigObjMagic[] = {
39319780Sdim    '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
40319780Sdim    '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8',
41319780Sdim};
42319780Sdim
43319780Sdimstatic const char ClGlObjMagic[] = {
44319780Sdim    '\x38', '\xfe', '\xb3', '\x0c', '\xa5', '\xd9', '\xab', '\x4d',
45319780Sdim    '\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
46319780Sdim};
47319780Sdim
48320397Sdim// The signature bytes that start a .res file.
49320397Sdimstatic const char WinResMagic[] = {
50320397Sdim    '\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00',
51320397Sdim    '\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00',
52320397Sdim};
53320397Sdim
54319780Sdim// Sizes in bytes of various things in the COFF format.
55319780Sdimenum {
56319780Sdim  Header16Size = 20,
57319780Sdim  Header32Size = 56,
58319780Sdim  NameSize = 8,
59319780Sdim  Symbol16Size = 18,
60319780Sdim  Symbol32Size = 20,
61319780Sdim  SectionSize = 40,
62319780Sdim  RelocationSize = 10
63319780Sdim};
64319780Sdim
65319780Sdimstruct header {
66319780Sdim  uint16_t Machine;
67319780Sdim  int32_t NumberOfSections;
68319780Sdim  uint32_t TimeDateStamp;
69319780Sdim  uint32_t PointerToSymbolTable;
70319780Sdim  uint32_t NumberOfSymbols;
71319780Sdim  uint16_t SizeOfOptionalHeader;
72319780Sdim  uint16_t Characteristics;
73319780Sdim};
74319780Sdim
75319780Sdimstruct BigObjHeader {
76319780Sdim  enum : uint16_t { MinBigObjectVersion = 2 };
77319780Sdim
78319780Sdim  uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
79319780Sdim  uint16_t Sig2; ///< Must be 0xFFFF.
80319780Sdim  uint16_t Version;
81319780Sdim  uint16_t Machine;
82319780Sdim  uint32_t TimeDateStamp;
83319780Sdim  uint8_t UUID[16];
84319780Sdim  uint32_t unused1;
85319780Sdim  uint32_t unused2;
86319780Sdim  uint32_t unused3;
87319780Sdim  uint32_t unused4;
88319780Sdim  uint32_t NumberOfSections;
89319780Sdim  uint32_t PointerToSymbolTable;
90319780Sdim  uint32_t NumberOfSymbols;
91319780Sdim};
92319780Sdim
93327952Sdimenum MachineTypes : unsigned {
94319780Sdim  MT_Invalid = 0xffff,
95319780Sdim
96319780Sdim  IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
97327952Sdim  IMAGE_FILE_MACHINE_AM33 = 0x1D3,
98319780Sdim  IMAGE_FILE_MACHINE_AMD64 = 0x8664,
99319780Sdim  IMAGE_FILE_MACHINE_ARM = 0x1C0,
100319780Sdim  IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
101319780Sdim  IMAGE_FILE_MACHINE_ARM64 = 0xAA64,
102319780Sdim  IMAGE_FILE_MACHINE_EBC = 0xEBC,
103319780Sdim  IMAGE_FILE_MACHINE_I386 = 0x14C,
104319780Sdim  IMAGE_FILE_MACHINE_IA64 = 0x200,
105319780Sdim  IMAGE_FILE_MACHINE_M32R = 0x9041,
106319780Sdim  IMAGE_FILE_MACHINE_MIPS16 = 0x266,
107319780Sdim  IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
108319780Sdim  IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
109319780Sdim  IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
110319780Sdim  IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
111319780Sdim  IMAGE_FILE_MACHINE_R4000 = 0x166,
112341825Sdim  IMAGE_FILE_MACHINE_RISCV32 = 0x5032,
113341825Sdim  IMAGE_FILE_MACHINE_RISCV64 = 0x5064,
114341825Sdim  IMAGE_FILE_MACHINE_RISCV128 = 0x5128,
115319780Sdim  IMAGE_FILE_MACHINE_SH3 = 0x1A2,
116319780Sdim  IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
117319780Sdim  IMAGE_FILE_MACHINE_SH4 = 0x1A6,
118319780Sdim  IMAGE_FILE_MACHINE_SH5 = 0x1A8,
119319780Sdim  IMAGE_FILE_MACHINE_THUMB = 0x1C2,
120319780Sdim  IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
121319780Sdim};
122319780Sdim
123327952Sdimenum Characteristics : unsigned {
124319780Sdim  C_Invalid = 0,
125319780Sdim
126319780Sdim  /// The file does not contain base relocations and must be loaded at its
127319780Sdim  /// preferred base. If this cannot be done, the loader will error.
128319780Sdim  IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
129319780Sdim  /// The file is valid and can be run.
130319780Sdim  IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
131319780Sdim  /// COFF line numbers have been stripped. This is deprecated and should be
132319780Sdim  /// 0.
133319780Sdim  IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
134319780Sdim  /// COFF symbol table entries for local symbols have been removed. This is
135319780Sdim  /// deprecated and should be 0.
136319780Sdim  IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
137319780Sdim  /// Aggressively trim working set. This is deprecated and must be 0.
138319780Sdim  IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
139319780Sdim  /// Image can handle > 2GiB addresses.
140319780Sdim  IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
141319780Sdim  /// Little endian: the LSB precedes the MSB in memory. This is deprecated
142319780Sdim  /// and should be 0.
143319780Sdim  IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
144319780Sdim  /// Machine is based on a 32bit word architecture.
145319780Sdim  IMAGE_FILE_32BIT_MACHINE = 0x0100,
146319780Sdim  /// Debugging info has been removed.
147319780Sdim  IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
148319780Sdim  /// If the image is on removable media, fully load it and copy it to swap.
149319780Sdim  IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
150319780Sdim  /// If the image is on network media, fully load it and copy it to swap.
151319780Sdim  IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
152319780Sdim  /// The image file is a system file, not a user program.
153319780Sdim  IMAGE_FILE_SYSTEM = 0x1000,
154319780Sdim  /// The image file is a DLL.
155319780Sdim  IMAGE_FILE_DLL = 0x2000,
156319780Sdim  /// This file should only be run on a uniprocessor machine.
157319780Sdim  IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
158319780Sdim  /// Big endian: the MSB precedes the LSB in memory. This is deprecated
159319780Sdim  /// and should be 0.
160319780Sdim  IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
161319780Sdim};
162319780Sdim
163327952Sdimenum ResourceTypeID : unsigned {
164319780Sdim  RID_Cursor = 1,
165319780Sdim  RID_Bitmap = 2,
166319780Sdim  RID_Icon = 3,
167319780Sdim  RID_Menu = 4,
168319780Sdim  RID_Dialog = 5,
169319780Sdim  RID_String = 6,
170319780Sdim  RID_FontDir = 7,
171319780Sdim  RID_Font = 8,
172319780Sdim  RID_Accelerator = 9,
173319780Sdim  RID_RCData = 10,
174319780Sdim  RID_MessageTable = 11,
175319780Sdim  RID_Group_Cursor = 12,
176319780Sdim  RID_Group_Icon = 14,
177319780Sdim  RID_Version = 16,
178319780Sdim  RID_DLGInclude = 17,
179319780Sdim  RID_PlugPlay = 19,
180319780Sdim  RID_VXD = 20,
181319780Sdim  RID_AniCursor = 21,
182319780Sdim  RID_AniIcon = 22,
183319780Sdim  RID_HTML = 23,
184319780Sdim  RID_Manifest = 24,
185319780Sdim};
186319780Sdim
187319780Sdimstruct symbol {
188319780Sdim  char Name[NameSize];
189319780Sdim  uint32_t Value;
190319780Sdim  int32_t SectionNumber;
191319780Sdim  uint16_t Type;
192319780Sdim  uint8_t StorageClass;
193319780Sdim  uint8_t NumberOfAuxSymbols;
194319780Sdim};
195319780Sdim
196319780Sdimenum SymbolSectionNumber : int32_t {
197319780Sdim  IMAGE_SYM_DEBUG = -2,
198319780Sdim  IMAGE_SYM_ABSOLUTE = -1,
199319780Sdim  IMAGE_SYM_UNDEFINED = 0
200319780Sdim};
201319780Sdim
202319780Sdim/// Storage class tells where and what the symbol represents
203319780Sdimenum SymbolStorageClass {
204319780Sdim  SSC_Invalid = 0xff,
205319780Sdim
206319780Sdim  IMAGE_SYM_CLASS_END_OF_FUNCTION = -1,  ///< Physical end of function
207319780Sdim  IMAGE_SYM_CLASS_NULL = 0,              ///< No symbol
208319780Sdim  IMAGE_SYM_CLASS_AUTOMATIC = 1,         ///< Stack variable
209319780Sdim  IMAGE_SYM_CLASS_EXTERNAL = 2,          ///< External symbol
210319780Sdim  IMAGE_SYM_CLASS_STATIC = 3,            ///< Static
211319780Sdim  IMAGE_SYM_CLASS_REGISTER = 4,          ///< Register variable
212319780Sdim  IMAGE_SYM_CLASS_EXTERNAL_DEF = 5,      ///< External definition
213319780Sdim  IMAGE_SYM_CLASS_LABEL = 6,             ///< Label
214319780Sdim  IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7,   ///< Undefined label
215319780Sdim  IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8,  ///< Member of structure
216319780Sdim  IMAGE_SYM_CLASS_ARGUMENT = 9,          ///< Function argument
217319780Sdim  IMAGE_SYM_CLASS_STRUCT_TAG = 10,       ///< Structure tag
218319780Sdim  IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11,  ///< Member of union
219319780Sdim  IMAGE_SYM_CLASS_UNION_TAG = 12,        ///< Union tag
220319780Sdim  IMAGE_SYM_CLASS_TYPE_DEFINITION = 13,  ///< Type definition
221319780Sdim  IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14, ///< Undefined static
222319780Sdim  IMAGE_SYM_CLASS_ENUM_TAG = 15,         ///< Enumeration tag
223319780Sdim  IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16,   ///< Member of enumeration
224319780Sdim  IMAGE_SYM_CLASS_REGISTER_PARAM = 17,   ///< Register parameter
225319780Sdim  IMAGE_SYM_CLASS_BIT_FIELD = 18,        ///< Bit field
226319780Sdim  /// ".bb" or ".eb" - beginning or end of block
227319780Sdim  IMAGE_SYM_CLASS_BLOCK = 100,
228319780Sdim  /// ".bf" or ".ef" - beginning or end of function
229319780Sdim  IMAGE_SYM_CLASS_FUNCTION = 101,
230319780Sdim  IMAGE_SYM_CLASS_END_OF_STRUCT = 102, ///< End of structure
231319780Sdim  IMAGE_SYM_CLASS_FILE = 103,          ///< File name
232319780Sdim  /// Line number, reformatted as symbol
233319780Sdim  IMAGE_SYM_CLASS_SECTION = 104,
234319780Sdim  IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105, ///< Duplicate tag
235319780Sdim  /// External symbol in dmert public lib
236319780Sdim  IMAGE_SYM_CLASS_CLR_TOKEN = 107
237319780Sdim};
238319780Sdim
239327952Sdimenum SymbolBaseType : unsigned {
240319780Sdim  IMAGE_SYM_TYPE_NULL = 0,   ///< No type information or unknown base type.
241319780Sdim  IMAGE_SYM_TYPE_VOID = 1,   ///< Used with void pointers and functions.
242319780Sdim  IMAGE_SYM_TYPE_CHAR = 2,   ///< A character (signed byte).
243319780Sdim  IMAGE_SYM_TYPE_SHORT = 3,  ///< A 2-byte signed integer.
244319780Sdim  IMAGE_SYM_TYPE_INT = 4,    ///< A natural integer type on the target.
245319780Sdim  IMAGE_SYM_TYPE_LONG = 5,   ///< A 4-byte signed integer.
246319780Sdim  IMAGE_SYM_TYPE_FLOAT = 6,  ///< A 4-byte floating-point number.
247319780Sdim  IMAGE_SYM_TYPE_DOUBLE = 7, ///< An 8-byte floating-point number.
248319780Sdim  IMAGE_SYM_TYPE_STRUCT = 8, ///< A structure.
249319780Sdim  IMAGE_SYM_TYPE_UNION = 9,  ///< An union.
250319780Sdim  IMAGE_SYM_TYPE_ENUM = 10,  ///< An enumerated type.
251319780Sdim  IMAGE_SYM_TYPE_MOE = 11,   ///< A member of enumeration (a specific value).
252319780Sdim  IMAGE_SYM_TYPE_BYTE = 12,  ///< A byte; unsigned 1-byte integer.
253319780Sdim  IMAGE_SYM_TYPE_WORD = 13,  ///< A word; unsigned 2-byte integer.
254319780Sdim  IMAGE_SYM_TYPE_UINT = 14,  ///< An unsigned integer of natural size.
255319780Sdim  IMAGE_SYM_TYPE_DWORD = 15  ///< An unsigned 4-byte integer.
256319780Sdim};
257319780Sdim
258327952Sdimenum SymbolComplexType : unsigned {
259319780Sdim  IMAGE_SYM_DTYPE_NULL = 0,     ///< No complex type; simple scalar variable.
260319780Sdim  IMAGE_SYM_DTYPE_POINTER = 1,  ///< A pointer to base type.
261319780Sdim  IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
262319780Sdim  IMAGE_SYM_DTYPE_ARRAY = 3,    ///< An array of base type.
263319780Sdim
264319780Sdim  /// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
265319780Sdim  SCT_COMPLEX_TYPE_SHIFT = 4
266319780Sdim};
267319780Sdim
268319780Sdimenum AuxSymbolType { IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1 };
269319780Sdim
270319780Sdimstruct section {
271319780Sdim  char Name[NameSize];
272319780Sdim  uint32_t VirtualSize;
273319780Sdim  uint32_t VirtualAddress;
274319780Sdim  uint32_t SizeOfRawData;
275319780Sdim  uint32_t PointerToRawData;
276319780Sdim  uint32_t PointerToRelocations;
277319780Sdim  uint32_t PointerToLineNumbers;
278319780Sdim  uint16_t NumberOfRelocations;
279319780Sdim  uint16_t NumberOfLineNumbers;
280319780Sdim  uint32_t Characteristics;
281319780Sdim};
282319780Sdim
283319780Sdimenum SectionCharacteristics : uint32_t {
284319780Sdim  SC_Invalid = 0xffffffff,
285319780Sdim
286319780Sdim  IMAGE_SCN_TYPE_NOLOAD = 0x00000002,
287319780Sdim  IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
288319780Sdim  IMAGE_SCN_CNT_CODE = 0x00000020,
289319780Sdim  IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
290319780Sdim  IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
291319780Sdim  IMAGE_SCN_LNK_OTHER = 0x00000100,
292319780Sdim  IMAGE_SCN_LNK_INFO = 0x00000200,
293319780Sdim  IMAGE_SCN_LNK_REMOVE = 0x00000800,
294319780Sdim  IMAGE_SCN_LNK_COMDAT = 0x00001000,
295319780Sdim  IMAGE_SCN_GPREL = 0x00008000,
296319780Sdim  IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
297319780Sdim  IMAGE_SCN_MEM_16BIT = 0x00020000,
298319780Sdim  IMAGE_SCN_MEM_LOCKED = 0x00040000,
299319780Sdim  IMAGE_SCN_MEM_PRELOAD = 0x00080000,
300319780Sdim  IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
301319780Sdim  IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
302319780Sdim  IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
303319780Sdim  IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
304319780Sdim  IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
305319780Sdim  IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
306319780Sdim  IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
307319780Sdim  IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
308319780Sdim  IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
309319780Sdim  IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
310319780Sdim  IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
311319780Sdim  IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
312319780Sdim  IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
313319780Sdim  IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
314319780Sdim  IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
315319780Sdim  IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
316319780Sdim  IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
317319780Sdim  IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
318319780Sdim  IMAGE_SCN_MEM_SHARED = 0x10000000,
319319780Sdim  IMAGE_SCN_MEM_EXECUTE = 0x20000000,
320319780Sdim  IMAGE_SCN_MEM_READ = 0x40000000,
321319780Sdim  IMAGE_SCN_MEM_WRITE = 0x80000000
322319780Sdim};
323319780Sdim
324319780Sdimstruct relocation {
325319780Sdim  uint32_t VirtualAddress;
326319780Sdim  uint32_t SymbolTableIndex;
327319780Sdim  uint16_t Type;
328319780Sdim};
329319780Sdim
330327952Sdimenum RelocationTypeI386 : unsigned {
331319780Sdim  IMAGE_REL_I386_ABSOLUTE = 0x0000,
332319780Sdim  IMAGE_REL_I386_DIR16 = 0x0001,
333319780Sdim  IMAGE_REL_I386_REL16 = 0x0002,
334319780Sdim  IMAGE_REL_I386_DIR32 = 0x0006,
335319780Sdim  IMAGE_REL_I386_DIR32NB = 0x0007,
336319780Sdim  IMAGE_REL_I386_SEG12 = 0x0009,
337319780Sdim  IMAGE_REL_I386_SECTION = 0x000A,
338319780Sdim  IMAGE_REL_I386_SECREL = 0x000B,
339319780Sdim  IMAGE_REL_I386_TOKEN = 0x000C,
340319780Sdim  IMAGE_REL_I386_SECREL7 = 0x000D,
341319780Sdim  IMAGE_REL_I386_REL32 = 0x0014
342319780Sdim};
343319780Sdim
344327952Sdimenum RelocationTypeAMD64 : unsigned {
345319780Sdim  IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
346319780Sdim  IMAGE_REL_AMD64_ADDR64 = 0x0001,
347319780Sdim  IMAGE_REL_AMD64_ADDR32 = 0x0002,
348319780Sdim  IMAGE_REL_AMD64_ADDR32NB = 0x0003,
349319780Sdim  IMAGE_REL_AMD64_REL32 = 0x0004,
350319780Sdim  IMAGE_REL_AMD64_REL32_1 = 0x0005,
351319780Sdim  IMAGE_REL_AMD64_REL32_2 = 0x0006,
352319780Sdim  IMAGE_REL_AMD64_REL32_3 = 0x0007,
353319780Sdim  IMAGE_REL_AMD64_REL32_4 = 0x0008,
354319780Sdim  IMAGE_REL_AMD64_REL32_5 = 0x0009,
355319780Sdim  IMAGE_REL_AMD64_SECTION = 0x000A,
356319780Sdim  IMAGE_REL_AMD64_SECREL = 0x000B,
357319780Sdim  IMAGE_REL_AMD64_SECREL7 = 0x000C,
358319780Sdim  IMAGE_REL_AMD64_TOKEN = 0x000D,
359319780Sdim  IMAGE_REL_AMD64_SREL32 = 0x000E,
360319780Sdim  IMAGE_REL_AMD64_PAIR = 0x000F,
361319780Sdim  IMAGE_REL_AMD64_SSPAN32 = 0x0010
362319780Sdim};
363319780Sdim
364327952Sdimenum RelocationTypesARM : unsigned {
365319780Sdim  IMAGE_REL_ARM_ABSOLUTE = 0x0000,
366319780Sdim  IMAGE_REL_ARM_ADDR32 = 0x0001,
367319780Sdim  IMAGE_REL_ARM_ADDR32NB = 0x0002,
368319780Sdim  IMAGE_REL_ARM_BRANCH24 = 0x0003,
369319780Sdim  IMAGE_REL_ARM_BRANCH11 = 0x0004,
370319780Sdim  IMAGE_REL_ARM_TOKEN = 0x0005,
371319780Sdim  IMAGE_REL_ARM_BLX24 = 0x0008,
372319780Sdim  IMAGE_REL_ARM_BLX11 = 0x0009,
373353358Sdim  IMAGE_REL_ARM_REL32 = 0x000A,
374319780Sdim  IMAGE_REL_ARM_SECTION = 0x000E,
375319780Sdim  IMAGE_REL_ARM_SECREL = 0x000F,
376319780Sdim  IMAGE_REL_ARM_MOV32A = 0x0010,
377319780Sdim  IMAGE_REL_ARM_MOV32T = 0x0011,
378319780Sdim  IMAGE_REL_ARM_BRANCH20T = 0x0012,
379319780Sdim  IMAGE_REL_ARM_BRANCH24T = 0x0014,
380353358Sdim  IMAGE_REL_ARM_BLX23T = 0x0015,
381353358Sdim  IMAGE_REL_ARM_PAIR = 0x0016,
382319780Sdim};
383319780Sdim
384327952Sdimenum RelocationTypesARM64 : unsigned {
385319780Sdim  IMAGE_REL_ARM64_ABSOLUTE = 0x0000,
386319780Sdim  IMAGE_REL_ARM64_ADDR32 = 0x0001,
387319780Sdim  IMAGE_REL_ARM64_ADDR32NB = 0x0002,
388319780Sdim  IMAGE_REL_ARM64_BRANCH26 = 0x0003,
389320572Sdim  IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004,
390319780Sdim  IMAGE_REL_ARM64_REL21 = 0x0005,
391319780Sdim  IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006,
392319780Sdim  IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007,
393319780Sdim  IMAGE_REL_ARM64_SECREL = 0x0008,
394319780Sdim  IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009,
395319780Sdim  IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A,
396319780Sdim  IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B,
397319780Sdim  IMAGE_REL_ARM64_TOKEN = 0x000C,
398319780Sdim  IMAGE_REL_ARM64_SECTION = 0x000D,
399319780Sdim  IMAGE_REL_ARM64_ADDR64 = 0x000E,
400319780Sdim  IMAGE_REL_ARM64_BRANCH19 = 0x000F,
401319780Sdim  IMAGE_REL_ARM64_BRANCH14 = 0x0010,
402353358Sdim  IMAGE_REL_ARM64_REL32 = 0x0011,
403319780Sdim};
404319780Sdim
405353358Sdimenum COMDATType : uint8_t {
406319780Sdim  IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
407319780Sdim  IMAGE_COMDAT_SELECT_ANY,
408319780Sdim  IMAGE_COMDAT_SELECT_SAME_SIZE,
409319780Sdim  IMAGE_COMDAT_SELECT_EXACT_MATCH,
410319780Sdim  IMAGE_COMDAT_SELECT_ASSOCIATIVE,
411319780Sdim  IMAGE_COMDAT_SELECT_LARGEST,
412319780Sdim  IMAGE_COMDAT_SELECT_NEWEST
413319780Sdim};
414319780Sdim
415319780Sdim// Auxiliary Symbol Formats
416319780Sdimstruct AuxiliaryFunctionDefinition {
417319780Sdim  uint32_t TagIndex;
418319780Sdim  uint32_t TotalSize;
419319780Sdim  uint32_t PointerToLinenumber;
420319780Sdim  uint32_t PointerToNextFunction;
421319780Sdim  char unused[2];
422319780Sdim};
423319780Sdim
424319780Sdimstruct AuxiliarybfAndefSymbol {
425319780Sdim  uint8_t unused1[4];
426319780Sdim  uint16_t Linenumber;
427319780Sdim  uint8_t unused2[6];
428319780Sdim  uint32_t PointerToNextFunction;
429319780Sdim  uint8_t unused3[2];
430319780Sdim};
431319780Sdim
432319780Sdimstruct AuxiliaryWeakExternal {
433319780Sdim  uint32_t TagIndex;
434319780Sdim  uint32_t Characteristics;
435319780Sdim  uint8_t unused[10];
436319780Sdim};
437319780Sdim
438327952Sdimenum WeakExternalCharacteristics : unsigned {
439319780Sdim  IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
440319780Sdim  IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
441319780Sdim  IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
442319780Sdim};
443319780Sdim
444319780Sdimstruct AuxiliarySectionDefinition {
445319780Sdim  uint32_t Length;
446319780Sdim  uint16_t NumberOfRelocations;
447319780Sdim  uint16_t NumberOfLinenumbers;
448319780Sdim  uint32_t CheckSum;
449319780Sdim  uint32_t Number;
450319780Sdim  uint8_t Selection;
451319780Sdim  char unused;
452319780Sdim};
453319780Sdim
454319780Sdimstruct AuxiliaryCLRToken {
455319780Sdim  uint8_t AuxType;
456319780Sdim  uint8_t unused1;
457319780Sdim  uint32_t SymbolTableIndex;
458319780Sdim  char unused2[12];
459319780Sdim};
460319780Sdim
461319780Sdimunion Auxiliary {
462319780Sdim  AuxiliaryFunctionDefinition FunctionDefinition;
463319780Sdim  AuxiliarybfAndefSymbol bfAndefSymbol;
464319780Sdim  AuxiliaryWeakExternal WeakExternal;
465319780Sdim  AuxiliarySectionDefinition SectionDefinition;
466319780Sdim};
467319780Sdim
468341825Sdim/// The Import Directory Table.
469319780Sdim///
470319780Sdim/// There is a single array of these and one entry per imported DLL.
471319780Sdimstruct ImportDirectoryTableEntry {
472319780Sdim  uint32_t ImportLookupTableRVA;
473319780Sdim  uint32_t TimeDateStamp;
474319780Sdim  uint32_t ForwarderChain;
475319780Sdim  uint32_t NameRVA;
476319780Sdim  uint32_t ImportAddressTableRVA;
477319780Sdim};
478319780Sdim
479341825Sdim/// The PE32 Import Lookup Table.
480319780Sdim///
481319780Sdim/// There is an array of these for each imported DLL. It represents either
482319780Sdim/// the ordinal to import from the target DLL, or a name to lookup and import
483319780Sdim/// from the target DLL.
484319780Sdim///
485319780Sdim/// This also happens to be the same format used by the Import Address Table
486319780Sdim/// when it is initially written out to the image.
487319780Sdimstruct ImportLookupTableEntry32 {
488319780Sdim  uint32_t data;
489319780Sdim
490341825Sdim  /// Is this entry specified by ordinal, or name?
491319780Sdim  bool isOrdinal() const { return data & 0x80000000; }
492319780Sdim
493341825Sdim  /// Get the ordinal value of this entry. isOrdinal must be true.
494319780Sdim  uint16_t getOrdinal() const {
495319780Sdim    assert(isOrdinal() && "ILT entry is not an ordinal!");
496319780Sdim    return data & 0xFFFF;
497319780Sdim  }
498319780Sdim
499341825Sdim  /// Set the ordinal value and set isOrdinal to true.
500319780Sdim  void setOrdinal(uint16_t o) {
501319780Sdim    data = o;
502319780Sdim    data |= 0x80000000;
503319780Sdim  }
504319780Sdim
505341825Sdim  /// Get the Hint/Name entry RVA. isOrdinal must be false.
506319780Sdim  uint32_t getHintNameRVA() const {
507319780Sdim    assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
508319780Sdim    return data;
509319780Sdim  }
510319780Sdim
511341825Sdim  /// Set the Hint/Name entry RVA and set isOrdinal to false.
512319780Sdim  void setHintNameRVA(uint32_t rva) { data = rva; }
513319780Sdim};
514319780Sdim
515341825Sdim/// The DOS compatible header at the front of all PEs.
516319780Sdimstruct DOSHeader {
517319780Sdim  uint16_t Magic;
518319780Sdim  uint16_t UsedBytesInTheLastPage;
519319780Sdim  uint16_t FileSizeInPages;
520319780Sdim  uint16_t NumberOfRelocationItems;
521319780Sdim  uint16_t HeaderSizeInParagraphs;
522319780Sdim  uint16_t MinimumExtraParagraphs;
523319780Sdim  uint16_t MaximumExtraParagraphs;
524319780Sdim  uint16_t InitialRelativeSS;
525319780Sdim  uint16_t InitialSP;
526319780Sdim  uint16_t Checksum;
527319780Sdim  uint16_t InitialIP;
528319780Sdim  uint16_t InitialRelativeCS;
529319780Sdim  uint16_t AddressOfRelocationTable;
530319780Sdim  uint16_t OverlayNumber;
531319780Sdim  uint16_t Reserved[4];
532319780Sdim  uint16_t OEMid;
533319780Sdim  uint16_t OEMinfo;
534319780Sdim  uint16_t Reserved2[10];
535319780Sdim  uint32_t AddressOfNewExeHeader;
536319780Sdim};
537319780Sdim
538319780Sdimstruct PE32Header {
539319780Sdim  enum { PE32 = 0x10b, PE32_PLUS = 0x20b };
540319780Sdim
541319780Sdim  uint16_t Magic;
542319780Sdim  uint8_t MajorLinkerVersion;
543319780Sdim  uint8_t MinorLinkerVersion;
544319780Sdim  uint32_t SizeOfCode;
545319780Sdim  uint32_t SizeOfInitializedData;
546319780Sdim  uint32_t SizeOfUninitializedData;
547319780Sdim  uint32_t AddressOfEntryPoint; // RVA
548319780Sdim  uint32_t BaseOfCode;          // RVA
549319780Sdim  uint32_t BaseOfData;          // RVA
550360784Sdim  uint64_t ImageBase;
551319780Sdim  uint32_t SectionAlignment;
552319780Sdim  uint32_t FileAlignment;
553319780Sdim  uint16_t MajorOperatingSystemVersion;
554319780Sdim  uint16_t MinorOperatingSystemVersion;
555319780Sdim  uint16_t MajorImageVersion;
556319780Sdim  uint16_t MinorImageVersion;
557319780Sdim  uint16_t MajorSubsystemVersion;
558319780Sdim  uint16_t MinorSubsystemVersion;
559319780Sdim  uint32_t Win32VersionValue;
560319780Sdim  uint32_t SizeOfImage;
561319780Sdim  uint32_t SizeOfHeaders;
562319780Sdim  uint32_t CheckSum;
563319780Sdim  uint16_t Subsystem;
564319780Sdim  // FIXME: This should be DllCharacteristics to match the COFF spec.
565319780Sdim  uint16_t DLLCharacteristics;
566360784Sdim  uint64_t SizeOfStackReserve;
567360784Sdim  uint64_t SizeOfStackCommit;
568360784Sdim  uint64_t SizeOfHeapReserve;
569360784Sdim  uint64_t SizeOfHeapCommit;
570319780Sdim  uint32_t LoaderFlags;
571319780Sdim  // FIXME: This should be NumberOfRvaAndSizes to match the COFF spec.
572319780Sdim  uint32_t NumberOfRvaAndSize;
573319780Sdim};
574319780Sdim
575319780Sdimstruct DataDirectory {
576319780Sdim  uint32_t RelativeVirtualAddress;
577319780Sdim  uint32_t Size;
578319780Sdim};
579319780Sdim
580327952Sdimenum DataDirectoryIndex : unsigned {
581319780Sdim  EXPORT_TABLE = 0,
582319780Sdim  IMPORT_TABLE,
583319780Sdim  RESOURCE_TABLE,
584319780Sdim  EXCEPTION_TABLE,
585319780Sdim  CERTIFICATE_TABLE,
586319780Sdim  BASE_RELOCATION_TABLE,
587319780Sdim  DEBUG_DIRECTORY,
588319780Sdim  ARCHITECTURE,
589319780Sdim  GLOBAL_PTR,
590319780Sdim  TLS_TABLE,
591319780Sdim  LOAD_CONFIG_TABLE,
592319780Sdim  BOUND_IMPORT,
593319780Sdim  IAT,
594319780Sdim  DELAY_IMPORT_DESCRIPTOR,
595319780Sdim  CLR_RUNTIME_HEADER,
596319780Sdim
597319780Sdim  NUM_DATA_DIRECTORIES
598319780Sdim};
599319780Sdim
600327952Sdimenum WindowsSubsystem : unsigned {
601319780Sdim  IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
602319780Sdim  IMAGE_SUBSYSTEM_NATIVE = 1,  ///< Device drivers and native Windows processes
603319780Sdim  IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,      ///< The Windows GUI subsystem.
604319780Sdim  IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,      ///< The Windows character subsystem.
605319780Sdim  IMAGE_SUBSYSTEM_OS2_CUI = 5,          ///< The OS/2 character subsytem.
606319780Sdim  IMAGE_SUBSYSTEM_POSIX_CUI = 7,        ///< The POSIX character subsystem.
607319780Sdim  IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8,   ///< Native Windows 9x driver.
608319780Sdim  IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,   ///< Windows CE.
609319780Sdim  IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
610319780Sdim  IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
611319780Sdim                                                ///  services.
612319780Sdim  IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,      ///< An EFI driver with run-time
613319780Sdim                                                ///  services.
614319780Sdim  IMAGE_SUBSYSTEM_EFI_ROM = 13,                 ///< An EFI ROM image.
615319780Sdim  IMAGE_SUBSYSTEM_XBOX = 14,                    ///< XBOX.
616319780Sdim  IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 ///< A BCD application.
617319780Sdim};
618319780Sdim
619327952Sdimenum DLLCharacteristics : unsigned {
620319780Sdim  /// ASLR with 64 bit address space.
621319780Sdim  IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
622319780Sdim  /// DLL can be relocated at load time.
623319780Sdim  IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
624319780Sdim  /// Code integrity checks are enforced.
625319780Sdim  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
626319780Sdim  ///< Image is NX compatible.
627319780Sdim  IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
628319780Sdim  /// Isolation aware, but do not isolate the image.
629319780Sdim  IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
630319780Sdim  /// Does not use structured exception handling (SEH). No SEH handler may be
631319780Sdim  /// called in this image.
632319780Sdim  IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
633319780Sdim  /// Do not bind the image.
634319780Sdim  IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
635319780Sdim  ///< Image should execute in an AppContainer.
636319780Sdim  IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
637319780Sdim  ///< A WDM driver.
638319780Sdim  IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
639319780Sdim  ///< Image supports Control Flow Guard.
640319780Sdim  IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
641319780Sdim  /// Terminal Server aware.
642319780Sdim  IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
643319780Sdim};
644319780Sdim
645327952Sdimenum DebugType : unsigned {
646319780Sdim  IMAGE_DEBUG_TYPE_UNKNOWN = 0,
647319780Sdim  IMAGE_DEBUG_TYPE_COFF = 1,
648319780Sdim  IMAGE_DEBUG_TYPE_CODEVIEW = 2,
649319780Sdim  IMAGE_DEBUG_TYPE_FPO = 3,
650319780Sdim  IMAGE_DEBUG_TYPE_MISC = 4,
651319780Sdim  IMAGE_DEBUG_TYPE_EXCEPTION = 5,
652319780Sdim  IMAGE_DEBUG_TYPE_FIXUP = 6,
653319780Sdim  IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
654319780Sdim  IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
655319780Sdim  IMAGE_DEBUG_TYPE_BORLAND = 9,
656319780Sdim  IMAGE_DEBUG_TYPE_RESERVED10 = 10,
657319780Sdim  IMAGE_DEBUG_TYPE_CLSID = 11,
658319780Sdim  IMAGE_DEBUG_TYPE_VC_FEATURE = 12,
659319780Sdim  IMAGE_DEBUG_TYPE_POGO = 13,
660319780Sdim  IMAGE_DEBUG_TYPE_ILTCG = 14,
661319780Sdim  IMAGE_DEBUG_TYPE_MPX = 15,
662319780Sdim  IMAGE_DEBUG_TYPE_REPRO = 16,
663319780Sdim};
664319780Sdim
665327952Sdimenum BaseRelocationType : unsigned {
666319780Sdim  IMAGE_REL_BASED_ABSOLUTE = 0,
667319780Sdim  IMAGE_REL_BASED_HIGH = 1,
668319780Sdim  IMAGE_REL_BASED_LOW = 2,
669319780Sdim  IMAGE_REL_BASED_HIGHLOW = 3,
670319780Sdim  IMAGE_REL_BASED_HIGHADJ = 4,
671319780Sdim  IMAGE_REL_BASED_MIPS_JMPADDR = 5,
672319780Sdim  IMAGE_REL_BASED_ARM_MOV32A = 5,
673319780Sdim  IMAGE_REL_BASED_ARM_MOV32T = 7,
674319780Sdim  IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
675319780Sdim  IMAGE_REL_BASED_DIR64 = 10
676319780Sdim};
677319780Sdim
678327952Sdimenum ImportType : unsigned {
679327952Sdim  IMPORT_CODE = 0,
680327952Sdim  IMPORT_DATA = 1,
681327952Sdim  IMPORT_CONST = 2
682327952Sdim};
683319780Sdim
684327952Sdimenum ImportNameType : unsigned {
685319780Sdim  /// Import is by ordinal. This indicates that the value in the Ordinal/Hint
686319780Sdim  /// field of the import header is the import's ordinal. If this constant is
687319780Sdim  /// not specified, then the Ordinal/Hint field should always be interpreted
688319780Sdim  /// as the import's hint.
689319780Sdim  IMPORT_ORDINAL = 0,
690319780Sdim  /// The import name is identical to the public symbol name
691319780Sdim  IMPORT_NAME = 1,
692319780Sdim  /// The import name is the public symbol name, but skipping the leading ?,
693319780Sdim  /// @, or optionally _.
694319780Sdim  IMPORT_NAME_NOPREFIX = 2,
695319780Sdim  /// The import name is the public symbol name, but skipping the leading ?,
696319780Sdim  /// @, or optionally _, and truncating at the first @.
697319780Sdim  IMPORT_NAME_UNDECORATE = 3
698319780Sdim};
699319780Sdim
700319780Sdimstruct ImportHeader {
701319780Sdim  uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
702319780Sdim  uint16_t Sig2; ///< Must be 0xFFFF.
703319780Sdim  uint16_t Version;
704319780Sdim  uint16_t Machine;
705319780Sdim  uint32_t TimeDateStamp;
706319780Sdim  uint32_t SizeOfData;
707319780Sdim  uint16_t OrdinalHint;
708319780Sdim  uint16_t TypeInfo;
709319780Sdim
710319780Sdim  ImportType getType() const { return static_cast<ImportType>(TypeInfo & 0x3); }
711319780Sdim
712319780Sdim  ImportNameType getNameType() const {
713319780Sdim    return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 2);
714319780Sdim  }
715319780Sdim};
716319780Sdim
717319780Sdimenum CodeViewIdentifiers {
718319780Sdim  DEBUG_SECTION_MAGIC = 0x4,
719327952Sdim  DEBUG_HASHES_SECTION_MAGIC = 0x133C9C5
720319780Sdim};
721319780Sdim
722319780Sdiminline bool isReservedSectionNumber(int32_t SectionNumber) {
723319780Sdim  return SectionNumber <= 0;
724319780Sdim}
725319780Sdim
726319780Sdim} // End namespace COFF.
727319780Sdim} // End namespace llvm.
728319780Sdim
729319780Sdim#endif
730