1 /** Microsoft COFF object file format
2 *
3 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/mscoff.d, backend/_mscoff.d)
4 */
5
6 module dmd.backend.mscoff;
7
8 // Online documentation: https://dlang.org/phobos/dmd_backend_mscoff.html
9
10 version(Windows):
11 align (1):
12
13 /***********************************************/
14
15 struct BIGOBJ_HEADER
16 {
17 ushort Sig1; // IMAGE_FILE_MACHINE_UNKNOWN
18 ushort Sig2; // 0xFFFF
19 ushort Version; // 2
20 ushort Machine; // identifies type of target machine
21 uint TimeDateStamp; // creation date, number of seconds since 1970
22 ubyte[16] UUID; // { '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
23 // '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8' };
24 uint[4] unused; // { 0, 0, 0, 0 }
25 uint NumberOfSections; // number of sections
26 uint PointerToSymbolTable; // file offset of symbol table
27 uint NumberOfSymbols; // number of entries in the symbol table
28 }
29
30 enum
31 {
32 IMAGE_FILE_MACHINE_UNKNOWN = 0, // applies to any machine type
33 IMAGE_FILE_MACHINE_I386 = 0x14C, // x86
34 IMAGE_FILE_MACHINE_AMD64 = 0x8664, // x86_64
35
36 IMAGE_FILE_RELOCS_STRIPPED = 1,
37 IMAGE_FILE_EXECUTABLE_IMAGE = 2,
38 IMAGE_FILE_LINE_NUMS_STRIPPED = 4,
39 IMAGE_FILE_LOCAL_SYMS_STRIPPED = 8,
40 IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x10,
41 IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x20,
42 IMAGE_FILE_BYTES_REVERSED_LO = 0x80,
43 IMAGE_FILE_32BIT_MACHINE = 0x100,
44 IMAGE_FILE_DEBUG_STRIPPED = 0x200,
45 IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x400,
46 IMAGE_FILE_NET_RUN_FROM_SWAP = 0x800,
47 IMAGE_FILE_SYSTEM = 0x1000,
48 IMAGE_FILE_DLL = 0x2000,
49 IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
50 IMAGE_FILE_BYTES_REVERSED_HI = 0x8000,
51 }
52
53 struct IMAGE_FILE_HEADER
54 {
55 ushort Machine;
56 ushort NumberOfSections;
57 uint TimeDateStamp;
58 uint PointerToSymbolTable;
59 uint NumberOfSymbols;
60 ushort SizeOfOptionalHeader;
61 ushort Characteristics;
62 }
63
64 /***********************************************/
65
66 enum IMAGE_SIZEOF_SHORT_NAME = 8;
67
68 struct IMAGE_SECTION_HEADER
69 {
70 ubyte[IMAGE_SIZEOF_SHORT_NAME] Name;
71 uint VirtualSize;
72 uint VirtualAddress;
73 uint SizeOfRawData;
74 uint PointerToRawData;
75 uint PointerToRelocations;
76 uint PointerToLinenumbers;
77 ushort NumberOfRelocations;
78 ushort NumberOfLinenumbers;
79 uint Characteristics;
80 }
81
82 enum
83 {
84 IMAGE_SCN_TYPE_NO_PAD = 8, // obsolete
85 IMAGE_SCN_CNT_CODE = 0x20, // code section
86 IMAGE_SCN_CNT_INITIALIZED_DATA = 0x40,
87 IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x80,
88 IMAGE_SCN_LNK_OTHER = 0x100,
89 IMAGE_SCN_LNK_INFO = 0x200, // comments; for .drectve section
90 IMAGE_SCN_LNK_REMOVE = 0x800, // do not put in image file
91 IMAGE_SCN_LNK_COMDAT = 0x1000, // COMDAT section
92 IMAGE_SCN_GPREL = 0x8000, // data referenced through global pointer GP
93 IMAGE_SCN_MEM_PURGEABLE = 0x20000,
94 IMAGE_SCN_MEM_16BIT = 0x20000,
95 IMAGE_SCN_MEM_LOCKED = 0x40000,
96 IMAGE_SCN_MEM_PRELOAD = 0x80000,
97 IMAGE_SCN_ALIGN_1BYTES = 0x100000,
98 IMAGE_SCN_ALIGN_2BYTES = 0x200000,
99 IMAGE_SCN_ALIGN_4BYTES = 0x300000,
100 IMAGE_SCN_ALIGN_8BYTES = 0x400000,
101 IMAGE_SCN_ALIGN_16BYTES = 0x500000,
102 IMAGE_SCN_ALIGN_32BYTES = 0x600000,
103 IMAGE_SCN_ALIGN_64BYTES = 0x700000,
104 IMAGE_SCN_ALIGN_128BYTES = 0x800000,
105 IMAGE_SCN_ALIGN_256BYTES = 0x900000,
106 IMAGE_SCN_ALIGN_512BYTES = 0xA00000,
107 IMAGE_SCN_ALIGN_1024BYTES = 0xB00000,
108 IMAGE_SCN_ALIGN_2048BYTES = 0xC00000,
109 IMAGE_SCN_ALIGN_4096BYTES = 0xD00000,
110 IMAGE_SCN_ALIGN_8192BYTES = 0xE00000,
111 IMAGE_SCN_LNK_NRELOC_OVFL = 0x1000000, // more than 0xFFFF relocations
112 IMAGE_SCN_MEM_DISCARDABLE = 0x2000000, // can be discarded
113 IMAGE_SCN_MEM_NOT_CACHED = 0x4000000, // cannot be cached
114 IMAGE_SCN_MEM_NOT_PAGED = 0x8000000, // cannot be paged
115 IMAGE_SCN_MEM_SHARED = 0x10000000, // can be shared
116 IMAGE_SCN_MEM_EXECUTE = 0x20000000, // executable code
117 IMAGE_SCN_MEM_READ = 0x40000000, // readable
118 IMAGE_SCN_MEM_WRITE = 0x80000000, // writeable
119 }
120
121 /***********************************************/
122
123 enum SYMNMLEN = 8;
124
125 enum
126 {
127 IMAGE_SYM_DEBUG = -2,
128 IMAGE_SYM_ABSOLUTE = -1,
129 IMAGE_SYM_UNDEFINED = 0,
130
131 /* Values for n_sclass */
132 IMAGE_SYM_CLASS_EXTERNAL = 2,
133 IMAGE_SYM_CLASS_STATIC = 3,
134 IMAGE_SYM_CLASS_LABEL = 6,
135 IMAGE_SYM_CLASS_FUNCTION = 101,
136 IMAGE_SYM_CLASS_FILE = 103,
137 }
138
139 struct SymbolTable32
140 {
141 union
142 {
143 ubyte[SYMNMLEN] Name;
144 struct
145 {
146 uint Zeros;
147 uint Offset;
148 }
149 }
150 uint Value;
151 int SectionNumber;
152 ushort Type;
153 ubyte StorageClass;
154 ubyte NumberOfAuxSymbols;
155 }
156
157 struct SymbolTable
158 {
159 ubyte[SYMNMLEN] Name;
160 uint Value;
161 short SectionNumber;
162 ushort Type;
163 ubyte StorageClass;
164 ubyte NumberOfAuxSymbols;
165 }
166
167 /***********************************************/
168
169 struct reloc
170 {
171 align (1):
172 uint r_vaddr; // file offset of relocation
173 uint r_symndx; // symbol table index
174 ushort r_type; // IMAGE_REL_XXX kind of relocation to be performed
175 }
176
177 enum
178 {
179 IMAGE_REL_AMD64_ABSOLUTE = 0,
180 IMAGE_REL_AMD64_ADDR64 = 1,
181 IMAGE_REL_AMD64_ADDR32 = 2,
182 IMAGE_REL_AMD64_ADDR32NB = 3,
183 IMAGE_REL_AMD64_REL32 = 4,
184 IMAGE_REL_AMD64_REL32_1 = 5,
185 IMAGE_REL_AMD64_REL32_2 = 6,
186 IMAGE_REL_AMD64_REL32_3 = 7,
187 IMAGE_REL_AMD64_REL32_4 = 8,
188 IMAGE_REL_AMD64_REL32_5 = 9,
189 IMAGE_REL_AMD64_SECTION = 0xA,
190 IMAGE_REL_AMD64_SECREL = 0xB,
191 IMAGE_REL_AMD64_SECREL7 = 0xC,
192 IMAGE_REL_AMD64_TOKEN = 0xD,
193 IMAGE_REL_AMD64_SREL32 = 0xE,
194 IMAGE_REL_AMD64_PAIR = 0xF,
195 IMAGE_REL_AMD64_SSPAN32 = 0x10,
196
197 IMAGE_REL_I386_ABSOLUTE = 0,
198 IMAGE_REL_I386_DIR16 = 1,
199 IMAGE_REL_I386_REL16 = 2,
200 IMAGE_REL_I386_DIR32 = 6,
201 IMAGE_REL_I386_DIR32NB = 7,
202 IMAGE_REL_I386_SEG12 = 9,
203 IMAGE_REL_I386_SECTION = 0xA,
204 IMAGE_REL_I386_SECREL = 0xB,
205 IMAGE_REL_I386_TOKEN = 0xC,
206 IMAGE_REL_I386_SECREL7 = 0xD,
207 IMAGE_REL_I386_REL32 = 0x14,
208 }
209
210 /***********************************************/
211
212 struct lineno
213 {
214 union U
215 {
216 uint l_symndx;
217 uint l_paddr;
218 }
219 U l_addr;
220 ushort l_lnno;
221 }
222
223
224 /***********************************************/
225
226 union auxent
227 {
228 align (1):
229 // Function definitions
230 struct FD
231 { uint TagIndex;
232 uint TotalSize;
233 uint PointerToLinenumber;
234 uint PointerToNextFunction;
235 ushort Zeros;
236 }
237 FD x_fd;
238
239 // .bf symbols
240 struct BF
241 {
242 align (1):
243 uint Unused;
244 ushort Linenumber;
245 char[6] filler;
246 uint PointerToNextFunction;
247 ushort Zeros;
248 }
249 BF x_bf;
250
251 // .ef symbols
252 struct EF
253 { uint Unused;
254 ushort Linenumber;
255 ushort Zeros;
256 }
257 EF x_ef;
258
259 // Weak externals
260 struct WE
261 { uint TagIndex;
262 uint Characteristics;
263 ushort Zeros;
264 // IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
265 // IMAGE_WEAK_EXTERN_SEARCH_LIBRARY
266 // IMAGE_WEAK_EXTERN_SEARCH_ALIAS
267 }
268 WE x_weak;
269
270 // Section definitions
271 struct S
272 {
273 uint length;
274 ushort NumberOfRelocations;
275 ushort NumberOfLinenumbers;
276 uint CheckSum;
277 ushort NumberLowPart;
278 ubyte Selection;
279 ubyte Unused;
280 ushort NumberHighPart;
281 ushort Zeros;
282 }
283 S x_section;
284
285 char[18] filler;
286 }
287
288 // auxent.x_section.Zeros
289 enum
290 {
291 IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
292 IMAGE_COMDAT_SELECT_ANY = 2,
293 IMAGE_COMDAT_SELECT_SAME_SIZE = 3,
294 IMAGE_COMDAT_SELECT_EXACT_MATCH = 4,
295 IMAGE_COMDAT_SELECT_ASSOCIATIVE = 5,
296 IMAGE_COMDAT_SELECT_LARGEST = 6,
297 }
298
299 /***********************************************/
300