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