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 /***********************************************/