[llvm] 5f1e509 - [llvm-objdump] -p: Dump PE header for PE/COFF
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 9 10:08:45 PST 2021
Author: Fangrui Song
Date: 2021-11-09T10:08:41-08:00
New Revision: 5f1e509579e49e97c4ad7deb0dd3069393ccd461
URL: https://github.com/llvm/llvm-project/commit/5f1e509579e49e97c4ad7deb0dd3069393ccd461
DIFF: https://github.com/llvm/llvm-project/commit/5f1e509579e49e97c4ad7deb0dd3069393ccd461.diff
LOG: [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
Added:
llvm/test/tools/llvm-objdump/COFF/private-headers-old.test
llvm/test/tools/llvm-objdump/COFF/private-headers.yaml
Modified:
llvm/tools/llvm-objdump/COFFDump.cpp
llvm/tools/llvm-objdump/COFFDump.h
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
llvm/test/tools/llvm-objdump/COFF/private-headers.test
################################################################################
diff --git a/llvm/test/tools/llvm-objdump/COFF/private-headers.test b/llvm/test/tools/llvm-objdump/COFF/private-headers-old.test
similarity index 100%
rename from llvm/test/tools/llvm-objdump/COFF/private-headers.test
rename to llvm/test/tools/llvm-objdump/COFF/private-headers-old.test
diff --git a/llvm/test/tools/llvm-objdump/COFF/private-headers.yaml b/llvm/test/tools/llvm-objdump/COFF/private-headers.yaml
new file mode 100644
index 0000000000000..990cf681c2639
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/COFF/private-headers.yaml
@@ -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:
diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp b/llvm/tools/llvm-objdump/COFFDump.cpp
index 54ae3cfb6c924..750c76cd25289 100644
--- a/llvm/tools/llvm-objdump/COFFDump.cpp
+++ b/llvm/tools/llvm-objdump/COFFDump.cpp
@@ -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) {
diff --git a/llvm/tools/llvm-objdump/COFFDump.h b/llvm/tools/llvm-objdump/COFFDump.h
index 21f97bdeb83cd..f933f79523a09 100644
--- a/llvm/tools/llvm-objdump/COFFDump.h
+++ b/llvm/tools/llvm-objdump/COFFDump.h
@@ -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
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index ed605e65bbe83..6f6f543f2f476 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -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()) {
More information about the llvm-commits
mailing list