[llvm] [llvm-objdump] print out xcoff file header and load section header for xcoff object file with option private-headers (PR #96350)
zhijian lin via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 21 12:38:26 PDT 2024
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/96350
>From e2e335cadeb32d5eb10175793978f504c101ffef Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Fri, 21 Jun 2024 15:29:23 -0400
Subject: [PATCH 1/2] implement the print xcoff file header and load section
header for option private-headers
---
llvm/tools/llvm-objdump/XCOFFDump.cpp | 124 +++++++++++++++++++++++++-
1 file changed, 122 insertions(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index d9c00c0962098..54b94ba7161b9 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -20,7 +20,9 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
@@ -30,10 +32,128 @@ using namespace llvm::support;
namespace {
class XCOFFDumper : public objdump::Dumper {
+ const XCOFFObjectFile &Obj;
+ unsigned Width;
public:
- XCOFFDumper(const object::XCOFFObjectFile &O) : Dumper(O) {}
- void printPrivateHeaders() override {}
+ XCOFFDumper(const object::XCOFFObjectFile &O) : Dumper(O), Obj(O) {}
+ void printPrivateHeaders() override;
+ void printFileHeader();
+ void printAuxiliaryHeader(){};
+ void printLoaderSectionHeader();
+ FormattedString formatName(StringRef Name);
+ void printHex(StringRef Name, uint64_t Value);
+ void printNumber(StringRef Name, uint64_t Value);
+ void printStrHex(StringRef Name, StringRef Str, uint64_t Value);
+ void setWidth(unsigned W) {Width =W;};
};
+
+void XCOFFDumper::printPrivateHeaders() {
+ printFileHeader();
+ printAuxiliaryHeader();
+ printLoaderSectionHeader();
+}
+
+FormattedString XCOFFDumper::formatName(StringRef Name) {
+ return FormattedString(Name, Width, FormattedString::JustifyLeft);
+}
+
+void XCOFFDumper::printHex(StringRef Name, uint64_t Value) {
+ outs() << formatName(Name) << format_hex(Value, 0) << "\n";
+}
+
+void XCOFFDumper::printNumber(StringRef Name, uint64_t Value) {
+ outs() << formatName(Name) << format_decimal(Value, 0) << "\n";
+}
+
+void XCOFFDumper::printStrHex(StringRef Name, StringRef Str, uint64_t Value) {
+ outs() << formatName(Name) << Str << " (" << format_decimal(Value, 0) << ")"
+ << "\n";
+}
+
+void XCOFFDumper::printFileHeader() {
+ setWidth(20);
+ outs() << "\n---File Header:\n";
+ printHex("Magic:", Obj.getMagic());
+ printNumber("NumberOfSections:", Obj.getNumberOfSections());
+
+ // Negative timestamp values are reserved for future use.
+ int32_t TimeStamp = Obj.getTimeStamp();
+ if (TimeStamp > 0) {
+ // This handling of the time stamp assumes that the host
+ // system's time_t is
+ // compatible with AIX time_t. If a platform is not
+ // compatible, the lit
+ // tests will let us know.
+ time_t TimeDate = TimeStamp;
+
+ char FormattedTime[80] = {};
+
+ size_t BytesFormatted = strftime(FormattedTime, sizeof(FormattedTime),
+ "%F %T", gmtime(&TimeDate));
+ if (BytesFormatted)
+ printStrHex("TimeStamp:", FormattedTime, TimeStamp);
+ else
+ printHex("Timestamp:", TimeStamp);
+ } else {
+ printStrHex("TimeStamp:", TimeStamp == 0 ? "None" : "Reserved Value",
+ TimeStamp);
+ }
+
+ // The number of symbol table entries is an unsigned value in
+ // 64-bit objects and a signed value (with negative values
+ // being 'reserved') in 32-bit objects.
+
+ if (Obj.is64Bit()) {
+ printHex("SymbolTableOffset:", Obj.getSymbolTableOffset64());
+ printNumber("SymbolTableEntries:", Obj.getNumberOfSymbolTableEntries64());
+ } else {
+ printHex("SymbolTableOffset:", Obj.getSymbolTableOffset32());
+ int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries32();
+ if (SymTabEntries >= 0)
+ printNumber("SymbolTableEntries:", SymTabEntries);
+ else
+ printStrHex("SymbolTableEntries:", "Reserved Value", SymTabEntries);
+ }
+
+ printHex("OptionalHeaderSize:", Obj.getOptionalHeaderSize());
+ printHex("Flags:", Obj.getFlags());
+}
+
+void XCOFFDumper::printLoaderSectionHeader() {
+ Expected<uintptr_t> LoaderSectionAddrOrError =
+ Obj.getSectionFileOffsetToRawData(XCOFF::STYP_LOADER);
+ if (!LoaderSectionAddrOrError) {
+ reportUniqueWarning(LoaderSectionAddrOrError.takeError());
+ return;
+ }
+ uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
+
+ auto PrintLoadSecHeaderCommon = [&](const auto *LDHeader) {
+ printNumber("Version:", LDHeader->Version);
+ printNumber("NumberOfSymbolEntries:", LDHeader->NumberOfSymTabEnt);
+ printNumber("NumberOfRelocationEntries:", LDHeader->NumberOfRelTabEnt);
+ printNumber("LengthOfImportFileIDStringTable:",
+ LDHeader->LengthOfImpidStrTbl);
+ printNumber("NumberOfImportFileIDs:", LDHeader->NumberOfImpid);
+ printHex("OffsetToImportFileIDs:", LDHeader->OffsetToImpid);
+ printNumber("LengthOfStringTable:", LDHeader->LengthOfStrTbl);
+ printHex("OffsetToStringTable:", LDHeader->OffsetToStrTbl);
+ };
+
+ setWidth(35);
+ outs() << "\n---Loader Section Header:\n";
+ if (Obj.is64Bit()) {
+ const LoaderSectionHeader64 *LoaderSec64 =
+ reinterpret_cast<const LoaderSectionHeader64 *>(LoaderSectionAddr);
+ PrintLoadSecHeaderCommon(LoaderSec64);
+ printHex("OffsetToSymbolTable", LoaderSec64->OffsetToSymTbl);
+ printHex("OffsetToRelocationEntries", LoaderSec64->OffsetToRelEnt);
+ } else {
+ const LoaderSectionHeader32 *LoaderSec32 =
+ reinterpret_cast<const LoaderSectionHeader32 *>(LoaderSectionAddr);
+ PrintLoadSecHeaderCommon(LoaderSec32);
+ }
+}
} // namespace
std::unique_ptr<objdump::Dumper>
>From 553e8f556e75766efb2dd18243a360a20abccf5b Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Fri, 21 Jun 2024 15:38:16 -0400
Subject: [PATCH 2/2] add test case
---
.../XCOFF/private-headers-option.test | 83 +++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 llvm/test/tools/llvm-objdump/XCOFF/private-headers-option.test
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-headers-option.test b/llvm/test/tools/llvm-objdump/XCOFF/private-headers-option.test
new file mode 100644
index 0000000000000..21469ec67d150
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-headers-option.test
@@ -0,0 +1,83 @@
+## Test the --privated-headers option for XCOFF object files.
+
+# RUN: yaml2obj --docnum=1 %s -o %t_xcoff32.o
+# RUN: yaml2obj --docnum=2 %s -o %t_xcoff64.o
+# RUN: llvm-objdump --private-headers %t_xcoff32.o |\
+# RUN: FileCheck %s --check-prefixes=CHECK32 --match-full-lines
+# RUN: llvm-objdump --private-headers %t_xcoff64.o |\
+# RUN: FileCheck %s --check-prefixes=CHECK64 --match-full-lines
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x1DF
+Sections:
+ - Name: .loader
+ Flags: [ STYP_LOADER ]
+ SectionData: "0000000100000003000000050000016D00000001000000A40000001800000211"
+## ^------- -Version=1
+## ^------- -NumberOfSymbolEntries=3
+## ^------- -NumberOfRelocationEntries=5
+## ^------- -LengthOfImportFileIDStringTable=365
+## ^------- -NumberOfImportFileIDs=1
+## ^------- -OffsetToImportFileIDs=0xA4
+## ^------- -LengthOfStringTable=24
+## ^------- -OffsetToStringTable=0x211
+
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x1F7
+Sections:
+ - Name: .loader
+ Flags: [ STYP_LOADER ]
+ SectionData: "0000000200000003000000050000016D000000010000002300000000000000D0000000000000023D00000000000000380000000000000080"
+## ^------- -Version=2
+## ^------- -NumberOfSymbolEntries=3
+## ^------- -NumberOfRelocationEntries=5
+## ^------- -LengthOfImportFileIDStringTable=365
+## ^------- -NumberOfImportFileIDs=1
+## ^------- --LengthOfStringTable=0x23
+## ^--------------- -OffsetToImportFileIDs=0xD0
+## ^--------------- -OffsetToStringTable=0x23D
+## ^-------------- -OffsetToSymbolTable=0x38
+## ^--------------- -OffsetToRelocationEntries=0x80
+
+# CHECK32: ---File Header:
+# CHECK32-NEXT: Magic: 0x1df
+# CHECK32-NEXT: NumberOfSections: 1
+# CHECK32-NEXT: TimeStamp: None (0)
+# CHECK32-NEXT: SymbolTableOffset: 0x0
+# CHECK32-NEXT: SymbolTableEntries: 0
+# CHECK32-NEXT: OptionalHeaderSize: 0x0
+# CHECK32-NEXT: Flags: 0x0
+
+# CHECK32: ---Loader Section Header:
+# CHECK32-NEXT: Version: 1
+# CHECK32-NEXT: NumberOfSymbolEntries: 3
+# CHECK32-NEXT: NumberOfRelocationEntries: 5
+# CHECK32-NEXT: LengthOfImportFileIDStringTable: 365
+# CHECK32-NEXT: NumberOfImportFileIDs: 1
+# CHECK32-NEXT: OffsetToImportFileIDs: 0xa4
+# CHECK32-NEXT: LengthOfStringTable: 24
+# CHECK32-NEXT: OffsetToStringTable: 0x211
+
+# CHECK64: ---File Header:
+# CHECK64-NEXT: Magic: 0x1f7
+# CHECK64-NEXT: NumberOfSections: 1
+# CHECK64-NEXT: TimeStamp: None (0)
+# CHECK64-NEXT: SymbolTableOffset: 0x0
+# CHECK64-NEXT: SymbolTableEntries: 0
+# CHECK64-NEXT: OptionalHeaderSize: 0x0
+# CHECK64-NEXT: Flags: 0x0
+
+# CHECK64: ---Loader Section Header:
+# CHECK64-NEXT: Version: 2
+# CHECK64-NEXT: NumberOfSymbolEntries: 3
+# CHECK64-NEXT: NumberOfRelocationEntries: 5
+# CHECK64-NEXT: LengthOfImportFileIDStringTable: 365
+# CHECK64-NEXT: NumberOfImportFileIDs: 1
+# CHECK64-NEXT: OffsetToImportFileIDs: 0xd0
+# CHECK64-NEXT: LengthOfStringTable: 35
+# CHECK64-NEXT: OffsetToStringTable: 0x23d
+# CHECK64-NEXT: OffsetToSymbolTable 0x38
+# CHECK64-NEXT: OffsetToRelocationEntries 0x80
More information about the llvm-commits
mailing list