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