Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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