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