//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the COFFObjectFile class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_OBJECT_COFF_H
#define LLVM_OBJECT_COFF_H

#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/CVDebugRecord.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <system_error>

namespace llvm {

template <typename T> class ArrayRef;

namespace object {

class BaseRelocRef;
class DelayImportDirectoryEntryRef;
class ExportDirectoryEntryRef;
class ImportDirectoryEntryRef;
class ImportedSymbolRef;
class ResourceSectionRef;

using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
using delay_import_directory_iterator =
    content_iterator<DelayImportDirectoryEntryRef>;
using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
using base_reloc_iterator = content_iterator<BaseRelocRef>;

/// The DOS compatible header at the front of all PE/COFF executables.
struct dos_header {
  char                 Magic[2];
  support::ulittle16_t UsedBytesInTheLastPage;
  support::ulittle16_t FileSizeInPages;
  support::ulittle16_t NumberOfRelocationItems;
  support::ulittle16_t HeaderSizeInParagraphs;
  support::ulittle16_t MinimumExtraParagraphs;
  support::ulittle16_t MaximumExtraParagraphs;
  support::ulittle16_t InitialRelativeSS;
  support::ulittle16_t InitialSP;
  support::ulittle16_t Checksum;
  support::ulittle16_t InitialIP;
  support::ulittle16_t InitialRelativeCS;
  support::ulittle16_t AddressOfRelocationTable;
  support::ulittle16_t OverlayNumber;
  support::ulittle16_t Reserved[4];
  support::ulittle16_t OEMid;
  support::ulittle16_t OEMinfo;
  support::ulittle16_t Reserved2[10];
  support::ulittle32_t AddressOfNewExeHeader;
};

struct coff_file_header {
  support::ulittle16_t Machine;
  support::ulittle16_t NumberOfSections;
  support::ulittle32_t TimeDateStamp;
  support::ulittle32_t PointerToSymbolTable;
  support::ulittle32_t NumberOfSymbols;
  support::ulittle16_t SizeOfOptionalHeader;
  support::ulittle16_t Characteristics;

  bool isImportLibrary() const { return NumberOfSections == 0xffff; }
};

struct coff_bigobj_file_header {
  support::ulittle16_t Sig1;
  support::ulittle16_t Sig2;
  support::ulittle16_t Version;
  support::ulittle16_t Machine;
  support::ulittle32_t TimeDateStamp;
  uint8_t              UUID[16];
  support::ulittle32_t unused1;
  support::ulittle32_t unused2;
  support::ulittle32_t unused3;
  support::ulittle32_t unused4;
  support::ulittle32_t NumberOfSections;
  support::ulittle32_t PointerToSymbolTable;
  support::ulittle32_t NumberOfSymbols;
};

/// The 32-bit PE header that follows the COFF header.
struct pe32_header {
  support::ulittle16_t Magic;
  uint8_t MajorLinkerVersion;
  uint8_t MinorLinkerVersion;
  support::ulittle32_t SizeOfCode;
  support::ulittle32_t SizeOfInitializedData;
  support::ulittle32_t SizeOfUninitializedData;
  support::ulittle32_t AddressOfEntryPoint;
  support::ulittle32_t BaseOfCode;
  support::ulittle32_t BaseOfData;
  support::ulittle32_t ImageBase;
  support::ulittle32_t SectionAlignment;
  support::ulittle32_t FileAlignment;
  support::ulittle16_t MajorOperatingSystemVersion;
  support::ulittle16_t MinorOperatingSystemVersion;
  support::ulittle16_t MajorImageVersion;
  support::ulittle16_t MinorImageVersion;
  support::ulittle16_t MajorSubsystemVersion;
  support::ulittle16_t MinorSubsystemVersion;
  support::ulittle32_t Win32VersionValue;
  support::ulittle32_t SizeOfImage;
  support::ulittle32_t SizeOfHeaders;
  support::ulittle32_t CheckSum;
  support::ulittle16_t Subsystem;
  // FIXME: This should be DllCharacteristics.
  support::ulittle16_t DLLCharacteristics;
  support::ulittle32_t SizeOfStackReserve;
  support::ulittle32_t SizeOfStackCommit;
  support::ulittle32_t SizeOfHeapReserve;
  support::ulittle32_t SizeOfHeapCommit;
  support::ulittle32_t LoaderFlags;
  // FIXME: This should be NumberOfRvaAndSizes.
  support::ulittle32_t NumberOfRvaAndSize;
};

/// The 64-bit PE header that follows the COFF header.
struct pe32plus_header {
  support::ulittle16_t Magic;
  uint8_t MajorLinkerVersion;
  uint8_t MinorLinkerVersion;
  support::ulittle32_t SizeOfCode;
  support::ulittle32_t SizeOfInitializedData;
  support::ulittle32_t SizeOfUninitializedData;
  support::ulittle32_t AddressOfEntryPoint;
  support::ulittle32_t BaseOfCode;
  support::ulittle64_t ImageBase;
  support::ulittle32_t SectionAlignment;
  support::ulittle32_t FileAlignment;
  support::ulittle16_t MajorOperatingSystemVersion;
  support::ulittle16_t MinorOperatingSystemVersion;
  support::ulittle16_t MajorImageVersion;
  support::ulittle16_t MinorImageVersion;
  support::ulittle16_t MajorSubsystemVersion;
  support::ulittle16_t MinorSubsystemVersion;
  support::ulittle32_t Win32VersionValue;
  support::ulittle32_t SizeOfImage;
  support::ulittle32_t SizeOfHeaders;
  support::ulittle32_t CheckSum;
  support::ulittle16_t Subsystem;
  support::ulittle16_t DLLCharacteristics;
  support::ulittle64_t SizeOfStackReserve;
  support::ulittle64_t SizeOfStackCommit;
  support::ulittle64_t SizeOfHeapReserve;
  support::ulittle64_t SizeOfHeapCommit;
  support::ulittle32_t LoaderFlags;
  support::ulittle32_t NumberOfRvaAndSize;
};

struct data_directory {
  support::ulittle32_t RelativeVirtualAddress;
  support::ulittle32_t Size;
};

struct debug_directory {
  support::ulittle32_t Characteristics;
  support::ulittle32_t TimeDateStamp;
  support::ulittle16_t MajorVersion;
  support::ulittle16_t MinorVersion;
  support::ulittle32_t Type;
  support::ulittle32_t SizeOfData;
  support::ulittle32_t AddressOfRawData;
  support::ulittle32_t PointerToRawData;
};

template <typename IntTy>
struct import_lookup_table_entry {
  IntTy Data;

  bool isOrdinal() const { return Data < 0; }

  uint16_t getOrdinal() const {
    assert(isOrdinal() && "ILT entry is not an ordinal!");
    return Data & 0xFFFF;
  }

  uint32_t getHintNameRVA() const {
    assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
    return Data & 0xFFFFFFFF;
  }
};

using import_lookup_table_entry32 =
    import_lookup_table_entry<support::little32_t>;
using import_lookup_table_entry64 =
    import_lookup_table_entry<support::little64_t>;

struct delay_import_directory_table_entry {
  // dumpbin reports this field as "Characteristics" instead of "Attributes".
  support::ulittle32_t Attributes;
  support::ulittle32_t Name;
  support::ulittle32_t ModuleHandle;
  support::ulittle32_t DelayImportAddressTable;
  support::ulittle32_t DelayImportNameTable;
  support::ulittle32_t BoundDelayImportTable;
  support::ulittle32_t UnloadDelayImportTable;
  support::ulittle32_t TimeStamp;
};

struct export_directory_table_entry {
  support::ulittle32_t ExportFlags;
  support::ulittle32_t TimeDateStamp;
  support::ulittle16_t MajorVersion;
  support::ulittle16_t MinorVersion;
  support::ulittle32_t NameRVA;
  support::ulittle32_t OrdinalBase;
  support::ulittle32_t AddressTableEntries;
  support::ulittle32_t NumberOfNamePointers;
  support::ulittle32_t ExportAddressTableRVA;
  support::ulittle32_t NamePointerRVA;
  support::ulittle32_t OrdinalTableRVA;
};

union export_address_table_entry {
  support::ulittle32_t ExportRVA;
  support::ulittle32_t ForwarderRVA;
};

using export_name_pointer_table_entry = support::ulittle32_t;
using export_ordinal_table_entry = support::ulittle16_t;

struct StringTableOffset {
  support::ulittle32_t Zeroes;
  support::ulittle32_t Offset;
};

template <typename SectionNumberType>
struct coff_symbol {
  union {
    char ShortName[COFF::NameSize];
    StringTableOffset Offset;
  } Name;

  support::ulittle32_t Value;
  SectionNumberType SectionNumber;

  support::ulittle16_t Type;

  uint8_t StorageClass;
  uint8_t NumberOfAuxSymbols;
};

using coff_symbol16 = coff_symbol<support::ulittle16_t>;
using coff_symbol32 = coff_symbol<support::ulittle32_t>;

// Contains only common parts of coff_symbol16 and coff_symbol32.
struct coff_symbol_generic {
  union {
    char ShortName[COFF::NameSize];
    StringTableOffset Offset;
  } Name;
  support::ulittle32_t Value;
};

struct coff_aux_section_definition;
struct coff_aux_weak_external;

class COFFSymbolRef {
public:
  COFFSymbolRef() = default;
  COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
  COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}

  const void *getRawPtr() const {
    return CS16 ? static_cast<const void *>(CS16) : CS32;
  }

  const coff_symbol_generic *getGeneric() const {
    if (CS16)
      return reinterpret_cast<const coff_symbol_generic *>(CS16);
    return reinterpret_cast<const coff_symbol_generic *>(CS32);
  }

  friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
    return A.getRawPtr() < B.getRawPtr();
  }

  bool isBigObj() const {
    if (CS16)
      return false;
    if (CS32)
      return true;
    llvm_unreachable("COFFSymbolRef points to nothing!");
  }

  const char *getShortName() const {
    return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
  }

  const StringTableOffset &getStringTableOffset() const {
    assert(isSet() && "COFFSymbolRef points to nothing!");
    return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
  }

  uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; }

  int32_t getSectionNumber() const {
    assert(isSet() && "COFFSymbolRef points to nothing!");
    if (CS16) {
      // Reserved sections are returned as negative numbers.
      if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
        return CS16->SectionNumber;
      return static_cast<int16_t>(CS16->SectionNumber);
    }
    return static_cast<int32_t>(CS32->SectionNumber);
  }

  uint16_t getType() const {
    assert(isSet() && "COFFSymbolRef points to nothing!");
    return CS16 ? CS16->Type : CS32->Type;
  }

  uint8_t getStorageClass() const {
    assert(isSet() && "COFFSymbolRef points to nothing!");
    return CS16 ? CS16->StorageClass : CS32->StorageClass;
  }

  uint8_t getNumberOfAuxSymbols() const {
    assert(isSet() && "COFFSymbolRef points to nothing!");
    return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
  }

  uint8_t getBaseType() const { return getType() & 0x0F; }

  uint8_t getComplexType() const {
    return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
  }

  template <typename T> const T *getAux() const {
    return CS16 ? reinterpret_cast<const T *>(CS16 + 1)
                : reinterpret_cast<const T *>(CS32 + 1);
  }

  const coff_aux_section_definition *getSectionDefinition() const {
    if (!getNumberOfAuxSymbols() ||
        getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC)
      return nullptr;
    return getAux<coff_aux_section_definition>();
  }

  const coff_aux_weak_external *getWeakExternal() const {
    if (!getNumberOfAuxSymbols() ||
        getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
      return nullptr;
    return getAux<coff_aux_weak_external>();
  }

  bool isAbsolute() const {
    return getSectionNumber() == -1;
  }

  bool isExternal() const {
    return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
  }

  bool isCommon() const {
    return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
           getValue() != 0;
  }

  bool isUndefined() const {
    return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
           getValue() == 0;
  }

  bool isWeakExternal() const {
    return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
  }

  bool isFunctionDefinition() const {
    return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
           getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
           !COFF::isReservedSectionNumber(getSectionNumber());
  }

  bool isFunctionLineInfo() const {
    return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
  }

  bool isAnyUndefined() const {
    return isUndefined() || isWeakExternal();
  }

  bool isFileRecord() const {
    return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
  }

  bool isSection() const {
    return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
  }

  bool isSectionDefinition() const {
    // C++/CLI creates external ABS symbols for non-const appdomain globals.
    // These are also followed by an auxiliary section definition.
    bool isAppdomainGlobal =
        getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
        getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
    bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
    if (!getNumberOfAuxSymbols())
      return false;
    return isAppdomainGlobal || isOrdinarySection;
  }

  bool isCLRToken() const {
    return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
  }

private:
  bool isSet() const { return CS16 || CS32; }

  const coff_symbol16 *CS16 = nullptr;
  const coff_symbol32 *CS32 = nullptr;
};

struct coff_section {
  char Name[COFF::NameSize];
  support::ulittle32_t VirtualSize;
  support::ulittle32_t VirtualAddress;
  support::ulittle32_t SizeOfRawData;
  support::ulittle32_t PointerToRawData;
  support::ulittle32_t PointerToRelocations;
  support::ulittle32_t PointerToLinenumbers;
  support::ulittle16_t NumberOfRelocations;
  support::ulittle16_t NumberOfLinenumbers;
  support::ulittle32_t Characteristics;

  // Returns true if the actual number of relocations is stored in
  // VirtualAddress field of the first relocation table entry.
  bool hasExtendedRelocations() const {
    return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
           NumberOfRelocations == UINT16_MAX;
  }

  uint32_t getAlignment() const {
    // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
    // IMAGE_SCN_ALIGN_1BYTES.
    if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
      return 1;

    // Bit [20:24] contains section alignment. 0 means use a default alignment
    // of 16.
    uint32_t Shift = (Characteristics >> 20) & 0xF;
    if (Shift > 0)
      return 1U << (Shift - 1);
    return 16;
  }
};

struct coff_relocation {
  support::ulittle32_t VirtualAddress;
  support::ulittle32_t SymbolTableIndex;
  support::ulittle16_t Type;
};

struct coff_aux_function_definition {
  support::ulittle32_t TagIndex;
  support::ulittle32_t TotalSize;
  support::ulittle32_t PointerToLinenumber;
  support::ulittle32_t PointerToNextFunction;
  char Unused1[2];
};

static_assert(sizeof(coff_aux_function_definition) == 18,
              "auxiliary entry must be 18 bytes");

struct coff_aux_bf_and_ef_symbol {
  char Unused1[4];
  support::ulittle16_t Linenumber;
  char Unused2[6];
  support::ulittle32_t PointerToNextFunction;
  char Unused3[2];
};

static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
              "auxiliary entry must be 18 bytes");

struct coff_aux_weak_external {
  support::ulittle32_t TagIndex;
  support::ulittle32_t Characteristics;
  char Unused1[10];
};

static_assert(sizeof(coff_aux_weak_external) == 18,
              "auxiliary entry must be 18 bytes");

struct coff_aux_section_definition {
  support::ulittle32_t Length;
  support::ulittle16_t NumberOfRelocations;
  support::ulittle16_t NumberOfLinenumbers;
  support::ulittle32_t CheckSum;
  support::ulittle16_t NumberLowPart;
  uint8_t              Selection;
  uint8_t              Unused;
  support::ulittle16_t NumberHighPart;
  int32_t getNumber(bool IsBigObj) const {
    uint32_t Number = static_cast<uint32_t>(NumberLowPart);
    if (IsBigObj)
      Number |= static_cast<uint32_t>(NumberHighPart) << 16;
    return static_cast<int32_t>(Number);
  }
};

static_assert(sizeof(coff_aux_section_definition) == 18,
              "auxiliary entry must be 18 bytes");

struct coff_aux_clr_token {
  uint8_t              AuxType;
  uint8_t              Reserved;
  support::ulittle32_t SymbolTableIndex;
  char                 MBZ[12];
};

static_assert(sizeof(coff_aux_clr_token) == 18,
              "auxiliary entry must be 18 bytes");

struct coff_import_header {
  support::ulittle16_t Sig1;
  support::ulittle16_t Sig2;
  support::ulittle16_t Version;
  support::ulittle16_t Machine;
  support::ulittle32_t TimeDateStamp;
  support::ulittle32_t SizeOfData;
  support::ulittle16_t OrdinalHint;
  support::ulittle16_t TypeInfo;

  int getType() const { return TypeInfo & 0x3; }
  int getNameType() const { return (TypeInfo >> 2) & 0x7; }
};

struct coff_import_directory_table_entry {
  support::ulittle32_t ImportLookupTableRVA;
  support::ulittle32_t TimeDateStamp;
  support::ulittle32_t ForwarderChain;
  support::ulittle32_t NameRVA;
  support::ulittle32_t ImportAddressTableRVA;

  bool isNull() const {
    return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
           ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
  }
};

template <typename IntTy>
struct coff_tls_directory {
  IntTy StartAddressOfRawData;
  IntTy EndAddressOfRawData;
  IntTy AddressOfIndex;
  IntTy AddressOfCallBacks;
  support::ulittle32_t SizeOfZeroFill;
  support::ulittle32_t Characteristics;

  uint32_t getAlignment() const {
    // Bit [20:24] contains section alignment.
    uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
    if (Shift > 0)
      return 1U << (Shift - 1);
    return 0;
  }
};

using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
using coff_tls_directory64 = coff_tls_directory<support::little64_t>;

/// Bits in control flow guard flags as we understand them.
enum class coff_guard_flags : uint32_t {
  CFInstrumented = 0x00000100,
  HasFidTable = 0x00000400,
  ProtectDelayLoadIAT = 0x00001000,
  DelayLoadIATSection = 0x00002000, // Delay load in separate section
  HasLongJmpTable = 0x00010000,
  FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
};

enum class frame_type : uint16_t { Fpo = 0, Trap = 1, Tss = 2, NonFpo = 3 };

struct coff_load_config_code_integrity {
  support::ulittle16_t Flags;
  support::ulittle16_t Catalog;
  support::ulittle32_t CatalogOffset;
  support::ulittle32_t Reserved;
};

/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
struct coff_load_configuration32 {
  support::ulittle32_t Size;
  support::ulittle32_t TimeDateStamp;
  support::ulittle16_t MajorVersion;
  support::ulittle16_t MinorVersion;
  support::ulittle32_t GlobalFlagsClear;
  support::ulittle32_t GlobalFlagsSet;
  support::ulittle32_t CriticalSectionDefaultTimeout;
  support::ulittle32_t DeCommitFreeBlockThreshold;
  support::ulittle32_t DeCommitTotalFreeThreshold;
  support::ulittle32_t LockPrefixTable;
  support::ulittle32_t MaximumAllocationSize;
  support::ulittle32_t VirtualMemoryThreshold;
  support::ulittle32_t ProcessAffinityMask;
  support::ulittle32_t ProcessHeapFlags;
  support::ulittle16_t CSDVersion;
  support::ulittle16_t DependentLoadFlags;
  support::ulittle32_t EditList;
  support::ulittle32_t SecurityCookie;
  support::ulittle32_t SEHandlerTable;
  support::ulittle32_t SEHandlerCount;

  // Added in MSVC 2015 for /guard:cf.
  support::ulittle32_t GuardCFCheckFunction;
  support::ulittle32_t GuardCFCheckDispatch;
  support::ulittle32_t GuardCFFunctionTable;
  support::ulittle32_t GuardCFFunctionCount;
  support::ulittle32_t GuardFlags; // coff_guard_flags

  // Added in MSVC 2017
  coff_load_config_code_integrity CodeIntegrity;
  support::ulittle32_t GuardAddressTakenIatEntryTable;
  support::ulittle32_t GuardAddressTakenIatEntryCount;
  support::ulittle32_t GuardLongJumpTargetTable;
  support::ulittle32_t GuardLongJumpTargetCount;
  support::ulittle32_t DynamicValueRelocTable;
  support::ulittle32_t CHPEMetadataPointer;
  support::ulittle32_t GuardRFFailureRoutine;
  support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
  support::ulittle32_t DynamicValueRelocTableOffset;
  support::ulittle16_t DynamicValueRelocTableSection;
  support::ulittle16_t Reserved2;
  support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
  support::ulittle32_t HotPatchTableOffset;
};

/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
struct coff_load_configuration64 {
  support::ulittle32_t Size;
  support::ulittle32_t TimeDateStamp;
  support::ulittle16_t MajorVersion;
  support::ulittle16_t MinorVersion;
  support::ulittle32_t GlobalFlagsClear;
  support::ulittle32_t GlobalFlagsSet;
  support::ulittle32_t CriticalSectionDefaultTimeout;
  support::ulittle64_t DeCommitFreeBlockThreshold;
  support::ulittle64_t DeCommitTotalFreeThreshold;
  support::ulittle64_t LockPrefixTable;
  support::ulittle64_t MaximumAllocationSize;
  support::ulittle64_t VirtualMemoryThreshold;
  support::ulittle64_t ProcessAffinityMask;
  support::ulittle32_t ProcessHeapFlags;
  support::ulittle16_t CSDVersion;
  support::ulittle16_t DependentLoadFlags;
  support::ulittle64_t EditList;
  support::ulittle64_t SecurityCookie;
  support::ulittle64_t SEHandlerTable;
  support::ulittle64_t SEHandlerCount;

  // Added in MSVC 2015 for /guard:cf.
  support::ulittle64_t GuardCFCheckFunction;
  support::ulittle64_t GuardCFCheckDispatch;
  support::ulittle64_t GuardCFFunctionTable;
  support::ulittle64_t GuardCFFunctionCount;
  support::ulittle32_t GuardFlags;

  // Added in MSVC 2017
  coff_load_config_code_integrity CodeIntegrity;
  support::ulittle64_t GuardAddressTakenIatEntryTable;
  support::ulittle64_t GuardAddressTakenIatEntryCount;
  support::ulittle64_t GuardLongJumpTargetTable;
  support::ulittle64_t GuardLongJumpTargetCount;
  support::ulittle64_t DynamicValueRelocTable;
  support::ulittle64_t CHPEMetadataPointer;
  support::ulittle64_t GuardRFFailureRoutine;
  support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
  support::ulittle32_t DynamicValueRelocTableOffset;
  support::ulittle16_t DynamicValueRelocTableSection;
  support::ulittle16_t Reserved2;
  support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
  support::ulittle32_t HotPatchTableOffset;
};

struct coff_runtime_function_x64 {
  support::ulittle32_t BeginAddress;
  support::ulittle32_t EndAddress;
  support::ulittle32_t UnwindInformation;
};

struct coff_base_reloc_block_header {
  support::ulittle32_t PageRVA;
  support::ulittle32_t BlockSize;
};

struct coff_base_reloc_block_entry {
  support::ulittle16_t Data;

  int getType() const { return Data >> 12; }
  int getOffset() const { return Data & ((1 << 12) - 1); }
};

struct coff_resource_dir_entry {
  union {
    support::ulittle32_t NameOffset;
    support::ulittle32_t ID;
    uint32_t getNameOffset() const {
      return maskTrailingOnes<uint32_t>(31) & NameOffset;
    }
    // Even though the PE/COFF spec doesn't mention this, the high bit of a name
    // offset is set.
    void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
  } Identifier;
  union {
    support::ulittle32_t DataEntryOffset;
    support::ulittle32_t SubdirOffset;

    bool isSubDir() const { return SubdirOffset >> 31; }
    uint32_t value() const {
      return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
    }

  } Offset;
};

struct coff_resource_data_entry {
  support::ulittle32_t DataRVA;
  support::ulittle32_t DataSize;
  support::ulittle32_t Codepage;
  support::ulittle32_t Reserved;
};

struct coff_resource_dir_table {
  support::ulittle32_t Characteristics;
  support::ulittle32_t TimeDateStamp;
  support::ulittle16_t MajorVersion;
  support::ulittle16_t MinorVersion;
  support::ulittle16_t NumberOfNameEntries;
  support::ulittle16_t NumberOfIDEntries;
};

struct debug_h_header {
  support::ulittle32_t Magic;
  support::ulittle16_t Version;
  support::ulittle16_t HashAlgorithm;
};

class COFFObjectFile : public ObjectFile {
private:
  friend class ImportDirectoryEntryRef;
  friend class ExportDirectoryEntryRef;
  const coff_file_header *COFFHeader;
  const coff_bigobj_file_header *COFFBigObjHeader;
  const pe32_header *PE32Header;
  const pe32plus_header *PE32PlusHeader;
  const data_directory *DataDirectory;
  const coff_section *SectionTable;
  const coff_symbol16 *SymbolTable16;
  const coff_symbol32 *SymbolTable32;
  const char *StringTable;
  uint32_t StringTableSize;
  const coff_import_directory_table_entry *ImportDirectory;
  const delay_import_directory_table_entry *DelayImportDirectory;
  uint32_t NumberOfDelayImportDirectory;
  const export_directory_table_entry *ExportDirectory;
  const coff_base_reloc_block_header *BaseRelocHeader;
  const coff_base_reloc_block_header *BaseRelocEnd;
  const debug_directory *DebugDirectoryBegin;
  const debug_directory *DebugDirectoryEnd;
  // Either coff_load_configuration32 or coff_load_configuration64.
  const void *LoadConfig = nullptr;

  std::error_code getString(uint32_t offset, StringRef &Res) const;

  template <typename coff_symbol_type>
  const coff_symbol_type *toSymb(DataRefImpl Symb) const;
  const coff_section *toSec(DataRefImpl Sec) const;
  const coff_relocation *toRel(DataRefImpl Rel) const;

  std::error_code initSymbolTablePtr();
  std::error_code initImportTablePtr();
  std::error_code initDelayImportTablePtr();
  std::error_code initExportTablePtr();
  std::error_code initBaseRelocPtr();
  std::error_code initDebugDirectoryPtr();
  std::error_code initLoadConfigPtr();

public:
  uintptr_t getSymbolTable() const {
    if (SymbolTable16)
      return reinterpret_cast<uintptr_t>(SymbolTable16);
    if (SymbolTable32)
      return reinterpret_cast<uintptr_t>(SymbolTable32);
    return uintptr_t(0);
  }

  uint16_t getMachine() const {
    if (COFFHeader)
      return COFFHeader->Machine;
    if (COFFBigObjHeader)
      return COFFBigObjHeader->Machine;
    llvm_unreachable("no COFF header!");
  }

  uint16_t getSizeOfOptionalHeader() const {
    if (COFFHeader)
      return COFFHeader->isImportLibrary() ? 0
                                           : COFFHeader->SizeOfOptionalHeader;
    // bigobj doesn't have this field.
    if (COFFBigObjHeader)
      return 0;
    llvm_unreachable("no COFF header!");
  }

  uint16_t getCharacteristics() const {
    if (COFFHeader)
      return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
    // bigobj doesn't have characteristics to speak of,
    // editbin will silently lie to you if you attempt to set any.
    if (COFFBigObjHeader)
      return 0;
    llvm_unreachable("no COFF header!");
  }

  uint32_t getTimeDateStamp() const {
    if (COFFHeader)
      return COFFHeader->TimeDateStamp;
    if (COFFBigObjHeader)
      return COFFBigObjHeader->TimeDateStamp;
    llvm_unreachable("no COFF header!");
  }

  uint32_t getNumberOfSections() const {
    if (COFFHeader)
      return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
    if (COFFBigObjHeader)
      return COFFBigObjHeader->NumberOfSections;
    llvm_unreachable("no COFF header!");
  }

  uint32_t getPointerToSymbolTable() const {
    if (COFFHeader)
      return COFFHeader->isImportLibrary() ? 0
                                           : COFFHeader->PointerToSymbolTable;
    if (COFFBigObjHeader)
      return COFFBigObjHeader->PointerToSymbolTable;
    llvm_unreachable("no COFF header!");
  }

  uint32_t getRawNumberOfSymbols() const {
    if (COFFHeader)
      return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
    if (COFFBigObjHeader)
      return COFFBigObjHeader->NumberOfSymbols;
    llvm_unreachable("no COFF header!");
  }

  uint32_t getNumberOfSymbols() const {
    if (!SymbolTable16 && !SymbolTable32)
      return 0;
    return getRawNumberOfSymbols();
  }

  const coff_load_configuration32 *getLoadConfig32() const {
    assert(!is64());
    return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
  }

  const coff_load_configuration64 *getLoadConfig64() const {
    assert(is64());
    return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
  }
  StringRef getRelocationTypeName(uint16_t Type) const;

protected:
  void moveSymbolNext(DataRefImpl &Symb) const override;
  Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
  Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
  uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
  uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
  uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
  uint32_t getSymbolFlags(DataRefImpl Symb) const override;
  Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
  Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
  void moveSectionNext(DataRefImpl &Sec) const override;
  std::error_code getSectionName(DataRefImpl Sec,
                                 StringRef &Res) const override;
  uint64_t getSectionAddress(DataRefImpl Sec) const override;
  uint64_t getSectionIndex(DataRefImpl Sec) const override;
  uint64_t getSectionSize(DataRefImpl Sec) const override;
  std::error_code getSectionContents(DataRefImpl Sec,
                                     StringRef &Res) const override;
  uint64_t getSectionAlignment(DataRefImpl Sec) const override;
  bool isSectionCompressed(DataRefImpl Sec) const override;
  bool isSectionText(DataRefImpl Sec) const override;
  bool isSectionData(DataRefImpl Sec) const override;
  bool isSectionBSS(DataRefImpl Sec) const override;
  bool isSectionVirtual(DataRefImpl Sec) const override;
  relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
  relocation_iterator section_rel_end(DataRefImpl Sec) const override;

  void moveRelocationNext(DataRefImpl &Rel) const override;
  uint64_t getRelocationOffset(DataRefImpl Rel) const override;
  symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
  uint64_t getRelocationType(DataRefImpl Rel) const override;
  void getRelocationTypeName(DataRefImpl Rel,
                             SmallVectorImpl<char> &Result) const override;

public:
  COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);

  basic_symbol_iterator symbol_begin() const override;
  basic_symbol_iterator symbol_end() const override;
  section_iterator section_begin() const override;
  section_iterator section_end() const override;

  const coff_section *getCOFFSection(const SectionRef &Section) const;
  COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
  COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
  const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
  unsigned getSectionID(SectionRef Sec) const;
  unsigned getSymbolSectionID(SymbolRef Sym) const;

  uint8_t getBytesInAddress() const override;
  StringRef getFileFormatName() const override;
  Triple::ArchType getArch() const override;
  Expected<uint64_t> getStartAddress() const override;
  SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }

  import_directory_iterator import_directory_begin() const;
  import_directory_iterator import_directory_end() const;
  delay_import_directory_iterator delay_import_directory_begin() const;
  delay_import_directory_iterator delay_import_directory_end() const;
  export_directory_iterator export_directory_begin() const;
  export_directory_iterator export_directory_end() const;
  base_reloc_iterator base_reloc_begin() const;
  base_reloc_iterator base_reloc_end() const;
  const debug_directory *debug_directory_begin() const {
    return DebugDirectoryBegin;
  }
  const debug_directory *debug_directory_end() const {
    return DebugDirectoryEnd;
  }

  iterator_range<import_directory_iterator> import_directories() const;
  iterator_range<delay_import_directory_iterator>
      delay_import_directories() const;
  iterator_range<export_directory_iterator> export_directories() const;
  iterator_range<base_reloc_iterator> base_relocs() const;
  iterator_range<const debug_directory *> debug_directories() const {
    return make_range(debug_directory_begin(), debug_directory_end());
  }

  const dos_header *getDOSHeader() const {
    if (!PE32Header && !PE32PlusHeader)
      return nullptr;
    return reinterpret_cast<const dos_header *>(base());
  }
  std::error_code getCOFFHeader(const coff_file_header *&Res) const;
  std::error_code
  getCOFFBigObjHeader(const coff_bigobj_file_header *&Res) const;
  std::error_code getPE32Header(const pe32_header *&Res) const;
  std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
  std::error_code getDataDirectory(uint32_t index,
                                   const data_directory *&Res) const;
  std::error_code getSection(int32_t index, const coff_section *&Res) const;
  std::error_code getSection(StringRef SectionName,
                             const coff_section *&Res) const;

  template <typename coff_symbol_type>
  std::error_code getSymbol(uint32_t Index,
                            const coff_symbol_type *&Res) const {
    if (Index >= getNumberOfSymbols())
      return object_error::parse_failed;

    Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index;
    return std::error_code();
  }
  Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
    if (SymbolTable16) {
      const coff_symbol16 *Symb = nullptr;
      if (std::error_code EC = getSymbol(index, Symb))
        return errorCodeToError(EC);
      return COFFSymbolRef(Symb);
    }
    if (SymbolTable32) {
      const coff_symbol32 *Symb = nullptr;
      if (std::error_code EC = getSymbol(index, Symb))
        return errorCodeToError(EC);
      return COFFSymbolRef(Symb);
    }
    return errorCodeToError(object_error::parse_failed);
  }

  template <typename T>
  std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
    Expected<COFFSymbolRef> S = getSymbol(index);
    if (Error E = S.takeError())
      return errorToErrorCode(std::move(E));
    Res = reinterpret_cast<const T *>(S->getRawPtr());
    return std::error_code();
  }

  std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
  std::error_code getSymbolName(const coff_symbol_generic *Symbol,
                                StringRef &Res) const;

  ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;

  uint32_t getSymbolIndex(COFFSymbolRef Symbol) const;

  size_t getSymbolTableEntrySize() const {
    if (COFFHeader)
      return sizeof(coff_symbol16);
    if (COFFBigObjHeader)
      return sizeof(coff_symbol32);
    llvm_unreachable("null symbol table pointer!");
  }

  ArrayRef<coff_relocation> getRelocations(const coff_section *Sec) const;

  std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
  uint64_t getSectionSize(const coff_section *Sec) const;
  std::error_code getSectionContents(const coff_section *Sec,
                                     ArrayRef<uint8_t> &Res) const;

  uint64_t getImageBase() const;
  std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
  std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;

  /// Given an RVA base and size, returns a valid array of bytes or an error
  /// code if the RVA and size is not contained completely within a valid
  /// section.
  std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
                                       ArrayRef<uint8_t> &Contents) const;

  std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
                              StringRef &Name) const;

  /// Get PDB information out of a codeview debug directory entry.
  std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
                                  const codeview::DebugInfo *&Info,
                                  StringRef &PDBFileName) const;

  /// Get PDB information from an executable. If the information is not present,
  /// Info will be set to nullptr and PDBFileName will be empty. An error is
  /// returned only on corrupt object files. Convenience accessor that can be
  /// used if the debug directory is not already handy.
  std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info,
                                  StringRef &PDBFileName) const;

  bool isRelocatableObject() const override;
  bool is64() const { return PE32PlusHeader; }

  StringRef mapDebugSectionName(StringRef Name) const override;

  static bool classof(const Binary *v) { return v->isCOFF(); }
};

// The iterator for the import directory table.
class ImportDirectoryEntryRef {
public:
  ImportDirectoryEntryRef() = default;
  ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
                          uint32_t I, const COFFObjectFile *Owner)
      : ImportTable(Table), Index(I), OwningObject(Owner) {}

  bool operator==(const ImportDirectoryEntryRef &Other) const;
  void moveNext();

  imported_symbol_iterator imported_symbol_begin() const;
  imported_symbol_iterator imported_symbol_end() const;
  iterator_range<imported_symbol_iterator> imported_symbols() const;

  imported_symbol_iterator lookup_table_begin() const;
  imported_symbol_iterator lookup_table_end() const;
  iterator_range<imported_symbol_iterator> lookup_table_symbols() const;

  std::error_code getName(StringRef &Result) const;
  std::error_code getImportLookupTableRVA(uint32_t &Result) const;
  std::error_code getImportAddressTableRVA(uint32_t &Result) const;

  std::error_code
  getImportTableEntry(const coff_import_directory_table_entry *&Result) const;

private:
  const coff_import_directory_table_entry *ImportTable;
  uint32_t Index;
  const COFFObjectFile *OwningObject = nullptr;
};

class DelayImportDirectoryEntryRef {
public:
  DelayImportDirectoryEntryRef() = default;
  DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
                               uint32_t I, const COFFObjectFile *Owner)
      : Table(T), Index(I), OwningObject(Owner) {}

  bool operator==(const DelayImportDirectoryEntryRef &Other) const;
  void moveNext();

  imported_symbol_iterator imported_symbol_begin() const;
  imported_symbol_iterator imported_symbol_end() const;
  iterator_range<imported_symbol_iterator> imported_symbols() const;

  std::error_code getName(StringRef &Result) const;
  std::error_code getDelayImportTable(
      const delay_import_directory_table_entry *&Result) const;
  std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const;

private:
  const delay_import_directory_table_entry *Table;
  uint32_t Index;
  const COFFObjectFile *OwningObject = nullptr;
};

// The iterator for the export directory table entry.
class ExportDirectoryEntryRef {
public:
  ExportDirectoryEntryRef() = default;
  ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
                          const COFFObjectFile *Owner)
      : ExportTable(Table), Index(I), OwningObject(Owner) {}

  bool operator==(const ExportDirectoryEntryRef &Other) const;
  void moveNext();

  std::error_code getDllName(StringRef &Result) const;
  std::error_code getOrdinalBase(uint32_t &Result) const;
  std::error_code getOrdinal(uint32_t &Result) const;
  std::error_code getExportRVA(uint32_t &Result) const;
  std::error_code getSymbolName(StringRef &Result) const;

  std::error_code isForwarder(bool &Result) const;
  std::error_code getForwardTo(StringRef &Result) const;

private:
  const export_directory_table_entry *ExportTable;
  uint32_t Index;
  const COFFObjectFile *OwningObject = nullptr;
};

class ImportedSymbolRef {
public:
  ImportedSymbolRef() = default;
  ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
                    const COFFObjectFile *Owner)
      : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
  ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
                    const COFFObjectFile *Owner)
      : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}

  bool operator==(const ImportedSymbolRef &Other) const;
  void moveNext();

  std::error_code getSymbolName(StringRef &Result) const;
  std::error_code isOrdinal(bool &Result) const;
  std::error_code getOrdinal(uint16_t &Result) const;
  std::error_code getHintNameRVA(uint32_t &Result) const;

private:
  const import_lookup_table_entry32 *Entry32;
  const import_lookup_table_entry64 *Entry64;
  uint32_t Index;
  const COFFObjectFile *OwningObject = nullptr;
};

class BaseRelocRef {
public:
  BaseRelocRef() = default;
  BaseRelocRef(const coff_base_reloc_block_header *Header,
               const COFFObjectFile *Owner)
      : Header(Header), Index(0) {}

  bool operator==(const BaseRelocRef &Other) const;
  void moveNext();

  std::error_code getType(uint8_t &Type) const;
  std::error_code getRVA(uint32_t &Result) const;

private:
  const coff_base_reloc_block_header *Header;
  uint32_t Index;
};

class ResourceSectionRef {
public:
  ResourceSectionRef() = default;
  explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}

  Expected<ArrayRef<UTF16>>
  getEntryNameString(const coff_resource_dir_entry &Entry);
  Expected<const coff_resource_dir_table &>
  getEntrySubDir(const coff_resource_dir_entry &Entry);
  Expected<const coff_resource_dir_table &> getBaseTable();

private:
  BinaryByteStream BBS;

  Expected<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
  Expected<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
};

// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
struct FpoData {
  support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
  support::ulittle32_t Size;   // cbProcSize: # bytes in function
  support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
  support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
  support::ulittle16_t Attributes;

  // cbProlog: # bytes in prolog
  int getPrologSize() const { return Attributes & 0xF; }

  // cbRegs: # regs saved
  int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }

  // fHasSEH: true if seh is func
  bool hasSEH() const { return (Attributes >> 9) & 1; }

  // fUseBP: true if EBP has been allocated
  bool useBP() const { return (Attributes >> 10) & 1; }

  // cbFrame: frame pointer
  frame_type getFP() const { return static_cast<frame_type>(Attributes >> 14); }
};

} // end namespace object

} // end namespace llvm

#endif // LLVM_OBJECT_COFF_H
