Home | History | Annotate | Download | only in llvm-readobj
      1 //===-- COFFDumper.cpp - COFF-specific dumper -------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief This file implements the COFF-specific dumper for llvm-readobj.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "ARMWinEHPrinter.h"
     16 #include "CodeView.h"
     17 #include "Error.h"
     18 #include "ObjDumper.h"
     19 #include "StackMapPrinter.h"
     20 #include "Win64EHDumper.h"
     21 #include "llvm-readobj.h"
     22 #include "llvm/ADT/DenseMap.h"
     23 #include "llvm/ADT/SmallString.h"
     24 #include "llvm/ADT/StringExtras.h"
     25 #include "llvm/DebugInfo/CodeView/ByteStream.h"
     26 #include "llvm/DebugInfo/CodeView/CodeView.h"
     27 #include "llvm/DebugInfo/CodeView/Line.h"
     28 #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
     29 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
     30 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
     31 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
     32 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
     33 #include "llvm/DebugInfo/CodeView/TypeDumper.h"
     34 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
     35 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
     36 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
     37 #include "llvm/Object/COFF.h"
     38 #include "llvm/Object/ObjectFile.h"
     39 #include "llvm/Support/COFF.h"
     40 #include "llvm/Support/Casting.h"
     41 #include "llvm/Support/Compiler.h"
     42 #include "llvm/Support/DataExtractor.h"
     43 #include "llvm/Support/Format.h"
     44 #include "llvm/Support/ScopedPrinter.h"
     45 #include "llvm/Support/SourceMgr.h"
     46 #include "llvm/Support/Win64EH.h"
     47 #include "llvm/Support/raw_ostream.h"
     48 #include <algorithm>
     49 #include <cstring>
     50 #include <system_error>
     51 #include <time.h>
     52 
     53 using namespace llvm;
     54 using namespace llvm::object;
     55 using namespace llvm::codeview;
     56 using namespace llvm::support;
     57 using namespace llvm::Win64EH;
     58 
     59 namespace {
     60 
     61 class COFFDumper : public ObjDumper {
     62 public:
     63   friend class COFFObjectDumpDelegate;
     64   COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
     65       : ObjDumper(Writer), Obj(Obj),
     66         CVTD(&Writer, opts::CodeViewSubsectionBytes) {}
     67 
     68   void printFileHeaders() override;
     69   void printSections() override;
     70   void printRelocations() override;
     71   void printSymbols() override;
     72   void printDynamicSymbols() override;
     73   void printUnwindInfo() override;
     74   void printCOFFImports() override;
     75   void printCOFFExports() override;
     76   void printCOFFDirectives() override;
     77   void printCOFFBaseReloc() override;
     78   void printCOFFDebugDirectory() override;
     79   void printCodeViewDebugInfo() override;
     80   void
     81   mergeCodeViewTypes(llvm::codeview::MemoryTypeTableBuilder &CVTypes) override;
     82   void printStackMap() const override;
     83 private:
     84   void printSymbol(const SymbolRef &Sym);
     85   void printRelocation(const SectionRef &Section, const RelocationRef &Reloc,
     86                        uint64_t Bias = 0);
     87   void printDataDirectory(uint32_t Index, const std::string &FieldName);
     88 
     89   void printDOSHeader(const dos_header *DH);
     90   template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
     91   void printBaseOfDataField(const pe32_header *Hdr);
     92   void printBaseOfDataField(const pe32plus_header *Hdr);
     93 
     94   void printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section);
     95   void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section);
     96   StringRef getTypeName(TypeIndex Ty);
     97   StringRef getFileNameForFileOffset(uint32_t FileOffset);
     98   void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
     99   void printTypeIndex(StringRef FieldName, TypeIndex TI) {
    100     // Forward to CVTypeDumper for simplicity.
    101     CVTD.printTypeIndex(FieldName, TI);
    102   }
    103 
    104   void printCodeViewSymbolsSubsection(StringRef Subsection,
    105                                       const SectionRef &Section,
    106                                       StringRef SectionContents);
    107 
    108   void printCodeViewFileChecksums(StringRef Subsection);
    109 
    110   void printCodeViewInlineeLines(StringRef Subsection);
    111 
    112   void printRelocatedField(StringRef Label, const coff_section *Sec,
    113                            uint32_t RelocOffset, uint32_t Offset,
    114                            StringRef *RelocSym = nullptr);
    115 
    116   void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec,
    117                                   StringRef SectionContents, StringRef Block);
    118 
    119   /// Given a .debug$S section, find the string table and file checksum table.
    120   void initializeFileAndStringTables(StringRef Data);
    121 
    122   void cacheRelocations();
    123 
    124   std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
    125                                 SymbolRef &Sym);
    126   std::error_code resolveSymbolName(const coff_section *Section,
    127                                     uint64_t Offset, StringRef &Name);
    128   std::error_code resolveSymbolName(const coff_section *Section,
    129                                     StringRef SectionContents,
    130                                     const void *RelocPtr, StringRef &Name);
    131   void printImportedSymbols(iterator_range<imported_symbol_iterator> Range);
    132   void printDelayImportedSymbols(
    133       const DelayImportDirectoryEntryRef &I,
    134       iterator_range<imported_symbol_iterator> Range);
    135 
    136   typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
    137 
    138   const llvm::object::COFFObjectFile *Obj;
    139   bool RelocCached = false;
    140   RelocMapTy RelocMap;
    141   StringRef CVFileChecksumTable;
    142   StringRef CVStringTable;
    143 
    144   CVTypeDumper CVTD;
    145 };
    146 
    147 class COFFObjectDumpDelegate : public SymbolDumpDelegate {
    148 public:
    149   COFFObjectDumpDelegate(COFFDumper &CD, const SectionRef &SR,
    150                          const COFFObjectFile *Obj, StringRef SectionContents)
    151       : CD(CD), SR(SR), SectionContents(SectionContents) {
    152     Sec = Obj->getCOFFSection(SR);
    153   }
    154 
    155   uint32_t getRecordOffset(ArrayRef<uint8_t> Record) override {
    156     return Record.data() - SectionContents.bytes_begin();
    157   }
    158 
    159   void printRelocatedField(StringRef Label, uint32_t RelocOffset,
    160                            uint32_t Offset, StringRef *RelocSym) override {
    161     CD.printRelocatedField(Label, Sec, RelocOffset, Offset, RelocSym);
    162   }
    163 
    164   void printBinaryBlockWithRelocs(StringRef Label,
    165                                   ArrayRef<uint8_t> Block) override {
    166     StringRef SBlock(reinterpret_cast<const char *>(Block.data()),
    167                      Block.size());
    168     if (opts::CodeViewSubsectionBytes)
    169       CD.printBinaryBlockWithRelocs(Label, SR, SectionContents, SBlock);
    170   }
    171 
    172   StringRef getFileNameForFileOffset(uint32_t FileOffset) override {
    173     return CD.getFileNameForFileOffset(FileOffset);
    174   }
    175 
    176   StringRef getStringTable() override { return CD.CVStringTable; }
    177 
    178 private:
    179   COFFDumper &CD;
    180   const SectionRef &SR;
    181   const coff_section *Sec;
    182   StringRef SectionContents;
    183 };
    184 
    185 } // end namespace
    186 
    187 namespace llvm {
    188 
    189 std::error_code createCOFFDumper(const object::ObjectFile *Obj,
    190                                  ScopedPrinter &Writer,
    191                                  std::unique_ptr<ObjDumper> &Result) {
    192   const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(Obj);
    193   if (!COFFObj)
    194     return readobj_error::unsupported_obj_file_format;
    195 
    196   Result.reset(new COFFDumper(COFFObj, Writer));
    197   return readobj_error::success;
    198 }
    199 
    200 } // namespace llvm
    201 
    202 // Given a a section and an offset into this section the function returns the
    203 // symbol used for the relocation at the offset.
    204 std::error_code COFFDumper::resolveSymbol(const coff_section *Section,
    205                                           uint64_t Offset, SymbolRef &Sym) {
    206   cacheRelocations();
    207   const auto &Relocations = RelocMap[Section];
    208   auto SymI = Obj->symbol_end();
    209   for (const auto &Relocation : Relocations) {
    210     uint64_t RelocationOffset = Relocation.getOffset();
    211 
    212     if (RelocationOffset == Offset) {
    213       SymI = Relocation.getSymbol();
    214       break;
    215     }
    216   }
    217   if (SymI == Obj->symbol_end())
    218     return readobj_error::unknown_symbol;
    219   Sym = *SymI;
    220   return readobj_error::success;
    221 }
    222 
    223 // Given a section and an offset into this section the function returns the name
    224 // of the symbol used for the relocation at the offset.
    225 std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
    226                                               uint64_t Offset,
    227                                               StringRef &Name) {
    228   SymbolRef Symbol;
    229   if (std::error_code EC = resolveSymbol(Section, Offset, Symbol))
    230     return EC;
    231   Expected<StringRef> NameOrErr = Symbol.getName();
    232   if (!NameOrErr)
    233     return errorToErrorCode(NameOrErr.takeError());
    234   Name = *NameOrErr;
    235   return std::error_code();
    236 }
    237 
    238 // Helper for when you have a pointer to real data and you want to know about
    239 // relocations against it.
    240 std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
    241                                               StringRef SectionContents,
    242                                               const void *RelocPtr,
    243                                               StringRef &Name) {
    244   assert(SectionContents.data() < RelocPtr &&
    245          RelocPtr < SectionContents.data() + SectionContents.size() &&
    246          "pointer to relocated object is not in section");
    247   uint64_t Offset = ptrdiff_t(reinterpret_cast<const char *>(RelocPtr) -
    248                               SectionContents.data());
    249   return resolveSymbolName(Section, Offset, Name);
    250 }
    251 
    252 void COFFDumper::printRelocatedField(StringRef Label, const coff_section *Sec,
    253                                      uint32_t RelocOffset, uint32_t Offset,
    254                                      StringRef *RelocSym) {
    255   StringRef SymStorage;
    256   StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;
    257   if (!resolveSymbolName(Sec, RelocOffset, Symbol))
    258     W.printSymbolOffset(Label, Symbol, Offset);
    259   else
    260     W.printHex(Label, RelocOffset);
    261 }
    262 
    263 void COFFDumper::printBinaryBlockWithRelocs(StringRef Label,
    264                                             const SectionRef &Sec,
    265                                             StringRef SectionContents,
    266                                             StringRef Block) {
    267   W.printBinaryBlock(Label, Block);
    268 
    269   assert(SectionContents.begin() < Block.begin() &&
    270          SectionContents.end() >= Block.end() &&
    271          "Block is not contained in SectionContents");
    272   uint64_t OffsetStart = Block.data() - SectionContents.data();
    273   uint64_t OffsetEnd = OffsetStart + Block.size();
    274 
    275   W.flush();
    276   cacheRelocations();
    277   ListScope D(W, "BlockRelocations");
    278   const coff_section *Section = Obj->getCOFFSection(Sec);
    279   const auto &Relocations = RelocMap[Section];
    280   for (const auto &Relocation : Relocations) {
    281     uint64_t RelocationOffset = Relocation.getOffset();
    282     if (OffsetStart <= RelocationOffset && RelocationOffset < OffsetEnd)
    283       printRelocation(Sec, Relocation, OffsetStart);
    284   }
    285 }
    286 
    287 static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
    288   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN  ),
    289   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33     ),
    290   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64    ),
    291   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM      ),
    292   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT    ),
    293   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC      ),
    294   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386     ),
    295   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64     ),
    296   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R     ),
    297   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16   ),
    298   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU  ),
    299   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16),
    300   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC  ),
    301   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP),
    302   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000    ),
    303   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3      ),
    304   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP   ),
    305   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4      ),
    306   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5      ),
    307   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB    ),
    308   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2)
    309 };
    310 
    311 static const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = {
    312   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED        ),
    313   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_EXECUTABLE_IMAGE       ),
    314   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LINE_NUMS_STRIPPED     ),
    315   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LOCAL_SYMS_STRIPPED    ),
    316   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_AGGRESSIVE_WS_TRIM     ),
    317   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LARGE_ADDRESS_AWARE    ),
    318   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_LO      ),
    319   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_32BIT_MACHINE          ),
    320   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DEBUG_STRIPPED         ),
    321   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP),
    322   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_NET_RUN_FROM_SWAP      ),
    323   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_SYSTEM                 ),
    324   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DLL                    ),
    325   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_UP_SYSTEM_ONLY         ),
    326   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI      )
    327 };
    328 
    329 static const EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = {
    330   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_UNKNOWN                ),
    331   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_NATIVE                 ),
    332   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_GUI            ),
    333   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CUI            ),
    334   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_POSIX_CUI              ),
    335   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI         ),
    336   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_APPLICATION        ),
    337   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER),
    338   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER     ),
    339   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_ROM                ),
    340   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_XBOX                   ),
    341 };
    342 
    343 static const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = {
    344   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA      ),
    345   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE         ),
    346   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY      ),
    347   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT            ),
    348   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION         ),
    349   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_SEH               ),
    350   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_BIND              ),
    351   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_APPCONTAINER         ),
    352   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER           ),
    353   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_GUARD_CF             ),
    354   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE),
    355 };
    356 
    357 static const EnumEntry<COFF::SectionCharacteristics>
    358 ImageSectionCharacteristics[] = {
    359   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD           ),
    360   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD           ),
    361   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE              ),
    362   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA  ),
    363   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
    364   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER             ),
    365   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO              ),
    366   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE            ),
    367   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT            ),
    368   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_GPREL                 ),
    369   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE         ),
    370   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT             ),
    371   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED            ),
    372   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD           ),
    373   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES          ),
    374   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES          ),
    375   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES          ),
    376   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES          ),
    377   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES         ),
    378   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES         ),
    379   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES         ),
    380   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES        ),
    381   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES        ),
    382   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES        ),
    383   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES       ),
    384   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES       ),
    385   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES       ),
    386   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES       ),
    387   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL       ),
    388   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE       ),
    389   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED        ),
    390   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED         ),
    391   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED            ),
    392   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE           ),
    393   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ              ),
    394   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE             )
    395 };
    396 
    397 static const EnumEntry<COFF::SymbolBaseType> ImageSymType[] = {
    398   { "Null"  , COFF::IMAGE_SYM_TYPE_NULL   },
    399   { "Void"  , COFF::IMAGE_SYM_TYPE_VOID   },
    400   { "Char"  , COFF::IMAGE_SYM_TYPE_CHAR   },
    401   { "Short" , COFF::IMAGE_SYM_TYPE_SHORT  },
    402   { "Int"   , COFF::IMAGE_SYM_TYPE_INT    },
    403   { "Long"  , COFF::IMAGE_SYM_TYPE_LONG   },
    404   { "Float" , COFF::IMAGE_SYM_TYPE_FLOAT  },
    405   { "Double", COFF::IMAGE_SYM_TYPE_DOUBLE },
    406   { "Struct", COFF::IMAGE_SYM_TYPE_STRUCT },
    407   { "Union" , COFF::IMAGE_SYM_TYPE_UNION  },
    408   { "Enum"  , COFF::IMAGE_SYM_TYPE_ENUM   },
    409   { "MOE"   , COFF::IMAGE_SYM_TYPE_MOE    },
    410   { "Byte"  , COFF::IMAGE_SYM_TYPE_BYTE   },
    411   { "Word"  , COFF::IMAGE_SYM_TYPE_WORD   },
    412   { "UInt"  , COFF::IMAGE_SYM_TYPE_UINT   },
    413   { "DWord" , COFF::IMAGE_SYM_TYPE_DWORD  }
    414 };
    415 
    416 static const EnumEntry<COFF::SymbolComplexType> ImageSymDType[] = {
    417   { "Null"    , COFF::IMAGE_SYM_DTYPE_NULL     },
    418   { "Pointer" , COFF::IMAGE_SYM_DTYPE_POINTER  },
    419   { "Function", COFF::IMAGE_SYM_DTYPE_FUNCTION },
    420   { "Array"   , COFF::IMAGE_SYM_DTYPE_ARRAY    }
    421 };
    422 
    423 static const EnumEntry<COFF::SymbolStorageClass> ImageSymClass[] = {
    424   { "EndOfFunction"  , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION  },
    425   { "Null"           , COFF::IMAGE_SYM_CLASS_NULL             },
    426   { "Automatic"      , COFF::IMAGE_SYM_CLASS_AUTOMATIC        },
    427   { "External"       , COFF::IMAGE_SYM_CLASS_EXTERNAL         },
    428   { "Static"         , COFF::IMAGE_SYM_CLASS_STATIC           },
    429   { "Register"       , COFF::IMAGE_SYM_CLASS_REGISTER         },
    430   { "ExternalDef"    , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF     },
    431   { "Label"          , COFF::IMAGE_SYM_CLASS_LABEL            },
    432   { "UndefinedLabel" , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL  },
    433   { "MemberOfStruct" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT },
    434   { "Argument"       , COFF::IMAGE_SYM_CLASS_ARGUMENT         },
    435   { "StructTag"      , COFF::IMAGE_SYM_CLASS_STRUCT_TAG       },
    436   { "MemberOfUnion"  , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION  },
    437   { "UnionTag"       , COFF::IMAGE_SYM_CLASS_UNION_TAG        },
    438   { "TypeDefinition" , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION  },
    439   { "UndefinedStatic", COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC },
    440   { "EnumTag"        , COFF::IMAGE_SYM_CLASS_ENUM_TAG         },
    441   { "MemberOfEnum"   , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM   },
    442   { "RegisterParam"  , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM   },
    443   { "BitField"       , COFF::IMAGE_SYM_CLASS_BIT_FIELD        },
    444   { "Block"          , COFF::IMAGE_SYM_CLASS_BLOCK            },
    445   { "Function"       , COFF::IMAGE_SYM_CLASS_FUNCTION         },
    446   { "EndOfStruct"    , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT    },
    447   { "File"           , COFF::IMAGE_SYM_CLASS_FILE             },
    448   { "Section"        , COFF::IMAGE_SYM_CLASS_SECTION          },
    449   { "WeakExternal"   , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL    },
    450   { "CLRToken"       , COFF::IMAGE_SYM_CLASS_CLR_TOKEN        }
    451 };
    452 
    453 static const EnumEntry<COFF::COMDATType> ImageCOMDATSelect[] = {
    454   { "NoDuplicates", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES },
    455   { "Any"         , COFF::IMAGE_COMDAT_SELECT_ANY          },
    456   { "SameSize"    , COFF::IMAGE_COMDAT_SELECT_SAME_SIZE    },
    457   { "ExactMatch"  , COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH  },
    458   { "Associative" , COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE  },
    459   { "Largest"     , COFF::IMAGE_COMDAT_SELECT_LARGEST      },
    460   { "Newest"      , COFF::IMAGE_COMDAT_SELECT_NEWEST       }
    461 };
    462 
    463 static const EnumEntry<COFF::DebugType> ImageDebugType[] = {
    464   { "Unknown"    , COFF::IMAGE_DEBUG_TYPE_UNKNOWN       },
    465   { "COFF"       , COFF::IMAGE_DEBUG_TYPE_COFF          },
    466   { "CodeView"   , COFF::IMAGE_DEBUG_TYPE_CODEVIEW      },
    467   { "FPO"        , COFF::IMAGE_DEBUG_TYPE_FPO           },
    468   { "Misc"       , COFF::IMAGE_DEBUG_TYPE_MISC          },
    469   { "Exception"  , COFF::IMAGE_DEBUG_TYPE_EXCEPTION     },
    470   { "Fixup"      , COFF::IMAGE_DEBUG_TYPE_FIXUP         },
    471   { "OmapToSrc"  , COFF::IMAGE_DEBUG_TYPE_OMAP_TO_SRC   },
    472   { "OmapFromSrc", COFF::IMAGE_DEBUG_TYPE_OMAP_FROM_SRC },
    473   { "Borland"    , COFF::IMAGE_DEBUG_TYPE_BORLAND       },
    474   { "Reserved10" , COFF::IMAGE_DEBUG_TYPE_RESERVED10    },
    475   { "CLSID"      , COFF::IMAGE_DEBUG_TYPE_CLSID         },
    476   { "VCFeature"  , COFF::IMAGE_DEBUG_TYPE_VC_FEATURE    },
    477   { "POGO"       , COFF::IMAGE_DEBUG_TYPE_POGO          },
    478   { "ILTCG"      , COFF::IMAGE_DEBUG_TYPE_ILTCG         },
    479   { "MPX"        , COFF::IMAGE_DEBUG_TYPE_MPX           },
    480   { "Repro"      , COFF::IMAGE_DEBUG_TYPE_REPRO         },
    481 };
    482 
    483 static const EnumEntry<COFF::WeakExternalCharacteristics>
    484 WeakExternalCharacteristics[] = {
    485   { "NoLibrary", COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY },
    486   { "Library"  , COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY   },
    487   { "Alias"    , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS     }
    488 };
    489 
    490 static const EnumEntry<uint32_t> SubSectionTypes[] = {
    491   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols),
    492   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines),
    493   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, StringTable),
    494   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FileChecksums),
    495   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FrameData),
    496   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, InlineeLines),
    497   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeImports),
    498   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeExports),
    499   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, ILLines),
    500   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FuncMDTokenMap),
    501   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, TypeMDTokenMap),
    502   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, MergedAssemblyInput),
    503   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA),
    504 };
    505 
    506 static const EnumEntry<uint32_t> FrameDataFlags[] = {
    507     LLVM_READOBJ_ENUM_ENT(FrameData, HasSEH),
    508     LLVM_READOBJ_ENUM_ENT(FrameData, HasEH),
    509     LLVM_READOBJ_ENUM_ENT(FrameData, IsFunctionStart),
    510 };
    511 
    512 static const EnumEntry<uint8_t> FileChecksumKindNames[] = {
    513   LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, None),
    514   LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, MD5),
    515   LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA1),
    516   LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
    517 };
    518 
    519 template <typename T>
    520 static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
    521                                         COFFSymbolRef Symbol,
    522                                         uint8_t AuxSymbolIdx, const T *&Aux) {
    523   ArrayRef<uint8_t> AuxData = Obj->getSymbolAuxData(Symbol);
    524   AuxData = AuxData.slice(AuxSymbolIdx * Obj->getSymbolTableEntrySize());
    525   Aux = reinterpret_cast<const T*>(AuxData.data());
    526   return readobj_error::success;
    527 }
    528 
    529 void COFFDumper::cacheRelocations() {
    530   if (RelocCached)
    531     return;
    532   RelocCached = true;
    533 
    534   for (const SectionRef &S : Obj->sections()) {
    535     const coff_section *Section = Obj->getCOFFSection(S);
    536 
    537     for (const RelocationRef &Reloc : S.relocations())
    538       RelocMap[Section].push_back(Reloc);
    539 
    540     // Sort relocations by address.
    541     std::sort(RelocMap[Section].begin(), RelocMap[Section].end(),
    542               relocAddressLess);
    543   }
    544 }
    545 
    546 void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName) {
    547   const data_directory *Data;
    548   if (Obj->getDataDirectory(Index, Data))
    549     return;
    550   W.printHex(FieldName + "RVA", Data->RelativeVirtualAddress);
    551   W.printHex(FieldName + "Size", Data->Size);
    552 }
    553 
    554 void COFFDumper::printFileHeaders() {
    555   time_t TDS = Obj->getTimeDateStamp();
    556   char FormattedTime[20] = { };
    557   strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
    558 
    559   {
    560     DictScope D(W, "ImageFileHeader");
    561     W.printEnum  ("Machine", Obj->getMachine(),
    562                     makeArrayRef(ImageFileMachineType));
    563     W.printNumber("SectionCount", Obj->getNumberOfSections());
    564     W.printHex   ("TimeDateStamp", FormattedTime, Obj->getTimeDateStamp());
    565     W.printHex   ("PointerToSymbolTable", Obj->getPointerToSymbolTable());
    566     W.printNumber("SymbolCount", Obj->getNumberOfSymbols());
    567     W.printNumber("OptionalHeaderSize", Obj->getSizeOfOptionalHeader());
    568     W.printFlags ("Characteristics", Obj->getCharacteristics(),
    569                     makeArrayRef(ImageFileCharacteristics));
    570   }
    571 
    572   // Print PE header. This header does not exist if this is an object file and
    573   // not an executable.
    574   const pe32_header *PEHeader = nullptr;
    575   error(Obj->getPE32Header(PEHeader));
    576   if (PEHeader)
    577     printPEHeader<pe32_header>(PEHeader);
    578 
    579   const pe32plus_header *PEPlusHeader = nullptr;
    580   error(Obj->getPE32PlusHeader(PEPlusHeader));
    581   if (PEPlusHeader)
    582     printPEHeader<pe32plus_header>(PEPlusHeader);
    583 
    584   if (const dos_header *DH = Obj->getDOSHeader())
    585     printDOSHeader(DH);
    586 }
    587 
    588 void COFFDumper::printDOSHeader(const dos_header *DH) {
    589   DictScope D(W, "DOSHeader");
    590   W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));
    591   W.printNumber("UsedBytesInTheLastPage", DH->UsedBytesInTheLastPage);
    592   W.printNumber("FileSizeInPages", DH->FileSizeInPages);
    593   W.printNumber("NumberOfRelocationItems", DH->NumberOfRelocationItems);
    594   W.printNumber("HeaderSizeInParagraphs", DH->HeaderSizeInParagraphs);
    595   W.printNumber("MinimumExtraParagraphs", DH->MinimumExtraParagraphs);
    596   W.printNumber("MaximumExtraParagraphs", DH->MaximumExtraParagraphs);
    597   W.printNumber("InitialRelativeSS", DH->InitialRelativeSS);
    598   W.printNumber("InitialSP", DH->InitialSP);
    599   W.printNumber("Checksum", DH->Checksum);
    600   W.printNumber("InitialIP", DH->InitialIP);
    601   W.printNumber("InitialRelativeCS", DH->InitialRelativeCS);
    602   W.printNumber("AddressOfRelocationTable", DH->AddressOfRelocationTable);
    603   W.printNumber("OverlayNumber", DH->OverlayNumber);
    604   W.printNumber("OEMid", DH->OEMid);
    605   W.printNumber("OEMinfo", DH->OEMinfo);
    606   W.printNumber("AddressOfNewExeHeader", DH->AddressOfNewExeHeader);
    607 }
    608 
    609 template <class PEHeader>
    610 void COFFDumper::printPEHeader(const PEHeader *Hdr) {
    611   DictScope D(W, "ImageOptionalHeader");
    612   W.printNumber("MajorLinkerVersion", Hdr->MajorLinkerVersion);
    613   W.printNumber("MinorLinkerVersion", Hdr->MinorLinkerVersion);
    614   W.printNumber("SizeOfCode", Hdr->SizeOfCode);
    615   W.printNumber("SizeOfInitializedData", Hdr->SizeOfInitializedData);
    616   W.printNumber("SizeOfUninitializedData", Hdr->SizeOfUninitializedData);
    617   W.printHex   ("AddressOfEntryPoint", Hdr->AddressOfEntryPoint);
    618   W.printHex   ("BaseOfCode", Hdr->BaseOfCode);
    619   printBaseOfDataField(Hdr);
    620   W.printHex   ("ImageBase", Hdr->ImageBase);
    621   W.printNumber("SectionAlignment", Hdr->SectionAlignment);
    622   W.printNumber("FileAlignment", Hdr->FileAlignment);
    623   W.printNumber("MajorOperatingSystemVersion",
    624                 Hdr->MajorOperatingSystemVersion);
    625   W.printNumber("MinorOperatingSystemVersion",
    626                 Hdr->MinorOperatingSystemVersion);
    627   W.printNumber("MajorImageVersion", Hdr->MajorImageVersion);
    628   W.printNumber("MinorImageVersion", Hdr->MinorImageVersion);
    629   W.printNumber("MajorSubsystemVersion", Hdr->MajorSubsystemVersion);
    630   W.printNumber("MinorSubsystemVersion", Hdr->MinorSubsystemVersion);
    631   W.printNumber("SizeOfImage", Hdr->SizeOfImage);
    632   W.printNumber("SizeOfHeaders", Hdr->SizeOfHeaders);
    633   W.printEnum  ("Subsystem", Hdr->Subsystem, makeArrayRef(PEWindowsSubsystem));
    634   W.printFlags ("Characteristics", Hdr->DLLCharacteristics,
    635                 makeArrayRef(PEDLLCharacteristics));
    636   W.printNumber("SizeOfStackReserve", Hdr->SizeOfStackReserve);
    637   W.printNumber("SizeOfStackCommit", Hdr->SizeOfStackCommit);
    638   W.printNumber("SizeOfHeapReserve", Hdr->SizeOfHeapReserve);
    639   W.printNumber("SizeOfHeapCommit", Hdr->SizeOfHeapCommit);
    640   W.printNumber("NumberOfRvaAndSize", Hdr->NumberOfRvaAndSize);
    641 
    642   if (Hdr->NumberOfRvaAndSize > 0) {
    643     DictScope D(W, "DataDirectory");
    644     static const char * const directory[] = {
    645       "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable",
    646       "CertificateTable", "BaseRelocationTable", "Debug", "Architecture",
    647       "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT",
    648       "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved"
    649     };
    650 
    651     for (uint32_t i = 0; i < Hdr->NumberOfRvaAndSize; ++i)
    652       printDataDirectory(i, directory[i]);
    653   }
    654 }
    655 
    656 void COFFDumper::printCOFFDebugDirectory() {
    657   ListScope LS(W, "DebugDirectory");
    658   for (const debug_directory &D : Obj->debug_directories()) {
    659     char FormattedTime[20] = {};
    660     time_t TDS = D.TimeDateStamp;
    661     strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
    662     DictScope S(W, "DebugEntry");
    663     W.printHex("Characteristics", D.Characteristics);
    664     W.printHex("TimeDateStamp", FormattedTime, D.TimeDateStamp);
    665     W.printHex("MajorVersion", D.MajorVersion);
    666     W.printHex("MinorVersion", D.MinorVersion);
    667     W.printEnum("Type", D.Type, makeArrayRef(ImageDebugType));
    668     W.printHex("SizeOfData", D.SizeOfData);
    669     W.printHex("AddressOfRawData", D.AddressOfRawData);
    670     W.printHex("PointerToRawData", D.PointerToRawData);
    671     if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW) {
    672       const debug_pdb_info *PDBInfo;
    673       StringRef PDBFileName;
    674       error(Obj->getDebugPDBInfo(&D, PDBInfo, PDBFileName));
    675       DictScope PDBScope(W, "PDBInfo");
    676       W.printHex("PDBSignature", PDBInfo->Signature);
    677       W.printBinary("PDBGUID", makeArrayRef(PDBInfo->Guid));
    678       W.printNumber("PDBAge", PDBInfo->Age);
    679       W.printString("PDBFileName", PDBFileName);
    680     } else {
    681       // FIXME: Type values of 12 and 13 are commonly observed but are not in
    682       // the documented type enum.  Figure out what they mean.
    683       ArrayRef<uint8_t> RawData;
    684       error(
    685           Obj->getRvaAndSizeAsBytes(D.AddressOfRawData, D.SizeOfData, RawData));
    686       W.printBinaryBlock("RawData", RawData);
    687     }
    688   }
    689 }
    690 
    691 void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) {
    692   W.printHex("BaseOfData", Hdr->BaseOfData);
    693 }
    694 
    695 void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}
    696 
    697 void COFFDumper::printCodeViewDebugInfo() {
    698   // Print types first to build CVUDTNames, then print symbols.
    699   for (const SectionRef &S : Obj->sections()) {
    700     StringRef SectionName;
    701     error(S.getName(SectionName));
    702     if (SectionName == ".debug$T")
    703       printCodeViewTypeSection(SectionName, S);
    704   }
    705   for (const SectionRef &S : Obj->sections()) {
    706     StringRef SectionName;
    707     error(S.getName(SectionName));
    708     if (SectionName == ".debug$S")
    709       printCodeViewSymbolSection(SectionName, S);
    710   }
    711 }
    712 
    713 void COFFDumper::initializeFileAndStringTables(StringRef Data) {
    714   while (!Data.empty() && (CVFileChecksumTable.data() == nullptr ||
    715                            CVStringTable.data() == nullptr)) {
    716     // The section consists of a number of subsection in the following format:
    717     // |SubSectionType|SubSectionSize|Contents...|
    718     uint32_t SubType, SubSectionSize;
    719     error(consume(Data, SubType));
    720     error(consume(Data, SubSectionSize));
    721     if (SubSectionSize > Data.size())
    722       return error(object_error::parse_failed);
    723     switch (ModuleSubstreamKind(SubType)) {
    724     case ModuleSubstreamKind::FileChecksums:
    725       CVFileChecksumTable = Data.substr(0, SubSectionSize);
    726       break;
    727     case ModuleSubstreamKind::StringTable:
    728       CVStringTable = Data.substr(0, SubSectionSize);
    729       break;
    730     default:
    731       break;
    732     }
    733     uint32_t PaddedSize = alignTo(SubSectionSize, 4);
    734     if (PaddedSize > Data.size())
    735       error(object_error::parse_failed);
    736     Data = Data.drop_front(PaddedSize);
    737   }
    738 }
    739 
    740 void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
    741                                             const SectionRef &Section) {
    742   StringRef SectionContents;
    743   error(Section.getContents(SectionContents));
    744   StringRef Data = SectionContents;
    745 
    746   SmallVector<StringRef, 10> FunctionNames;
    747   StringMap<StringRef> FunctionLineTables;
    748 
    749   ListScope D(W, "CodeViewDebugInfo");
    750   // Print the section to allow correlation with printSections.
    751   W.printNumber("Section", SectionName, Obj->getSectionID(Section));
    752 
    753   uint32_t Magic;
    754   error(consume(Data, Magic));
    755   W.printHex("Magic", Magic);
    756   if (Magic != COFF::DEBUG_SECTION_MAGIC)
    757     return error(object_error::parse_failed);
    758 
    759   initializeFileAndStringTables(Data);
    760 
    761   // TODO: Convert this over to using ModuleSubstreamVisitor.
    762   while (!Data.empty()) {
    763     // The section consists of a number of subsection in the following format:
    764     // |SubSectionType|SubSectionSize|Contents...|
    765     uint32_t SubType, SubSectionSize;
    766     error(consume(Data, SubType));
    767     error(consume(Data, SubSectionSize));
    768 
    769     ListScope S(W, "Subsection");
    770     W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes));
    771     W.printHex("SubSectionSize", SubSectionSize);
    772 
    773     // Get the contents of the subsection.
    774     if (SubSectionSize > Data.size())
    775       return error(object_error::parse_failed);
    776     StringRef Contents = Data.substr(0, SubSectionSize);
    777 
    778     // Add SubSectionSize to the current offset and align that offset to find
    779     // the next subsection.
    780     size_t SectionOffset = Data.data() - SectionContents.data();
    781     size_t NextOffset = SectionOffset + SubSectionSize;
    782     NextOffset = alignTo(NextOffset, 4);
    783     if (NextOffset > SectionContents.size())
    784       return error(object_error::parse_failed);
    785     Data = SectionContents.drop_front(NextOffset);
    786 
    787     // Optionally print the subsection bytes in case our parsing gets confused
    788     // later.
    789     if (opts::CodeViewSubsectionBytes)
    790       printBinaryBlockWithRelocs("SubSectionContents", Section, SectionContents,
    791                                  Contents);
    792 
    793     switch (ModuleSubstreamKind(SubType)) {
    794     case ModuleSubstreamKind::Symbols:
    795       printCodeViewSymbolsSubsection(Contents, Section, SectionContents);
    796       break;
    797 
    798     case ModuleSubstreamKind::InlineeLines:
    799       printCodeViewInlineeLines(Contents);
    800       break;
    801 
    802     case ModuleSubstreamKind::FileChecksums:
    803       printCodeViewFileChecksums(Contents);
    804       break;
    805 
    806     case ModuleSubstreamKind::Lines: {
    807       // Holds a PC to file:line table.  Some data to parse this subsection is
    808       // stored in the other subsections, so just check sanity and store the
    809       // pointers for deferred processing.
    810 
    811       if (SubSectionSize < 12) {
    812         // There should be at least three words to store two function
    813         // relocations and size of the code.
    814         error(object_error::parse_failed);
    815         return;
    816       }
    817 
    818       StringRef LinkageName;
    819       error(resolveSymbolName(Obj->getCOFFSection(Section), SectionOffset,
    820                               LinkageName));
    821       W.printString("LinkageName", LinkageName);
    822       if (FunctionLineTables.count(LinkageName) != 0) {
    823         // Saw debug info for this function already?
    824         error(object_error::parse_failed);
    825         return;
    826       }
    827 
    828       FunctionLineTables[LinkageName] = Contents;
    829       FunctionNames.push_back(LinkageName);
    830       break;
    831     }
    832     case ModuleSubstreamKind::FrameData: {
    833       // First four bytes is a relocation against the function.
    834       const uint32_t *CodePtr;
    835       error(consumeObject(Contents, CodePtr));
    836       StringRef LinkageName;
    837       error(resolveSymbolName(Obj->getCOFFSection(Section), SectionContents,
    838                               CodePtr, LinkageName));
    839       W.printString("LinkageName", LinkageName);
    840 
    841       // To find the active frame description, search this array for the
    842       // smallest PC range that includes the current PC.
    843       while (!Contents.empty()) {
    844         const FrameData *FD;
    845         error(consumeObject(Contents, FD));
    846 
    847         if (FD->FrameFunc >= CVStringTable.size())
    848           error(object_error::parse_failed);
    849 
    850         StringRef FrameFunc =
    851             CVStringTable.drop_front(FD->FrameFunc).split('\0').first;
    852 
    853         DictScope S(W, "FrameData");
    854         W.printHex("RvaStart", FD->RvaStart);
    855         W.printHex("CodeSize", FD->CodeSize);
    856         W.printHex("LocalSize", FD->LocalSize);
    857         W.printHex("ParamsSize", FD->ParamsSize);
    858         W.printHex("MaxStackSize", FD->MaxStackSize);
    859         W.printString("FrameFunc", FrameFunc);
    860         W.printHex("PrologSize", FD->PrologSize);
    861         W.printHex("SavedRegsSize", FD->SavedRegsSize);
    862         W.printFlags("Flags", FD->Flags, makeArrayRef(FrameDataFlags));
    863       }
    864       break;
    865     }
    866 
    867     // Do nothing for unrecognized subsections.
    868     default:
    869       break;
    870     }
    871     W.flush();
    872   }
    873 
    874   // Dump the line tables now that we've read all the subsections and know all
    875   // the required information.
    876   for (unsigned I = 0, E = FunctionNames.size(); I != E; ++I) {
    877     StringRef Name = FunctionNames[I];
    878     ListScope S(W, "FunctionLineTable");
    879     W.printString("LinkageName", Name);
    880 
    881     DataExtractor DE(FunctionLineTables[Name], true, 4);
    882     uint32_t Offset = 6;  // Skip relocations.
    883     uint16_t Flags = DE.getU16(&Offset);
    884     W.printHex("Flags", Flags);
    885     bool HasColumnInformation = Flags & codeview::LineFlags::HaveColumns;
    886     uint32_t FunctionSize = DE.getU32(&Offset);
    887     W.printHex("CodeSize", FunctionSize);
    888     while (DE.isValidOffset(Offset)) {
    889       // For each range of lines with the same filename, we have a segment
    890       // in the line table.  The filename string is accessed using double
    891       // indirection to the string table subsection using the index subsection.
    892       uint32_t OffsetInIndex = DE.getU32(&Offset),
    893                NumLines = DE.getU32(&Offset),
    894                FullSegmentSize = DE.getU32(&Offset);
    895 
    896       uint32_t ColumnOffset = Offset + 8 * NumLines;
    897       DataExtractor ColumnDE(DE.getData(), true, 4);
    898 
    899       if (FullSegmentSize !=
    900           12 + 8 * NumLines + (HasColumnInformation ? 4 * NumLines : 0)) {
    901         error(object_error::parse_failed);
    902         return;
    903       }
    904 
    905       ListScope S(W, "FilenameSegment");
    906       printFileNameForOffset("Filename", OffsetInIndex);
    907       for (unsigned LineIdx = 0;
    908            LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) {
    909         // Then go the (PC, LineNumber) pairs.  The line number is stored in the
    910         // least significant 31 bits of the respective word in the table.
    911         uint32_t PC = DE.getU32(&Offset), LineData = DE.getU32(&Offset);
    912         if (PC >= FunctionSize) {
    913           error(object_error::parse_failed);
    914           return;
    915         }
    916         char Buffer[32];
    917         format("+0x%X", PC).snprint(Buffer, 32);
    918         ListScope PCScope(W, Buffer);
    919         LineInfo LI(LineData);
    920         if (LI.isAlwaysStepInto())
    921           W.printString("StepInto", StringRef("Always"));
    922         else if (LI.isNeverStepInto())
    923           W.printString("StepInto", StringRef("Never"));
    924         else
    925           W.printNumber("LineNumberStart", LI.getStartLine());
    926         W.printNumber("LineNumberEndDelta", LI.getLineDelta());
    927         W.printBoolean("IsStatement", LI.isStatement());
    928         if (HasColumnInformation &&
    929             ColumnDE.isValidOffsetForDataOfSize(ColumnOffset, 4)) {
    930           uint16_t ColStart = ColumnDE.getU16(&ColumnOffset);
    931           W.printNumber("ColStart", ColStart);
    932           uint16_t ColEnd = ColumnDE.getU16(&ColumnOffset);
    933           W.printNumber("ColEnd", ColEnd);
    934         }
    935       }
    936       // Skip over the column data.
    937       if (HasColumnInformation) {
    938         for (unsigned LineIdx = 0;
    939              LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) {
    940           DE.getU32(&Offset);
    941         }
    942       }
    943     }
    944   }
    945 }
    946 
    947 void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
    948                                                 const SectionRef &Section,
    949                                                 StringRef SectionContents) {
    950   ArrayRef<uint8_t> BinaryData(Subsection.bytes_begin(),
    951                                Subsection.bytes_end());
    952   auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
    953                                                         SectionContents);
    954 
    955   CVSymbolDumper CVSD(W, CVTD, std::move(CODD), opts::CodeViewSubsectionBytes);
    956   ByteStream<> Stream(BinaryData);
    957   CVSymbolArray Symbols;
    958   StreamReader Reader(Stream);
    959   if (auto EC = Reader.readArray(Symbols, Reader.getLength())) {
    960     consumeError(std::move(EC));
    961     W.flush();
    962     error(object_error::parse_failed);
    963   }
    964 
    965   if (!CVSD.dump(Symbols)) {
    966     W.flush();
    967     error(object_error::parse_failed);
    968   }
    969   W.flush();
    970 }
    971 
    972 void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
    973   StringRef Data = Subsection;
    974   while (!Data.empty()) {
    975     DictScope S(W, "FileChecksum");
    976     const FileChecksum *FC;
    977     error(consumeObject(Data, FC));
    978     if (FC->FileNameOffset >= CVStringTable.size())
    979       error(object_error::parse_failed);
    980     StringRef Filename =
    981         CVStringTable.drop_front(FC->FileNameOffset).split('\0').first;
    982     W.printHex("Filename", Filename, FC->FileNameOffset);
    983     W.printHex("ChecksumSize", FC->ChecksumSize);
    984     W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind),
    985                 makeArrayRef(FileChecksumKindNames));
    986     if (FC->ChecksumSize >= Data.size())
    987       error(object_error::parse_failed);
    988     StringRef ChecksumBytes = Data.substr(0, FC->ChecksumSize);
    989     W.printBinary("ChecksumBytes", ChecksumBytes);
    990     unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) -
    991                           sizeof(FileChecksum);
    992     if (PaddedSize > Data.size())
    993       error(object_error::parse_failed);
    994     Data = Data.drop_front(PaddedSize);
    995   }
    996 }
    997 
    998 void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
    999   StringRef Data = Subsection;
   1000   uint32_t Signature;
   1001   error(consume(Data, Signature));
   1002   bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles);
   1003 
   1004   while (!Data.empty()) {
   1005     const InlineeSourceLine *ISL;
   1006     error(consumeObject(Data, ISL));
   1007     DictScope S(W, "InlineeSourceLine");
   1008     printTypeIndex("Inlinee", ISL->Inlinee);
   1009     printFileNameForOffset("FileID", ISL->FileID);
   1010     W.printNumber("SourceLineNum", ISL->SourceLineNum);
   1011 
   1012     if (HasExtraFiles) {
   1013       uint32_t ExtraFileCount;
   1014       error(consume(Data, ExtraFileCount));
   1015       W.printNumber("ExtraFileCount", ExtraFileCount);
   1016       ListScope ExtraFiles(W, "ExtraFiles");
   1017       for (unsigned I = 0; I < ExtraFileCount; ++I) {
   1018         uint32_t FileID;
   1019         error(consume(Data, FileID));
   1020         printFileNameForOffset("FileID", FileID);
   1021       }
   1022     }
   1023   }
   1024 }
   1025 
   1026 StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) {
   1027   // The file checksum subsection should precede all references to it.
   1028   if (!CVFileChecksumTable.data() || !CVStringTable.data())
   1029     error(object_error::parse_failed);
   1030   // Check if the file checksum table offset is valid.
   1031   if (FileOffset >= CVFileChecksumTable.size())
   1032     error(object_error::parse_failed);
   1033 
   1034   // The string table offset comes first before the file checksum.
   1035   StringRef Data = CVFileChecksumTable.drop_front(FileOffset);
   1036   uint32_t StringOffset;
   1037   error(consume(Data, StringOffset));
   1038 
   1039   // Check if the string table offset is valid.
   1040   if (StringOffset >= CVStringTable.size())
   1041     error(object_error::parse_failed);
   1042 
   1043   // Return the null-terminated string.
   1044   return CVStringTable.drop_front(StringOffset).split('\0').first;
   1045 }
   1046 
   1047 void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) {
   1048   W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset);
   1049 }
   1050 
   1051 void COFFDumper::mergeCodeViewTypes(MemoryTypeTableBuilder &CVTypes) {
   1052   for (const SectionRef &S : Obj->sections()) {
   1053     StringRef SectionName;
   1054     error(S.getName(SectionName));
   1055     if (SectionName == ".debug$T") {
   1056       StringRef Data;
   1057       error(S.getContents(Data));
   1058       uint32_t Magic;
   1059       error(consume(Data, Magic));
   1060       if (Magic != 4)
   1061         error(object_error::parse_failed);
   1062       ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
   1063                               Data.size());
   1064       ByteStream<> Stream(Bytes);
   1065       CVTypeArray Types;
   1066       StreamReader Reader(Stream);
   1067       if (auto EC = Reader.readArray(Types, Reader.getLength())) {
   1068         consumeError(std::move(EC));
   1069         W.flush();
   1070         error(object_error::parse_failed);
   1071       }
   1072 
   1073       if (!mergeTypeStreams(CVTypes, Types))
   1074         return error(object_error::parse_failed);
   1075     }
   1076   }
   1077 }
   1078 
   1079 void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
   1080                                           const SectionRef &Section) {
   1081   ListScope D(W, "CodeViewTypes");
   1082   W.printNumber("Section", SectionName, Obj->getSectionID(Section));
   1083 
   1084   StringRef Data;
   1085   error(Section.getContents(Data));
   1086   if (opts::CodeViewSubsectionBytes)
   1087     W.printBinaryBlock("Data", Data);
   1088 
   1089   uint32_t Magic;
   1090   error(consume(Data, Magic));
   1091   W.printHex("Magic", Magic);
   1092   if (Magic != COFF::DEBUG_SECTION_MAGIC)
   1093     return error(object_error::parse_failed);
   1094 
   1095   if (auto EC = CVTD.dump({Data.bytes_begin(), Data.bytes_end()})) {
   1096     W.flush();
   1097     error(llvm::errorToErrorCode(std::move(EC)));
   1098   }
   1099 }
   1100 
   1101 void COFFDumper::printSections() {
   1102   ListScope SectionsD(W, "Sections");
   1103   int SectionNumber = 0;
   1104   for (const SectionRef &Sec : Obj->sections()) {
   1105     ++SectionNumber;
   1106     const coff_section *Section = Obj->getCOFFSection(Sec);
   1107 
   1108     StringRef Name;
   1109     error(Sec.getName(Name));
   1110 
   1111     DictScope D(W, "Section");
   1112     W.printNumber("Number", SectionNumber);
   1113     W.printBinary("Name", Name, Section->Name);
   1114     W.printHex   ("VirtualSize", Section->VirtualSize);
   1115     W.printHex   ("VirtualAddress", Section->VirtualAddress);
   1116     W.printNumber("RawDataSize", Section->SizeOfRawData);
   1117     W.printHex   ("PointerToRawData", Section->PointerToRawData);
   1118     W.printHex   ("PointerToRelocations", Section->PointerToRelocations);
   1119     W.printHex   ("PointerToLineNumbers", Section->PointerToLinenumbers);
   1120     W.printNumber("RelocationCount", Section->NumberOfRelocations);
   1121     W.printNumber("LineNumberCount", Section->NumberOfLinenumbers);
   1122     W.printFlags ("Characteristics", Section->Characteristics,
   1123                     makeArrayRef(ImageSectionCharacteristics),
   1124                     COFF::SectionCharacteristics(0x00F00000));
   1125 
   1126     if (opts::SectionRelocations) {
   1127       ListScope D(W, "Relocations");
   1128       for (const RelocationRef &Reloc : Sec.relocations())
   1129         printRelocation(Sec, Reloc);
   1130     }
   1131 
   1132     if (opts::SectionSymbols) {
   1133       ListScope D(W, "Symbols");
   1134       for (const SymbolRef &Symbol : Obj->symbols()) {
   1135         if (!Sec.containsSymbol(Symbol))
   1136           continue;
   1137 
   1138         printSymbol(Symbol);
   1139       }
   1140     }
   1141 
   1142     if (opts::SectionData &&
   1143         !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
   1144       StringRef Data;
   1145       error(Sec.getContents(Data));
   1146 
   1147       W.printBinaryBlock("SectionData", Data);
   1148     }
   1149   }
   1150 }
   1151 
   1152 void COFFDumper::printRelocations() {
   1153   ListScope D(W, "Relocations");
   1154 
   1155   int SectionNumber = 0;
   1156   for (const SectionRef &Section : Obj->sections()) {
   1157     ++SectionNumber;
   1158     StringRef Name;
   1159     error(Section.getName(Name));
   1160 
   1161     bool PrintedGroup = false;
   1162     for (const RelocationRef &Reloc : Section.relocations()) {
   1163       if (!PrintedGroup) {
   1164         W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
   1165         W.indent();
   1166         PrintedGroup = true;
   1167       }
   1168 
   1169       printRelocation(Section, Reloc);
   1170     }
   1171 
   1172     if (PrintedGroup) {
   1173       W.unindent();
   1174       W.startLine() << "}\n";
   1175     }
   1176   }
   1177 }
   1178 
   1179 void COFFDumper::printRelocation(const SectionRef &Section,
   1180                                  const RelocationRef &Reloc, uint64_t Bias) {
   1181   uint64_t Offset = Reloc.getOffset() - Bias;
   1182   uint64_t RelocType = Reloc.getType();
   1183   SmallString<32> RelocName;
   1184   StringRef SymbolName;
   1185   Reloc.getTypeName(RelocName);
   1186   symbol_iterator Symbol = Reloc.getSymbol();
   1187   if (Symbol != Obj->symbol_end()) {
   1188     Expected<StringRef> SymbolNameOrErr = Symbol->getName();
   1189     error(errorToErrorCode(SymbolNameOrErr.takeError()));
   1190     SymbolName = *SymbolNameOrErr;
   1191   }
   1192 
   1193   if (opts::ExpandRelocs) {
   1194     DictScope Group(W, "Relocation");
   1195     W.printHex("Offset", Offset);
   1196     W.printNumber("Type", RelocName, RelocType);
   1197     W.printString("Symbol", SymbolName.empty() ? "-" : SymbolName);
   1198   } else {
   1199     raw_ostream& OS = W.startLine();
   1200     OS << W.hex(Offset)
   1201        << " " << RelocName
   1202        << " " << (SymbolName.empty() ? "-" : SymbolName)
   1203        << "\n";
   1204   }
   1205 }
   1206 
   1207 void COFFDumper::printSymbols() {
   1208   ListScope Group(W, "Symbols");
   1209 
   1210   for (const SymbolRef &Symbol : Obj->symbols())
   1211     printSymbol(Symbol);
   1212 }
   1213 
   1214 void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }
   1215 
   1216 static ErrorOr<StringRef>
   1217 getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber,
   1218                const coff_section *Section) {
   1219   if (Section) {
   1220     StringRef SectionName;
   1221     if (std::error_code EC = Obj->getSectionName(Section, SectionName))
   1222       return EC;
   1223     return SectionName;
   1224   }
   1225   if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
   1226     return StringRef("IMAGE_SYM_DEBUG");
   1227   if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE)
   1228     return StringRef("IMAGE_SYM_ABSOLUTE");
   1229   if (SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
   1230     return StringRef("IMAGE_SYM_UNDEFINED");
   1231   return StringRef("");
   1232 }
   1233 
   1234 void COFFDumper::printSymbol(const SymbolRef &Sym) {
   1235   DictScope D(W, "Symbol");
   1236 
   1237   COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym);
   1238   const coff_section *Section;
   1239   if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) {
   1240     W.startLine() << "Invalid section number: " << EC.message() << "\n";
   1241     W.flush();
   1242     return;
   1243   }
   1244 
   1245   StringRef SymbolName;
   1246   if (Obj->getSymbolName(Symbol, SymbolName))
   1247     SymbolName = "";
   1248 
   1249   StringRef SectionName = "";
   1250   ErrorOr<StringRef> Res =
   1251       getSectionName(Obj, Symbol.getSectionNumber(), Section);
   1252   if (Res)
   1253     SectionName = *Res;
   1254 
   1255   W.printString("Name", SymbolName);
   1256   W.printNumber("Value", Symbol.getValue());
   1257   W.printNumber("Section", SectionName, Symbol.getSectionNumber());
   1258   W.printEnum  ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType));
   1259   W.printEnum  ("ComplexType", Symbol.getComplexType(),
   1260                                                    makeArrayRef(ImageSymDType));
   1261   W.printEnum  ("StorageClass", Symbol.getStorageClass(),
   1262                                                    makeArrayRef(ImageSymClass));
   1263   W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols());
   1264 
   1265   for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) {
   1266     if (Symbol.isFunctionDefinition()) {
   1267       const coff_aux_function_definition *Aux;
   1268       error(getSymbolAuxData(Obj, Symbol, I, Aux));
   1269 
   1270       DictScope AS(W, "AuxFunctionDef");
   1271       W.printNumber("TagIndex", Aux->TagIndex);
   1272       W.printNumber("TotalSize", Aux->TotalSize);
   1273       W.printHex("PointerToLineNumber", Aux->PointerToLinenumber);
   1274       W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
   1275 
   1276     } else if (Symbol.isAnyUndefined()) {
   1277       const coff_aux_weak_external *Aux;
   1278       error(getSymbolAuxData(Obj, Symbol, I, Aux));
   1279 
   1280       ErrorOr<COFFSymbolRef> Linked = Obj->getSymbol(Aux->TagIndex);
   1281       StringRef LinkedName;
   1282       std::error_code EC = Linked.getError();
   1283       if (EC || (EC = Obj->getSymbolName(*Linked, LinkedName))) {
   1284         LinkedName = "";
   1285         error(EC);
   1286       }
   1287 
   1288       DictScope AS(W, "AuxWeakExternal");
   1289       W.printNumber("Linked", LinkedName, Aux->TagIndex);
   1290       W.printEnum  ("Search", Aux->Characteristics,
   1291                     makeArrayRef(WeakExternalCharacteristics));
   1292 
   1293     } else if (Symbol.isFileRecord()) {
   1294       const char *FileName;
   1295       error(getSymbolAuxData(Obj, Symbol, I, FileName));
   1296 
   1297       DictScope AS(W, "AuxFileRecord");
   1298 
   1299       StringRef Name(FileName, Symbol.getNumberOfAuxSymbols() *
   1300                                    Obj->getSymbolTableEntrySize());
   1301       W.printString("FileName", Name.rtrim(StringRef("\0", 1)));
   1302       break;
   1303     } else if (Symbol.isSectionDefinition()) {
   1304       const coff_aux_section_definition *Aux;
   1305       error(getSymbolAuxData(Obj, Symbol, I, Aux));
   1306 
   1307       int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj());
   1308 
   1309       DictScope AS(W, "AuxSectionDef");
   1310       W.printNumber("Length", Aux->Length);
   1311       W.printNumber("RelocationCount", Aux->NumberOfRelocations);
   1312       W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers);
   1313       W.printHex("Checksum", Aux->CheckSum);
   1314       W.printNumber("Number", AuxNumber);
   1315       W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));
   1316 
   1317       if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
   1318           && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
   1319         const coff_section *Assoc;
   1320         StringRef AssocName = "";
   1321         std::error_code EC = Obj->getSection(AuxNumber, Assoc);
   1322         ErrorOr<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc);
   1323         if (Res)
   1324           AssocName = *Res;
   1325         if (!EC)
   1326           EC = Res.getError();
   1327         if (EC) {
   1328           AssocName = "";
   1329           error(EC);
   1330         }
   1331 
   1332         W.printNumber("AssocSection", AssocName, AuxNumber);
   1333       }
   1334     } else if (Symbol.isCLRToken()) {
   1335       const coff_aux_clr_token *Aux;
   1336       error(getSymbolAuxData(Obj, Symbol, I, Aux));
   1337 
   1338       ErrorOr<COFFSymbolRef> ReferredSym =
   1339           Obj->getSymbol(Aux->SymbolTableIndex);
   1340       StringRef ReferredName;
   1341       std::error_code EC = ReferredSym.getError();
   1342       if (EC || (EC = Obj->getSymbolName(*ReferredSym, ReferredName))) {
   1343         ReferredName = "";
   1344         error(EC);
   1345       }
   1346 
   1347       DictScope AS(W, "AuxCLRToken");
   1348       W.printNumber("AuxType", Aux->AuxType);
   1349       W.printNumber("Reserved", Aux->Reserved);
   1350       W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex);
   1351 
   1352     } else {
   1353       W.startLine() << "<unhandled auxiliary record>\n";
   1354     }
   1355   }
   1356 }
   1357 
   1358 void COFFDumper::printUnwindInfo() {
   1359   ListScope D(W, "UnwindInformation");
   1360   switch (Obj->getMachine()) {
   1361   case COFF::IMAGE_FILE_MACHINE_AMD64: {
   1362     Win64EH::Dumper Dumper(W);
   1363     Win64EH::Dumper::SymbolResolver
   1364     Resolver = [](const object::coff_section *Section, uint64_t Offset,
   1365                   SymbolRef &Symbol, void *user_data) -> std::error_code {
   1366       COFFDumper *Dumper = reinterpret_cast<COFFDumper *>(user_data);
   1367       return Dumper->resolveSymbol(Section, Offset, Symbol);
   1368     };
   1369     Win64EH::Dumper::Context Ctx(*Obj, Resolver, this);
   1370     Dumper.printData(Ctx);
   1371     break;
   1372   }
   1373   case COFF::IMAGE_FILE_MACHINE_ARMNT: {
   1374     ARM::WinEH::Decoder Decoder(W);
   1375     Decoder.dumpProcedureData(*Obj);
   1376     break;
   1377   }
   1378   default:
   1379     W.printEnum("unsupported Image Machine", Obj->getMachine(),
   1380                 makeArrayRef(ImageFileMachineType));
   1381     break;
   1382   }
   1383 }
   1384 
   1385 void COFFDumper::printImportedSymbols(
   1386     iterator_range<imported_symbol_iterator> Range) {
   1387   for (const ImportedSymbolRef &I : Range) {
   1388     StringRef Sym;
   1389     error(I.getSymbolName(Sym));
   1390     uint16_t Ordinal;
   1391     error(I.getOrdinal(Ordinal));
   1392     W.printNumber("Symbol", Sym, Ordinal);
   1393   }
   1394 }
   1395 
   1396 void COFFDumper::printDelayImportedSymbols(
   1397     const DelayImportDirectoryEntryRef &I,
   1398     iterator_range<imported_symbol_iterator> Range) {
   1399   int Index = 0;
   1400   for (const ImportedSymbolRef &S : Range) {
   1401     DictScope Import(W, "Import");
   1402     StringRef Sym;
   1403     error(S.getSymbolName(Sym));
   1404     uint16_t Ordinal;
   1405     error(S.getOrdinal(Ordinal));
   1406     W.printNumber("Symbol", Sym, Ordinal);
   1407     uint64_t Addr;
   1408     error(I.getImportAddress(Index++, Addr));
   1409     W.printHex("Address", Addr);
   1410   }
   1411 }
   1412 
   1413 void COFFDumper::printCOFFImports() {
   1414   // Regular imports
   1415   for (const ImportDirectoryEntryRef &I : Obj->import_directories()) {
   1416     DictScope Import(W, "Import");
   1417     StringRef Name;
   1418     error(I.getName(Name));
   1419     W.printString("Name", Name);
   1420     uint32_t Addr;
   1421     error(I.getImportLookupTableRVA(Addr));
   1422     W.printHex("ImportLookupTableRVA", Addr);
   1423     error(I.getImportAddressTableRVA(Addr));
   1424     W.printHex("ImportAddressTableRVA", Addr);
   1425     printImportedSymbols(I.imported_symbols());
   1426   }
   1427 
   1428   // Delay imports
   1429   for (const DelayImportDirectoryEntryRef &I : Obj->delay_import_directories()) {
   1430     DictScope Import(W, "DelayImport");
   1431     StringRef Name;
   1432     error(I.getName(Name));
   1433     W.printString("Name", Name);
   1434     const delay_import_directory_table_entry *Table;
   1435     error(I.getDelayImportTable(Table));
   1436     W.printHex("Attributes", Table->Attributes);
   1437     W.printHex("ModuleHandle", Table->ModuleHandle);
   1438     W.printHex("ImportAddressTable", Table->DelayImportAddressTable);
   1439     W.printHex("ImportNameTable", Table->DelayImportNameTable);
   1440     W.printHex("BoundDelayImportTable", Table->BoundDelayImportTable);
   1441     W.printHex("UnloadDelayImportTable", Table->UnloadDelayImportTable);
   1442     printDelayImportedSymbols(I, I.imported_symbols());
   1443   }
   1444 }
   1445 
   1446 void COFFDumper::printCOFFExports() {
   1447   for (const ExportDirectoryEntryRef &E : Obj->export_directories()) {
   1448     DictScope Export(W, "Export");
   1449 
   1450     StringRef Name;
   1451     uint32_t Ordinal, RVA;
   1452 
   1453     error(E.getSymbolName(Name));
   1454     error(E.getOrdinal(Ordinal));
   1455     error(E.getExportRVA(RVA));
   1456 
   1457     W.printNumber("Ordinal", Ordinal);
   1458     W.printString("Name", Name);
   1459     W.printHex("RVA", RVA);
   1460   }
   1461 }
   1462 
   1463 void COFFDumper::printCOFFDirectives() {
   1464   for (const SectionRef &Section : Obj->sections()) {
   1465     StringRef Contents;
   1466     StringRef Name;
   1467 
   1468     error(Section.getName(Name));
   1469     if (Name != ".drectve")
   1470       continue;
   1471 
   1472     error(Section.getContents(Contents));
   1473 
   1474     W.printString("Directive(s)", Contents);
   1475   }
   1476 }
   1477 
   1478 static StringRef getBaseRelocTypeName(uint8_t Type) {
   1479   switch (Type) {
   1480   case COFF::IMAGE_REL_BASED_ABSOLUTE: return "ABSOLUTE";
   1481   case COFF::IMAGE_REL_BASED_HIGH: return "HIGH";
   1482   case COFF::IMAGE_REL_BASED_LOW: return "LOW";
   1483   case COFF::IMAGE_REL_BASED_HIGHLOW: return "HIGHLOW";
   1484   case COFF::IMAGE_REL_BASED_HIGHADJ: return "HIGHADJ";
   1485   case COFF::IMAGE_REL_BASED_ARM_MOV32T: return "ARM_MOV32(T)";
   1486   case COFF::IMAGE_REL_BASED_DIR64: return "DIR64";
   1487   default: return "unknown (" + llvm::utostr(Type) + ")";
   1488   }
   1489 }
   1490 
   1491 void COFFDumper::printCOFFBaseReloc() {
   1492   ListScope D(W, "BaseReloc");
   1493   for (const BaseRelocRef &I : Obj->base_relocs()) {
   1494     uint8_t Type;
   1495     uint32_t RVA;
   1496     error(I.getRVA(RVA));
   1497     error(I.getType(Type));
   1498     DictScope Import(W, "Entry");
   1499     W.printString("Type", getBaseRelocTypeName(Type));
   1500     W.printHex("Address", RVA);
   1501   }
   1502 }
   1503 
   1504 void COFFDumper::printStackMap() const {
   1505   object::SectionRef StackMapSection;
   1506   for (auto Sec : Obj->sections()) {
   1507     StringRef Name;
   1508     Sec.getName(Name);
   1509     if (Name == ".llvm_stackmaps") {
   1510       StackMapSection = Sec;
   1511       break;
   1512     }
   1513   }
   1514 
   1515   if (StackMapSection == object::SectionRef())
   1516     return;
   1517 
   1518   StringRef StackMapContents;
   1519   StackMapSection.getContents(StackMapContents);
   1520   ArrayRef<uint8_t> StackMapContentsArray(
   1521       reinterpret_cast<const uint8_t*>(StackMapContents.data()),
   1522       StackMapContents.size());
   1523 
   1524   if (Obj->isLittleEndian())
   1525     prettyPrintStackMap(
   1526                       llvm::outs(),
   1527                       StackMapV1Parser<support::little>(StackMapContentsArray));
   1528   else
   1529     prettyPrintStackMap(llvm::outs(),
   1530                         StackMapV1Parser<support::big>(StackMapContentsArray));
   1531 }
   1532 
   1533 void llvm::dumpCodeViewMergedTypes(
   1534     ScopedPrinter &Writer, llvm::codeview::MemoryTypeTableBuilder &CVTypes) {
   1535   // Flatten it first, then run our dumper on it.
   1536   ListScope S(Writer, "MergedTypeStream");
   1537   SmallString<0> Buf;
   1538   CVTypes.ForEachRecord([&](TypeIndex TI, StringRef Record) {
   1539     Buf.append(Record.begin(), Record.end());
   1540   });
   1541   CVTypeDumper CVTD(&Writer, opts::CodeViewSubsectionBytes);
   1542   if (auto EC = CVTD.dump({Buf.str().bytes_begin(), Buf.str().bytes_end()})) {
   1543     Writer.flush();
   1544     error(llvm::errorToErrorCode(std::move(EC)));
   1545   }
   1546 }
   1547