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 @@ -116,7 +116,7 @@ support::ubig16_t SecNumOfTBSS; }; -struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader { +struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader { support::ubig16_t AuxMagic; support::ubig16_t Version; support::ubig32_t ReservedForDebugger; diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-exec b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc32-exec rename from llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-exec rename to llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc32-exec diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-obj-malform.o b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc32-obj-malform.o rename from llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-obj-malform.o rename to llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc32-obj-malform.o diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-obj.o b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc32-obj.o rename from llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-32-xlc-obj.o rename to llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc32-obj.o diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-64-xlc-exec b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc64-exec rename from llvm/test/tools/llvm-readobj/XCOFF/Inputs/xcoff-64-xlc-exec rename to llvm/test/tools/llvm-readobj/XCOFF/Inputs/xlc64-exec diff --git a/llvm/test/tools/llvm-readobj/XCOFF/xcoff-auxiliary-header.test b/llvm/test/tools/llvm-readobj/XCOFF/xcoff-auxiliary-header.test deleted file mode 100644 --- a/llvm/test/tools/llvm-readobj/XCOFF/xcoff-auxiliary-header.test +++ /dev/null @@ -1,126 +0,0 @@ -# REQUIRES: system-aix -## This file tests the ability of llvm-readobj to display the auxiliary header for 64 bits XCOFF and 32 bits XCOFF object file. -# RUN: llvm-readobj --auxiliary-header %p/Inputs/xcoff-64-xlc-exec 2>&1 | \ -# RUN: FileCheck --check-prefixes=XLC64EXEC,WARN64 %s - -# RUN: llvm-readobj --auxiliary-header %p/Inputs/xcoff-32-xlc-exec | \ -# RUN: FileCheck --check-prefix=XLC32EXEC %s - -# RUN: llvm-readobj --auxiliary-header %p/Inputs/xcoff-32-xlc-obj.o | \ -# RUN: FileCheck --check-prefix=XLC32OBJ %s - -# RUN: llvm-readobj --headers %p/Inputs/xcoff-32-xlc-obj.o | \ -# RUN: FileCheck --check-prefix=XLC32OBJ %s - -# RUN: llvm-readobj --auxiliary-header %p/Inputs/xcoff-32-xlc-obj-malform.o 2>&1 | \ -# RUN: FileCheck --check-prefixes=XLC32OBJ-PART,WARN-PART %s - -# XLC32EXEC: File: {{.*}}xcoff-32-xlc-exec -# XLC32EXEC-NEXT: Format: aixcoff-rs6000 -# XLC32EXEC-NEXT: Arch: powerpc -# XLC32EXEC-NEXT: AddressSize: 32bit -# XLC32EXEC-NEXT: AuxiliaryHeader { -# XLC32EXEC-NEXT: Magic: 0x10B -# XLC32EXEC-NEXT: Version: 0x1 -# XLC32EXEC-NEXT: Size of .text section: 0x498 -# XLC32EXEC-NEXT: Size of .data section: 0xF0 -# XLC32EXEC-NEXT: Size of .bss section: 0x4 -# XLC32EXEC-NEXT: Entry point address: 0x20000658 -# XLC32EXEC-NEXT: .text section start address: 0x10000128 -# XLC32EXEC-NEXT: .data section start address: 0x200005C0 -# XLC32EXEC-NEXT: TOC anchor address: 0x2000066C -# XLC32EXEC-NEXT: Section number of entryPoint: 2 -# XLC32EXEC-NEXT: Section number of .text: 1 -# XLC32EXEC-NEXT: Section number of .data: 2 -# XLC32EXEC-NEXT: Section number of TOC: 2 -# XLC32EXEC-NEXT: Section number of loader data: 4 -# XLC32EXEC-NEXT: Section number of .bss: 3 -# XLC32EXEC-NEXT: Maxium alignment of .text: 0x7 -# XLC32EXEC-NEXT: Maxium alignment of .data: 0x3 -# XLC32EXEC-NEXT: Module type: 0x314C -# XLC32EXEC-NEXT: CPU type of objects: 0x0 -# XLC32EXEC-NEXT: (Reserved): 0x0 -# XLC32EXEC-NEXT: Maximum stack size: 0x0 -# XLC32EXEC-NEXT: Maximum data size: 0x0 -# XLC32EXEC-NEXT: Reserved for debugger: 0x0 -# XLC32EXEC-NEXT: Text page size: 0x0 -# XLC32EXEC-NEXT: Data page size: 0x0 -# XLC32EXEC-NEXT: Stack page size: 0x0 -# XLC32EXEC-NEXT: Flag: 0x0 -# XLC32EXEC-NEXT: Alignment of thread-local storage: 0x0 -# XLC32EXEC-NEXT: Section number for .tdata: 0 -# XLC32EXEC-NEXT: Section number for .tbss: 0 -# XLC32EXEC-NEXT: } - - -# XLC64EXEC: File: {{.*}}xcoff-64-xlc-exec -# XLC64EXEC-NEXT: Format: aix5coff64-rs6000 -# XLC64EXEC-NEXT: Arch: powerpc64 -# XLC64EXEC-NEXT: AddressSize: 64bit -# XLC64EXEC-NEXT: AuxiliaryHeader { -# XLC64EXEC-NEXT: Magic: 0x10B -# XLC64EXEC-NEXT: Version: 0x1 -# XLC64EXEC-NEXT: Reserved for debugger: 0x0 -# XLC64EXEC-NEXT: .text section start address: 0x1000001F8 -# XLC64EXEC-NEXT: .data section start address: 0x110000640 -# XLC64EXEC-NEXT: TOC anchor address: 0x110000738 -# XLC64EXEC-NEXT: Section number of entryPoint: 2 -# XLC64EXEC-NEXT: Section number of .text: 1 -# XLC64EXEC-NEXT: Section number of .data: 2 -# XLC64EXEC-NEXT: Section number of TOC: 2 -# XLC64EXEC-NEXT: Section number of loader data: 4 -# XLC64EXEC-NEXT: Section number of .bss: 3 -# XLC64EXEC-NEXT: Maxium alignment of .text: 0x7 -# XLC64EXEC-NEXT: Maxium alignment of .data: 0x3 -# XLC64EXEC-NEXT: Module type: 0x314C -# XLC64EXEC-NEXT: CPU type of objects: 0x0 -# XLC64EXEC-NEXT: (Reserved): 0x0 -# XLC64EXEC-NEXT: Text page size: 0x0 -# XLC64EXEC-NEXT: Data page size: 0x0 -# XLC64EXEC-NEXT: Stack page size: 0x0 -# XLC64EXEC-NEXT: Flag: 0x0 -# XLC64EXEC-NEXT: Alignment of thread-local storage: 0x0 -# XLC64EXEC-NEXT: Size of .text section: 0x448 -# XLC64EXEC-NEXT: Size of .data section: 0x180 -# XLC64EXEC-NEXT: Size of .bss section: 0x8 -# XLC64EXEC-NEXT: Entry point address: 0x110000710 -# XLC64EXEC-NEXT: Maximum stack size: 0x0 -# XLC64EXEC-NEXT: Maximum data size: 0x0 -# XLC64EXEC-NEXT: Section number for .tdata: 0 -# XLC64EXEC-NEXT: Section number for .tbss: 0 -# XLC64EXEC-NEXT: Additional flags 64-bit XCOFF: 0x0 -# WARN64: {{.*}}llvm-readobj: warning: '': There are extra data beyond auxiliary header -# XLC64EXEC-NEXT: Extra raw data: (00 00 00 00 00 00 00 00 00 00) -# XLC64EXEC-NEXT: } - -# XLC32OBJ: File: {{.*}}xcoff-32-xlc-obj.o -# XLC32OBJ-NEXT: Format: aixcoff-rs6000 -# XLC32OBJ-NEXT: Arch: powerpc -# XLC32OBJ-NEXT: AddressSize: 32bit -# XLC32OBJ: AuxiliaryHeader { -# XLC32OBJ-NEXT: Magic: 0x10B -# XLC32OBJ-NEXT: Version: 0x0 -# XLC32OBJ-NEXT: Size of .text section: 0x200 -# XLC32OBJ-NEXT: Size of .data section: 0x3C -# XLC32OBJ-NEXT: Size of .bss section: 0x0 -# XLC32OBJ-NEXT: Entry point address: 0x0 -# XLC32OBJ-NEXT: .text section start address: 0x0 -# XLC32OBJ-NEXT: .data section start address: 0x200 -# XLC32OBJ-NEXT: } - -# XLC32OBJ-PART: File: {{.*}}xcoff-32-xlc-obj-malform.o -# XLC32OBJ-PART-NEXT: Format: aixcoff-rs6000 -# XLC32OBJ-PART-NEXT: Arch: powerpc -# XLC32OBJ-PART-NEXT: AddressSize: 32bit -# XLC32OBJ-PART-NEXT: AuxiliaryHeader { -# XLC32OBJ-PART-NEXT: Magic: 0x10B -# XLC32OBJ-PART-NEXT: Version: 0x0 -# XLC32OBJ-PART-NEXT: Size of .text section: 0x200 -# XLC32OBJ-PART-NEXT: Size of .data section: 0x3C -# XLC32OBJ-PART-NEXT: Size of .bss section: 0x0 -# XLC32OBJ-PART-NEXT: Entry point address: 0x0 -# XLC32OBJ-PART-NEXT: .text section start address: 0x0 -# WARN-PART: {{.*}}llvm-readobj: warning: '': Only partial field for .data section start address at offset (24). -# XLC32OBJ-PART-NEXT: Raw data: (00 00 02) -# XLC32OBJ-PART-NEXT: } - diff --git a/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml b/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml @@ -104,7 +104,7 @@ # CASE2-NEXT: Text page size: 0x0 # CASE2-NEXT: Data page size: 0x0 # CASE2-NEXT: Stack page size: 0x0 -# CASE2-NEXT: Flag: 0x0 +# CASE2-NEXT: Flag: 0x80 # CASE2-NEXT: Alignment of thread-local storage: 0x0 # CASE2-NEXT: Size of .text section: 0x8 # CASE2-NEXT: Size of .data section: 0x8 @@ -185,7 +185,7 @@ # CASE4-NEXT: Text page size: 0x0 # CASE4-NEXT: Data page size: 0x0 # CASE4-NEXT: Stack page size: 0x0 -# CASE4-NEXT: Flag: 0x0 +# CASE4-NEXT: Flag: 0x80 # CASE4-NEXT: Alignment of thread-local storage: 0x0 # CASE4-NEXT: Size of .text section: 0x0 # CASE4-NEXT: Size of .data section: 0x0 diff --git a/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-full-contents.yaml b/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-full-contents.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-full-contents.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-full-contents.yaml @@ -67,7 +67,7 @@ # CHECK64-NEXT: Data page size: 0x1 # CHECK64-NEXT: Stack page size: 0x1 # CHECK64-NEXT: Flag: 0x0 -# CHECK64-NEXT: Alignment of thread-local storage: 0x0 +# CHECK64-NEXT: Alignment of thread-local storage: 0x1 # CHECK64-NEXT: Size of .text section: 0x8 # CHECK64-NEXT: Size of .data section: 0x9 # CHECK64-NEXT: Size of .bss section: 0x10 diff --git a/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml b/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml @@ -46,6 +46,8 @@ # CHECK-NEXT: OptionalHeaderSize: 0x0 # CHECK-NEXT: Flags: 0x0 # CHECK-NEXT: } +# CHECK-NEXT: AuxiliaryHeader { +# CHECK-NEXT: } # CHECK-NEXT: Sections [ # CHECK-NEXT: Section { # CHECK-NEXT: Index: 1 diff --git a/llvm/test/tools/yaml2obj/XCOFF/basic-doc64.yaml b/llvm/test/tools/yaml2obj/XCOFF/basic-doc64.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/basic-doc64.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/basic-doc64.yaml @@ -42,6 +42,8 @@ # CHECK64-NEXT: OptionalHeaderSize: 0x0 # CHECK64-NEXT: Flags: 0x0 # CHECK64-NEXT: } +# CHECK64-NEXT: AuxiliaryHeader { +# CHECK64-NEXT: } # CHECK64-NEXT: Sections [ # CHECK64-NEXT: Section { # CHECK64-NEXT: Index: 1 diff --git a/llvm/test/tools/yaml2obj/XCOFF/full-contents.yaml b/llvm/test/tools/yaml2obj/XCOFF/full-contents.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/full-contents.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/full-contents.yaml @@ -60,6 +60,8 @@ # CHECK-NEXT: OptionalHeaderSize: 0x0 # CHECK-NEXT: Flags: 0x0 # CHECK-NEXT: } +# CHECK-NEXT: AuxiliaryHeader { +# CHECK-NEXT: } # CHECK-NEXT: Sections [ # CHECK-NEXT: Section { # CHECK-NEXT: Index: 1 diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td --- a/llvm/tools/llvm-readobj/Opts.td +++ b/llvm/tools/llvm-readobj/Opts.td @@ -86,7 +86,7 @@ // XCOFF specific options. def grp_xcoff : OptionGroup<"kind">, HelpText<"OPTIONS (XCOFF specific)">; -def auxiliary_header : FF<"auxiliary-header" , "display the auxiliary header">, Group; +def auxiliary_header : FF<"auxiliary-header" , "Display the auxiliary header">, Group; 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 --- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp +++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp @@ -17,7 +17,6 @@ #include "llvm/Support/ScopedPrinter.h" #include -#include using namespace llvm; using namespace object; @@ -41,6 +40,8 @@ void printNeededLibraries() override; void printStringTable() override; + ScopedPrinter &getScopedPrinter() const { return W; } + private: template void printSectionHeaders(ArrayRef Sections); template void printGenericSectionHeader(T &Sec) const; @@ -113,6 +114,8 @@ } void XCOFFDumper::printAuxiliaryHeader() { + DictScope DS(W, "AuxiliaryHeader"); + if (Obj.is64Bit()) printAuxiliaryHeader(Obj.auxiliaryHeader64()); else @@ -736,6 +739,46 @@ W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers); } +enum PrintStyle { Hex, Number }; +template +static void printAuxMemberHelper(PrintStyle Style, const char *MemberName, + const T &Member, const V *AuxHeader, + uint16_t AuxSize, uint16_t &PartialFieldOffset, + const char *&PartialFieldName, + ScopedPrinter &W) { + ptrdiff_t Offset = reinterpret_cast(&Member) - + reinterpret_cast(AuxHeader); + if (Offset + sizeof(Member) <= AuxSize) + Style == Hex ? W.printHex(MemberName, Member) + : W.printNumber(MemberName, Member); + else if (Offset < AuxSize) { + PartialFieldOffset = Offset; + PartialFieldName = MemberName; + } +} + +template +void checkAndPrintAuxHeaderParseError(const char *PartialFieldName, + uint16_t PartialFieldOffset, + uint16_t AuxSize, T &AuxHeader, + XCOFFDumper *Dumper) { + if (PartialFieldOffset < AuxSize) { + Dumper->reportUniqueWarning(Twine("only partial field for ") + + PartialFieldName + " at offset (" + + Twine(PartialFieldOffset) + ")"); + Dumper->getScopedPrinter().printBinary( + "Raw data", "", + ArrayRef(reinterpret_cast(&AuxHeader) + + PartialFieldOffset, + AuxSize - PartialFieldOffset)); + } else if (sizeof(AuxHeader) < AuxSize) + Dumper->getScopedPrinter().printBinary( + "Extra raw data", "", + ArrayRef(reinterpret_cast(&AuxHeader) + + sizeof(AuxHeader), + AuxSize - sizeof(AuxHeader))); +} + void XCOFFDumper::printAuxiliaryHeader( const XCOFFAuxiliaryHeader32 *AuxHeader) { if (AuxHeader == nullptr) @@ -744,44 +787,40 @@ uint16_t PartialFieldOffset = AuxSize; const char *PartialFieldName = nullptr; - DictScope DS(W, "AuxiliaryHeader"); - -#define PrintAuxMember32(H, S, T) \ - if (offsetof(XCOFFAuxiliaryHeader32, T) + \ - sizeof(XCOFFAuxiliaryHeader32::T) <= \ - AuxSize) \ - W.print##H(S, AuxHeader->T); \ - else if (offsetof(XCOFFAuxiliaryHeader32, T) < AuxSize) { \ - PartialFieldOffset = offsetof(XCOFFAuxiliaryHeader32, T); \ - PartialFieldName = S; \ - } + auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName, + auto &Member) { + printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize, + PartialFieldOffset, PartialFieldName, W); + }; - PrintAuxMember32(Hex, "Magic", AuxMagic); - PrintAuxMember32(Hex, "Version", Version); - PrintAuxMember32(Hex, "Size of .text section", TextSize); - PrintAuxMember32(Hex, "Size of .data section", InitDataSize); - PrintAuxMember32(Hex, "Size of .bss section", BssDataSize); - PrintAuxMember32(Hex, "Entry point address", EntryPointAddr); - PrintAuxMember32(Hex, ".text section start address", TextStartAddr); - PrintAuxMember32(Hex, ".data section start address", DataStartAddr); - PrintAuxMember32(Hex, "TOC anchor address", TOCAnchorAddr); - PrintAuxMember32(Number, "Section number of entryPoint", SecNumOfEntryPoint); - PrintAuxMember32(Number, "Section number of .text", SecNumOfText); - PrintAuxMember32(Number, "Section number of .data", SecNumOfData); - PrintAuxMember32(Number, "Section number of TOC", SecNumOfTOC); - PrintAuxMember32(Number, "Section number of loader data", SecNumOfLoader); - PrintAuxMember32(Number, "Section number of .bss", SecNumOfBSS); - PrintAuxMember32(Hex, "Maxium alignment of .text", MaxAlignOfText); - PrintAuxMember32(Hex, "Maxium alignment of .data", MaxAlignOfData); - PrintAuxMember32(Hex, "Module type", ModuleType); - PrintAuxMember32(Hex, "CPU type of objects", CpuFlag); - PrintAuxMember32(Hex, "(Reserved)", CpuType); - PrintAuxMember32(Hex, "Maximum stack size", MaxStackSize); - PrintAuxMember32(Hex, "Maximum data size", MaxDataSize); - PrintAuxMember32(Hex, "Reserved for debugger", ReservedForDebugger); - PrintAuxMember32(Hex, "Text page size", TextPageSize); - PrintAuxMember32(Hex, "Data page size", DataPageSize); - PrintAuxMember32(Hex, "Stack page size", StackPageSize); + PrintAuxMember(Hex, "Magic", AuxHeader->AuxMagic); + PrintAuxMember(Hex, "Version", AuxHeader->Version); + PrintAuxMember(Hex, "Size of .text section", AuxHeader->TextSize); + PrintAuxMember(Hex, "Size of .data section", AuxHeader->InitDataSize); + PrintAuxMember(Hex, "Size of .bss section", AuxHeader->BssDataSize); + PrintAuxMember(Hex, "Entry point address", AuxHeader->EntryPointAddr); + PrintAuxMember(Hex, ".text section start address", AuxHeader->TextStartAddr); + PrintAuxMember(Hex, ".data section start address", AuxHeader->DataStartAddr); + PrintAuxMember(Hex, "TOC anchor address", AuxHeader->TOCAnchorAddr); + PrintAuxMember(Number, "Section number of entryPoint", + AuxHeader->SecNumOfEntryPoint); + PrintAuxMember(Number, "Section number of .text", AuxHeader->SecNumOfText); + PrintAuxMember(Number, "Section number of .data", AuxHeader->SecNumOfData); + PrintAuxMember(Number, "Section number of TOC", AuxHeader->SecNumOfTOC); + PrintAuxMember(Number, "Section number of loader data", + AuxHeader->SecNumOfLoader); + PrintAuxMember(Number, "Section number of .bss", AuxHeader->SecNumOfBSS); + PrintAuxMember(Hex, "Maxium alignment of .text", AuxHeader->MaxAlignOfText); + PrintAuxMember(Hex, "Maxium alignment of .data", AuxHeader->MaxAlignOfData); + PrintAuxMember(Hex, "Module type", AuxHeader->ModuleType); + PrintAuxMember(Hex, "CPU type of objects", AuxHeader->CpuFlag); + PrintAuxMember(Hex, "(Reserved)", AuxHeader->CpuType); + PrintAuxMember(Hex, "Maximum stack size", AuxHeader->MaxStackSize); + PrintAuxMember(Hex, "Maximum data size", AuxHeader->MaxDataSize); + PrintAuxMember(Hex, "Reserved for debugger", AuxHeader->ReservedForDebugger); + PrintAuxMember(Hex, "Text page size", AuxHeader->TextPageSize); + PrintAuxMember(Hex, "Data page size", AuxHeader->DataPageSize); + PrintAuxMember(Hex, "Stack page size", AuxHeader->StackPageSize); if (offsetof(XCOFFAuxiliaryHeader32, FlagAndTDataAlignment) + sizeof(XCOFFAuxiliaryHeader32::FlagAndTDataAlignment) <= AuxSize) { @@ -790,35 +829,11 @@ AuxHeader->getTDataAlignment()); } - PrintAuxMember32(Number, "Section number for .tdata", SecNumOfTData); - PrintAuxMember32(Number, "Section number for .tbss", SecNumOfTBSS); + PrintAuxMember(Number, "Section number for .tdata", AuxHeader->SecNumOfTData); + PrintAuxMember(Number, "Section number for .tbss", AuxHeader->SecNumOfTBSS); - // Deal with error. - if (PartialFieldOffset < AuxSize) { - std::string ErrInfo; - llvm::raw_string_ostream StringOS(ErrInfo); - StringOS << "Only partial field for " << PartialFieldName << " at offset (" - << PartialFieldOffset << ")."; - StringOS.flush(); - reportWarning( - make_error(ErrInfo, object_error::parse_failed), - "-"); - W.printBinary( - "Raw data", "", - ArrayRef((const uint8_t *)(AuxHeader) + PartialFieldOffset, - AuxSize - PartialFieldOffset)); - } else if (sizeof(XCOFFAuxiliaryHeader32) < AuxSize) { - reportWarning(make_error( - "There are extra data beyond auxiliary header", - object_error::parse_failed), - "-"); - W.printBinary("Extra raw data", "", - ArrayRef((const uint8_t *)(AuxHeader) + - sizeof(XCOFFAuxiliaryHeader32), - AuxSize - sizeof(XCOFFAuxiliaryHeader32))); - } - -#undef PrintAuxMember32 + checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset, + AuxSize, *AuxHeader, this); } void XCOFFDumper::printAuxiliaryHeader( @@ -829,38 +844,34 @@ uint16_t PartialFieldOffset = AuxSize; const char *PartialFieldName = nullptr; - DictScope DS(W, "AuxiliaryHeader"); - -#define PrintAuxMember64(H, S, T) \ - if (offsetof(XCOFFAuxiliaryHeader64, T) + \ - sizeof(XCOFFAuxiliaryHeader64::T) <= \ - AuxSize) \ - W.print##H(S, AuxHeader->T); \ - else if (offsetof(XCOFFAuxiliaryHeader64, T) < AuxSize) { \ - PartialFieldOffset = offsetof(XCOFFAuxiliaryHeader64, T); \ - PartialFieldName = S; \ - } + auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName, + auto &Member) { + printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize, + PartialFieldOffset, PartialFieldName, W); + }; - PrintAuxMember64(Hex, "Magic", AuxMagic); - PrintAuxMember64(Hex, "Version", Version); - PrintAuxMember64(Hex, "Reserved for debugger", ReservedForDebugger); - PrintAuxMember64(Hex, ".text section start address", TextStartAddr); - PrintAuxMember64(Hex, ".data section start address", DataStartAddr); - PrintAuxMember64(Hex, "TOC anchor address", TOCAnchorAddr); - PrintAuxMember64(Number, "Section number of entryPoint", SecNumOfEntryPoint); - PrintAuxMember64(Number, "Section number of .text", SecNumOfText); - PrintAuxMember64(Number, "Section number of .data", SecNumOfData); - PrintAuxMember64(Number, "Section number of TOC", SecNumOfTOC); - PrintAuxMember64(Number, "Section number of loader data", SecNumOfLoader); - PrintAuxMember64(Number, "Section number of .bss", SecNumOfBSS); - PrintAuxMember64(Hex, "Maxium alignment of .text", MaxAlignOfText); - PrintAuxMember64(Hex, "Maxium alignment of .data", MaxAlignOfData); - PrintAuxMember64(Hex, "Module type", ModuleType); - PrintAuxMember64(Hex, "CPU type of objects", CpuFlag); - PrintAuxMember64(Hex, "(Reserved)", CpuType); - PrintAuxMember64(Hex, "Text page size", TextPageSize); - PrintAuxMember64(Hex, "Data page size", DataPageSize); - PrintAuxMember64(Hex, "Stack page size", StackPageSize); + PrintAuxMember(Hex, "Magic", AuxHeader->AuxMagic); + PrintAuxMember(Hex, "Version", AuxHeader->Version); + PrintAuxMember(Hex, "Reserved for debugger", AuxHeader->ReservedForDebugger); + PrintAuxMember(Hex, ".text section start address", AuxHeader->TextStartAddr); + PrintAuxMember(Hex, ".data section start address", AuxHeader->DataStartAddr); + PrintAuxMember(Hex, "TOC anchor address", AuxHeader->TOCAnchorAddr); + PrintAuxMember(Number, "Section number of entryPoint", + AuxHeader->SecNumOfEntryPoint); + PrintAuxMember(Number, "Section number of .text", AuxHeader->SecNumOfText); + PrintAuxMember(Number, "Section number of .data", AuxHeader->SecNumOfData); + PrintAuxMember(Number, "Section number of TOC", AuxHeader->SecNumOfTOC); + PrintAuxMember(Number, "Section number of loader data", + AuxHeader->SecNumOfLoader); + PrintAuxMember(Number, "Section number of .bss", AuxHeader->SecNumOfBSS); + PrintAuxMember(Hex, "Maxium alignment of .text", AuxHeader->MaxAlignOfText); + PrintAuxMember(Hex, "Maxium alignment of .data", AuxHeader->MaxAlignOfData); + PrintAuxMember(Hex, "Module type", AuxHeader->ModuleType); + PrintAuxMember(Hex, "CPU type of objects", AuxHeader->CpuFlag); + PrintAuxMember(Hex, "(Reserved)", AuxHeader->CpuType); + PrintAuxMember(Hex, "Text page size", AuxHeader->TextPageSize); + PrintAuxMember(Hex, "Data page size", AuxHeader->DataPageSize); + PrintAuxMember(Hex, "Stack page size", AuxHeader->StackPageSize); if (offsetof(XCOFFAuxiliaryHeader64, FlagAndTDataAlignment) + sizeof(XCOFFAuxiliaryHeader64::FlagAndTDataAlignment) <= AuxSize) { @@ -868,42 +879,18 @@ W.printHex("Alignment of thread-local storage", AuxHeader->getTDataAlignment()); } - PrintAuxMember64(Hex, "Size of .text section", TextSize); - PrintAuxMember64(Hex, "Size of .data section", InitDataSize); - PrintAuxMember64(Hex, "Size of .bss section", BssDataSize); - PrintAuxMember64(Hex, "Entry point address", EntryPointAddr); - PrintAuxMember64(Hex, "Maximum stack size", MaxStackSize); - PrintAuxMember64(Hex, "Maximum data size", MaxDataSize); - PrintAuxMember64(Number, "Section number for .tdata", SecNumOfTData); - PrintAuxMember64(Number, "Section number for .tbss", SecNumOfTBSS); - PrintAuxMember64(Hex, "Additional flags 64-bit XCOFF", XCOFF64Flag); - - if (PartialFieldOffset < AuxSize) { - std::string ErrInfo; - llvm::raw_string_ostream StringOS(ErrInfo); - StringOS << "Only partial field for " << PartialFieldName << " at offset (" - << PartialFieldOffset << ")."; - StringOS.flush(); - reportWarning( - make_error(ErrInfo, object_error::parse_failed), - "-"); - ; - W.printBinary( - "Raw data", "", - ArrayRef((const uint8_t *)(AuxHeader) + PartialFieldOffset, - AuxSize - PartialFieldOffset)); - } else if (sizeof(XCOFFAuxiliaryHeader64) < AuxSize) { - reportWarning(make_error( - "There are extra data beyond auxiliary header", - object_error::parse_failed), - "-"); - W.printBinary("Extra raw data", "", - ArrayRef((const uint8_t *)(AuxHeader) + - sizeof(XCOFFAuxiliaryHeader64), - AuxSize - sizeof(XCOFFAuxiliaryHeader64))); - } - -#undef PrintAuxMember64 + PrintAuxMember(Hex, "Size of .text section", AuxHeader->TextSize); + PrintAuxMember(Hex, "Size of .data section", AuxHeader->InitDataSize); + PrintAuxMember(Hex, "Size of .bss section", AuxHeader->BssDataSize); + PrintAuxMember(Hex, "Entry point address", AuxHeader->EntryPointAddr); + PrintAuxMember(Hex, "Maximum stack size", AuxHeader->MaxStackSize); + PrintAuxMember(Hex, "Maximum data size", AuxHeader->MaxDataSize); + PrintAuxMember(Number, "Section number for .tdata", AuxHeader->SecNumOfTData); + PrintAuxMember(Number, "Section number for .tbss", AuxHeader->SecNumOfTBSS); + PrintAuxMember(Hex, "Additional flags 64-bit XCOFF", AuxHeader->XCOFF64Flag); + + checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset, + AuxSize, *AuxHeader, this); } template