[llvm] r305979 - [llvm-readobj] Dump the COFF image load config

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 21 18:10:30 PDT 2017


Author: rnk
Date: Wed Jun 21 20:10:29 2017
New Revision: 305979

URL: http://llvm.org/viewvc/llvm-project?rev=305979&view=rev
Log:
[llvm-readobj] Dump the COFF image load config

This includes the safe SEH tables and the control flow guard function
table. LLD will emit the guard table soon, and I need a tool that dumps
them for testing.

Added:
    llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x64.dll   (with props)
    llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x86.dll   (with props)
    llvm/trunk/test/tools/llvm-readobj/coff-load-config.test
Modified:
    llvm/trunk/include/llvm/Object/COFF.h
    llvm/trunk/lib/Object/COFFObjectFile.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/tools/llvm-readobj/ObjDumper.h
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp

Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=305979&r1=305978&r2=305979&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Wed Jun 21 20:10:29 2017
@@ -562,8 +562,26 @@ struct coff_tls_directory {
 using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
 using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
 
+/// Bits in control flow guard flags as we understand them.
+enum class coff_guard_flags : uint32_t {
+  CFInstrumented = 0x00000100,
+  HasFidTable = 0x00000400,
+  ProtectDelayLoadIAT = 0x00001000,
+  DelayLoadIATSection = 0x00002000, // Delay load in separate section
+  HasLongJmpTable = 0x00010000,
+  FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
+};
+
+struct coff_load_config_code_integrity {
+  support::ulittle16_t Flags;
+  support::ulittle16_t Catalog;
+  support::ulittle32_t CatalogOffset;
+  support::ulittle32_t Reserved;
+};
+
+/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
 struct coff_load_configuration32 {
-  support::ulittle32_t Characteristics;
+  support::ulittle32_t Size;
   support::ulittle32_t TimeDateStamp;
   support::ulittle16_t MajorVersion;
   support::ulittle16_t MinorVersion;
@@ -578,34 +596,81 @@ struct coff_load_configuration32 {
   support::ulittle32_t ProcessAffinityMask;
   support::ulittle32_t ProcessHeapFlags;
   support::ulittle16_t CSDVersion;
-  support::ulittle16_t Reserved;
+  support::ulittle16_t DependentLoadFlags;
   support::ulittle32_t EditList;
   support::ulittle32_t SecurityCookie;
   support::ulittle32_t SEHandlerTable;
   support::ulittle32_t SEHandlerCount;
+
+  // Added in MSVC 2015 for /guard:cf.
+  support::ulittle32_t GuardCFCheckFunction;
+  support::ulittle32_t GuardCFCheckDispatch;
+  support::ulittle32_t GuardCFFunctionTable;
+  support::ulittle32_t GuardCFFunctionCount;
+  support::ulittle32_t GuardFlags; // coff_guard_flags
+
+  // Added in MSVC 2017
+  coff_load_config_code_integrity CodeIntegrity;
+  support::ulittle32_t GuardAddressTakenIatEntryTable;
+  support::ulittle32_t GuardAddressTakenIatEntryCount;
+  support::ulittle32_t GuardLongJumpTargetTable;
+  support::ulittle32_t GuardLongJumpTargetCount;
+  support::ulittle32_t DynamicValueRelocTable;
+  support::ulittle32_t CHPEMetadataPointer;
+  support::ulittle32_t GuardRFFailureRoutine;
+  support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
+  support::ulittle32_t DynamicValueRelocTableOffset;
+  support::ulittle16_t DynamicValueRelocTableSection;
+  support::ulittle16_t Reserved2;
+  support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
+  support::ulittle32_t HotPatchTableOffset;
 };
 
+/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
 struct coff_load_configuration64 {
-  support::ulittle32_t Characteristics;
+  support::ulittle32_t Size;
   support::ulittle32_t TimeDateStamp;
   support::ulittle16_t MajorVersion;
   support::ulittle16_t MinorVersion;
   support::ulittle32_t GlobalFlagsClear;
   support::ulittle32_t GlobalFlagsSet;
   support::ulittle32_t CriticalSectionDefaultTimeout;
-  support::ulittle32_t DeCommitFreeBlockThreshold;
-  support::ulittle32_t DeCommitTotalFreeThreshold;
-  support::ulittle32_t LockPrefixTable;
-  support::ulittle32_t MaximumAllocationSize;
-  support::ulittle32_t VirtualMemoryThreshold;
-  support::ulittle32_t ProcessAffinityMask;
+  support::ulittle64_t DeCommitFreeBlockThreshold;
+  support::ulittle64_t DeCommitTotalFreeThreshold;
+  support::ulittle64_t LockPrefixTable;
+  support::ulittle64_t MaximumAllocationSize;
+  support::ulittle64_t VirtualMemoryThreshold;
+  support::ulittle64_t ProcessAffinityMask;
   support::ulittle32_t ProcessHeapFlags;
   support::ulittle16_t CSDVersion;
-  support::ulittle16_t Reserved;
-  support::ulittle32_t EditList;
+  support::ulittle16_t DependentLoadFlags;
+  support::ulittle64_t EditList;
   support::ulittle64_t SecurityCookie;
   support::ulittle64_t SEHandlerTable;
   support::ulittle64_t SEHandlerCount;
+
+  // Added in MSVC 2015 for /guard:cf.
+  support::ulittle64_t GuardCFCheckFunction;
+  support::ulittle64_t GuardCFCheckDispatch;
+  support::ulittle64_t GuardCFFunctionTable;
+  support::ulittle64_t GuardCFFunctionCount;
+  support::ulittle32_t GuardFlags;
+
+  // Added in MSVC 2017
+  coff_load_config_code_integrity CodeIntegrity;
+  support::ulittle64_t GuardAddressTakenIatEntryTable;
+  support::ulittle64_t GuardAddressTakenIatEntryCount;
+  support::ulittle64_t GuardLongJumpTargetTable;
+  support::ulittle64_t GuardLongJumpTargetCount;
+  support::ulittle64_t DynamicValueRelocTable;
+  support::ulittle64_t CHPEMetadataPointer;
+  support::ulittle64_t GuardRFFailureRoutine;
+  support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
+  support::ulittle32_t DynamicValueRelocTableOffset;
+  support::ulittle16_t DynamicValueRelocTableSection;
+  support::ulittle16_t Reserved2;
+  support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
+  support::ulittle32_t HotPatchTableOffset;
 };
 
 struct coff_runtime_function_x64 {
@@ -684,6 +749,8 @@ private:
   const coff_base_reloc_block_header *BaseRelocEnd;
   const debug_directory *DebugDirectoryBegin;
   const debug_directory *DebugDirectoryEnd;
+  // Either coff_load_configuration32 or coff_load_configuration64.
+  const void *LoadConfig;
 
   std::error_code getString(uint32_t offset, StringRef &Res) const;
 
@@ -698,6 +765,7 @@ private:
   std::error_code initExportTablePtr();
   std::error_code initBaseRelocPtr();
   std::error_code initDebugDirectoryPtr();
+  std::error_code initLoadConfigPtr();
 
 public:
   uintptr_t getSymbolTable() const {
@@ -775,6 +843,16 @@ public:
     return getRawNumberOfSymbols();
   }
 
+  const coff_load_configuration32 *getLoadConfig32() const {
+    assert(!is64());
+    return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
+  }
+
+  const coff_load_configuration64 *getLoadConfig64() const {
+    assert(is64());
+    return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
+  }
+
 protected:
   void moveSymbolNext(DataRefImpl &Symb) const override;
   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;

Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=305979&r1=305978&r2=305979&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Wed Jun 21 20:10:29 2017
@@ -650,6 +650,23 @@ std::error_code COFFObjectFile::initDebu
   return std::error_code();
 }
 
+std::error_code COFFObjectFile::initLoadConfigPtr() {
+  // Get the RVA of the debug directory. Do nothing if it does not exist.
+  const data_directory *DataEntry;
+  if (getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataEntry))
+    return std::error_code();
+
+  // Do nothing if the RVA is NULL.
+  if (DataEntry->RelativeVirtualAddress == 0)
+    return std::error_code();
+  uintptr_t IntPtr = 0;
+  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+    return EC;
+
+  LoadConfig = (const void *)IntPtr;
+  return std::error_code();
+}
+
 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
     : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
       COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
@@ -784,6 +801,9 @@ COFFObjectFile::COFFObjectFile(MemoryBuf
   if ((EC = initDebugDirectoryPtr()))
     return;
 
+  if ((EC = initLoadConfigPtr()))
+    return;
+
   EC = std::error_code();
 }
 

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x64.dll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x64.dll?rev=305979&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x64.dll
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x86.dll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x86.dll?rev=305979&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/coff-load-config-x86.dll
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-readobj/coff-load-config.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/coff-load-config.test?rev=305979&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/coff-load-config.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/coff-load-config.test Wed Jun 21 20:10:29 2017
@@ -0,0 +1,87 @@
+RUN: llvm-readobj -coff-load-config %S/Inputs/coff-load-config-x86.dll | FileCheck %s --check-prefix=X86
+RUN: llvm-readobj -coff-load-config %S/Inputs/coff-load-config-x64.dll | FileCheck %s --check-prefix=X64
+
+X86: LoadConfig [
+X86:   Size: 0x5C
+X86:   TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+X86:   MajorVersion: 0x0
+X86:   MinorVersion: 0x0
+X86:   GlobalFlagsClear: 0x0
+X86:   GlobalFlagsSet: 0x0
+X86:   CriticalSectionDefaultTimeout: 0x0
+X86:   DeCommitFreeBlockThreshold: 0x0
+X86:   DeCommitTotalFreeThreshold: 0x0
+X86:   LockPrefixTable: 0x0
+X86:   MaximumAllocationSize: 0x0
+X86:   VirtualMemoryThreshold: 0x0
+X86:   ProcessHeapFlags: 0x0
+X86:   ProcessAffinityMask: 0x0
+X86:   CSDVersion: 0x0
+X86:   DependentLoadFlags: 0x0
+X86:   EditList: 0x0
+X86:   SecurityCookie: 0x10003004
+X86:   SEHandlerTable: 0x100021C0
+X86:   SEHandlerCount: 2
+X86:   GuardCFCheckFunction: 0x1000207C
+X86:   GuardCFCheckDispatch: 0x0
+X86:   GuardCFFunctionTable: 0x100020A4
+X86:   GuardCFFunctionCount: 11
+X86:   GuardFlags: 0x13500
+X86: ]
+X86: SEHTable [
+X86:   0x10001BE0
+X86:   0x10001E30
+X86: ]
+X86: GuardFidTable [
+X86:   0x10001000
+X86:   0x10001040
+X86:   0x10001060
+X86:   0x10001100
+X86:   0x10001120
+X86:   0x10001150
+X86:   0x10001460
+X86:   0x100019B0
+X86:   0x10001B40
+X86:   0x10001BE0
+X86:   0x10001DC0
+X86: ]
+
+X64: LoadConfig [
+X64:   Size: 0x94
+X64:   TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+X64:   MajorVersion: 0x0
+X64:   MinorVersion: 0x0
+X64:   GlobalFlagsClear: 0x0
+X64:   GlobalFlagsSet: 0x0
+X64:   CriticalSectionDefaultTimeout: 0x0
+X64:   DeCommitFreeBlockThreshold: 0x0
+X64:   DeCommitTotalFreeThreshold: 0x0
+X64:   LockPrefixTable: 0x0
+X64:   MaximumAllocationSize: 0x0
+X64:   VirtualMemoryThreshold: 0x0
+X64:   ProcessHeapFlags: 0x0
+X64:   ProcessAffinityMask: 0x0
+X64:   CSDVersion: 0x0
+X64:   DependentLoadFlags: 0x0
+X64:   EditList: 0x0
+X64:   SecurityCookie: 0x180003018
+X64:   SEHandlerTable: 0
+X64:   SEHandlerCount: 0
+X64:   GuardCFCheckFunction: 0x180002100
+X64:   GuardCFCheckDispatch: 0x180002108
+X64:   GuardCFFunctionTable: 0x180002158
+X64:   GuardCFFunctionCount: 9
+X64:   GuardFlags: 0x13500
+X64: ]
+X64-NOT: SEHTable
+X64: GuardFidTable [
+X64:   0x180001000
+X64:   0x180001050
+X64:   0x180001070
+X64:   0x1800010E0
+X64:   0x180001110
+X64:   0x180001460
+X64:   0x180001970
+X64:   0x180001B50
+X64:   0x180001D90
+X64: ]

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=305979&r1=305978&r2=305979&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Wed Jun 21 20:10:29 2017
@@ -68,6 +68,14 @@ using namespace llvm::Win64EH;
 
 namespace {
 
+struct LoadConfigTables {
+  uint64_t SEHTableVA = 0;
+  uint64_t SEHTableCount = 0;
+  uint32_t GuardFlags = 0;
+  uint64_t GuardFidTableVA = 0;
+  uint64_t GuardFidTableCount = 0;
+};
+
 class COFFDumper : public ObjDumper {
 public:
   friend class COFFObjectDumpDelegate;
@@ -86,6 +94,7 @@ public:
   void printCOFFBaseReloc() override;
   void printCOFFDebugDirectory() override;
   void printCOFFResources() override;
+  void printCOFFLoadConfig() override;
   void printCodeViewDebugInfo() override;
   void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs,
                           llvm::codeview::TypeTableBuilder &CVTypes) override;
@@ -100,6 +109,11 @@ private:
   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);
@@ -745,6 +759,125 @@ void COFFDumper::printCOFFDebugDirectory
   }
 }
 
+void COFFDumper::printRVATable(uint64_t TableVA, uint64_t Count,
+                               uint64_t EntrySize, PrintExtraCB PrintExtra) {
+  uintptr_t TableStart, TableEnd;
+  error(Obj->getVaPtr(TableVA, TableStart));
+  error(Obj->getVaPtr(TableVA + Count * EntrySize, 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 << "0x" << utohexstr(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);
+    }
+  }
+}
+
+template <typename T>
+void COFFDumper::printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables) {
+  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);
+}
+
 void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) {
   W.printHex("BaseOfData", Hdr->BaseOfData);
 }

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=305979&r1=305978&r2=305979&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Wed Jun 21 20:10:29 2017
@@ -68,6 +68,7 @@ public:
   virtual void printCOFFBaseReloc() { }
   virtual void printCOFFDebugDirectory() { }
   virtual void printCOFFResources() {}
+  virtual void printCOFFLoadConfig() { }
   virtual void printCodeViewDebugInfo() { }
   virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs,
                                   llvm::codeview::TypeTableBuilder &CVTypes) {}

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=305979&r1=305978&r2=305979&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Wed Jun 21 20:10:29 2017
@@ -218,6 +218,11 @@ namespace opts {
   cl::opt<bool> COFFResources("coff-resources",
                               cl::desc("Display the PE/COFF .rsrc section"));
 
+  // -coff-load-config
+  cl::opt<bool>
+  COFFLoadConfig("coff-load-config",
+                 cl::desc("Display the PE/COFF load config"));
+
   // -macho-data-in-code
   cl::opt<bool>
   MachODataInCode("macho-data-in-code",
@@ -444,6 +449,8 @@ static void dumpObject(const ObjectFile
       Dumper->printCOFFDebugDirectory();
     if (opts::COFFResources)
       Dumper->printCOFFResources();
+    if (opts::COFFLoadConfig)
+      Dumper->printCOFFLoadConfig();
     if (opts::CodeView)
       Dumper->printCodeViewDebugInfo();
     if (opts::CodeViewMergedTypes)




More information about the llvm-commits mailing list