[llvm] 1c84831 - [XCOFF] llvm-readobj support decoding the loader section header field for XCOFF object file.
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 24 10:31:40 PDT 2022
Author: zhijian
Date: 2022-10-24T13:31:01-04:00
New Revision: 1c84831feaab77ccaed64817aa4120304981ee61
URL: https://github.com/llvm/llvm-project/commit/1c84831feaab77ccaed64817aa4120304981ee61
DIFF: https://github.com/llvm/llvm-project/commit/1c84831feaab77ccaed64817aa4120304981ee61.diff
LOG: [XCOFF] llvm-readobj support decoding the loader section header field for XCOFF object file.
Reviewers: James Henderson, Esme Yi
Differential Revision: https://reviews.llvm.org/D134883
Added:
llvm/test/tools/llvm-readobj/XCOFF/loader-section-header.test
Modified:
llvm/docs/CommandGuide/llvm-readobj.rst
llvm/include/llvm/Object/XCOFFObjectFile.h
llvm/tools/llvm-readobj/ObjDumper.h
llvm/tools/llvm-readobj/Opts.td
llvm/tools/llvm-readobj/XCOFFDumper.cpp
llvm/tools/llvm-readobj/llvm-readobj.cpp
Removed:
################################################################################
diff --git a/llvm/docs/CommandGuide/llvm-readobj.rst b/llvm/docs/CommandGuide/llvm-readobj.rst
index 859b49003bbb3..eb1bb933eccaf 100644
--- a/llvm/docs/CommandGuide/llvm-readobj.rst
+++ b/llvm/docs/CommandGuide/llvm-readobj.rst
@@ -334,6 +334,10 @@ The following options are implemented only for the XCOFF file format.
Display XCOFF exception section entries.
+.. option:: --loader-section-header
+
+ Display XCOFF loader section header.
+
EXIT STATUS
-----------
diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index 3622f466b8e44..da27fc0b52a64 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -216,8 +216,7 @@ struct LoaderSectionHeader64 {
support::big64_t OffsetToImpid;
support::big64_t OffsetToStrTbl;
support::big64_t OffsetToSymTbl;
- char Padding[16];
- support::big32_t OffsetToRelEnt;
+ support::big64_t OffsetToRelEnt;
};
template <typename AddressType> struct ExceptionSectionEntry {
@@ -494,8 +493,6 @@ class XCOFFObjectFile : public ObjectFile {
DataRefImpl getSectionByType(XCOFF::SectionTypeFlags SectType) const;
uint64_t getSectionFileOffsetToRawData(DataRefImpl Sec) const;
- Expected<uintptr_t>
- getSectionFileOffsetToRawData(XCOFF::SectionTypeFlags SectType) const;
// This returns a pointer to the start of the storage for the name field of
// the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
@@ -638,6 +635,9 @@ class XCOFFObjectFile : public ObjectFile {
int32_t getSectionFlags(DataRefImpl Sec) const;
Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
+ Expected<uintptr_t>
+ getSectionFileOffsetToRawData(XCOFF::SectionTypeFlags SectType) const;
+
void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
// Relocation-related interfaces.
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/loader-section-header.test b/llvm/test/tools/llvm-readobj/XCOFF/loader-section-header.test
new file mode 100644
index 0000000000000..5aa456537a11d
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/XCOFF/loader-section-header.test
@@ -0,0 +1,71 @@
+## Test the --loader-section-header option.
+
+# RUN: yaml2obj --docnum=1 %s -o %t_xcoff32.o
+# RUN: yaml2obj --docnum=2 %s -o %t_xcoff64.o
+# RUN: llvm-readobj --loader-section-header %t_xcoff32.o |\
+# RUN: FileCheck %s --check-prefixes=CHECK32
+# RUN: llvm-readobj --loader-section-header %t_xcoff64.o |\
+# RUN: FileCheck %s --check-prefixes=CHECK64
+
+--- !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: Loader Section {
+# CHECK32-NEXT: 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
+# CHECK32-NEXT: }
+# CHECK32-NEXT: }
+
+# CHECK64: Loader Section {
+# CHECK64-NEXT: 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
+# CHECK64-NEXT: }
+# CHECK64-NEXT: }
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index f1cbdcf0ca05c..2a6af54eb14a1 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -158,6 +158,7 @@ class ObjDumper {
// Only implement for XCOFF
virtual void printAuxiliaryHeader() {}
virtual void printExceptionSection() {}
+ virtual void printLoaderSection(bool PrintHeader) {}
// Only implemented for MachO.
virtual void printMachODataInCode() { }
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index eee8c685eb507..4f126d673c462 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -89,6 +89,7 @@ def coff_tls_directory : FF<"coff-tls-directory", "Display TLS directory">, Grou
def grp_xcoff : OptionGroup<"kind">, HelpText<"OPTIONS (XCOFF specific)">;
def auxiliary_header : FF<"auxiliary-header" , "Display the auxiliary header">, Group<grp_xcoff>;
def exception_section : FF<"exception-section" , "Display the exception section entries">, Group<grp_xcoff>;
+def loader_section_header : FF<"loader-section-header" , "Display the loader section header">, Group<grp_xcoff>;
def help : FF<"help", "Display this help">;
def version : FF<"version", "Display the version">;
diff --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
index b2a647543814c..a2ca5b86f35e9 100644
--- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -40,6 +40,7 @@ class XCOFFDumper : public ObjDumper {
void printNeededLibraries() override;
void printStringTable() override;
void printExceptionSection() override;
+ void printLoaderSection(bool PrintHeader) override;
ScopedPrinter &getScopedPrinter() const { return W; }
@@ -66,6 +67,7 @@ class XCOFFDumper : public ObjDumper {
void printRelocations(ArrayRef<Shdr> Sections);
void printAuxiliaryHeader(const XCOFFAuxiliaryHeader32 *AuxHeader);
void printAuxiliaryHeader(const XCOFFAuxiliaryHeader64 *AuxHeader);
+ void printLoaderSectionHeader(uintptr_t LoaderSectAddr);
const XCOFFObjectFile &Obj;
};
} // anonymous namespace
@@ -133,6 +135,56 @@ void XCOFFDumper::printSectionHeaders() {
printSectionHeaders(Obj.sections32());
}
+void XCOFFDumper::printLoaderSection(bool PrintHeader) {
+ DictScope DS(W, "Loader Section");
+ Expected<uintptr_t> LoaderSectionAddrOrError =
+ Obj.getSectionFileOffsetToRawData(XCOFF::STYP_LOADER);
+ if (!LoaderSectionAddrOrError) {
+ reportUniqueWarning(LoaderSectionAddrOrError.takeError());
+ return;
+ }
+ uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
+
+ W.indent();
+ if (PrintHeader)
+ printLoaderSectionHeader(LoaderSectionAddr);
+ // TODO: Need to print symbol table, relocation entry of loader section later.
+ // For example:
+ // if (PrintSymbolTable)
+ // printLoaderSectionSymbolTable();
+ // if (PrintRelocation)
+ // printLoaderSectionRelocationEntry();
+ W.unindent();
+}
+
+void XCOFFDumper::printLoaderSectionHeader(uintptr_t LoaderSectionAddr) {
+ DictScope DS(W, "Loader Section Header");
+
+ auto PrintLoadSecHeaderCommon = [&](const auto *LDHeader) {
+ W.printNumber("Version", LDHeader->Version);
+ W.printNumber("NumberOfSymbolEntries", LDHeader->NumberOfSymTabEnt);
+ W.printNumber("NumberOfRelocationEntries", LDHeader->NumberOfRelTabEnt);
+ W.printNumber("LengthOfImportFileIDStringTable",
+ LDHeader->LengthOfImpidStrTbl);
+ W.printNumber("NumberOfImportFileIDs", LDHeader->NumberOfImpid);
+ W.printHex("OffsetToImportFileIDs", LDHeader->OffsetToImpid);
+ W.printNumber("LengthOfStringTable", LDHeader->LengthOfStrTbl);
+ W.printHex("OffsetToStringTable", LDHeader->OffsetToStrTbl);
+ };
+
+ if (Obj.is64Bit()) {
+ const LoaderSectionHeader64 *LoaderSec64 =
+ reinterpret_cast<const LoaderSectionHeader64 *>(LoaderSectionAddr);
+ PrintLoadSecHeaderCommon(LoaderSec64);
+ W.printHex("OffsetToSymbolTable", LoaderSec64->OffsetToSymTbl);
+ W.printHex("OffsetToRelocationEntries", LoaderSec64->OffsetToRelEnt);
+ } else {
+ const LoaderSectionHeader32 *LoaderSec32 =
+ reinterpret_cast<const LoaderSectionHeader32 *>(LoaderSectionAddr);
+ PrintLoadSecHeaderCommon(LoaderSec32);
+ }
+}
+
template <typename T>
void XCOFFDumper::printExceptionSectionEntry(const T &ExceptionSectEnt) const {
if (ExceptionSectEnt.getReason())
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index f3f89497d8bd9..fadf1445b76dd 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -162,6 +162,7 @@ static bool COFFTLSDirectory;
// XCOFF specific options.
static bool XCOFFAuxiliaryHeader;
+static bool XCOFFLoaderSectionHeader;
static bool XCOFFExceptionSection;
OutputStyleTy Output = OutputStyleTy::LLVM;
@@ -303,6 +304,7 @@ static void parseOptions(const opt::InputArgList &Args) {
// XCOFF specific options.
opts::XCOFFAuxiliaryHeader = Args.hasArg(OPT_auxiliary_header);
+ opts::XCOFFLoaderSectionHeader = Args.hasArg(OPT_loader_section_header);
opts::XCOFFExceptionSection = Args.hasArg(OPT_exception_section);
opts::InputFilenames = Args.getAllArgValues(OPT_INPUT);
@@ -507,8 +509,13 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printCGProfile();
}
- if (Obj.isXCOFF() && opts::XCOFFExceptionSection)
- Dumper->printExceptionSection();
+ if (Obj.isXCOFF()) {
+ if (opts::XCOFFLoaderSectionHeader)
+ Dumper->printLoaderSection(opts::XCOFFLoaderSectionHeader);
+
+ if (opts::XCOFFExceptionSection)
+ Dumper->printExceptionSection();
+ }
if (opts::PrintStackMap)
Dumper->printStackMap();
More information about the llvm-commits
mailing list