//===-- COFFDumper.cpp - COFF-specific dumper -------------------*- 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the COFF-specific dumper for llvm-readobj.
///
//===----------------------------------------------------------------------===//

#include "ARMWinEHPrinter.h"
#include "Error.h"
#include "ObjDumper.h"
#include "StackMapPrinter.h"
#include "Win64EHDumper.h"
#include "llvm-readobj.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/WindowsResource.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/Win64EH.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::object;
using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::Win64EH;

static inline Error createError(const Twine &Err) {
  return make_error<StringError>(Err, object_error::parse_failed);
}

namespace {

struct LoadConfigTables {
  uint64_t SEHTableVA = 0;
  uint64_t SEHTableCount = 0;
  uint32_t GuardFlags = 0;
  uint64_t GuardFidTableVA = 0;
  uint64_t GuardFidTableCount = 0;
  uint64_t GuardLJmpTableVA = 0;
  uint64_t GuardLJmpTableCount = 0;
};

class COFFDumper : public ObjDumper {
public:
  friend class COFFObjectDumpDelegate;
  COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
      : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {}

  void printFileHeaders() override;
  void printSectionHeaders() override;
  void printRelocations() override;
  void printUnwindInfo() override;

  void printNeededLibraries() override;

  void printCOFFImports() override;
  void printCOFFExports() override;
  void printCOFFDirectives() override;
  void printCOFFBaseReloc() override;
  void printCOFFDebugDirectory() override;
  void printCOFFResources() override;
  void printCOFFLoadConfig() override;
  void printCodeViewDebugInfo() override;
  void mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs,
                          llvm::codeview::MergingTypeTableBuilder &CVTypes,
                          llvm::codeview::GlobalTypeTableBuilder &GlobalCVIDs,
                          llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes,
                          bool GHash) override;
  void printStackMap() const override;
  void printAddrsig() override;
private:
  void printSymbols() override;
  void printDynamicSymbols() override;
  void printSymbol(const SymbolRef &Sym);
  void printRelocation(const SectionRef &Section, const RelocationRef &Reloc,
                       uint64_t Bias = 0);
  void printDataDirectory(uint32_t Index, const std::string &FieldName);

  void printDOSHeader(const dos_header *DH);
  template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
  void printBaseOfDataField(const pe32_header *Hdr);
  void printBaseOfDataField(const pe32plus_header *Hdr);
  template <typename T>
  void printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables);
  typedef void (*PrintExtraCB)(raw_ostream &, const uint8_t *);
  void printRVATable(uint64_t TableVA, uint64_t Count, uint64_t EntrySize,
                     PrintExtraCB PrintExtra = 0);

  void printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section);
  void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section);
  StringRef getTypeName(TypeIndex Ty);
  StringRef getFileNameForFileOffset(uint32_t FileOffset);
  void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
  void printTypeIndex(StringRef FieldName, TypeIndex TI) {
    // Forward to CVTypeDumper for simplicity.
    codeview::printTypeIndex(Writer, FieldName, TI, Types);
  }

  void printCodeViewSymbolsSubsection(StringRef Subsection,
                                      const SectionRef &Section,
                                      StringRef SectionContents);

  void printCodeViewFileChecksums(StringRef Subsection);

  void printCodeViewInlineeLines(StringRef Subsection);

  void printRelocatedField(StringRef Label, const coff_section *Sec,
                           uint32_t RelocOffset, uint32_t Offset,
                           StringRef *RelocSym = nullptr);

  uint32_t countTotalTableEntries(ResourceSectionRef RSF,
                                  const coff_resource_dir_table &Table,
                                  StringRef Level);

  void printResourceDirectoryTable(ResourceSectionRef RSF,
                                   const coff_resource_dir_table &Table,
                                   StringRef Level);

  void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec,
                                  StringRef SectionContents, StringRef Block);

  /// Given a .debug$S section, find the string table and file checksum table.
  void initializeFileAndStringTables(BinaryStreamReader &Reader);

  void cacheRelocations();

  std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
                                SymbolRef &Sym);
  std::error_code resolveSymbolName(const coff_section *Section,
                                    uint64_t Offset, StringRef &Name);
  std::error_code resolveSymbolName(const coff_section *Section,
                                    StringRef SectionContents,
                                    const void *RelocPtr, StringRef &Name);
  void printImportedSymbols(iterator_range<imported_symbol_iterator> Range);
  void printDelayImportedSymbols(
      const DelayImportDirectoryEntryRef &I,
      iterator_range<imported_symbol_iterator> Range);

  typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;

  const llvm::object::COFFObjectFile *Obj;
  bool RelocCached = false;
  RelocMapTy RelocMap;

  DebugChecksumsSubsectionRef CVFileChecksumTable;

  DebugStringTableSubsectionRef CVStringTable;

  /// Track the compilation CPU type. S_COMPILE3 symbol records typically come
  /// first, but if we don't see one, just assume an X64 CPU type. It is common.
  CPUType CompilationCPUType = CPUType::X64;

  ScopedPrinter &Writer;
  BinaryByteStream TypeContents;
  LazyRandomTypeCollection Types;
};

class COFFObjectDumpDelegate : public SymbolDumpDelegate {
public:
  COFFObjectDumpDelegate(COFFDumper &CD, const SectionRef &SR,
                         const COFFObjectFile *Obj, StringRef SectionContents)
      : CD(CD), SR(SR), SectionContents(SectionContents) {
    Sec = Obj->getCOFFSection(SR);
  }

  uint32_t getRecordOffset(BinaryStreamReader Reader) override {
    ArrayRef<uint8_t> Data;
    if (auto EC = Reader.readLongestContiguousChunk(Data)) {
      llvm::consumeError(std::move(EC));
      return 0;
    }
    return Data.data() - SectionContents.bytes_begin();
  }

  void printRelocatedField(StringRef Label, uint32_t RelocOffset,
                           uint32_t Offset, StringRef *RelocSym) override {
    CD.printRelocatedField(Label, Sec, RelocOffset, Offset, RelocSym);
  }

  void printBinaryBlockWithRelocs(StringRef Label,
                                  ArrayRef<uint8_t> Block) override {
    StringRef SBlock(reinterpret_cast<const char *>(Block.data()),
                     Block.size());
    if (opts::CodeViewSubsectionBytes)
      CD.printBinaryBlockWithRelocs(Label, SR, SectionContents, SBlock);
  }

  StringRef getFileNameForFileOffset(uint32_t FileOffset) override {
    return CD.getFileNameForFileOffset(FileOffset);
  }

  DebugStringTableSubsectionRef getStringTable() override {
    return CD.CVStringTable;
  }

private:
  COFFDumper &CD;
  const SectionRef &SR;
  const coff_section *Sec;
  StringRef SectionContents;
};

} // end namespace

namespace llvm {

std::error_code createCOFFDumper(const object::ObjectFile *Obj,
                                 ScopedPrinter &Writer,
                                 std::unique_ptr<ObjDumper> &Result) {
  const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(Obj);
  if (!COFFObj)
    return readobj_error::unsupported_obj_file_format;

  Result.reset(new COFFDumper(COFFObj, Writer));
  return readobj_error::success;
}

} // namespace llvm

// Given a section and an offset into this section the function returns the
// symbol used for the relocation at the offset.
std::error_code COFFDumper::resolveSymbol(const coff_section *Section,
                                          uint64_t Offset, SymbolRef &Sym) {
  cacheRelocations();
  const auto &Relocations = RelocMap[Section];
  auto SymI = Obj->symbol_end();
  for (const auto &Relocation : Relocations) {
    uint64_t RelocationOffset = Relocation.getOffset();

    if (RelocationOffset == Offset) {
      SymI = Relocation.getSymbol();
      break;
    }
  }
  if (SymI == Obj->symbol_end())
    return readobj_error::unknown_symbol;
  Sym = *SymI;
  return readobj_error::success;
}

// Given a section and an offset into this section the function returns the name
// of the symbol used for the relocation at the offset.
std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
                                              uint64_t Offset,
                                              StringRef &Name) {
  SymbolRef Symbol;
  if (std::error_code EC = resolveSymbol(Section, Offset, Symbol))
    return EC;
  Expected<StringRef> NameOrErr = Symbol.getName();
  if (!NameOrErr)
    return errorToErrorCode(NameOrErr.takeError());
  Name = *NameOrErr;
  return std::error_code();
}

// Helper for when you have a pointer to real data and you want to know about
// relocations against it.
std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
                                              StringRef SectionContents,
                                              const void *RelocPtr,
                                              StringRef &Name) {
  assert(SectionContents.data() < RelocPtr &&
         RelocPtr < SectionContents.data() + SectionContents.size() &&
         "pointer to relocated object is not in section");
  uint64_t Offset = ptrdiff_t(reinterpret_cast<const char *>(RelocPtr) -
                              SectionContents.data());
  return resolveSymbolName(Section, Offset, Name);
}

void COFFDumper::printRelocatedField(StringRef Label, const coff_section *Sec,
                                     uint32_t RelocOffset, uint32_t Offset,
                                     StringRef *RelocSym) {
  StringRef SymStorage;
  StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;
  if (!resolveSymbolName(Sec, RelocOffset, Symbol))
    W.printSymbolOffset(Label, Symbol, Offset);
  else
    W.printHex(Label, RelocOffset);
}

void COFFDumper::printBinaryBlockWithRelocs(StringRef Label,
                                            const SectionRef &Sec,
                                            StringRef SectionContents,
                                            StringRef Block) {
  W.printBinaryBlock(Label, Block);

  assert(SectionContents.begin() < Block.begin() &&
         SectionContents.end() >= Block.end() &&
         "Block is not contained in SectionContents");
  uint64_t OffsetStart = Block.data() - SectionContents.data();
  uint64_t OffsetEnd = OffsetStart + Block.size();

  W.flush();
  cacheRelocations();
  ListScope D(W, "BlockRelocations");
  const coff_section *Section = Obj->getCOFFSection(Sec);
  const auto &Relocations = RelocMap[Section];
  for (const auto &Relocation : Relocations) {
    uint64_t RelocationOffset = Relocation.getOffset();
    if (OffsetStart <= RelocationOffset && RelocationOffset < OffsetEnd)
      printRelocation(Sec, Relocation, OffsetStart);
  }
}

static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN  ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16   ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU  ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC  ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP   ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2)
};

static const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = {
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED        ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_EXECUTABLE_IMAGE       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LINE_NUMS_STRIPPED     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LOCAL_SYMS_STRIPPED    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_AGGRESSIVE_WS_TRIM     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LARGE_ADDRESS_AWARE    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_LO      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_32BIT_MACHINE          ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DEBUG_STRIPPED         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_NET_RUN_FROM_SWAP      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_SYSTEM                 ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DLL                    ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_UP_SYSTEM_ONLY         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI      )
};

static const EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = {
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_UNKNOWN                ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_NATIVE                 ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_GUI            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CUI            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_POSIX_CUI              ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_APPLICATION        ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER     ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_ROM                ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_XBOX                   ),
};

static const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = {
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY      ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_SEH               ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_BIND              ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_APPCONTAINER         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER           ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_GUARD_CF             ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE),
};

static const EnumEntry<COFF::SectionCharacteristics>
ImageSectionCharacteristics[] = {
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD           ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD           ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE              ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA  ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER             ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO              ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_GPREL                 ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT             ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD           ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES          ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES          ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES          ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES          ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES        ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES        ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES        ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE       ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED        ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED         ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED            ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE           ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ              ),
  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE             )
};

static const EnumEntry<COFF::SymbolBaseType> ImageSymType[] = {
  { "Null"  , COFF::IMAGE_SYM_TYPE_NULL   },
  { "Void"  , COFF::IMAGE_SYM_TYPE_VOID   },
  { "Char"  , COFF::IMAGE_SYM_TYPE_CHAR   },
  { "Short" , COFF::IMAGE_SYM_TYPE_SHORT  },
  { "Int"   , COFF::IMAGE_SYM_TYPE_INT    },
  { "Long"  , COFF::IMAGE_SYM_TYPE_LONG   },
  { "Float" , COFF::IMAGE_SYM_TYPE_FLOAT  },
  { "Double", COFF::IMAGE_SYM_TYPE_DOUBLE },
  { "Struct", COFF::IMAGE_SYM_TYPE_STRUCT },
  { "Union" , COFF::IMAGE_SYM_TYPE_UNION  },
  { "Enum"  , COFF::IMAGE_SYM_TYPE_ENUM   },
  { "MOE"   , COFF::IMAGE_SYM_TYPE_MOE    },
  { "Byte"  , COFF::IMAGE_SYM_TYPE_BYTE   },
  { "Word"  , COFF::IMAGE_SYM_TYPE_WORD   },
  { "UInt"  , COFF::IMAGE_SYM_TYPE_UINT   },
  { "DWord" , COFF::IMAGE_SYM_TYPE_DWORD  }
};

static const EnumEntry<COFF::SymbolComplexType> ImageSymDType[] = {
  { "Null"    , COFF::IMAGE_SYM_DTYPE_NULL     },
  { "Pointer" , COFF::IMAGE_SYM_DTYPE_POINTER  },
  { "Function", COFF::IMAGE_SYM_DTYPE_FUNCTION },
  { "Array"   , COFF::IMAGE_SYM_DTYPE_ARRAY    }
};

static const EnumEntry<COFF::SymbolStorageClass> ImageSymClass[] = {
  { "EndOfFunction"  , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION  },
  { "Null"           , COFF::IMAGE_SYM_CLASS_NULL             },
  { "Automatic"      , COFF::IMAGE_SYM_CLASS_AUTOMATIC        },
  { "External"       , COFF::IMAGE_SYM_CLASS_EXTERNAL         },
  { "Static"         , COFF::IMAGE_SYM_CLASS_STATIC           },
  { "Register"       , COFF::IMAGE_SYM_CLASS_REGISTER         },
  { "ExternalDef"    , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF     },
  { "Label"          , COFF::IMAGE_SYM_CLASS_LABEL            },
  { "UndefinedLabel" , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL  },
  { "MemberOfStruct" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT },
  { "Argument"       , COFF::IMAGE_SYM_CLASS_ARGUMENT         },
  { "StructTag"      , COFF::IMAGE_SYM_CLASS_STRUCT_TAG       },
  { "MemberOfUnion"  , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION  },
  { "UnionTag"       , COFF::IMAGE_SYM_CLASS_UNION_TAG        },
  { "TypeDefinition" , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION  },
  { "UndefinedStatic", COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC },
  { "EnumTag"        , COFF::IMAGE_SYM_CLASS_ENUM_TAG         },
  { "MemberOfEnum"   , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM   },
  { "RegisterParam"  , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM   },
  { "BitField"       , COFF::IMAGE_SYM_CLASS_BIT_FIELD        },
  { "Block"          , COFF::IMAGE_SYM_CLASS_BLOCK            },
  { "Function"       , COFF::IMAGE_SYM_CLASS_FUNCTION         },
  { "EndOfStruct"    , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT    },
  { "File"           , COFF::IMAGE_SYM_CLASS_FILE             },
  { "Section"        , COFF::IMAGE_SYM_CLASS_SECTION          },
  { "WeakExternal"   , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL    },
  { "CLRToken"       , COFF::IMAGE_SYM_CLASS_CLR_TOKEN        }
};

static const EnumEntry<COFF::COMDATType> ImageCOMDATSelect[] = {
  { "NoDuplicates", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES },
  { "Any"         , COFF::IMAGE_COMDAT_SELECT_ANY          },
  { "SameSize"    , COFF::IMAGE_COMDAT_SELECT_SAME_SIZE    },
  { "ExactMatch"  , COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH  },
  { "Associative" , COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE  },
  { "Largest"     , COFF::IMAGE_COMDAT_SELECT_LARGEST      },
  { "Newest"      , COFF::IMAGE_COMDAT_SELECT_NEWEST       }
};

static const EnumEntry<COFF::DebugType> ImageDebugType[] = {
  { "Unknown"    , COFF::IMAGE_DEBUG_TYPE_UNKNOWN       },
  { "COFF"       , COFF::IMAGE_DEBUG_TYPE_COFF          },
  { "CodeView"   , COFF::IMAGE_DEBUG_TYPE_CODEVIEW      },
  { "FPO"        , COFF::IMAGE_DEBUG_TYPE_FPO           },
  { "Misc"       , COFF::IMAGE_DEBUG_TYPE_MISC          },
  { "Exception"  , COFF::IMAGE_DEBUG_TYPE_EXCEPTION     },
  { "Fixup"      , COFF::IMAGE_DEBUG_TYPE_FIXUP         },
  { "OmapToSrc"  , COFF::IMAGE_DEBUG_TYPE_OMAP_TO_SRC   },
  { "OmapFromSrc", COFF::IMAGE_DEBUG_TYPE_OMAP_FROM_SRC },
  { "Borland"    , COFF::IMAGE_DEBUG_TYPE_BORLAND       },
  { "Reserved10" , COFF::IMAGE_DEBUG_TYPE_RESERVED10    },
  { "CLSID"      , COFF::IMAGE_DEBUG_TYPE_CLSID         },
  { "VCFeature"  , COFF::IMAGE_DEBUG_TYPE_VC_FEATURE    },
  { "POGO"       , COFF::IMAGE_DEBUG_TYPE_POGO          },
  { "ILTCG"      , COFF::IMAGE_DEBUG_TYPE_ILTCG         },
  { "MPX"        , COFF::IMAGE_DEBUG_TYPE_MPX           },
  { "Repro"      , COFF::IMAGE_DEBUG_TYPE_REPRO         },
};

static const EnumEntry<COFF::WeakExternalCharacteristics>
WeakExternalCharacteristics[] = {
  { "NoLibrary", COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY },
  { "Library"  , COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY   },
  { "Alias"    , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS     }
};

static const EnumEntry<uint32_t> SubSectionTypes[] = {
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
    LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
};

static const EnumEntry<uint32_t> FrameDataFlags[] = {
    LLVM_READOBJ_ENUM_ENT(FrameData, HasSEH),
    LLVM_READOBJ_ENUM_ENT(FrameData, HasEH),
    LLVM_READOBJ_ENUM_ENT(FrameData, IsFunctionStart),
};

static const EnumEntry<uint8_t> FileChecksumKindNames[] = {
  LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, None),
  LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, MD5),
  LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA1),
  LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
};

template <typename T>
static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
                                        COFFSymbolRef Symbol,
                                        uint8_t AuxSymbolIdx, const T *&Aux) {
  ArrayRef<uint8_t> AuxData = Obj->getSymbolAuxData(Symbol);
  AuxData = AuxData.slice(AuxSymbolIdx * Obj->getSymbolTableEntrySize());
  Aux = reinterpret_cast<const T*>(AuxData.data());
  return readobj_error::success;
}

void COFFDumper::cacheRelocations() {
  if (RelocCached)
    return;
  RelocCached = true;

  for (const SectionRef &S : Obj->sections()) {
    const coff_section *Section = Obj->getCOFFSection(S);

    for (const RelocationRef &Reloc : S.relocations())
      RelocMap[Section].push_back(Reloc);

    // Sort relocations by address.
    llvm::sort(RelocMap[Section], [](RelocationRef L, RelocationRef R) {
      return L.getOffset() < R.getOffset();
    });
  }
}

void COFFDumper::printDataDirectory(uint32_t Index,
                                    const std::string &FieldName) {
  const data_directory *Data;
  if (Obj->getDataDirectory(Index, Data))
    return;
  W.printHex(FieldName + "RVA", Data->RelativeVirtualAddress);
  W.printHex(FieldName + "Size", Data->Size);
}

void COFFDumper::printFileHeaders() {
  time_t TDS = Obj->getTimeDateStamp();
  char FormattedTime[20] = { };
  strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));

  {
    DictScope D(W, "ImageFileHeader");
    W.printEnum  ("Machine", Obj->getMachine(),
                    makeArrayRef(ImageFileMachineType));
    W.printNumber("SectionCount", Obj->getNumberOfSections());
    W.printHex   ("TimeDateStamp", FormattedTime, Obj->getTimeDateStamp());
    W.printHex   ("PointerToSymbolTable", Obj->getPointerToSymbolTable());
    W.printNumber("SymbolCount", Obj->getNumberOfSymbols());
    W.printNumber("OptionalHeaderSize", Obj->getSizeOfOptionalHeader());
    W.printFlags ("Characteristics", Obj->getCharacteristics(),
                    makeArrayRef(ImageFileCharacteristics));
  }

  // Print PE header. This header does not exist if this is an object file and
  // not an executable.
  if (const pe32_header *PEHeader = Obj->getPE32Header())
    printPEHeader<pe32_header>(PEHeader);

  if (const pe32plus_header *PEPlusHeader = Obj->getPE32PlusHeader())
    printPEHeader<pe32plus_header>(PEPlusHeader);

  if (const dos_header *DH = Obj->getDOSHeader())
    printDOSHeader(DH);
}

void COFFDumper::printDOSHeader(const dos_header *DH) {
  DictScope D(W, "DOSHeader");
  W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));
  W.printNumber("UsedBytesInTheLastPage", DH->UsedBytesInTheLastPage);
  W.printNumber("FileSizeInPages", DH->FileSizeInPages);
  W.printNumber("NumberOfRelocationItems", DH->NumberOfRelocationItems);
  W.printNumber("HeaderSizeInParagraphs", DH->HeaderSizeInParagraphs);
  W.printNumber("MinimumExtraParagraphs", DH->MinimumExtraParagraphs);
  W.printNumber("MaximumExtraParagraphs", DH->MaximumExtraParagraphs);
  W.printNumber("InitialRelativeSS", DH->InitialRelativeSS);
  W.printNumber("InitialSP", DH->InitialSP);
  W.printNumber("Checksum", DH->Checksum);
  W.printNumber("InitialIP", DH->InitialIP);
  W.printNumber("InitialRelativeCS", DH->InitialRelativeCS);
  W.printNumber("AddressOfRelocationTable", DH->AddressOfRelocationTable);
  W.printNumber("OverlayNumber", DH->OverlayNumber);
  W.printNumber("OEMid", DH->OEMid);
  W.printNumber("OEMinfo", DH->OEMinfo);
  W.printNumber("AddressOfNewExeHeader", DH->AddressOfNewExeHeader);
}

template <class PEHeader>
void COFFDumper::printPEHeader(const PEHeader *Hdr) {
  DictScope D(W, "ImageOptionalHeader");
  W.printHex   ("Magic", Hdr->Magic);
  W.printNumber("MajorLinkerVersion", Hdr->MajorLinkerVersion);
  W.printNumber("MinorLinkerVersion", Hdr->MinorLinkerVersion);
  W.printNumber("SizeOfCode", Hdr->SizeOfCode);
  W.printNumber("SizeOfInitializedData", Hdr->SizeOfInitializedData);
  W.printNumber("SizeOfUninitializedData", Hdr->SizeOfUninitializedData);
  W.printHex   ("AddressOfEntryPoint", Hdr->AddressOfEntryPoint);
  W.printHex   ("BaseOfCode", Hdr->BaseOfCode);
  printBaseOfDataField(Hdr);
  W.printHex   ("ImageBase", Hdr->ImageBase);
  W.printNumber("SectionAlignment", Hdr->SectionAlignment);
  W.printNumber("FileAlignment", Hdr->FileAlignment);
  W.printNumber("MajorOperatingSystemVersion",
                Hdr->MajorOperatingSystemVersion);
  W.printNumber("MinorOperatingSystemVersion",
                Hdr->MinorOperatingSystemVersion);
  W.printNumber("MajorImageVersion", Hdr->MajorImageVersion);
  W.printNumber("MinorImageVersion", Hdr->MinorImageVersion);
  W.printNumber("MajorSubsystemVersion", Hdr->MajorSubsystemVersion);
  W.printNumber("MinorSubsystemVersion", Hdr->MinorSubsystemVersion);
  W.printNumber("SizeOfImage", Hdr->SizeOfImage);
  W.printNumber("SizeOfHeaders", Hdr->SizeOfHeaders);
  W.printEnum  ("Subsystem", Hdr->Subsystem, makeArrayRef(PEWindowsSubsystem));
  W.printFlags ("Characteristics", Hdr->DLLCharacteristics,
                makeArrayRef(PEDLLCharacteristics));
  W.printNumber("SizeOfStackReserve", Hdr->SizeOfStackReserve);
  W.printNumber("SizeOfStackCommit", Hdr->SizeOfStackCommit);
  W.printNumber("SizeOfHeapReserve", Hdr->SizeOfHeapReserve);
  W.printNumber("SizeOfHeapCommit", Hdr->SizeOfHeapCommit);
  W.printNumber("NumberOfRvaAndSize", Hdr->NumberOfRvaAndSize);

  if (Hdr->NumberOfRvaAndSize > 0) {
    DictScope D(W, "DataDirectory");
    static const char * const directory[] = {
      "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable",
      "CertificateTable", "BaseRelocationTable", "Debug", "Architecture",
      "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT",
      "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved"
    };

    for (uint32_t i = 0; i < Hdr->NumberOfRvaAndSize; ++i)
      printDataDirectory(i, directory[i]);
  }
}

void COFFDumper::printCOFFDebugDirectory() {
  ListScope LS(W, "DebugDirectory");
  for (const debug_directory &D : Obj->debug_directories()) {
    char FormattedTime[20] = {};
    time_t TDS = D.TimeDateStamp;
    strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
    DictScope S(W, "DebugEntry");
    W.printHex("Characteristics", D.Characteristics);
    W.printHex("TimeDateStamp", FormattedTime, D.TimeDateStamp);
    W.printHex("MajorVersion", D.MajorVersion);
    W.printHex("MinorVersion", D.MinorVersion);
    W.printEnum("Type", D.Type, makeArrayRef(ImageDebugType));
    W.printHex("SizeOfData", D.SizeOfData);
    W.printHex("AddressOfRawData", D.AddressOfRawData);
    W.printHex("PointerToRawData", D.PointerToRawData);
    if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW) {
      const codeview::DebugInfo *DebugInfo;
      StringRef PDBFileName;
      if (std::error_code EC = Obj->getDebugPDBInfo(&D, DebugInfo, PDBFileName))
        reportError(errorCodeToError(EC), Obj->getFileName());

      DictScope PDBScope(W, "PDBInfo");
      W.printHex("PDBSignature", DebugInfo->Signature.CVSignature);
      if (DebugInfo->Signature.CVSignature == OMF::Signature::PDB70) {
        W.printBinary("PDBGUID", makeArrayRef(DebugInfo->PDB70.Signature));
        W.printNumber("PDBAge", DebugInfo->PDB70.Age);
        W.printString("PDBFileName", PDBFileName);
      }
    } else if (D.SizeOfData != 0) {
      // FIXME: Type values of 12 and 13 are commonly observed but are not in
      // the documented type enum.  Figure out what they mean.
      ArrayRef<uint8_t> RawData;
      if (std::error_code EC = Obj->getRvaAndSizeAsBytes(D.AddressOfRawData,
                                                         D.SizeOfData, RawData))
        reportError(errorCodeToError(EC), Obj->getFileName());
      W.printBinaryBlock("RawData", RawData);
    }
  }
}

void COFFDumper::printRVATable(uint64_t TableVA, uint64_t Count,
                               uint64_t EntrySize, PrintExtraCB PrintExtra) {
  uintptr_t TableStart, TableEnd;
  if (std::error_code EC = Obj->getVaPtr(TableVA, TableStart))
    reportError(errorCodeToError(EC), Obj->getFileName());
  if (std::error_code EC =
          Obj->getVaPtr(TableVA + Count * EntrySize - 1, TableEnd))
    reportError(errorCodeToError(EC), Obj->getFileName());
  TableEnd++;
  for (uintptr_t I = TableStart; I < TableEnd; I += EntrySize) {
    uint32_t RVA = *reinterpret_cast<const ulittle32_t *>(I);
    raw_ostream &OS = W.startLine();
    OS << W.hex(Obj->getImageBase() + RVA);
    if (PrintExtra)
      PrintExtra(OS, reinterpret_cast<const uint8_t *>(I));
    OS << '\n';
  }
}

void COFFDumper::printCOFFLoadConfig() {
  LoadConfigTables Tables;
  if (Obj->is64())
    printCOFFLoadConfig(Obj->getLoadConfig64(), Tables);
  else
    printCOFFLoadConfig(Obj->getLoadConfig32(), Tables);

  if (Tables.SEHTableVA) {
    ListScope LS(W, "SEHTable");
    printRVATable(Tables.SEHTableVA, Tables.SEHTableCount, 4);
  }

  if (Tables.GuardFidTableVA) {
    ListScope LS(W, "GuardFidTable");
    if (Tables.GuardFlags & uint32_t(coff_guard_flags::FidTableHasFlags)) {
      auto PrintGuardFlags = [](raw_ostream &OS, const uint8_t *Entry) {
        uint8_t Flags = *reinterpret_cast<const uint8_t *>(Entry + 4);
        if (Flags)
          OS << " flags " << utohexstr(Flags);
      };
      printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 5,
                    PrintGuardFlags);
    } else {
      printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 4);
    }
  }

  if (Tables.GuardLJmpTableVA) {
    ListScope LS(W, "GuardLJmpTable");
    printRVATable(Tables.GuardLJmpTableVA, Tables.GuardLJmpTableCount, 4);
  }
}

template <typename T>
void COFFDumper::printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables) {
  if (!Conf)
    return;

  ListScope LS(W, "LoadConfig");
  char FormattedTime[20] = {};
  time_t TDS = Conf->TimeDateStamp;
  strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
  W.printHex("Size", Conf->Size);

  // Print everything before SecurityCookie. The vast majority of images today
  // have all these fields.
  if (Conf->Size < offsetof(T, SEHandlerTable))
    return;
  W.printHex("TimeDateStamp", FormattedTime, TDS);
  W.printHex("MajorVersion", Conf->MajorVersion);
  W.printHex("MinorVersion", Conf->MinorVersion);
  W.printHex("GlobalFlagsClear", Conf->GlobalFlagsClear);
  W.printHex("GlobalFlagsSet", Conf->GlobalFlagsSet);
  W.printHex("CriticalSectionDefaultTimeout",
             Conf->CriticalSectionDefaultTimeout);
  W.printHex("DeCommitFreeBlockThreshold", Conf->DeCommitFreeBlockThreshold);
  W.printHex("DeCommitTotalFreeThreshold", Conf->DeCommitTotalFreeThreshold);
  W.printHex("LockPrefixTable", Conf->LockPrefixTable);
  W.printHex("MaximumAllocationSize", Conf->MaximumAllocationSize);
  W.printHex("VirtualMemoryThreshold", Conf->VirtualMemoryThreshold);
  W.printHex("ProcessHeapFlags", Conf->ProcessHeapFlags);
  W.printHex("ProcessAffinityMask", Conf->ProcessAffinityMask);
  W.printHex("CSDVersion", Conf->CSDVersion);
  W.printHex("DependentLoadFlags", Conf->DependentLoadFlags);
  W.printHex("EditList", Conf->EditList);
  W.printHex("SecurityCookie", Conf->SecurityCookie);

  // Print the safe SEH table if present.
  if (Conf->Size < offsetof(coff_load_configuration32, GuardCFCheckFunction))
    return;
  W.printHex("SEHandlerTable", Conf->SEHandlerTable);
  W.printNumber("SEHandlerCount", Conf->SEHandlerCount);

  Tables.SEHTableVA = Conf->SEHandlerTable;
  Tables.SEHTableCount = Conf->SEHandlerCount;

  // Print everything before CodeIntegrity. (2015)
  if (Conf->Size < offsetof(T, CodeIntegrity))
    return;
  W.printHex("GuardCFCheckFunction", Conf->GuardCFCheckFunction);
  W.printHex("GuardCFCheckDispatch", Conf->GuardCFCheckDispatch);
  W.printHex("GuardCFFunctionTable", Conf->GuardCFFunctionTable);
  W.printNumber("GuardCFFunctionCount", Conf->GuardCFFunctionCount);
  W.printHex("GuardFlags", Conf->GuardFlags);

  Tables.GuardFidTableVA = Conf->GuardCFFunctionTable;
  Tables.GuardFidTableCount = Conf->GuardCFFunctionCount;
  Tables.GuardFlags = Conf->GuardFlags;

  // Print the rest. (2017)
  if (Conf->Size < sizeof(T))
    return;
  W.printHex("GuardAddressTakenIatEntryTable",
             Conf->GuardAddressTakenIatEntryTable);
  W.printNumber("GuardAddressTakenIatEntryCount",
                Conf->GuardAddressTakenIatEntryCount);
  W.printHex("GuardLongJumpTargetTable", Conf->GuardLongJumpTargetTable);
  W.printNumber("GuardLongJumpTargetCount", Conf->GuardLongJumpTargetCount);
  W.printHex("DynamicValueRelocTable", Conf->DynamicValueRelocTable);
  W.printHex("CHPEMetadataPointer", Conf->CHPEMetadataPointer);
  W.printHex("GuardRFFailureRoutine", Conf->GuardRFFailureRoutine);
  W.printHex("GuardRFFailureRoutineFunctionPointer",
             Conf->GuardRFFailureRoutineFunctionPointer);
  W.printHex("DynamicValueRelocTableOffset",
             Conf->DynamicValueRelocTableOffset);
  W.printNumber("DynamicValueRelocTableSection",
                Conf->DynamicValueRelocTableSection);
  W.printHex("GuardRFVerifyStackPointerFunctionPointer",
             Conf->GuardRFVerifyStackPointerFunctionPointer);
  W.printHex("HotPatchTableOffset", Conf->HotPatchTableOffset);

  Tables.GuardLJmpTableVA = Conf->GuardLongJumpTargetTable;
  Tables.GuardLJmpTableCount = Conf->GuardLongJumpTargetCount;
}

void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) {
  W.printHex("BaseOfData", Hdr->BaseOfData);
}

void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}

void COFFDumper::printCodeViewDebugInfo() {
  // Print types first to build CVUDTNames, then print symbols.
  for (const SectionRef &S : Obj->sections()) {
    StringRef SectionName = unwrapOrError(Obj->getFileName(), S.getName());
    // .debug$T is a standard CodeView type section, while .debug$P is the same
    // format but used for MSVC precompiled header object files.
    if (SectionName == ".debug$T" || SectionName == ".debug$P")
      printCodeViewTypeSection(SectionName, S);
  }
  for (const SectionRef &S : Obj->sections()) {
    StringRef SectionName = unwrapOrError(Obj->getFileName(), S.getName());
    if (SectionName == ".debug$S")
      printCodeViewSymbolSection(SectionName, S);
  }
}

void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) {
  while (Reader.bytesRemaining() > 0 &&
         (!CVFileChecksumTable.valid() || !CVStringTable.valid())) {
    // The section consists of a number of subsection in the following format:
    // |SubSectionType|SubSectionSize|Contents...|
    uint32_t SubType, SubSectionSize;

    if (Error E = Reader.readInteger(SubType))
      reportError(std::move(E), Obj->getFileName());
    if (Error E = Reader.readInteger(SubSectionSize))
      reportError(std::move(E), Obj->getFileName());

    StringRef Contents;
    if (Error E = Reader.readFixedString(Contents, SubSectionSize))
      reportError(std::move(E), Obj->getFileName());

    BinaryStreamRef ST(Contents, support::little);
    switch (DebugSubsectionKind(SubType)) {
    case DebugSubsectionKind::FileChecksums:
      if (Error E = CVFileChecksumTable.initialize(ST))
        reportError(std::move(E), Obj->getFileName());
      break;
    case DebugSubsectionKind::StringTable:
      if (Error E = CVStringTable.initialize(ST))
        reportError(std::move(E), Obj->getFileName());
      break;
    default:
      break;
    }

    uint32_t PaddedSize = alignTo(SubSectionSize, 4);
    if (Error E = Reader.skip(PaddedSize - SubSectionSize))
      reportError(std::move(E), Obj->getFileName());
  }
}

void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
                                            const SectionRef &Section) {
  StringRef SectionContents =
      unwrapOrError(Obj->getFileName(), Section.getContents());
  StringRef Data = SectionContents;

  SmallVector<StringRef, 10> FunctionNames;
  StringMap<StringRef> FunctionLineTables;

  ListScope D(W, "CodeViewDebugInfo");
  // Print the section to allow correlation with printSectionHeaders.
  W.printNumber("Section", SectionName, Obj->getSectionID(Section));

  uint32_t Magic;
  if (Error E = consume(Data, Magic))
    reportError(std::move(E), Obj->getFileName());

  W.printHex("Magic", Magic);
  if (Magic != COFF::DEBUG_SECTION_MAGIC)
    reportError(errorCodeToError(object_error::parse_failed),
                Obj->getFileName());

  BinaryStreamReader FSReader(Data, support::little);
  initializeFileAndStringTables(FSReader);

  // TODO: Convert this over to using ModuleSubstreamVisitor.
  while (!Data.empty()) {
    // The section consists of a number of subsection in the following format:
    // |SubSectionType|SubSectionSize|Contents...|
    uint32_t SubType, SubSectionSize;
    if (Error E = consume(Data, SubType))
      reportError(std::move(E), Obj->getFileName());
    if (Error E = consume(Data, SubSectionSize))
      reportError(std::move(E), Obj->getFileName());

    ListScope S(W, "Subsection");
    // Dump the subsection as normal even if the ignore bit is set.
    if (SubType & SubsectionIgnoreFlag) {
      W.printHex("IgnoredSubsectionKind", SubType);
      SubType &= ~SubsectionIgnoreFlag;
    }
    W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes));
    W.printHex("SubSectionSize", SubSectionSize);

    // Get the contents of the subsection.
    if (SubSectionSize > Data.size())
      return reportError(errorCodeToError(object_error::parse_failed),
                         Obj->getFileName());
    StringRef Contents = Data.substr(0, SubSectionSize);

    // Add SubSectionSize to the current offset and align that offset to find
    // the next subsection.
    size_t SectionOffset = Data.data() - SectionContents.data();
    size_t NextOffset = SectionOffset + SubSectionSize;
    NextOffset = alignTo(NextOffset, 4);
    if (NextOffset > SectionContents.size())
      return reportError(errorCodeToError(object_error::parse_failed),
                         Obj->getFileName());
    Data = SectionContents.drop_front(NextOffset);

    // Optionally print the subsection bytes in case our parsing gets confused
    // later.
    if (opts::CodeViewSubsectionBytes)
      printBinaryBlockWithRelocs("SubSectionContents", Section, SectionContents,
                                 Contents);

    switch (DebugSubsectionKind(SubType)) {
    case DebugSubsectionKind::Symbols:
      printCodeViewSymbolsSubsection(Contents, Section, SectionContents);
      break;

    case DebugSubsectionKind::InlineeLines:
      printCodeViewInlineeLines(Contents);
      break;

    case DebugSubsectionKind::FileChecksums:
      printCodeViewFileChecksums(Contents);
      break;

    case DebugSubsectionKind::Lines: {
      // Holds a PC to file:line table.  Some data to parse this subsection is
      // stored in the other subsections, so just check sanity and store the
      // pointers for deferred processing.

      if (SubSectionSize < 12) {
        // There should be at least three words to store two function
        // relocations and size of the code.
        reportError(errorCodeToError(object_error::parse_failed),
                    Obj->getFileName());
        return;
      }

      StringRef LinkageName;
      if (std::error_code EC = resolveSymbolName(Obj->getCOFFSection(Section),
                                                 SectionOffset, LinkageName))
        reportError(errorCodeToError(EC), Obj->getFileName());

      W.printString("LinkageName", LinkageName);
      if (FunctionLineTables.count(LinkageName) != 0) {
        // Saw debug info for this function already?
        reportError(errorCodeToError(object_error::parse_failed),
                    Obj->getFileName());
        return;
      }

      FunctionLineTables[LinkageName] = Contents;
      FunctionNames.push_back(LinkageName);
      break;
    }
    case DebugSubsectionKind::FrameData: {
      // First four bytes is a relocation against the function.
      BinaryStreamReader SR(Contents, llvm::support::little);

      DebugFrameDataSubsectionRef FrameData;
      if (Error E = FrameData.initialize(SR))
        reportError(std::move(E), Obj->getFileName());

      StringRef LinkageName;
      if (std::error_code EC =
              resolveSymbolName(Obj->getCOFFSection(Section), SectionContents,
                                FrameData.getRelocPtr(), LinkageName))
        reportError(errorCodeToError(EC), Obj->getFileName());
      W.printString("LinkageName", LinkageName);

      // To find the active frame description, search this array for the
      // smallest PC range that includes the current PC.
      for (const auto &FD : FrameData) {
        StringRef FrameFunc = unwrapOrError(
            Obj->getFileName(), CVStringTable.getString(FD.FrameFunc));

        DictScope S(W, "FrameData");
        W.printHex("RvaStart", FD.RvaStart);
        W.printHex("CodeSize", FD.CodeSize);
        W.printHex("LocalSize", FD.LocalSize);
        W.printHex("ParamsSize", FD.ParamsSize);
        W.printHex("MaxStackSize", FD.MaxStackSize);
        W.printHex("PrologSize", FD.PrologSize);
        W.printHex("SavedRegsSize", FD.SavedRegsSize);
        W.printFlags("Flags", FD.Flags, makeArrayRef(FrameDataFlags));

        // The FrameFunc string is a small RPN program. It can be broken up into
        // statements that end in the '=' operator, which assigns the value on
        // the top of the stack to the previously pushed variable. Variables can
        // be temporary values ($T0) or physical registers ($esp). Print each
        // assignment on its own line to make these programs easier to read.
        {
          ListScope FFS(W, "FrameFunc");
          while (!FrameFunc.empty()) {
            size_t EqOrEnd = FrameFunc.find('=');
            if (EqOrEnd == StringRef::npos)
              EqOrEnd = FrameFunc.size();
            else
              ++EqOrEnd;
            StringRef Stmt = FrameFunc.substr(0, EqOrEnd);
            W.printString(Stmt);
            FrameFunc = FrameFunc.drop_front(EqOrEnd).trim();
          }
        }
      }
      break;
    }

    // Do nothing for unrecognized subsections.
    default:
      break;
    }
    W.flush();
  }

  // Dump the line tables now that we've read all the subsections and know all
  // the required information.
  for (unsigned I = 0, E = FunctionNames.size(); I != E; ++I) {
    StringRef Name = FunctionNames[I];
    ListScope S(W, "FunctionLineTable");
    W.printString("LinkageName", Name);

    BinaryStreamReader Reader(FunctionLineTables[Name], support::little);

    DebugLinesSubsectionRef LineInfo;
    if (Error E = LineInfo.initialize(Reader))
      reportError(std::move(E), Obj->getFileName());

    W.printHex("Flags", LineInfo.header()->Flags);
    W.printHex("CodeSize", LineInfo.header()->CodeSize);
    for (const auto &Entry : LineInfo) {

      ListScope S(W, "FilenameSegment");
      printFileNameForOffset("Filename", Entry.NameIndex);
      uint32_t ColumnIndex = 0;
      for (const auto &Line : Entry.LineNumbers) {
        if (Line.Offset >= LineInfo.header()->CodeSize) {
          reportError(errorCodeToError(object_error::parse_failed),
                      Obj->getFileName());
          return;
        }

        std::string PC = formatv("+{0:X}", uint32_t(Line.Offset));
        ListScope PCScope(W, PC);
        codeview::LineInfo LI(Line.Flags);

        if (LI.isAlwaysStepInto())
          W.printString("StepInto", StringRef("Always"));
        else if (LI.isNeverStepInto())
          W.printString("StepInto", StringRef("Never"));
        else
          W.printNumber("LineNumberStart", LI.getStartLine());
        W.printNumber("LineNumberEndDelta", LI.getLineDelta());
        W.printBoolean("IsStatement", LI.isStatement());
        if (LineInfo.hasColumnInfo()) {
          W.printNumber("ColStart", Entry.Columns[ColumnIndex].StartColumn);
          W.printNumber("ColEnd", Entry.Columns[ColumnIndex].EndColumn);
          ++ColumnIndex;
        }
      }
    }
  }
}

void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
                                                const SectionRef &Section,
                                                StringRef SectionContents) {
  ArrayRef<uint8_t> BinaryData(Subsection.bytes_begin(),
                               Subsection.bytes_end());
  auto CODD = std::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
                                                        SectionContents);
  CVSymbolDumper CVSD(W, Types, CodeViewContainer::ObjectFile, std::move(CODD),
                      CompilationCPUType, opts::CodeViewSubsectionBytes);
  CVSymbolArray Symbols;
  BinaryStreamReader Reader(BinaryData, llvm::support::little);
  if (Error E = Reader.readArray(Symbols, Reader.getLength())) {
    W.flush();
    reportError(std::move(E), Obj->getFileName());
  }

  if (Error E = CVSD.dump(Symbols)) {
    W.flush();
    reportError(std::move(E), Obj->getFileName());
  }
  CompilationCPUType = CVSD.getCompilationCPUType();
  W.flush();
}

void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
  BinaryStreamRef Stream(Subsection, llvm::support::little);
  DebugChecksumsSubsectionRef Checksums;
  if (Error E = Checksums.initialize(Stream))
    reportError(std::move(E), Obj->getFileName());

  for (auto &FC : Checksums) {
    DictScope S(W, "FileChecksum");

    StringRef Filename = unwrapOrError(
        Obj->getFileName(), CVStringTable.getString(FC.FileNameOffset));
    W.printHex("Filename", Filename, FC.FileNameOffset);
    W.printHex("ChecksumSize", FC.Checksum.size());
    W.printEnum("ChecksumKind", uint8_t(FC.Kind),
                makeArrayRef(FileChecksumKindNames));

    W.printBinary("ChecksumBytes", FC.Checksum);
  }
}

void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
  BinaryStreamReader SR(Subsection, llvm::support::little);
  DebugInlineeLinesSubsectionRef Lines;
  if (Error E = Lines.initialize(SR))
    reportError(std::move(E), Obj->getFileName());

  for (auto &Line : Lines) {
    DictScope S(W, "InlineeSourceLine");
    printTypeIndex("Inlinee", Line.Header->Inlinee);
    printFileNameForOffset("FileID", Line.Header->FileID);
    W.printNumber("SourceLineNum", Line.Header->SourceLineNum);

    if (Lines.hasExtraFiles()) {
      W.printNumber("ExtraFileCount", Line.ExtraFiles.size());
      ListScope ExtraFiles(W, "ExtraFiles");
      for (const auto &FID : Line.ExtraFiles) {
        printFileNameForOffset("FileID", FID);
      }
    }
  }
}

StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) {
  // The file checksum subsection should precede all references to it.
  if (!CVFileChecksumTable.valid() || !CVStringTable.valid())
    reportError(errorCodeToError(object_error::parse_failed),
                Obj->getFileName());

  auto Iter = CVFileChecksumTable.getArray().at(FileOffset);

  // Check if the file checksum table offset is valid.
  if (Iter == CVFileChecksumTable.end())
    reportError(errorCodeToError(object_error::parse_failed),
                Obj->getFileName());

  return unwrapOrError(Obj->getFileName(),
                       CVStringTable.getString(Iter->FileNameOffset));
}

void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) {
  W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset);
}

void COFFDumper::mergeCodeViewTypes(MergingTypeTableBuilder &CVIDs,
                                    MergingTypeTableBuilder &CVTypes,
                                    GlobalTypeTableBuilder &GlobalCVIDs,
                                    GlobalTypeTableBuilder &GlobalCVTypes,
                                    bool GHash) {
  for (const SectionRef &S : Obj->sections()) {
    StringRef SectionName = unwrapOrError(Obj->getFileName(), S.getName());
    if (SectionName == ".debug$T") {
      StringRef Data = unwrapOrError(Obj->getFileName(), S.getContents());
      uint32_t Magic;
      if (Error E = consume(Data, Magic))
        reportError(std::move(E), Obj->getFileName());

      if (Magic != 4)
        reportError(errorCodeToError(object_error::parse_failed),
                    Obj->getFileName());

      CVTypeArray Types;
      BinaryStreamReader Reader(Data, llvm::support::little);
      if (auto EC = Reader.readArray(Types, Reader.getLength())) {
        consumeError(std::move(EC));
        W.flush();
        reportError(errorCodeToError(object_error::parse_failed),
                    Obj->getFileName());
      }
      SmallVector<TypeIndex, 128> SourceToDest;
      Optional<uint32_t> PCHSignature;
      if (GHash) {
        std::vector<GloballyHashedType> Hashes =
            GloballyHashedType::hashTypes(Types);
        if (Error E =
                mergeTypeAndIdRecords(GlobalCVIDs, GlobalCVTypes, SourceToDest,
                                      Types, Hashes, PCHSignature))
          return reportError(std::move(E), Obj->getFileName());
      } else {
        if (Error E = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types,
                                            PCHSignature))
          return reportError(std::move(E), Obj->getFileName());
      }
    }
  }
}

void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
                                          const SectionRef &Section) {
  ListScope D(W, "CodeViewTypes");
  W.printNumber("Section", SectionName, Obj->getSectionID(Section));

  StringRef Data = unwrapOrError(Obj->getFileName(), Section.getContents());
  if (opts::CodeViewSubsectionBytes)
    W.printBinaryBlock("Data", Data);

  uint32_t Magic;
  if (Error E = consume(Data, Magic))
    reportError(std::move(E), Obj->getFileName());

  W.printHex("Magic", Magic);
  if (Magic != COFF::DEBUG_SECTION_MAGIC)
    reportError(errorCodeToError(object_error::parse_failed),
                Obj->getFileName());

  Types.reset(Data, 100);

  TypeDumpVisitor TDV(Types, &W, opts::CodeViewSubsectionBytes);
  if (Error E = codeview::visitTypeStream(Types, TDV))
    reportError(std::move(E), Obj->getFileName());

  W.flush();
}

void COFFDumper::printSectionHeaders() {
  ListScope SectionsD(W, "Sections");
  int SectionNumber = 0;
  for (const SectionRef &Sec : Obj->sections()) {
    ++SectionNumber;
    const coff_section *Section = Obj->getCOFFSection(Sec);

    StringRef Name = unwrapOrError(Obj->getFileName(), Sec.getName());

    DictScope D(W, "Section");
    W.printNumber("Number", SectionNumber);
    W.printBinary("Name", Name, Section->Name);
    W.printHex   ("VirtualSize", Section->VirtualSize);
    W.printHex   ("VirtualAddress", Section->VirtualAddress);
    W.printNumber("RawDataSize", Section->SizeOfRawData);
    W.printHex   ("PointerToRawData", Section->PointerToRawData);
    W.printHex   ("PointerToRelocations", Section->PointerToRelocations);
    W.printHex   ("PointerToLineNumbers", Section->PointerToLinenumbers);
    W.printNumber("RelocationCount", Section->NumberOfRelocations);
    W.printNumber("LineNumberCount", Section->NumberOfLinenumbers);
    W.printFlags ("Characteristics", Section->Characteristics,
                    makeArrayRef(ImageSectionCharacteristics),
                    COFF::SectionCharacteristics(0x00F00000));

    if (opts::SectionRelocations) {
      ListScope D(W, "Relocations");
      for (const RelocationRef &Reloc : Sec.relocations())
        printRelocation(Sec, Reloc);
    }

    if (opts::SectionSymbols) {
      ListScope D(W, "Symbols");
      for (const SymbolRef &Symbol : Obj->symbols()) {
        if (!Sec.containsSymbol(Symbol))
          continue;

        printSymbol(Symbol);
      }
    }

    if (opts::SectionData &&
        !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
      StringRef Data = unwrapOrError(Obj->getFileName(), Sec.getContents());
      W.printBinaryBlock("SectionData", Data);
    }
  }
}

void COFFDumper::printRelocations() {
  ListScope D(W, "Relocations");

  int SectionNumber = 0;
  for (const SectionRef &Section : Obj->sections()) {
    ++SectionNumber;
    StringRef Name = unwrapOrError(Obj->getFileName(), Section.getName());

    bool PrintedGroup = false;
    for (const RelocationRef &Reloc : Section.relocations()) {
      if (!PrintedGroup) {
        W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
        W.indent();
        PrintedGroup = true;
      }

      printRelocation(Section, Reloc);
    }

    if (PrintedGroup) {
      W.unindent();
      W.startLine() << "}\n";
    }
  }
}

void COFFDumper::printRelocation(const SectionRef &Section,
                                 const RelocationRef &Reloc, uint64_t Bias) {
  uint64_t Offset = Reloc.getOffset() - Bias;
  uint64_t RelocType = Reloc.getType();
  SmallString<32> RelocName;
  StringRef SymbolName;
  Reloc.getTypeName(RelocName);
  symbol_iterator Symbol = Reloc.getSymbol();
  int64_t SymbolIndex = -1;
  if (Symbol != Obj->symbol_end()) {
    Expected<StringRef> SymbolNameOrErr = Symbol->getName();
    if (!SymbolNameOrErr)
      reportError(SymbolNameOrErr.takeError(), Obj->getFileName());

    SymbolName = *SymbolNameOrErr;
    SymbolIndex = Obj->getSymbolIndex(Obj->getCOFFSymbol(*Symbol));
  }

  if (opts::ExpandRelocs) {
    DictScope Group(W, "Relocation");
    W.printHex("Offset", Offset);
    W.printNumber("Type", RelocName, RelocType);
    W.printString("Symbol", SymbolName.empty() ? "-" : SymbolName);
    W.printNumber("SymbolIndex", SymbolIndex);
  } else {
    raw_ostream& OS = W.startLine();
    OS << W.hex(Offset)
       << " " << RelocName
       << " " << (SymbolName.empty() ? "-" : SymbolName)
       << " (" << SymbolIndex << ")"
       << "\n";
  }
}

void COFFDumper::printSymbols() {
  ListScope Group(W, "Symbols");

  for (const SymbolRef &Symbol : Obj->symbols())
    printSymbol(Symbol);
}

void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }

static Expected<StringRef>
getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber,
               const coff_section *Section) {
  if (Section)
    return Obj->getSectionName(Section);
  if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
    return StringRef("IMAGE_SYM_DEBUG");
  if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE)
    return StringRef("IMAGE_SYM_ABSOLUTE");
  if (SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
    return StringRef("IMAGE_SYM_UNDEFINED");
  return StringRef("");
}

void COFFDumper::printSymbol(const SymbolRef &Sym) {
  DictScope D(W, "Symbol");

  COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym);
  const coff_section *Section;
  if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) {
    W.startLine() << "Invalid section number: " << EC.message() << "\n";
    W.flush();
    return;
  }

  StringRef SymbolName;
  if (Obj->getSymbolName(Symbol, SymbolName))
    SymbolName = "";

  StringRef SectionName;
  if (Expected<StringRef> NameOrErr =
          getSectionName(Obj, Symbol.getSectionNumber(), Section))
    SectionName = *NameOrErr;

  W.printString("Name", SymbolName);
  W.printNumber("Value", Symbol.getValue());
  W.printNumber("Section", SectionName, Symbol.getSectionNumber());
  W.printEnum  ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType));
  W.printEnum  ("ComplexType", Symbol.getComplexType(),
                                                   makeArrayRef(ImageSymDType));
  W.printEnum  ("StorageClass", Symbol.getStorageClass(),
                                                   makeArrayRef(ImageSymClass));
  W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols());

  for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) {
    if (Symbol.isFunctionDefinition()) {
      const coff_aux_function_definition *Aux;
      if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, Aux))
        reportError(errorCodeToError(EC), Obj->getFileName());

      DictScope AS(W, "AuxFunctionDef");
      W.printNumber("TagIndex", Aux->TagIndex);
      W.printNumber("TotalSize", Aux->TotalSize);
      W.printHex("PointerToLineNumber", Aux->PointerToLinenumber);
      W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);

    } else if (Symbol.isAnyUndefined()) {
      const coff_aux_weak_external *Aux;
      if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, Aux))
        reportError(errorCodeToError(EC), Obj->getFileName());

      Expected<COFFSymbolRef> Linked = Obj->getSymbol(Aux->TagIndex);
      if (!Linked)
        reportError(Linked.takeError(), Obj->getFileName());

      StringRef LinkedName;
      if (std::error_code EC = Obj->getSymbolName(*Linked, LinkedName))
        reportError(errorCodeToError(EC), Obj->getFileName());

      DictScope AS(W, "AuxWeakExternal");
      W.printNumber("Linked", LinkedName, Aux->TagIndex);
      W.printEnum  ("Search", Aux->Characteristics,
                    makeArrayRef(WeakExternalCharacteristics));

    } else if (Symbol.isFileRecord()) {
      const char *FileName;
      if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, FileName))
        reportError(errorCodeToError(EC), Obj->getFileName());
      DictScope AS(W, "AuxFileRecord");

      StringRef Name(FileName, Symbol.getNumberOfAuxSymbols() *
                                   Obj->getSymbolTableEntrySize());
      W.printString("FileName", Name.rtrim(StringRef("\0", 1)));
      break;
    } else if (Symbol.isSectionDefinition()) {
      const coff_aux_section_definition *Aux;
      if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, Aux))
        reportError(errorCodeToError(EC), Obj->getFileName());

      int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj());

      DictScope AS(W, "AuxSectionDef");
      W.printNumber("Length", Aux->Length);
      W.printNumber("RelocationCount", Aux->NumberOfRelocations);
      W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers);
      W.printHex("Checksum", Aux->CheckSum);
      W.printNumber("Number", AuxNumber);
      W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));

      if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
          && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
        const coff_section *Assoc;
        StringRef AssocName = "";
        if (std::error_code EC = Obj->getSection(AuxNumber, Assoc))
          reportError(errorCodeToError(EC), Obj->getFileName());
        Expected<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc);
        if (!Res)
          reportError(Res.takeError(), Obj->getFileName());
        AssocName = *Res;

        W.printNumber("AssocSection", AssocName, AuxNumber);
      }
    } else if (Symbol.isCLRToken()) {
      const coff_aux_clr_token *Aux;
      if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, Aux))
        reportError(errorCodeToError(EC), Obj->getFileName());

      Expected<COFFSymbolRef> ReferredSym =
          Obj->getSymbol(Aux->SymbolTableIndex);
      if (!ReferredSym)
        reportError(ReferredSym.takeError(), Obj->getFileName());

      StringRef ReferredName;
      if (std::error_code EC = Obj->getSymbolName(*ReferredSym, ReferredName))
        reportError(errorCodeToError(EC), Obj->getFileName());

      DictScope AS(W, "AuxCLRToken");
      W.printNumber("AuxType", Aux->AuxType);
      W.printNumber("Reserved", Aux->Reserved);
      W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex);

    } else {
      W.startLine() << "<unhandled auxiliary record>\n";
    }
  }
}

void COFFDumper::printUnwindInfo() {
  ListScope D(W, "UnwindInformation");
  switch (Obj->getMachine()) {
  case COFF::IMAGE_FILE_MACHINE_AMD64: {
    Win64EH::Dumper Dumper(W);
    Win64EH::Dumper::SymbolResolver
    Resolver = [](const object::coff_section *Section, uint64_t Offset,
                  SymbolRef &Symbol, void *user_data) -> std::error_code {
      COFFDumper *Dumper = reinterpret_cast<COFFDumper *>(user_data);
      return Dumper->resolveSymbol(Section, Offset, Symbol);
    };
    Win64EH::Dumper::Context Ctx(*Obj, Resolver, this);
    Dumper.printData(Ctx);
    break;
  }
  case COFF::IMAGE_FILE_MACHINE_ARM64:
  case COFF::IMAGE_FILE_MACHINE_ARMNT: {
    ARM::WinEH::Decoder Decoder(W, Obj->getMachine() ==
                                       COFF::IMAGE_FILE_MACHINE_ARM64);
    // TODO Propagate the error.
    consumeError(Decoder.dumpProcedureData(*Obj));
    break;
  }
  default:
    W.printEnum("unsupported Image Machine", Obj->getMachine(),
                makeArrayRef(ImageFileMachineType));
    break;
  }
}

void COFFDumper::printNeededLibraries() {
  ListScope D(W, "NeededLibraries");

  using LibsTy = std::vector<StringRef>;
  LibsTy Libs;

  for (const ImportDirectoryEntryRef &DirRef : Obj->import_directories()) {
    StringRef Name;
    if (!DirRef.getName(Name))
      Libs.push_back(Name);
  }

  llvm::stable_sort(Libs);

  for (const auto &L : Libs) {
    W.startLine() << L << "\n";
  }
}

void COFFDumper::printImportedSymbols(
    iterator_range<imported_symbol_iterator> Range) {
  for (const ImportedSymbolRef &I : Range) {
    StringRef Sym;
    if (std::error_code EC = I.getSymbolName(Sym))
      reportError(errorCodeToError(EC), Obj->getFileName());
    uint16_t Ordinal;
    if (std::error_code EC = I.getOrdinal(Ordinal))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printNumber("Symbol", Sym, Ordinal);
  }
}

void COFFDumper::printDelayImportedSymbols(
    const DelayImportDirectoryEntryRef &I,
    iterator_range<imported_symbol_iterator> Range) {
  int Index = 0;
  for (const ImportedSymbolRef &S : Range) {
    DictScope Import(W, "Import");
    StringRef Sym;
    if (std::error_code EC = S.getSymbolName(Sym))
      reportError(errorCodeToError(EC), Obj->getFileName());

    uint16_t Ordinal;
    if (std::error_code EC = S.getOrdinal(Ordinal))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printNumber("Symbol", Sym, Ordinal);

    uint64_t Addr;
    if (std::error_code EC = I.getImportAddress(Index++, Addr))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printHex("Address", Addr);
  }
}

void COFFDumper::printCOFFImports() {
  // Regular imports
  for (const ImportDirectoryEntryRef &I : Obj->import_directories()) {
    DictScope Import(W, "Import");
    StringRef Name;
    if (std::error_code EC = I.getName(Name))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printString("Name", Name);
    uint32_t ILTAddr;
    if (std::error_code EC = I.getImportLookupTableRVA(ILTAddr))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printHex("ImportLookupTableRVA", ILTAddr);
    uint32_t IATAddr;
    if (std::error_code EC = I.getImportAddressTableRVA(IATAddr))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printHex("ImportAddressTableRVA", IATAddr);
    // The import lookup table can be missing with certain older linkers, so
    // fall back to the import address table in that case.
    if (ILTAddr)
      printImportedSymbols(I.lookup_table_symbols());
    else
      printImportedSymbols(I.imported_symbols());
  }

  // Delay imports
  for (const DelayImportDirectoryEntryRef &I : Obj->delay_import_directories()) {
    DictScope Import(W, "DelayImport");
    StringRef Name;
    if (std::error_code EC = I.getName(Name))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printString("Name", Name);
    const delay_import_directory_table_entry *Table;
    if (std::error_code EC = I.getDelayImportTable(Table))
      reportError(errorCodeToError(EC), Obj->getFileName());
    W.printHex("Attributes", Table->Attributes);
    W.printHex("ModuleHandle", Table->ModuleHandle);
    W.printHex("ImportAddressTable", Table->DelayImportAddressTable);
    W.printHex("ImportNameTable", Table->DelayImportNameTable);
    W.printHex("BoundDelayImportTable", Table->BoundDelayImportTable);
    W.printHex("UnloadDelayImportTable", Table->UnloadDelayImportTable);
    printDelayImportedSymbols(I, I.imported_symbols());
  }
}

void COFFDumper::printCOFFExports() {
  for (const ExportDirectoryEntryRef &E : Obj->export_directories()) {
    DictScope Export(W, "Export");

    StringRef Name;
    uint32_t Ordinal, RVA;

    if (std::error_code EC = E.getSymbolName(Name))
      reportError(errorCodeToError(EC), Obj->getFileName());
    if (std::error_code EC = E.getOrdinal(Ordinal))
      reportError(errorCodeToError(EC), Obj->getFileName());
    if (std::error_code EC = E.getExportRVA(RVA))
      reportError(errorCodeToError(EC), Obj->getFileName());

    W.printNumber("Ordinal", Ordinal);
    W.printString("Name", Name);
    W.printHex("RVA", RVA);
  }
}

void COFFDumper::printCOFFDirectives() {
  for (const SectionRef &Section : Obj->sections()) {
    StringRef Name = unwrapOrError(Obj->getFileName(), Section.getName());
    if (Name != ".drectve")
      continue;

    StringRef Contents =
        unwrapOrError(Obj->getFileName(), Section.getContents());
    W.printString("Directive(s)", Contents);
  }
}

static std::string getBaseRelocTypeName(uint8_t Type) {
  switch (Type) {
  case COFF::IMAGE_REL_BASED_ABSOLUTE: return "ABSOLUTE";
  case COFF::IMAGE_REL_BASED_HIGH: return "HIGH";
  case COFF::IMAGE_REL_BASED_LOW: return "LOW";
  case COFF::IMAGE_REL_BASED_HIGHLOW: return "HIGHLOW";
  case COFF::IMAGE_REL_BASED_HIGHADJ: return "HIGHADJ";
  case COFF::IMAGE_REL_BASED_ARM_MOV32T: return "ARM_MOV32(T)";
  case COFF::IMAGE_REL_BASED_DIR64: return "DIR64";
  default: return "unknown (" + llvm::utostr(Type) + ")";
  }
}

void COFFDumper::printCOFFBaseReloc() {
  ListScope D(W, "BaseReloc");
  for (const BaseRelocRef &I : Obj->base_relocs()) {
    uint8_t Type;
    uint32_t RVA;
    if (std::error_code EC = I.getRVA(RVA))
      reportError(errorCodeToError(EC), Obj->getFileName());
    if (std::error_code EC = I.getType(Type))
      reportError(errorCodeToError(EC), Obj->getFileName());
    DictScope Import(W, "Entry");
    W.printString("Type", getBaseRelocTypeName(Type));
    W.printHex("Address", RVA);
  }
}

void COFFDumper::printCOFFResources() {
  ListScope ResourcesD(W, "Resources");
  for (const SectionRef &S : Obj->sections()) {
    StringRef Name = unwrapOrError(Obj->getFileName(), S.getName());
    if (!Name.startswith(".rsrc"))
      continue;

    StringRef Ref = unwrapOrError(Obj->getFileName(), S.getContents());

    if ((Name == ".rsrc") || (Name == ".rsrc$01")) {
      ResourceSectionRef RSF;
      Error E = RSF.load(Obj, S);
      if (E)
        reportError(std::move(E), Obj->getFileName());
      auto &BaseTable = unwrapOrError(Obj->getFileName(), RSF.getBaseTable());
      W.printNumber("Total Number of Resources",
                    countTotalTableEntries(RSF, BaseTable, "Type"));
      W.printHex("Base Table Address",
                 Obj->getCOFFSection(S)->PointerToRawData);
      W.startLine() << "\n";
      printResourceDirectoryTable(RSF, BaseTable, "Type");
    }
    if (opts::SectionData)
      W.printBinaryBlock(Name.str() + " Data", Ref);
  }
}

uint32_t
COFFDumper::countTotalTableEntries(ResourceSectionRef RSF,
                                   const coff_resource_dir_table &Table,
                                   StringRef Level) {
  uint32_t TotalEntries = 0;
  for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
       i++) {
    auto Entry = unwrapOrError(Obj->getFileName(), RSF.getTableEntry(Table, i));
    if (Entry.Offset.isSubDir()) {
      StringRef NextLevel;
      if (Level == "Name")
        NextLevel = "Language";
      else
        NextLevel = "Name";
      auto &NextTable =
          unwrapOrError(Obj->getFileName(), RSF.getEntrySubDir(Entry));
      TotalEntries += countTotalTableEntries(RSF, NextTable, NextLevel);
    } else {
      TotalEntries += 1;
    }
  }
  return TotalEntries;
}

void COFFDumper::printResourceDirectoryTable(
    ResourceSectionRef RSF, const coff_resource_dir_table &Table,
    StringRef Level) {

  W.printNumber("Number of String Entries", Table.NumberOfNameEntries);
  W.printNumber("Number of ID Entries", Table.NumberOfIDEntries);

  // Iterate through level in resource directory tree.
  for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
       i++) {
    auto Entry = unwrapOrError(Obj->getFileName(), RSF.getTableEntry(Table, i));
    StringRef Name;
    SmallString<20> IDStr;
    raw_svector_ostream OS(IDStr);
    if (i < Table.NumberOfNameEntries) {
      ArrayRef<UTF16> RawEntryNameString =
          unwrapOrError(Obj->getFileName(), RSF.getEntryNameString(Entry));
      std::vector<UTF16> EndianCorrectedNameString;
      if (llvm::sys::IsBigEndianHost) {
        EndianCorrectedNameString.resize(RawEntryNameString.size() + 1);
        std::copy(RawEntryNameString.begin(), RawEntryNameString.end(),
                  EndianCorrectedNameString.begin() + 1);
        EndianCorrectedNameString[0] = UNI_UTF16_BYTE_ORDER_MARK_SWAPPED;
        RawEntryNameString = makeArrayRef(EndianCorrectedNameString);
      }
      std::string EntryNameString;
      if (!llvm::convertUTF16ToUTF8String(RawEntryNameString, EntryNameString))
        reportError(errorCodeToError(object_error::parse_failed),
                    Obj->getFileName());
      OS << ": ";
      OS << EntryNameString;
    } else {
      if (Level == "Type") {
        OS << ": ";
        printResourceTypeName(Entry.Identifier.ID, OS);
      } else {
        OS << ": (ID " << Entry.Identifier.ID << ")";
      }
    }
    Name = StringRef(IDStr);
    ListScope ResourceType(W, Level.str() + Name.str());
    if (Entry.Offset.isSubDir()) {
      W.printHex("Table Offset", Entry.Offset.value());
      StringRef NextLevel;
      if (Level == "Name")
        NextLevel = "Language";
      else
        NextLevel = "Name";
      auto &NextTable =
          unwrapOrError(Obj->getFileName(), RSF.getEntrySubDir(Entry));
      printResourceDirectoryTable(RSF, NextTable, NextLevel);
    } else {
      W.printHex("Entry Offset", Entry.Offset.value());
      char FormattedTime[20] = {};
      time_t TDS = time_t(Table.TimeDateStamp);
      strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
      W.printHex("Time/Date Stamp", FormattedTime, Table.TimeDateStamp);
      W.printNumber("Major Version", Table.MajorVersion);
      W.printNumber("Minor Version", Table.MinorVersion);
      W.printNumber("Characteristics", Table.Characteristics);
      ListScope DataScope(W, "Data");
      auto &DataEntry =
          unwrapOrError(Obj->getFileName(), RSF.getEntryData(Entry));
      W.printHex("DataRVA", DataEntry.DataRVA);
      W.printNumber("DataSize", DataEntry.DataSize);
      W.printNumber("Codepage", DataEntry.Codepage);
      W.printNumber("Reserved", DataEntry.Reserved);
      StringRef Contents =
          unwrapOrError(Obj->getFileName(), RSF.getContents(DataEntry));
      W.printBinaryBlock("Data", Contents);
    }
  }
}

void COFFDumper::printStackMap() const {
  object::SectionRef StackMapSection;
  for (auto Sec : Obj->sections()) {
    StringRef Name;
    if (Expected<StringRef> NameOrErr = Sec.getName())
      Name = *NameOrErr;
    else
      consumeError(NameOrErr.takeError());

    if (Name == ".llvm_stackmaps") {
      StackMapSection = Sec;
      break;
    }
  }

  if (StackMapSection == object::SectionRef())
    return;

  StringRef StackMapContents =
      unwrapOrError(Obj->getFileName(), StackMapSection.getContents());
  ArrayRef<uint8_t> StackMapContentsArray =
      arrayRefFromStringRef(StackMapContents);

  if (Obj->isLittleEndian())
    prettyPrintStackMap(
        W, StackMapParser<support::little>(StackMapContentsArray));
  else
    prettyPrintStackMap(
        W, StackMapParser<support::big>(StackMapContentsArray));
}

void COFFDumper::printAddrsig() {
  object::SectionRef AddrsigSection;
  for (auto Sec : Obj->sections()) {
    StringRef Name;
    if (Expected<StringRef> NameOrErr = Sec.getName())
      Name = *NameOrErr;
    else
      consumeError(NameOrErr.takeError());

    if (Name == ".llvm_addrsig") {
      AddrsigSection = Sec;
      break;
    }
  }

  if (AddrsigSection == object::SectionRef())
    return;

  StringRef AddrsigContents =
      unwrapOrError(Obj->getFileName(), AddrsigSection.getContents());
  ArrayRef<uint8_t> AddrsigContentsArray(AddrsigContents.bytes_begin(),
                                         AddrsigContents.size());

  ListScope L(W, "Addrsig");
  const uint8_t *Cur = AddrsigContents.bytes_begin();
  const uint8_t *End = AddrsigContents.bytes_end();
  while (Cur != End) {
    unsigned Size;
    const char *Err;
    uint64_t SymIndex = decodeULEB128(Cur, &Size, End, &Err);
    if (Err)
      reportError(createError(Err), Obj->getFileName());

    Expected<COFFSymbolRef> Sym = Obj->getSymbol(SymIndex);
    if (!Sym)
      reportError(Sym.takeError(), Obj->getFileName());

    StringRef SymName;
    if (std::error_code EC = Obj->getSymbolName(*Sym, SymName))
      reportError(errorCodeToError(EC), Obj->getFileName());

    W.printNumber("Sym", SymName, SymIndex);
    Cur += Size;
  }
}

void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer,
                                   ArrayRef<ArrayRef<uint8_t>> IpiRecords,
                                   ArrayRef<ArrayRef<uint8_t>> TpiRecords) {
  TypeTableCollection TpiTypes(TpiRecords);
  {
    ListScope S(Writer, "MergedTypeStream");
    TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
    if (Error Err = codeview::visitTypeStream(TpiTypes, TDV))
      reportError(std::move(Err), "<?>");
    Writer.flush();
  }

  // Flatten the id stream and print it next. The ID stream refers to names from
  // the type stream.
  TypeTableCollection IpiTypes(IpiRecords);
  {
    ListScope S(Writer, "MergedIDStream");
    TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
    TDV.setIpiTypes(IpiTypes);
    if (Error Err = codeview::visitTypeStream(IpiTypes, TDV))
      reportError(std::move(Err), "<?>");
    Writer.flush();
  }
}
