forked from OSchip/llvm-project
[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. llvm-svn: 305979
This commit is contained in:
parent
ef5817579b
commit
b7d716c06f
|
@ -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;
|
||||
|
|
|
@ -650,6 +650,23 @@ std::error_code COFFObjectFile::initDebugDirectoryPtr() {
|
|||
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(MemoryBufferRef Object, std::error_code &EC)
|
|||
if ((EC = initDebugDirectoryPtr()))
|
||||
return;
|
||||
|
||||
if ((EC = initLoadConfigPtr()))
|
||||
return;
|
||||
|
||||
EC = std::error_code();
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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: ]
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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 *Obj) {
|
|||
Dumper->printCOFFDebugDirectory();
|
||||
if (opts::COFFResources)
|
||||
Dumper->printCOFFResources();
|
||||
if (opts::COFFLoadConfig)
|
||||
Dumper->printCOFFLoadConfig();
|
||||
if (opts::CodeView)
|
||||
Dumper->printCodeViewDebugInfo();
|
||||
if (opts::CodeViewMergedTypes)
|
||||
|
|
Loading…
Reference in New Issue