diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -62,6 +62,86 @@ bool isReservedSectionType() const; }; +struct XCOFFAuxiliaryHeader32 { + support::ubig16_t + AuxMagic; ///< If the value of the o_vstamp field is greater than 1, the + ///< o_mflags field is reserved for future use and it should + ///< contain 0. Otherwise, this field is not used. + support::ubig16_t + Version; ///< The valid values are 1 and 2. When the o_vstamp field is 2 + ///< in an XCOFF32 file, the new interpretation of the n_type + ///< field in the symbol table entry is used. + support::ubig32_t TextSize; + support::ubig32_t InitDataSize; + support::ubig32_t BssDataSize; + support::ubig32_t EntryPointVirtualAddr; + support::ubig32_t TextStartAddr; + support::ubig32_t DataStartAddr; + support::ubig32_t TOCAnchorAddr; + support::ubig16_t SecNumOfEntryPoint; + support::ubig16_t SecNumOfText; + support::ubig16_t SecNumOfData; + support::ubig16_t SecNumOfTOC; + support::ubig16_t SecNumOfLoader; + support::ubig16_t SecNumOfBSS; + support::ubig16_t MaxAlignOfText; + support::ubig16_t MaxAlignOfData; + support::ubig16_t ModuleType; + char CpuFlag; + char CpuType; + support::ubig32_t MaxStackSize; ///< If the value is 0, the system default + ///< maximum stack size is used. + support::ubig32_t MaxDataSize; ///< If the value is 0, the system default + ///< maximum data size is used. + support::ubig32_t + ReservedForDebugger; ///< This field should contain 0. When a loaded + ///< program is being debugged, the memory image of + ///< this field may be modified by a debugger to + ///< insert a trap instruction. + char TextPageSize; ///< Specifies the size of pages for the exec text. The + ///< default value is 0 (system-selected page size). + char DataPageSize; ///< Specifies the size of pages for the exec data. The + ///< default value is 0 (system-selected page size). + char StackPageSize; ///< Specifies the size of pages for the stack. The + ///< default value is 0 (system-selected page size). + char Flag; + support::ubig16_t SecNumOfTData; + support::ubig16_t SecNumOfTBSS; +}; + +struct XCOFFAuxiliaryHeader64 { + support::ubig16_t AuxMagic; + support::ubig16_t Version; + support::ubig32_t ReservedForDebugger; + support::ubig64_t TextStartAddr; + support::ubig64_t DataStartAddr; + support::ubig64_t TOCAnchorAddr; + support::ubig16_t SecNumOfEntryPoint; + support::ubig16_t SecNumOfText; + support::ubig16_t SecNumOfData; + support::ubig16_t SecNumOfTOC; + support::ubig16_t SecNumOfLoader; + support::ubig16_t SecNumOfBSS; + support::ubig16_t MaxAlignOfText; + support::ubig16_t MaxAlignOfData; + support::ubig16_t ModuleType; + char CpuFlag; + char CpuType; + char TextPageSize; + char DataPageSize; + char StackPageSize; + char Flag; + support::ubig64_t TextSize; + support::ubig64_t InitDataSize; + support::ubig64_t BssDataSize; + support::ubig64_t EntryPointVirtualAddr; + support::ubig64_t MaxStackSize; + support::ubig64_t MaxDataSize; + support::ubig16_t SecNumOfTData; + support::ubig16_t SecNumOfTBSS; + support::ubig16_t X64bitsFlag; +}; + // Explicit extern template declarations. struct XCOFFSectionHeader32; struct XCOFFSectionHeader64; @@ -216,6 +296,7 @@ class XCOFFObjectFile : public ObjectFile { private: const void *FileHeader = nullptr; + const void *AuxiliaryHeader = nullptr; const void *SectionHeaderTable = nullptr; const XCOFFSymbolEntry *SymbolTblPtr = nullptr; @@ -226,7 +307,6 @@ const XCOFFSectionHeader32 *sectionHeaderTable32() const; const XCOFFSectionHeader64 *sectionHeaderTable64() const; - size_t getFileHeaderSize() const; size_t getSectionHeaderSize() const; @@ -320,6 +400,9 @@ // Below here is the non-inherited interface. bool is64Bit() const; + const XCOFFAuxiliaryHeader32 *AuxiliaryHeader32() const; + const XCOFFAuxiliaryHeader64 *AuxiliaryHeader64() const; + const XCOFFSymbolEntry *getPointerToSymbolTable() const { assert(!is64Bit() && "Symbol table handling not supported yet."); return SymbolTblPtr; diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -130,6 +130,16 @@ return static_cast(FileHeader); } +const XCOFFAuxiliaryHeader32 *XCOFFObjectFile::AuxiliaryHeader32() const { + assert(!is64Bit() && "32-bit interface called on 64-bit object file."); + return static_cast(AuxiliaryHeader); +} + +const XCOFFAuxiliaryHeader64 *XCOFFObjectFile::AuxiliaryHeader64() const { + assert(is64Bit() && "64-bit interface called on a 64-bit object file."); + return static_cast(AuxiliaryHeader); +} + const XCOFFSectionHeader32 * XCOFFObjectFile::sectionHeaderTable32() const { assert(!is64Bit() && "32-bit interface called on 64-bit object file."); @@ -711,8 +721,15 @@ Obj->FileHeader = FileHeaderOrErr.get(); CurOffset += Obj->getFileHeaderSize(); - // TODO FIXME we don't have support for an optional header yet, so just skip - // past it. + + if (Obj->getOptionalHeaderSize()) { + auto AuxiliaryHeaderOrErr = + getObject(Data, Base + CurOffset, Obj->getOptionalHeaderSize()); + if (Error E = AuxiliaryHeaderOrErr.takeError()) + return std::move(E); + Obj->AuxiliaryHeader = AuxiliaryHeaderOrErr.get(); + } + CurOffset += Obj->getOptionalHeaderSize(); // Parse the section header table if it is present. diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-exec b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-exec new file mode 100755 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ Sections); + void printAuxiliaryHeaders(const XCOFFAuxiliaryHeader32 *AuxHeader); + void printAuxiliaryHeaders(const XCOFFAuxiliaryHeader64 *AuxHeader); const XCOFFObjectFile &Obj; }; } // anonymous namespace @@ -96,6 +99,16 @@ // XCOFFObjectFile has the necessary support. } +void XCOFFDumper::printAuxiliaryHeaders() { + if (Obj.is64Bit()) { + const XCOFFAuxiliaryHeader64 *AuxHeader64Prt = Obj.AuxiliaryHeader64(); + printAuxiliaryHeaders(AuxHeader64Prt); + } else { + const XCOFFAuxiliaryHeader32 *AuxHeader32Prt = Obj.AuxiliaryHeader32(); + printAuxiliaryHeaders(AuxHeader32Prt); + } +} + void XCOFFDumper::printSectionHeaders() { if (Obj.is64Bit()) printSectionHeaders(Obj.sections64()); @@ -473,6 +486,116 @@ W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers); } +#define PrintAuxMember(H, S, T, X) \ + W.print##H(S, T); \ + if ((X = X - sizeof(T)) == 0) \ + return + +void XCOFFDumper::printAuxiliaryHeaders(const XCOFFAuxiliaryHeader32 *AuxHeader) { + if (AuxHeader == nullptr) { + W.printString("The XCOFF object file do not have a auxiliary header."); + return; + } + int AuxSize = Obj.getOptionalHeaderSize(); + DictScope DS(W, "AuxiliaryHeader"); + PrintAuxMember(Hex, "Magic", AuxHeader->AuxMagic, AuxSize); + PrintAuxMember(Hex, "Version", AuxHeader->Version, AuxSize); + PrintAuxMember(Hex, "Size Of .text Section", AuxHeader->TextSize, AuxSize); + PrintAuxMember(Hex, "Size Of .data Section", AuxHeader->InitDataSize, AuxSize); + PrintAuxMember(Hex, "Size Of .bss Section", AuxHeader->BssDataSize, AuxSize); + PrintAuxMember(Hex, "Entry Point Address", AuxHeader->EntryPointVirtualAddr,AuxSize); + PrintAuxMember(Hex, ".text Section Start Address", AuxHeader->TextStartAddr, AuxSize); + PrintAuxMember(Hex, ".data Section Start Address", AuxHeader->DataStartAddr, AuxSize); + PrintAuxMember(Hex, "TOC anchor Address", AuxHeader->TOCAnchorAddr, AuxSize); + PrintAuxMember(Number, "Section Number Of EntryPoint", + AuxHeader->SecNumOfEntryPoint, AuxSize); + PrintAuxMember(Number, "Section Number Of .text", AuxHeader->SecNumOfText, AuxSize); + PrintAuxMember(Number, "Section Number Of .data", AuxHeader->SecNumOfData, + AuxSize); + PrintAuxMember(Number, "Section Number Of TOC", AuxHeader->SecNumOfTOC, + AuxSize); + PrintAuxMember(Number, "Section Number Of loader Data", + AuxHeader->SecNumOfLoader, AuxSize); + PrintAuxMember(Number, "Section Number Of .bss", AuxHeader->SecNumOfBSS, + AuxSize); + PrintAuxMember(Hex, "Maxium Alignment of .text", AuxHeader->MaxAlignOfText, + AuxSize); + PrintAuxMember(Hex, "Maxium Alignment of .data", AuxHeader->MaxAlignOfData, + AuxSize); + PrintAuxMember(Hex, "Module Type", AuxHeader->ModuleType, AuxSize); + PrintAuxMember(Hex, "Cpu Type Of Objects", AuxHeader->CpuFlag, AuxSize); + PrintAuxMember(Hex, "(Reserved)", AuxHeader->CpuType, AuxSize); + PrintAuxMember(Hex, "Maximum Stack Size", AuxHeader->MaxStackSize, AuxSize); + PrintAuxMember(Hex, "Maximum Data Size", AuxHeader->MaxDataSize, AuxSize); + PrintAuxMember(Hex, "Reserved For Debugger", AuxHeader->ReservedForDebugger, + AuxSize); + PrintAuxMember(Hex, "Text Page Size", AuxHeader->TextPageSize, AuxSize); + PrintAuxMember(Hex, "Data Page Size", AuxHeader->DataPageSize, AuxSize); + PrintAuxMember(Hex, "Stack Page Size", AuxHeader->StackPageSize, AuxSize); + PrintAuxMember(Hex, "Flag", AuxHeader->Flag, AuxSize); + PrintAuxMember(Number, "Section number for .tdata", AuxHeader->SecNumOfTData, + AuxSize); + PrintAuxMember(Number, "Section number for .tbss", AuxHeader->SecNumOfTBSS, + AuxSize); +} + +void XCOFFDumper::printAuxiliaryHeaders( + const XCOFFAuxiliaryHeader64 *AuxHeader) { + if (AuxHeader == nullptr) { + W.printString("The XCOFF object file do not have a auxiliary header."); + return; + } + int AuxSize = Obj.getOptionalHeaderSize(); + DictScope DS(W, "AuxiliaryHeader"); + PrintAuxMember(Hex, "Magic", AuxHeader->AuxMagic, AuxSize); + PrintAuxMember(Hex, "Version", AuxHeader->Version, AuxSize); + PrintAuxMember(Hex, "Reserved For Debugger", AuxHeader->ReservedForDebugger, + AuxSize); + PrintAuxMember(Hex, ".text Section Start Address", AuxHeader->TextStartAddr, + AuxSize); + PrintAuxMember(Hex, ".data Section Start Address", AuxHeader->DataStartAddr, + AuxSize); + PrintAuxMember(Hex, "TOC anchor Address", AuxHeader->TOCAnchorAddr, AuxSize); + PrintAuxMember(Number, "Section Number Of EntryPoint", + AuxHeader->SecNumOfEntryPoint, AuxSize); + PrintAuxMember(Number, "Section Number Of .text", AuxHeader->SecNumOfText, + AuxSize); + PrintAuxMember(Number, "Section Number Of .data", AuxHeader->SecNumOfData, + AuxSize); + PrintAuxMember(Number, "Section Number Of TOC", AuxHeader->SecNumOfTOC, + AuxSize); + PrintAuxMember(Number, "Section Number Of loader Data", + AuxHeader->SecNumOfLoader, AuxSize); + PrintAuxMember(Number, "Section Number Of .bss", AuxHeader->SecNumOfBSS, + AuxSize); + PrintAuxMember(Hex, "Maxium Alignment of .text", AuxHeader->MaxAlignOfText, + AuxSize); + PrintAuxMember(Hex, "Maxium Alignment of .data", AuxHeader->MaxAlignOfData, + AuxSize); + PrintAuxMember(Hex, "Module Type", AuxHeader->ModuleType, AuxSize); + PrintAuxMember(Hex, "Cpu Type Of Objects", AuxHeader->CpuFlag, AuxSize); + PrintAuxMember(Hex, "(Reserved)", AuxHeader->CpuType, AuxSize); + PrintAuxMember(Hex, "Text Page Size", AuxHeader->TextPageSize, AuxSize); + PrintAuxMember(Hex, "Data Page Size", AuxHeader->DataPageSize, AuxSize); + PrintAuxMember(Hex, "Stack Page Size", AuxHeader->StackPageSize, AuxSize); + PrintAuxMember(Hex, "Flag", AuxHeader->Flag, AuxSize); + PrintAuxMember(Hex, "Size Of .text Section", AuxHeader->TextSize, AuxSize); + PrintAuxMember(Hex, "Size Of .data Section", AuxHeader->InitDataSize, + AuxSize); + PrintAuxMember(Hex, "Size Of .bss Section", AuxHeader->BssDataSize, AuxSize); + PrintAuxMember(Hex, "Entry Point Address", AuxHeader->EntryPointVirtualAddr, + AuxSize); + PrintAuxMember(Hex, "Maximum Stack Size", AuxHeader->MaxStackSize, AuxSize); + PrintAuxMember(Hex, "Maximum Data Size", AuxHeader->MaxDataSize, AuxSize); + PrintAuxMember(Number, "Section number for .tdata", AuxHeader->SecNumOfTData, + AuxSize); + PrintAuxMember(Number, "Section number for .tbss", AuxHeader->SecNumOfTBSS, + AuxSize); + PrintAuxMember(Number, "64 bits XCOFF Flag", AuxHeader->X64bitsFlag, AuxSize); +} + +#undef PrintAuxMember + template void XCOFFDumper::printSectionHeaders(ArrayRef Sections) { ListScope Group(W, "Sections"); diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -174,6 +174,11 @@ cl::opt NeededLibraries("needed-libs", cl::desc("Display the needed libraries")); + // --auxiliary-headers + cl::opt + XCOFFAuxiliaryHeaders("auxiliary-headers", + cl::desc("Display XCOFF Auxiliary headers")); + // --program-headers, --segments, -l cl::opt ProgramHeaders("program-headers", cl::desc("Display ELF program headers")); @@ -548,6 +553,11 @@ if (opts::MachODysymtab) Dumper->printMachODysymtab(); } + + if (Obj->isXCOFF() && opts::XCOFFAuxiliaryHeaders) { + Dumper->printAuxiliaryHeaders(); + } + if (opts::PrintStackMap) Dumper->printStackMap(); if (opts::PrintStackSizes) @@ -688,6 +698,7 @@ if (opts::All) { opts::FileHeaders = true; opts::ProgramHeaders = true; + opts::XCOFFAuxiliaryHeaders = true; opts::SectionHeaders = true; opts::Symbols = true; opts::Relocations = true; @@ -705,6 +716,7 @@ if (opts::Headers) { opts::FileHeaders = true; + opts::XCOFFAuxiliaryHeaders = true; opts::ProgramHeaders = true; opts::SectionHeaders = true; }