]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Object/COFF.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302418, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Object / COFF.h
1 //===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the COFFObjectFile class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_OBJECT_COFF_H
15 #define LLVM_OBJECT_COFF_H
16
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
19 #include "llvm/MC/SubtargetFeature.h"
20 #include "llvm/Object/Binary.h"
21 #include "llvm/Object/Error.h"
22 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Support/BinaryByteStream.h"
24 #include "llvm/Support/COFF.h"
25 #include "llvm/Support/ConvertUTF.h"
26 #include "llvm/Support/Endian.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/ErrorOr.h"
29 #include <cassert>
30 #include <cstddef>
31 #include <cstdint>
32 #include <system_error>
33
34 namespace llvm {
35
36 template <typename T> class ArrayRef;
37
38 namespace object {
39
40 class BaseRelocRef;
41 class DelayImportDirectoryEntryRef;
42 class ExportDirectoryEntryRef;
43 class ImportDirectoryEntryRef;
44 class ImportedSymbolRef;
45 class ResourceSectionRef;
46
47 using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
48 using delay_import_directory_iterator =
49     content_iterator<DelayImportDirectoryEntryRef>;
50 using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
51 using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
52 using base_reloc_iterator = content_iterator<BaseRelocRef>;
53
54 /// The DOS compatible header at the front of all PE/COFF executables.
55 struct dos_header {
56   char                 Magic[2];
57   support::ulittle16_t UsedBytesInTheLastPage;
58   support::ulittle16_t FileSizeInPages;
59   support::ulittle16_t NumberOfRelocationItems;
60   support::ulittle16_t HeaderSizeInParagraphs;
61   support::ulittle16_t MinimumExtraParagraphs;
62   support::ulittle16_t MaximumExtraParagraphs;
63   support::ulittle16_t InitialRelativeSS;
64   support::ulittle16_t InitialSP;
65   support::ulittle16_t Checksum;
66   support::ulittle16_t InitialIP;
67   support::ulittle16_t InitialRelativeCS;
68   support::ulittle16_t AddressOfRelocationTable;
69   support::ulittle16_t OverlayNumber;
70   support::ulittle16_t Reserved[4];
71   support::ulittle16_t OEMid;
72   support::ulittle16_t OEMinfo;
73   support::ulittle16_t Reserved2[10];
74   support::ulittle32_t AddressOfNewExeHeader;
75 };
76
77 struct coff_file_header {
78   support::ulittle16_t Machine;
79   support::ulittle16_t NumberOfSections;
80   support::ulittle32_t TimeDateStamp;
81   support::ulittle32_t PointerToSymbolTable;
82   support::ulittle32_t NumberOfSymbols;
83   support::ulittle16_t SizeOfOptionalHeader;
84   support::ulittle16_t Characteristics;
85
86   bool isImportLibrary() const { return NumberOfSections == 0xffff; }
87 };
88
89 struct coff_bigobj_file_header {
90   support::ulittle16_t Sig1;
91   support::ulittle16_t Sig2;
92   support::ulittle16_t Version;
93   support::ulittle16_t Machine;
94   support::ulittle32_t TimeDateStamp;
95   uint8_t              UUID[16];
96   support::ulittle32_t unused1;
97   support::ulittle32_t unused2;
98   support::ulittle32_t unused3;
99   support::ulittle32_t unused4;
100   support::ulittle32_t NumberOfSections;
101   support::ulittle32_t PointerToSymbolTable;
102   support::ulittle32_t NumberOfSymbols;
103 };
104
105 /// The 32-bit PE header that follows the COFF header.
106 struct pe32_header {
107   support::ulittle16_t Magic;
108   uint8_t MajorLinkerVersion;
109   uint8_t MinorLinkerVersion;
110   support::ulittle32_t SizeOfCode;
111   support::ulittle32_t SizeOfInitializedData;
112   support::ulittle32_t SizeOfUninitializedData;
113   support::ulittle32_t AddressOfEntryPoint;
114   support::ulittle32_t BaseOfCode;
115   support::ulittle32_t BaseOfData;
116   support::ulittle32_t ImageBase;
117   support::ulittle32_t SectionAlignment;
118   support::ulittle32_t FileAlignment;
119   support::ulittle16_t MajorOperatingSystemVersion;
120   support::ulittle16_t MinorOperatingSystemVersion;
121   support::ulittle16_t MajorImageVersion;
122   support::ulittle16_t MinorImageVersion;
123   support::ulittle16_t MajorSubsystemVersion;
124   support::ulittle16_t MinorSubsystemVersion;
125   support::ulittle32_t Win32VersionValue;
126   support::ulittle32_t SizeOfImage;
127   support::ulittle32_t SizeOfHeaders;
128   support::ulittle32_t CheckSum;
129   support::ulittle16_t Subsystem;
130   // FIXME: This should be DllCharacteristics.
131   support::ulittle16_t DLLCharacteristics;
132   support::ulittle32_t SizeOfStackReserve;
133   support::ulittle32_t SizeOfStackCommit;
134   support::ulittle32_t SizeOfHeapReserve;
135   support::ulittle32_t SizeOfHeapCommit;
136   support::ulittle32_t LoaderFlags;
137   // FIXME: This should be NumberOfRvaAndSizes.
138   support::ulittle32_t NumberOfRvaAndSize;
139 };
140
141 /// The 64-bit PE header that follows the COFF header.
142 struct pe32plus_header {
143   support::ulittle16_t Magic;
144   uint8_t MajorLinkerVersion;
145   uint8_t MinorLinkerVersion;
146   support::ulittle32_t SizeOfCode;
147   support::ulittle32_t SizeOfInitializedData;
148   support::ulittle32_t SizeOfUninitializedData;
149   support::ulittle32_t AddressOfEntryPoint;
150   support::ulittle32_t BaseOfCode;
151   support::ulittle64_t ImageBase;
152   support::ulittle32_t SectionAlignment;
153   support::ulittle32_t FileAlignment;
154   support::ulittle16_t MajorOperatingSystemVersion;
155   support::ulittle16_t MinorOperatingSystemVersion;
156   support::ulittle16_t MajorImageVersion;
157   support::ulittle16_t MinorImageVersion;
158   support::ulittle16_t MajorSubsystemVersion;
159   support::ulittle16_t MinorSubsystemVersion;
160   support::ulittle32_t Win32VersionValue;
161   support::ulittle32_t SizeOfImage;
162   support::ulittle32_t SizeOfHeaders;
163   support::ulittle32_t CheckSum;
164   support::ulittle16_t Subsystem;
165   support::ulittle16_t DLLCharacteristics;
166   support::ulittle64_t SizeOfStackReserve;
167   support::ulittle64_t SizeOfStackCommit;
168   support::ulittle64_t SizeOfHeapReserve;
169   support::ulittle64_t SizeOfHeapCommit;
170   support::ulittle32_t LoaderFlags;
171   support::ulittle32_t NumberOfRvaAndSize;
172 };
173
174 struct data_directory {
175   support::ulittle32_t RelativeVirtualAddress;
176   support::ulittle32_t Size;
177 };
178
179 struct debug_directory {
180   support::ulittle32_t Characteristics;
181   support::ulittle32_t TimeDateStamp;
182   support::ulittle16_t MajorVersion;
183   support::ulittle16_t MinorVersion;
184   support::ulittle32_t Type;
185   support::ulittle32_t SizeOfData;
186   support::ulittle32_t AddressOfRawData;
187   support::ulittle32_t PointerToRawData;
188 };
189
190 template <typename IntTy>
191 struct import_lookup_table_entry {
192   IntTy Data;
193
194   bool isOrdinal() const { return Data < 0; }
195
196   uint16_t getOrdinal() const {
197     assert(isOrdinal() && "ILT entry is not an ordinal!");
198     return Data & 0xFFFF;
199   }
200
201   uint32_t getHintNameRVA() const {
202     assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
203     return Data & 0xFFFFFFFF;
204   }
205 };
206
207 using import_lookup_table_entry32 =
208     import_lookup_table_entry<support::little32_t>;
209 using import_lookup_table_entry64 =
210     import_lookup_table_entry<support::little64_t>;
211
212 struct delay_import_directory_table_entry {
213   // dumpbin reports this field as "Characteristics" instead of "Attributes".
214   support::ulittle32_t Attributes;
215   support::ulittle32_t Name;
216   support::ulittle32_t ModuleHandle;
217   support::ulittle32_t DelayImportAddressTable;
218   support::ulittle32_t DelayImportNameTable;
219   support::ulittle32_t BoundDelayImportTable;
220   support::ulittle32_t UnloadDelayImportTable;
221   support::ulittle32_t TimeStamp;
222 };
223
224 struct export_directory_table_entry {
225   support::ulittle32_t ExportFlags;
226   support::ulittle32_t TimeDateStamp;
227   support::ulittle16_t MajorVersion;
228   support::ulittle16_t MinorVersion;
229   support::ulittle32_t NameRVA;
230   support::ulittle32_t OrdinalBase;
231   support::ulittle32_t AddressTableEntries;
232   support::ulittle32_t NumberOfNamePointers;
233   support::ulittle32_t ExportAddressTableRVA;
234   support::ulittle32_t NamePointerRVA;
235   support::ulittle32_t OrdinalTableRVA;
236 };
237
238 union export_address_table_entry {
239   support::ulittle32_t ExportRVA;
240   support::ulittle32_t ForwarderRVA;
241 };
242
243 using export_name_pointer_table_entry = support::ulittle32_t;
244 using export_ordinal_table_entry = support::ulittle16_t;
245
246 struct StringTableOffset {
247   support::ulittle32_t Zeroes;
248   support::ulittle32_t Offset;
249 };
250
251 template <typename SectionNumberType>
252 struct coff_symbol {
253   union {
254     char ShortName[COFF::NameSize];
255     StringTableOffset Offset;
256   } Name;
257
258   support::ulittle32_t Value;
259   SectionNumberType SectionNumber;
260
261   support::ulittle16_t Type;
262
263   uint8_t StorageClass;
264   uint8_t NumberOfAuxSymbols;
265 };
266
267 using coff_symbol16 = coff_symbol<support::ulittle16_t>;
268 using coff_symbol32 = coff_symbol<support::ulittle32_t>;
269
270 // Contains only common parts of coff_symbol16 and coff_symbol32.
271 struct coff_symbol_generic {
272   union {
273     char ShortName[COFF::NameSize];
274     StringTableOffset Offset;
275   } Name;
276   support::ulittle32_t Value;
277 };
278
279 class COFFSymbolRef {
280 public:
281   COFFSymbolRef() = default;
282   COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
283   COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
284
285   const void *getRawPtr() const {
286     return CS16 ? static_cast<const void *>(CS16) : CS32;
287   }
288
289   const coff_symbol_generic *getGeneric() const {
290     if (CS16)
291       return reinterpret_cast<const coff_symbol_generic *>(CS16);
292     return reinterpret_cast<const coff_symbol_generic *>(CS32);
293   }
294
295   friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
296     return A.getRawPtr() < B.getRawPtr();
297   }
298
299   bool isBigObj() const {
300     if (CS16)
301       return false;
302     if (CS32)
303       return true;
304     llvm_unreachable("COFFSymbolRef points to nothing!");
305   }
306
307   const char *getShortName() const {
308     return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
309   }
310
311   const StringTableOffset &getStringTableOffset() const {
312     assert(isSet() && "COFFSymbolRef points to nothing!");
313     return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
314   }
315
316   uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; }
317
318   int32_t getSectionNumber() const {
319     assert(isSet() && "COFFSymbolRef points to nothing!");
320     if (CS16) {
321       // Reserved sections are returned as negative numbers.
322       if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
323         return CS16->SectionNumber;
324       return static_cast<int16_t>(CS16->SectionNumber);
325     }
326     return static_cast<int32_t>(CS32->SectionNumber);
327   }
328
329   uint16_t getType() const {
330     assert(isSet() && "COFFSymbolRef points to nothing!");
331     return CS16 ? CS16->Type : CS32->Type;
332   }
333
334   uint8_t getStorageClass() const {
335     assert(isSet() && "COFFSymbolRef points to nothing!");
336     return CS16 ? CS16->StorageClass : CS32->StorageClass;
337   }
338
339   uint8_t getNumberOfAuxSymbols() const {
340     assert(isSet() && "COFFSymbolRef points to nothing!");
341     return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
342   }
343
344   uint8_t getBaseType() const { return getType() & 0x0F; }
345
346   uint8_t getComplexType() const {
347     return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
348   }
349
350   bool isAbsolute() const {
351     return getSectionNumber() == -1;
352   }
353
354   bool isExternal() const {
355     return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
356   }
357
358   bool isCommon() const {
359     return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
360            getValue() != 0;
361   }
362
363   bool isUndefined() const {
364     return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
365            getValue() == 0;
366   }
367
368   bool isWeakExternal() const {
369     return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
370   }
371
372   bool isFunctionDefinition() const {
373     return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
374            getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
375            !COFF::isReservedSectionNumber(getSectionNumber());
376   }
377
378   bool isFunctionLineInfo() const {
379     return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
380   }
381
382   bool isAnyUndefined() const {
383     return isUndefined() || isWeakExternal();
384   }
385
386   bool isFileRecord() const {
387     return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
388   }
389
390   bool isSection() const {
391     return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
392   }
393
394   bool isSectionDefinition() const {
395     // C++/CLI creates external ABS symbols for non-const appdomain globals.
396     // These are also followed by an auxiliary section definition.
397     bool isAppdomainGlobal =
398         getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
399         getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
400     bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
401     if (!getNumberOfAuxSymbols())
402       return false;
403     return isAppdomainGlobal || isOrdinarySection;
404   }
405
406   bool isCLRToken() const {
407     return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
408   }
409
410 private:
411   bool isSet() const { return CS16 || CS32; }
412
413   const coff_symbol16 *CS16 = nullptr;
414   const coff_symbol32 *CS32 = nullptr;
415 };
416
417 struct coff_section {
418   char Name[COFF::NameSize];
419   support::ulittle32_t VirtualSize;
420   support::ulittle32_t VirtualAddress;
421   support::ulittle32_t SizeOfRawData;
422   support::ulittle32_t PointerToRawData;
423   support::ulittle32_t PointerToRelocations;
424   support::ulittle32_t PointerToLinenumbers;
425   support::ulittle16_t NumberOfRelocations;
426   support::ulittle16_t NumberOfLinenumbers;
427   support::ulittle32_t Characteristics;
428
429   // Returns true if the actual number of relocations is stored in
430   // VirtualAddress field of the first relocation table entry.
431   bool hasExtendedRelocations() const {
432     return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
433            NumberOfRelocations == UINT16_MAX;
434   }
435
436   uint32_t getAlignment() const {
437     // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
438     // IMAGE_SCN_ALIGN_1BYTES.
439     if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
440       return 1;
441
442     // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1.
443     uint32_t Shift = (Characteristics >> 20) & 0xF;
444     if (Shift > 0)
445       return 1U << (Shift - 1);
446     return 1;
447   }
448 };
449
450 struct coff_relocation {
451   support::ulittle32_t VirtualAddress;
452   support::ulittle32_t SymbolTableIndex;
453   support::ulittle16_t Type;
454 };
455
456 struct coff_aux_function_definition {
457   support::ulittle32_t TagIndex;
458   support::ulittle32_t TotalSize;
459   support::ulittle32_t PointerToLinenumber;
460   support::ulittle32_t PointerToNextFunction;
461   char Unused1[2];
462 };
463
464 static_assert(sizeof(coff_aux_function_definition) == 18,
465               "auxiliary entry must be 18 bytes");
466
467 struct coff_aux_bf_and_ef_symbol {
468   char Unused1[4];
469   support::ulittle16_t Linenumber;
470   char Unused2[6];
471   support::ulittle32_t PointerToNextFunction;
472   char Unused3[2];
473 };
474
475 static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
476               "auxiliary entry must be 18 bytes");
477
478 struct coff_aux_weak_external {
479   support::ulittle32_t TagIndex;
480   support::ulittle32_t Characteristics;
481   char Unused1[10];
482 };
483
484 static_assert(sizeof(coff_aux_weak_external) == 18,
485               "auxiliary entry must be 18 bytes");
486
487 struct coff_aux_section_definition {
488   support::ulittle32_t Length;
489   support::ulittle16_t NumberOfRelocations;
490   support::ulittle16_t NumberOfLinenumbers;
491   support::ulittle32_t CheckSum;
492   support::ulittle16_t NumberLowPart;
493   uint8_t              Selection;
494   uint8_t              Unused;
495   support::ulittle16_t NumberHighPart;
496   int32_t getNumber(bool IsBigObj) const {
497     uint32_t Number = static_cast<uint32_t>(NumberLowPart);
498     if (IsBigObj)
499       Number |= static_cast<uint32_t>(NumberHighPart) << 16;
500     return static_cast<int32_t>(Number);
501   }
502 };
503
504 static_assert(sizeof(coff_aux_section_definition) == 18,
505               "auxiliary entry must be 18 bytes");
506
507 struct coff_aux_clr_token {
508   uint8_t              AuxType;
509   uint8_t              Reserved;
510   support::ulittle32_t SymbolTableIndex;
511   char                 MBZ[12];
512 };
513
514 static_assert(sizeof(coff_aux_clr_token) == 18,
515               "auxiliary entry must be 18 bytes");
516
517 struct coff_import_header {
518   support::ulittle16_t Sig1;
519   support::ulittle16_t Sig2;
520   support::ulittle16_t Version;
521   support::ulittle16_t Machine;
522   support::ulittle32_t TimeDateStamp;
523   support::ulittle32_t SizeOfData;
524   support::ulittle16_t OrdinalHint;
525   support::ulittle16_t TypeInfo;
526
527   int getType() const { return TypeInfo & 0x3; }
528   int getNameType() const { return (TypeInfo >> 2) & 0x7; }
529 };
530
531 struct coff_import_directory_table_entry {
532   support::ulittle32_t ImportLookupTableRVA;
533   support::ulittle32_t TimeDateStamp;
534   support::ulittle32_t ForwarderChain;
535   support::ulittle32_t NameRVA;
536   support::ulittle32_t ImportAddressTableRVA;
537
538   bool isNull() const {
539     return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
540            ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
541   }
542 };
543
544 template <typename IntTy>
545 struct coff_tls_directory {
546   IntTy StartAddressOfRawData;
547   IntTy EndAddressOfRawData;
548   IntTy AddressOfIndex;
549   IntTy AddressOfCallBacks;
550   support::ulittle32_t SizeOfZeroFill;
551   support::ulittle32_t Characteristics;
552
553   uint32_t getAlignment() const {
554     // Bit [20:24] contains section alignment.
555     uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
556     if (Shift > 0)
557       return 1U << (Shift - 1);
558     return 0;
559   }
560 };
561
562 using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
563 using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
564
565 struct coff_load_configuration32 {
566   support::ulittle32_t Characteristics;
567   support::ulittle32_t TimeDateStamp;
568   support::ulittle16_t MajorVersion;
569   support::ulittle16_t MinorVersion;
570   support::ulittle32_t GlobalFlagsClear;
571   support::ulittle32_t GlobalFlagsSet;
572   support::ulittle32_t CriticalSectionDefaultTimeout;
573   support::ulittle32_t DeCommitFreeBlockThreshold;
574   support::ulittle32_t DeCommitTotalFreeThreshold;
575   support::ulittle32_t LockPrefixTable;
576   support::ulittle32_t MaximumAllocationSize;
577   support::ulittle32_t VirtualMemoryThreshold;
578   support::ulittle32_t ProcessAffinityMask;
579   support::ulittle32_t ProcessHeapFlags;
580   support::ulittle16_t CSDVersion;
581   support::ulittle16_t Reserved;
582   support::ulittle32_t EditList;
583   support::ulittle32_t SecurityCookie;
584   support::ulittle32_t SEHandlerTable;
585   support::ulittle32_t SEHandlerCount;
586 };
587
588 struct coff_load_configuration64 {
589   support::ulittle32_t Characteristics;
590   support::ulittle32_t TimeDateStamp;
591   support::ulittle16_t MajorVersion;
592   support::ulittle16_t MinorVersion;
593   support::ulittle32_t GlobalFlagsClear;
594   support::ulittle32_t GlobalFlagsSet;
595   support::ulittle32_t CriticalSectionDefaultTimeout;
596   support::ulittle32_t DeCommitFreeBlockThreshold;
597   support::ulittle32_t DeCommitTotalFreeThreshold;
598   support::ulittle32_t LockPrefixTable;
599   support::ulittle32_t MaximumAllocationSize;
600   support::ulittle32_t VirtualMemoryThreshold;
601   support::ulittle32_t ProcessAffinityMask;
602   support::ulittle32_t ProcessHeapFlags;
603   support::ulittle16_t CSDVersion;
604   support::ulittle16_t Reserved;
605   support::ulittle32_t EditList;
606   support::ulittle64_t SecurityCookie;
607   support::ulittle64_t SEHandlerTable;
608   support::ulittle64_t SEHandlerCount;
609 };
610
611 struct coff_runtime_function_x64 {
612   support::ulittle32_t BeginAddress;
613   support::ulittle32_t EndAddress;
614   support::ulittle32_t UnwindInformation;
615 };
616
617 struct coff_base_reloc_block_header {
618   support::ulittle32_t PageRVA;
619   support::ulittle32_t BlockSize;
620 };
621
622 struct coff_base_reloc_block_entry {
623   support::ulittle16_t Data;
624
625   int getType() const { return Data >> 12; }
626   int getOffset() const { return Data & ((1 << 12) - 1); }
627 };
628
629 struct coff_resource_dir_entry {
630   union {
631     support::ulittle32_t NameOffset;
632     support::ulittle32_t ID;
633     uint32_t getNameOffset() const {
634       return maskTrailingOnes<uint32_t>(31) & NameOffset;
635     }
636   } Identifier;
637   union {
638     support::ulittle32_t DataEntryOffset;
639     support::ulittle32_t SubdirOffset;
640
641     bool isSubDir() const { return SubdirOffset >> 31; }
642     uint32_t value() const {
643       return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
644     }
645
646   } Offset;
647 };
648
649 struct coff_resource_dir_table {
650   support::ulittle32_t Characteristics;
651   support::ulittle32_t TimeDateStamp;
652   support::ulittle16_t MajorVersion;
653   support::ulittle16_t MinorVersion;
654   support::ulittle16_t NumberOfNameEntries;
655   support::ulittle16_t NumberOfIDEntries;
656 };
657
658 class COFFObjectFile : public ObjectFile {
659 private:
660   friend class ImportDirectoryEntryRef;
661   friend class ExportDirectoryEntryRef;
662   const coff_file_header *COFFHeader;
663   const coff_bigobj_file_header *COFFBigObjHeader;
664   const pe32_header *PE32Header;
665   const pe32plus_header *PE32PlusHeader;
666   const data_directory *DataDirectory;
667   const coff_section *SectionTable;
668   const coff_symbol16 *SymbolTable16;
669   const coff_symbol32 *SymbolTable32;
670   const char *StringTable;
671   uint32_t StringTableSize;
672   const coff_import_directory_table_entry *ImportDirectory;
673   const delay_import_directory_table_entry *DelayImportDirectory;
674   uint32_t NumberOfDelayImportDirectory;
675   const export_directory_table_entry *ExportDirectory;
676   const coff_base_reloc_block_header *BaseRelocHeader;
677   const coff_base_reloc_block_header *BaseRelocEnd;
678   const debug_directory *DebugDirectoryBegin;
679   const debug_directory *DebugDirectoryEnd;
680
681   std::error_code getString(uint32_t offset, StringRef &Res) const;
682
683   template <typename coff_symbol_type>
684   const coff_symbol_type *toSymb(DataRefImpl Symb) const;
685   const coff_section *toSec(DataRefImpl Sec) const;
686   const coff_relocation *toRel(DataRefImpl Rel) const;
687
688   std::error_code initSymbolTablePtr();
689   std::error_code initImportTablePtr();
690   std::error_code initDelayImportTablePtr();
691   std::error_code initExportTablePtr();
692   std::error_code initBaseRelocPtr();
693   std::error_code initDebugDirectoryPtr();
694
695 public:
696   uintptr_t getSymbolTable() const {
697     if (SymbolTable16)
698       return reinterpret_cast<uintptr_t>(SymbolTable16);
699     if (SymbolTable32)
700       return reinterpret_cast<uintptr_t>(SymbolTable32);
701     return uintptr_t(0);
702   }
703
704   uint16_t getMachine() const {
705     if (COFFHeader)
706       return COFFHeader->Machine;
707     if (COFFBigObjHeader)
708       return COFFBigObjHeader->Machine;
709     llvm_unreachable("no COFF header!");
710   }
711
712   uint16_t getSizeOfOptionalHeader() const {
713     if (COFFHeader)
714       return COFFHeader->isImportLibrary() ? 0
715                                            : COFFHeader->SizeOfOptionalHeader;
716     // bigobj doesn't have this field.
717     if (COFFBigObjHeader)
718       return 0;
719     llvm_unreachable("no COFF header!");
720   }
721
722   uint16_t getCharacteristics() const {
723     if (COFFHeader)
724       return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
725     // bigobj doesn't have characteristics to speak of,
726     // editbin will silently lie to you if you attempt to set any.
727     if (COFFBigObjHeader)
728       return 0;
729     llvm_unreachable("no COFF header!");
730   }
731
732   uint32_t getTimeDateStamp() const {
733     if (COFFHeader)
734       return COFFHeader->TimeDateStamp;
735     if (COFFBigObjHeader)
736       return COFFBigObjHeader->TimeDateStamp;
737     llvm_unreachable("no COFF header!");
738   }
739
740   uint32_t getNumberOfSections() const {
741     if (COFFHeader)
742       return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
743     if (COFFBigObjHeader)
744       return COFFBigObjHeader->NumberOfSections;
745     llvm_unreachable("no COFF header!");
746   }
747
748   uint32_t getPointerToSymbolTable() const {
749     if (COFFHeader)
750       return COFFHeader->isImportLibrary() ? 0
751                                            : COFFHeader->PointerToSymbolTable;
752     if (COFFBigObjHeader)
753       return COFFBigObjHeader->PointerToSymbolTable;
754     llvm_unreachable("no COFF header!");
755   }
756
757   uint32_t getRawNumberOfSymbols() const {
758     if (COFFHeader)
759       return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
760     if (COFFBigObjHeader)
761       return COFFBigObjHeader->NumberOfSymbols;
762     llvm_unreachable("no COFF header!");
763   }
764
765   uint32_t getNumberOfSymbols() const {
766     if (!SymbolTable16 && !SymbolTable32)
767       return 0;
768     return getRawNumberOfSymbols();
769   }
770
771 protected:
772   void moveSymbolNext(DataRefImpl &Symb) const override;
773   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
774   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
775   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
776   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
777   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
778   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
779   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
780   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
781   void moveSectionNext(DataRefImpl &Sec) const override;
782   std::error_code getSectionName(DataRefImpl Sec,
783                                  StringRef &Res) const override;
784   uint64_t getSectionAddress(DataRefImpl Sec) const override;
785   uint64_t getSectionSize(DataRefImpl Sec) const override;
786   std::error_code getSectionContents(DataRefImpl Sec,
787                                      StringRef &Res) const override;
788   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
789   bool isSectionCompressed(DataRefImpl Sec) const override;
790   bool isSectionText(DataRefImpl Sec) const override;
791   bool isSectionData(DataRefImpl Sec) const override;
792   bool isSectionBSS(DataRefImpl Sec) const override;
793   bool isSectionVirtual(DataRefImpl Sec) const override;
794   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
795   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
796
797   void moveRelocationNext(DataRefImpl &Rel) const override;
798   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
799   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
800   uint64_t getRelocationType(DataRefImpl Rel) const override;
801   void getRelocationTypeName(DataRefImpl Rel,
802                              SmallVectorImpl<char> &Result) const override;
803
804 public:
805   COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
806
807   basic_symbol_iterator symbol_begin() const override;
808   basic_symbol_iterator symbol_end() const override;
809   section_iterator section_begin() const override;
810   section_iterator section_end() const override;
811
812   const coff_section *getCOFFSection(const SectionRef &Section) const;
813   COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
814   COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
815   const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
816   unsigned getSectionID(SectionRef Sec) const;
817   unsigned getSymbolSectionID(SymbolRef Sym) const;
818
819   uint8_t getBytesInAddress() const override;
820   StringRef getFileFormatName() const override;
821   unsigned getArch() const override;
822   SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
823
824   import_directory_iterator import_directory_begin() const;
825   import_directory_iterator import_directory_end() const;
826   delay_import_directory_iterator delay_import_directory_begin() const;
827   delay_import_directory_iterator delay_import_directory_end() const;
828   export_directory_iterator export_directory_begin() const;
829   export_directory_iterator export_directory_end() const;
830   base_reloc_iterator base_reloc_begin() const;
831   base_reloc_iterator base_reloc_end() const;
832   const debug_directory *debug_directory_begin() const {
833     return DebugDirectoryBegin;
834   }
835   const debug_directory *debug_directory_end() const {
836     return DebugDirectoryEnd;
837   }
838
839   iterator_range<import_directory_iterator> import_directories() const;
840   iterator_range<delay_import_directory_iterator>
841       delay_import_directories() const;
842   iterator_range<export_directory_iterator> export_directories() const;
843   iterator_range<base_reloc_iterator> base_relocs() const;
844   iterator_range<const debug_directory *> debug_directories() const {
845     return make_range(debug_directory_begin(), debug_directory_end());
846   }
847
848   const dos_header *getDOSHeader() const {
849     if (!PE32Header && !PE32PlusHeader)
850       return nullptr;
851     return reinterpret_cast<const dos_header *>(base());
852   }
853   std::error_code getPE32Header(const pe32_header *&Res) const;
854   std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
855   std::error_code getDataDirectory(uint32_t index,
856                                    const data_directory *&Res) const;
857   std::error_code getSection(int32_t index, const coff_section *&Res) const;
858
859   template <typename coff_symbol_type>
860   std::error_code getSymbol(uint32_t Index,
861                             const coff_symbol_type *&Res) const {
862     if (Index >= getNumberOfSymbols())
863       return object_error::parse_failed;
864
865     Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index;
866     return std::error_code();
867   }
868   ErrorOr<COFFSymbolRef> getSymbol(uint32_t index) const {
869     if (SymbolTable16) {
870       const coff_symbol16 *Symb = nullptr;
871       if (std::error_code EC = getSymbol(index, Symb))
872         return EC;
873       return COFFSymbolRef(Symb);
874     }
875     if (SymbolTable32) {
876       const coff_symbol32 *Symb = nullptr;
877       if (std::error_code EC = getSymbol(index, Symb))
878         return EC;
879       return COFFSymbolRef(Symb);
880     }
881     return object_error::parse_failed;
882   }
883
884   template <typename T>
885   std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
886     ErrorOr<COFFSymbolRef> s = getSymbol(index);
887     if (std::error_code EC = s.getError())
888       return EC;
889     Res = reinterpret_cast<const T *>(s->getRawPtr());
890     return std::error_code();
891   }
892
893   std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
894   std::error_code getSymbolName(const coff_symbol_generic *Symbol,
895                                 StringRef &Res) const;
896
897   ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
898
899   size_t getSymbolTableEntrySize() const {
900     if (COFFHeader)
901       return sizeof(coff_symbol16);
902     if (COFFBigObjHeader)
903       return sizeof(coff_symbol32);
904     llvm_unreachable("null symbol table pointer!");
905   }
906
907   iterator_range<const coff_relocation *>
908   getRelocations(const coff_section *Sec) const;
909
910   std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
911   uint64_t getSectionSize(const coff_section *Sec) const;
912   std::error_code getSectionContents(const coff_section *Sec,
913                                      ArrayRef<uint8_t> &Res) const;
914
915   uint64_t getImageBase() const;
916   std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
917   std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
918
919   /// Given an RVA base and size, returns a valid array of bytes or an error
920   /// code if the RVA and size is not contained completely within a valid
921   /// section.
922   std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
923                                        ArrayRef<uint8_t> &Contents) const;
924
925   std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
926                               StringRef &Name) const;
927
928   /// Get PDB information out of a codeview debug directory entry.
929   std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
930                                   const codeview::DebugInfo *&Info,
931                                   StringRef &PDBFileName) const;
932
933   /// Get PDB information from an executable. If the information is not present,
934   /// Info will be set to nullptr and PDBFileName will be empty. An error is
935   /// returned only on corrupt object files. Convenience accessor that can be
936   /// used if the debug directory is not already handy.
937   std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info,
938                                   StringRef &PDBFileName) const;
939
940   bool isRelocatableObject() const override;
941   bool is64() const { return PE32PlusHeader; }
942
943   static inline bool classof(const Binary *v) { return v->isCOFF(); }
944 };
945
946 // The iterator for the import directory table.
947 class ImportDirectoryEntryRef {
948 public:
949   ImportDirectoryEntryRef() = default;
950   ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
951                           uint32_t I, const COFFObjectFile *Owner)
952       : ImportTable(Table), Index(I), OwningObject(Owner) {}
953
954   bool operator==(const ImportDirectoryEntryRef &Other) const;
955   void moveNext();
956
957   imported_symbol_iterator imported_symbol_begin() const;
958   imported_symbol_iterator imported_symbol_end() const;
959   iterator_range<imported_symbol_iterator> imported_symbols() const;
960
961   imported_symbol_iterator lookup_table_begin() const;
962   imported_symbol_iterator lookup_table_end() const;
963   iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
964
965   std::error_code getName(StringRef &Result) const;
966   std::error_code getImportLookupTableRVA(uint32_t &Result) const;
967   std::error_code getImportAddressTableRVA(uint32_t &Result) const;
968
969   std::error_code
970   getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
971
972 private:
973   const coff_import_directory_table_entry *ImportTable;
974   uint32_t Index;
975   const COFFObjectFile *OwningObject = nullptr;
976 };
977
978 class DelayImportDirectoryEntryRef {
979 public:
980   DelayImportDirectoryEntryRef() = default;
981   DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
982                                uint32_t I, const COFFObjectFile *Owner)
983       : Table(T), Index(I), OwningObject(Owner) {}
984
985   bool operator==(const DelayImportDirectoryEntryRef &Other) const;
986   void moveNext();
987
988   imported_symbol_iterator imported_symbol_begin() const;
989   imported_symbol_iterator imported_symbol_end() const;
990   iterator_range<imported_symbol_iterator> imported_symbols() const;
991
992   std::error_code getName(StringRef &Result) const;
993   std::error_code getDelayImportTable(
994       const delay_import_directory_table_entry *&Result) const;
995   std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const;
996
997 private:
998   const delay_import_directory_table_entry *Table;
999   uint32_t Index;
1000   const COFFObjectFile *OwningObject = nullptr;
1001 };
1002
1003 // The iterator for the export directory table entry.
1004 class ExportDirectoryEntryRef {
1005 public:
1006   ExportDirectoryEntryRef() = default;
1007   ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
1008                           const COFFObjectFile *Owner)
1009       : ExportTable(Table), Index(I), OwningObject(Owner) {}
1010
1011   bool operator==(const ExportDirectoryEntryRef &Other) const;
1012   void moveNext();
1013
1014   std::error_code getDllName(StringRef &Result) const;
1015   std::error_code getOrdinalBase(uint32_t &Result) const;
1016   std::error_code getOrdinal(uint32_t &Result) const;
1017   std::error_code getExportRVA(uint32_t &Result) const;
1018   std::error_code getSymbolName(StringRef &Result) const;
1019
1020   std::error_code isForwarder(bool &Result) const;
1021   std::error_code getForwardTo(StringRef &Result) const;
1022
1023 private:
1024   const export_directory_table_entry *ExportTable;
1025   uint32_t Index;
1026   const COFFObjectFile *OwningObject = nullptr;
1027 };
1028
1029 class ImportedSymbolRef {
1030 public:
1031   ImportedSymbolRef() = default;
1032   ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
1033                     const COFFObjectFile *Owner)
1034       : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
1035   ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
1036                     const COFFObjectFile *Owner)
1037       : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}
1038
1039   bool operator==(const ImportedSymbolRef &Other) const;
1040   void moveNext();
1041
1042   std::error_code getSymbolName(StringRef &Result) const;
1043   std::error_code isOrdinal(bool &Result) const;
1044   std::error_code getOrdinal(uint16_t &Result) const;
1045   std::error_code getHintNameRVA(uint32_t &Result) const;
1046
1047 private:
1048   const import_lookup_table_entry32 *Entry32;
1049   const import_lookup_table_entry64 *Entry64;
1050   uint32_t Index;
1051   const COFFObjectFile *OwningObject = nullptr;
1052 };
1053
1054 class BaseRelocRef {
1055 public:
1056   BaseRelocRef() = default;
1057   BaseRelocRef(const coff_base_reloc_block_header *Header,
1058                const COFFObjectFile *Owner)
1059       : Header(Header), Index(0), OwningObject(Owner) {}
1060
1061   bool operator==(const BaseRelocRef &Other) const;
1062   void moveNext();
1063
1064   std::error_code getType(uint8_t &Type) const;
1065   std::error_code getRVA(uint32_t &Result) const;
1066
1067 private:
1068   const coff_base_reloc_block_header *Header;
1069   uint32_t Index;
1070   const COFFObjectFile *OwningObject = nullptr;
1071 };
1072
1073 class ResourceSectionRef {
1074 public:
1075   ResourceSectionRef() = default;
1076   explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
1077
1078   ErrorOr<ArrayRef<UTF16>> getEntryNameString(const coff_resource_dir_entry &Entry);
1079   ErrorOr<const coff_resource_dir_table &>
1080   getEntrySubDir(const coff_resource_dir_entry &Entry);
1081   ErrorOr<const coff_resource_dir_table &> getBaseTable();
1082
1083 private:
1084   BinaryByteStream BBS;
1085
1086   ErrorOr<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
1087   ErrorOr<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
1088 };
1089
1090 // Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
1091 struct FpoData {
1092   support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
1093   support::ulittle32_t Size;   // cbProcSize: # bytes in function
1094   support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
1095   support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
1096   support::ulittle16_t Attributes;
1097
1098   // cbProlog: # bytes in prolog
1099   int getPrologSize() const { return Attributes & 0xF; }
1100
1101   // cbRegs: # regs saved
1102   int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
1103
1104   // fHasSEH: true if seh is func
1105   bool hasSEH() const { return (Attributes >> 9) & 1; }
1106
1107   // fUseBP: true if EBP has been allocated
1108   bool useBP() const { return (Attributes >> 10) & 1; }
1109
1110   // cbFrame: frame pointer
1111   int getFP() const { return Attributes >> 14; }
1112 };
1113
1114 } // end namespace object
1115
1116 } // end namespace llvm
1117
1118 #endif // LLVM_OBJECT_COFF_H