[llvm-objdump] -p: Dump PE header for PE/COFF

For a trivial DLL built with `clang --target=x86_64-windows -O2 -c a.c; lld-link -subsystem:console -dll a.o -out:a.dll`,
`objdump -p` vs `llvm-objdump -p`:

```
-a.dll:     file format pei-x86-64
-
+a.dll: file format coff-x86-64
 Characteristics 0x2022
        executable
        large address aware
@@ -57,4 +56,4 @@
 Entry d 0000000000000000 00000000 Delay Import Directory
 Entry e 0000000000000000 00000000 CLR Runtime Header
 Entry f 0000000000000000 00000000 Reserved
-
+Export Table:
```

For a Linux image (`vmlinuz-5.10.76-gentoo-r1`) built with `CONFIG_EFI_STUB=y`

```
-vmlinuz-5.10.76-gentoo-r1:     file format pei-x86-64
-
-Characteristics 0x20e
+vmlinuz-5.10.76-gentoo-r1:     file format coff-x86-64
+Characteristics 0x206
        executable
        line numbers stripped
-       symbols stripped
        debugging information removed

 Time/Date              Wed Dec 31 16:00:00 1969
@@ -55,10 +53,4 @@
 Entry d 0000000000000000 00000000 Delay Import Directory
 Entry e 0000000000000000 00000000 CLR Runtime Header
 Entry f 0000000000000000 00000000 Reserved
-
-
-PE File Base Relocations (interpreted .reloc section contents)
-
-Virtual Address: 000037ca Chunk size 10 (0xa) Number of fixups 1
-       reloc    0 offset    0 [37ca] ABSOLUTE
-
+Export Table:
```

`symbols stripped` looks like a GNU objdump problem.

Reviewed By: jhenderson, alexander-shaposhnikov

Differential Revision: https://reviews.llvm.org/D113356
This commit is contained in:
Fangrui Song 2021-11-09 10:08:41 -08:00
parent ee88b8d63e
commit 5f1e509579
5 changed files with 379 additions and 8 deletions

View File

@ -0,0 +1,183 @@
# RUN: yaml2obj --docnum=1 %s -o %t
# RUN: llvm-objdump -p %t | FileCheck %s --check-prefix=PE32PLUS --strict-whitespace --match-full-lines
# PE32PLUS:{{.*}}file format coff-arm64
# PE32PLUS-NEXT:Characteristics 0x22
# PE32PLUS-NEXT: executable
# PE32PLUS-NEXT: large address aware
#PE32PLUS-EMPTY:
# PE32PLUS-NEXT:Time/Date {{.*}} 19{{69|70}}
# PE32PLUS-NEXT:Magic 020b (PE32+)
# PE32PLUS-NEXT:MajorLinkerVersion 0
# PE32PLUS-NEXT:MinorLinkerVersion 0
# PE32PLUS-NEXT:SizeOfCode 0000000000000200
# PE32PLUS-NEXT:SizeOfInitializedData 0000000000000400
# PE32PLUS-NEXT:SizeOfUninitializedData 0000000000000000
# PE32PLUS-NEXT:AddressOfEntryPoint 0000000000001000
# PE32PLUS-NEXT:BaseOfCode 0000000000001000
# PE32PLUS-NEXT:ImageBase 0000000140000000
# PE32PLUS-NEXT:SectionAlignment 00001000
# PE32PLUS-NEXT:FileAlignment 00000200
# PE32PLUS-NEXT:MajorOSystemVersion 6
# PE32PLUS-NEXT:MinorOSystemVersion 1
# PE32PLUS-NEXT:MajorImageVersion 7
# PE32PLUS-NEXT:MinorImageVersion 2
# PE32PLUS-NEXT:MajorSubsystemVersion 8
# PE32PLUS-NEXT:MinorSubsystemVersion 3
# PE32PLUS-NEXT:Win32Version 00000000
# PE32PLUS-NEXT:SizeOfImage 00004000
# PE32PLUS-NEXT:SizeOfHeaders 00000200
# PE32PLUS-NEXT:CheckSum 00000000
# PE32PLUS-NEXT:Subsystem 00000003 (Windows CUI)
# PE32PLUS-NEXT:DllCharacteristics 00008160
# PE32PLUS-NEXT: HIGH_ENTROPY_VA
# PE32PLUS-NEXT: DYNAMIC_BASE
# PE32PLUS-NEXT: NX_COMPAT
# PE32PLUS-NEXT: TERMINAL_SERVER_AWARE
# PE32PLUS-NEXT:SizeOfStackReserve 0000000000100000
# PE32PLUS-NEXT:SizeOfStackCommit 0000000000001000
# PE32PLUS-NEXT:SizeOfHeapReserve 0000000000100000
# PE32PLUS-NEXT:SizeOfHeapCommit 0000000000001000
# PE32PLUS-NEXT:LoaderFlags 00000000
# PE32PLUS-NEXT:NumberOfRvaAndSizes 00000010
#PE32PLUS-EMPTY:
# PE32PLUS-NEXT:The Data Directory
# PE32PLUS-NEXT:Entry 0 0000000000000000 00000000 Export Directory [.edata (or where ever we found it)]
# PE32PLUS-NEXT:Entry 1 0000000000000000 00000000 Import Directory [parts of .idata]
# PE32PLUS-NEXT:Entry 2 0000000000000000 00000000 Resource Directory [.rsrc]
# PE32PLUS-NEXT:Entry 3 0000000000003000 00000008 Exception Directory [.pdata]
# PE32PLUS-NEXT:Entry 4 0000000000000000 00000000 Security Directory
# PE32PLUS-NEXT:Entry 5 0000000000000000 00000000 Base Relocation Directory [.reloc]
# PE32PLUS-NEXT:Entry 6 0000000000000000 00000000 Debug Directory
# PE32PLUS-NEXT:Entry 7 0000000000000000 00000000 Description Directory
# PE32PLUS-NEXT:Entry 8 0000000000000000 00000000 Special Directory
# PE32PLUS-NEXT:Entry 9 0000000000000000 00000000 Thread Storage Directory [.tls]
# PE32PLUS-NEXT:Entry a 0000000000000000 00000000 Load Configuration Directory
# PE32PLUS-NEXT:Entry b 0000000000000000 00000000 Bound Import Directory
# PE32PLUS-NEXT:Entry c 0000000000000000 00000000 Import Address Table Directory
# PE32PLUS-NEXT:Entry d 0000000000000000 00000000 Delay Import Directory
# PE32PLUS-NEXT:Entry e 0000000000000000 00000000 CLR Runtime Header
# PE32PLUS-NEXT:Entry f 0000000000000000 00000000 Reserved
--- !COFF
OptionalHeader:
AddressOfEntryPoint: 4096
ImageBase: 0x140000000
SectionAlignment: 4096
FileAlignment: 512
MajorOperatingSystemVersion: 6
MinorOperatingSystemVersion: 1
MajorImageVersion: 7
MinorImageVersion: 2
MajorSubsystemVersion: 8
MinorSubsystemVersion: 3
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
SizeOfStackReserve: 1048576
SizeOfStackCommit: 4096
SizeOfHeapReserve: 1048576
SizeOfHeapCommit: 4096
ExceptionTable:
RelativeVirtualAddress: 12288
Size: 8
header:
Machine: IMAGE_FILE_MACHINE_ARM64
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
VirtualAddress: 4096
VirtualSize: 4
SectionData: C0035FD6
- Name: .rdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
VirtualAddress: 8192
VirtualSize: 12
SectionData: 0100400800000000E4E3E3E3
- Name: .pdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
VirtualAddress: 12288
VirtualSize: 8
SectionData: '0010000000200000'
symbols: []
...
## Test 32-bit object with full Characteristics and DllCharacteristics.
# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: llvm-objdump -p %t2 | FileCheck %s --check-prefix=PE32 --match-full-lines
# PE32:{{.*}}file format coff-i386
# PE32:Characteristics 0xffbf
# PE32-NEXT: relocations stripped
# PE32-NEXT: executable
# PE32-NEXT: line numbers stripped
# PE32-NEXT: symbols stripped
# PE32-NEXT: large address aware
# PE32-NEXT: little endian
# PE32-NEXT: 32 bit words
# PE32-NEXT: debugging information removed
# PE32-NEXT: copy to swap file if on removable media
# PE32-NEXT: copy to swap file if on network media
# PE32-NEXT: system file
# PE32-NEXT: DLL
# PE32-NEXT: run only on uniprocessor machine
# PE32-NEXT: big endian
#PE32-EMPTY:
# PE32:Time/Date {{.*}}
# PE32-NEXT:Magic 010b (PE32)
# PE32-NEXT:MajorLinkerVersion 0
# PE32-NEXT:MinorLinkerVersion 0
# PE32-NEXT:SizeOfCode 00000004
# PE32-NEXT:SizeOfInitializedData 00000000
# PE32-NEXT:SizeOfUninitializedData 00000000
# PE32-NEXT:AddressOfEntryPoint 00000000
# PE32-NEXT:BaseOfCode 00001000
# PE32-NEXT:BaseOfData 00000000
# PE32-NEXT:ImageBase 00000000
# PE32-NEXT:SectionAlignment 00000001
# PE32-NEXT:FileAlignment 00000001
# PE32-NEXT:MajorOSystemVersion 0
# PE32-NEXT:MinorOSystemVersion 0
# PE32-NEXT:MajorImageVersion 0
# PE32-NEXT:MinorImageVersion 0
# PE32-NEXT:MajorSubsystemVersion 0
# PE32-NEXT:MinorSubsystemVersion 0
# PE32-NEXT:Win32Version 00000000
# PE32-NEXT:SizeOfImage 000001a4
# PE32-NEXT:SizeOfHeaders 000001a0
# PE32-NEXT:CheckSum 00000000
# PE32-NEXT:Subsystem 0000000a (EFI application)
# PE32-NEXT:DllCharacteristics 0000ffe0
# PE32-NEXT: HIGH_ENTROPY_VA
# PE32-NEXT: DYNAMIC_BASE
# PE32-NEXT: FORCE_INTEGRITY
# PE32-NEXT: NX_COMPAT
# PE32-NEXT: NO_ISOLATION
# PE32-NEXT: NO_SEH
# PE32-NEXT: NO_BIND
# PE32-NEXT: APPCONTAINER
# PE32-NEXT: WDM_DRIVER
# PE32-NEXT: GUARD_CF
# PE32-NEXT: TERMINAL_SERVER_AWARE
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_I386
Characteristics: [ IMAGE_FILE_RELOCS_STRIPPED, IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LINE_NUMS_STRIPPED,
IMAGE_FILE_LOCAL_SYMS_STRIPPED, IMAGE_FILE_AGGRESSIVE_WS_TRIM, IMAGE_FILE_LARGE_ADDRESS_AWARE,
IMAGE_FILE_BYTES_REVERSED_LO, IMAGE_FILE_32BIT_MACHINE, IMAGE_FILE_DEBUG_STRIPPED,
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, IMAGE_FILE_NET_RUN_FROM_SWAP, IMAGE_FILE_SYSTEM,
IMAGE_FILE_DLL, IMAGE_FILE_UP_SYSTEM_ONLY, IMAGE_FILE_BYTES_REVERSED_HI ]
OptionalHeader:
Subsystem: IMAGE_SUBSYSTEM_EFI_APPLICATION
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT,
IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION, IMAGE_DLL_CHARACTERISTICS_NO_SEH,
IMAGE_DLL_CHARACTERISTICS_NO_BIND, IMAGE_DLL_CHARACTERISTICS_APPCONTAINER,
IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER, IMAGE_DLL_CHARACTERISTICS_GUARD_CF,
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
VirtualAddress: 4096
VirtualSize: 4
SectionData: C0035FD6
symbols:

View File

@ -31,6 +31,159 @@ using namespace llvm::objdump;
using namespace llvm::object;
using namespace llvm::Win64EH;
namespace {
template <typename T> struct EnumEntry {
T Value;
StringRef Name;
};
class COFFDumper {
public:
explicit COFFDumper(const llvm::object::COFFObjectFile &Obj) : Obj(Obj) {
Is64 = !Obj.getPE32Header();
}
template <class PEHeader> void printPEHeader(const PEHeader &Hdr) const;
private:
template <typename T> FormattedNumber formatAddr(T V) const {
return format_hex_no_prefix(V, Is64 ? 16 : 8);
};
uint32_t getBaseOfData(const void *Hdr) const {
return Is64 ? 0 : static_cast<const pe32_header *>(Hdr)->BaseOfData;
}
const llvm::object::COFFObjectFile &Obj;
bool Is64;
};
} // namespace
constexpr EnumEntry<uint16_t> PEHeaderMagic[] = {
{uint16_t(COFF::PE32Header::PE32), "PE32"},
{uint16_t(COFF::PE32Header::PE32_PLUS), "PE32+"},
};
constexpr EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = {
{COFF::IMAGE_SUBSYSTEM_UNKNOWN, "unspecified"},
{COFF::IMAGE_SUBSYSTEM_NATIVE, "NT native"},
{COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI, "Windows GUI"},
{COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, "Windows CUI"},
{COFF::IMAGE_SUBSYSTEM_POSIX_CUI, "POSIX CUI"},
{COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, "Wince CUI"},
{COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION, "EFI application"},
{COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, "EFI boot service driver"},
{COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, "EFI runtime driver"},
{COFF::IMAGE_SUBSYSTEM_EFI_ROM, "SAL runtime driver"},
{COFF::IMAGE_SUBSYSTEM_XBOX, "XBOX"},
};
template <typename T, typename TEnum>
static void printOptionalEnumName(T Value,
ArrayRef<EnumEntry<TEnum>> EnumValues) {
for (const EnumEntry<TEnum> &I : EnumValues)
if (I.Value == Value) {
outs() << "\t(" << I.Name << ')';
return;
}
}
template <class PEHeader>
void COFFDumper::printPEHeader(const PEHeader &Hdr) const {
auto print = [](const char *K, auto V, const char *Fmt = "%d\n") {
outs() << format("%-23s ", K) << format(Fmt, V);
};
auto printU16 = [&](const char *K, support::ulittle16_t V,
const char *Fmt = "%d\n") { print(K, uint16_t(V), Fmt); };
auto printU32 = [&](const char *K, support::ulittle32_t V,
const char *Fmt = "%d\n") { print(K, uint32_t(V), Fmt); };
auto printAddr = [=](const char *K, uint64_t V) {
outs() << format("%-23s ", K) << formatAddr(V) << '\n';
};
printU16("Magic", Hdr.Magic, "%04x");
printOptionalEnumName(Hdr.Magic, makeArrayRef(PEHeaderMagic));
outs() << '\n';
print("MajorLinkerVersion", Hdr.MajorLinkerVersion);
print("MinorLinkerVersion", Hdr.MinorLinkerVersion);
printAddr("SizeOfCode", Hdr.SizeOfCode);
printAddr("SizeOfInitializedData", Hdr.SizeOfInitializedData);
printAddr("SizeOfUninitializedData", Hdr.SizeOfUninitializedData);
printAddr("AddressOfEntryPoint", Hdr.AddressOfEntryPoint);
printAddr("BaseOfCode", Hdr.BaseOfCode);
if (!Is64)
printAddr("BaseOfData", getBaseOfData(&Hdr));
printAddr("ImageBase", Hdr.ImageBase);
printU32("SectionAlignment", Hdr.SectionAlignment, "%08x\n");
printU32("FileAlignment", Hdr.FileAlignment, "%08x\n");
printU16("MajorOSystemVersion", Hdr.MajorOperatingSystemVersion);
printU16("MinorOSystemVersion", Hdr.MinorOperatingSystemVersion);
printU16("MajorImageVersion", Hdr.MajorImageVersion);
printU16("MinorImageVersion", Hdr.MinorImageVersion);
printU16("MajorSubsystemVersion", Hdr.MajorSubsystemVersion);
printU16("MinorSubsystemVersion", Hdr.MinorSubsystemVersion);
printU32("Win32Version", Hdr.Win32VersionValue, "%08x\n");
printU32("SizeOfImage", Hdr.SizeOfImage, "%08x\n");
printU32("SizeOfHeaders", Hdr.SizeOfHeaders, "%08x\n");
printU32("CheckSum", Hdr.CheckSum, "%08x\n");
printU16("Subsystem", Hdr.Subsystem, "%08x");
printOptionalEnumName(Hdr.Subsystem, makeArrayRef(PEWindowsSubsystem));
outs() << '\n';
printU16("DllCharacteristics", Hdr.DLLCharacteristics, "%08x\n");
#define FLAG(Name) \
if (Hdr.DLLCharacteristics & COFF::IMAGE_DLL_CHARACTERISTICS_##Name) \
outs() << "\t\t\t\t\t" << #Name << '\n';
FLAG(HIGH_ENTROPY_VA);
FLAG(DYNAMIC_BASE);
FLAG(FORCE_INTEGRITY);
FLAG(NX_COMPAT);
FLAG(NO_ISOLATION);
FLAG(NO_SEH);
FLAG(NO_BIND);
FLAG(APPCONTAINER);
FLAG(WDM_DRIVER);
FLAG(GUARD_CF);
FLAG(TERMINAL_SERVER_AWARE);
#undef FLAG
printAddr("SizeOfStackReserve", Hdr.SizeOfStackReserve);
printAddr("SizeOfStackCommit", Hdr.SizeOfStackCommit);
printAddr("SizeOfHeapReserve", Hdr.SizeOfHeapReserve);
printAddr("SizeOfHeapCommit", Hdr.SizeOfHeapCommit);
printU32("LoaderFlags", Hdr.LoaderFlags, "%08x\n");
printU32("NumberOfRvaAndSizes", Hdr.NumberOfRvaAndSize, "%08x\n");
static const char *DirName[COFF::NUM_DATA_DIRECTORIES + 1] = {
"Export Directory [.edata (or where ever we found it)]",
"Import Directory [parts of .idata]",
"Resource Directory [.rsrc]",
"Exception Directory [.pdata]",
"Security Directory",
"Base Relocation Directory [.reloc]",
"Debug Directory",
"Description Directory",
"Special Directory",
"Thread Storage Directory [.tls]",
"Load Configuration Directory",
"Bound Import Directory",
"Import Address Table Directory",
"Delay Import Directory",
"CLR Runtime Header",
"Reserved",
};
outs() << "\nThe Data Directory\n";
for (uint32_t I = 0; I != array_lengthof(DirName); ++I) {
uint32_t Addr = 0, Size = 0;
if (const data_directory *Data = Obj.getDataDirectory(I)) {
Addr = Data->RelativeVirtualAddress;
Size = Data->Size;
}
outs() << format("Entry %x ", I) << formatAddr(Addr)
<< format(" %08x %s\n", uint32_t(Size), DirName[I]);
}
}
// Returns the name of the unwind code.
static StringRef getUnwindCodeTypeName(uint8_t Code) {
switch(Code) {
@ -622,12 +775,47 @@ void objdump::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
}
}
void objdump::printCOFFFileHeader(const object::ObjectFile *Obj) {
const COFFObjectFile *file = dyn_cast<const COFFObjectFile>(Obj);
printTLSDirectory(file);
printLoadConfiguration(file);
printImportTables(file);
printExportTable(file);
void objdump::printCOFFFileHeader(const COFFObjectFile &Obj) {
COFFDumper CD(Obj);
const uint16_t Cha = Obj.getCharacteristics();
outs() << "Characteristics 0x" << Twine::utohexstr(Cha) << '\n';
#define FLAG(F, Name) \
if (Cha & F) \
outs() << '\t' << Name << '\n';
FLAG(COFF::IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
FLAG(COFF::IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
FLAG(COFF::IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
FLAG(COFF::IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
FLAG(COFF::IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
FLAG(COFF::IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
FLAG(COFF::IMAGE_FILE_32BIT_MACHINE, "32 bit words");
FLAG(COFF::IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
FLAG(COFF::IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP,
"copy to swap file if on removable media");
FLAG(COFF::IMAGE_FILE_NET_RUN_FROM_SWAP,
"copy to swap file if on network media");
FLAG(COFF::IMAGE_FILE_SYSTEM, "system file");
FLAG(COFF::IMAGE_FILE_DLL, "DLL");
FLAG(COFF::IMAGE_FILE_UP_SYSTEM_ONLY, "run only on uniprocessor machine");
FLAG(COFF::IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
#undef FLAG
// TODO Support PE_IMAGE_DEBUG_TYPE_REPRO.
// Since ctime(3) returns a 26 character string of the form:
// "Sun Sep 16 01:03:52 1973\n\0"
// just print 24 characters.
const time_t Timestamp = Obj.getTimeDateStamp();
outs() << format("\nTime/Date %.24s\n", ctime(&Timestamp));
if (const pe32_header *Hdr = Obj.getPE32Header())
CD.printPEHeader<pe32_header>(*Hdr);
else if (const pe32plus_header *Hdr = Obj.getPE32PlusHeader())
CD.printPEHeader<pe32plus_header>(*Hdr);
printTLSDirectory(&Obj);
printLoadConfiguration(&Obj);
printImportTables(&Obj);
printExportTable(&Obj);
}
void objdump::printCOFFSymbolTable(const object::COFFImportFile *i) {

View File

@ -28,7 +28,7 @@ Error getCOFFRelocationValueString(const object::COFFObjectFile *Obj,
llvm::SmallVectorImpl<char> &Result);
void printCOFFUnwindInfo(const object::COFFObjectFile *O);
void printCOFFFileHeader(const object::ObjectFile *O);
void printCOFFFileHeader(const object::COFFObjectFile &Obj);
void printCOFFSymbolTable(const object::COFFImportFile *I);
void printCOFFSymbolTable(const object::COFFObjectFile *O);
} // namespace objdump

View File

@ -2245,7 +2245,7 @@ static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
return;
}
if (O->isCOFF())
return printCOFFFileHeader(O);
return printCOFFFileHeader(cast<object::COFFObjectFile>(*O));
if (O->isWasm())
return printWasmFileHeader(O);
if (O->isMachO()) {