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