[llvm] [llvm-objdump] Implement decoding auxiliary header for xcoff with llvm-objdump --private-headers (PR #105682)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 21 11:01:10 PDT 2024


https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/105682

>From 3a52dd23bac83d66573cb9be0359cfb756d38396 Mon Sep 17 00:00:00 2001
From: Zhijian Lin <zhijian at kuat.aus.stglabs.ibm.com>
Date: Thu, 22 Aug 2024 10:33:59 -0500
Subject: [PATCH 1/7] implement decoding auxiliary header for xcoff with
 llvm-objdump --private-headers

---
 .../XCOFF/private-header-auxiliary.test       | 126 ++++++++++++
 llvm/tools/llvm-objdump/XCOFFDump.cpp         | 188 +++++++++++++++++-
 2 files changed, 310 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test

diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
new file mode 100644
index 00000000000000..848b43b5db2d74
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
@@ -0,0 +1,126 @@
+## Test that `the llvm-objdump --private-headers` print out the auxiliary header of XCOFF object file.
+
+# RUN: yaml2obj %s -o %t1
+# RUN: llvm-objdump --private-headers %t1 | FileCheck %s --check-prefix=CHECK32
+# RUN: cp %t1 %t1_err1
+# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45')"
+# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(4); input.write(b'\x00')"
+# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1
+# RUN: cp %t1 %t1_extra
+# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(4); input.write(b'\x00')"
+# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f')"
+# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA
+# RUN: yaml2obj %s -DMAGIC=0x1F7 -DFLAG64=0x2 -o %t2
+# RUN: llvm-objdump --private-headers %t2 | FileCheck %s --check-prefix=CHECK64
+
+
+# CHECK32:      ---Auxiliary Header:
+# CHECK32-NEXT: Magic:                              0x10b
+# CHECK32-NEXT: Version:                            0x1
+# CHECK32-NEXT: Size of .text section:              0x8
+# CHECK32-NEXT: Size of .data section:              0x9
+# CHECK32-NEXT: Size of .bss section:               0x10
+# CHECK32-NEXT: Entry point address:                0x1111
+# CHECK32-NEXT: .text section start address:        0x2222
+# CHECK32-NEXT: .data section start address;        0x3333
+# CHECK32-NEXT: TOC anchor address:                 0x4444
+# CHECK32-NEXT: Section number of entryPoint:       1
+# CHECK32-NEXT: Section number of .text:            2
+# CHECK32-NEXT: Section number of .data:            3
+# CHECK32-NEXT: Section number of TOC:              4
+# CHECK32-NEXT: Section number of loader data:      5
+# CHECK32-NEXT: Section number of .bss:             6
+# CHECK32-NEXT: Maxium alignment of .text:          0x7
+# CHECK32-NEXT: Maxium alignment of .data:          0x3
+# CHECK32-NEXT: Module type;                        0x0
+# CHECK32-NEXT: CPU type of objects:                0x1
+# CHECK32-NEXT: (Reserved):                         0x0
+# CHECK32-NEXT: Maximum stack size:                 0x0
+# CHECK32-NEXT: Maximum data size:                  0x0
+# CHECK32-NEXT: Reserved for debugger:              0x0
+# CHECK32-NEXT: Text page size:                     0x1
+# CHECK32-NEXT: Data page size:                     0x1
+# CHECK32-NEXT: Stack page size:                    0x1
+# CHECK32-NEXT: Flag:                               0x0
+# CHECK32-NEXT: Alignment of thread-local storage:  0x1
+# CHECK32-NEXT: Section number for .tdata:          7
+# CHECK32-NEXT: Section number for .tbss:           8
+
+# CHECK64:      ---Auxiliary Header:
+# CHECK64-NEXT: Magic:                              0x10b
+# CHECK64-NEXT: Version:                            0x1
+# CHECK64-NEXT: Reserved for debugger:              0x0
+# CHECK64-NEXT: .text section start address:        0x2222
+# CHECK64-NEXT: .data section start address:        0x3333
+# CHECK64-NEXT: TOC anchor address:                 0x4444
+# CHECK64-NEXT: Section number of entryPoint:       1
+# CHECK64-NEXT: Section number of .text:            2
+# CHECK64-NEXT: Section number of .data:            3
+# CHECK64-NEXT: Section number of TOC:              4
+# CHECK64-NEXT: Section number of loader data:      5
+# CHECK64-NEXT: Section number of .bss:             6
+# CHECK64-NEXT: Maxium alignment of .text:          0x7
+# CHECK64-NEXT: Maxium alignment of .data:          0x3
+# CHECK64-NEXT: Module type:                        0x0
+# CHECK64-NEXT: CPU type of objects:                0x1
+# CHECK64-NEXT: (Reserved):                         0x0
+# CHECK64-NEXT: Text page size:                     0x1
+# CHECK64-NEXT: Data page size:                     0x1
+# CHECK64-NEXT: Stack page size:                    0x1
+# CHECK64-NEXT: Flag:                               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
+# CHECK64-NEXT: Entry point address:                0x1111
+# CHECK64-NEXT: Maximum stack size:                 0x0
+# CHECK64-NEXT: Maximum data size:                  0x0
+# CHECK64-NEXT: Section number for .tdata:          7
+# CHECK64-NEXT: Section number for .tbss:           8
+# CHECK64-NEXT: Additional flags 64-bit XCOFF:      0x2
+
+# WARN1:       {{.*}}: only partial field for Section number for .tdata: at offset (68)
+# WARN1-NEXT:  Raw data (00)
+
+# EXTRA: Extra raw data (00000000 000000)
+
+--- !XCOFF
+FileHeader:
+  MagicNumber: [[MAGIC=0x1DF]]
+AuxiliaryHeader:
+  Magic:                 0x10B
+  Version:               0x1
+  TextSectionSize:       0x8
+  DataSectionSize:       0x9
+  BssSectionSize:        0x10
+  EntryPointAddr:        0x1111
+  TextStartAddr:         0x2222
+  DataStartAddr:         0x3333
+  TOCAnchorAddr:         0x4444
+  SecNumOfEntryPoint:    1
+  SecNumOfText:          2
+  SecNumOfData:          3
+  SecNumOfTOC:           4
+  SecNumOfLoader:        5
+  SecNumOfBSS:           6
+  MaxAlignOfText:        0x7
+  MaxAlignOfData:        0x3
+  ModuleType:            0x1
+  TextPageSize:          0x1
+  DataPageSize:          0x1
+  StackPageSize:         0x1
+  SecNumOfTData:         7
+  SecNumOfTBSS:          8
+  FlagAndTDataAlignment: 0x1
+  Flag:                  [[FLAG64=<none>]]
+Sections:
+  - Flags:       [ STYP_TEXT ]
+    SectionData: "1232"
+  - Flags:       [ STYP_DATA ]
+    SectionData: "5678"
+  - Flags:       [ STYP_BSS ]
+    SectionData: "9101"
+  - Flags:       [ STYP_TDATA ]
+    SectionData: "1112"
+  - Flags:       [ STYP_TBSS ]
+    SectionData: "1314"
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 524bf07c372a9b..34718fedfc14b5 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -37,18 +37,26 @@ class XCOFFDumper : public objdump::Dumper {
 
 public:
   XCOFFDumper(const object::XCOFFObjectFile &O) : Dumper(O), Obj(O) {}
+  void printBinary(StringRef Name, ArrayRef<uint8_t> B);
+  void printHex(StringRef Name, uint64_t Value);
+  void printNumber(StringRef Name, uint64_t Value);
 
 private:
   void printPrivateHeaders() override;
   void printFileHeader();
+  void printAuxiliaryHeader();
+  void printAuxiliaryHeader(const XCOFFAuxiliaryHeader32 *AuxHeader);
+  void printAuxiliaryHeader(const XCOFFAuxiliaryHeader64 *AuxHeader);
   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; };
+  unsigned getWidth() { return Width; }
 };
 
-void XCOFFDumper::printPrivateHeaders() { printFileHeader(); }
+void XCOFFDumper::printPrivateHeaders() {
+  printFileHeader();
+  printAuxiliaryHeader();
+}
 
 FormattedString XCOFFDumper::formatName(StringRef Name) {
   return FormattedString(Name, Width, FormattedString::JustifyLeft);
@@ -67,6 +75,179 @@ void XCOFFDumper::printStrHex(StringRef Name, StringRef Str, uint64_t Value) {
          << ")\n";
 }
 
+void XCOFFDumper::printBinary(StringRef Name, ArrayRef<uint8_t> B) {
+  unsigned OrgWidth = getWidth();
+  setWidth(0);
+  outs() << formatName(Name) << " (" << format_bytes(B) << ")\n";
+  setWidth(OrgWidth);
+}
+
+void XCOFFDumper::printAuxiliaryHeader() {
+  setWidth(36);
+  if (Obj.is64Bit())
+    printAuxiliaryHeader(Obj.auxiliaryHeader64());
+  else
+    printAuxiliaryHeader(Obj.auxiliaryHeader32());
+}
+
+enum PrintStyle { Hex, Number };
+template <typename T, typename V>
+static void printAuxMemberHelper(PrintStyle Style, const char *MemberName,
+                                 const T &Member, const V *AuxHeader,
+                                 uint16_t AuxSize, uint16_t &PartialFieldOffset,
+                                 const char *&PartialFieldName,
+                                 XCOFFDumper *Dumper) {
+  ptrdiff_t Offset = reinterpret_cast<const char *>(&Member) -
+                     reinterpret_cast<const char *>(AuxHeader);
+  if (Offset + sizeof(Member) <= AuxSize)
+    Style == Hex ? Dumper->printHex(MemberName, Member)
+                 : Dumper->printNumber(MemberName, Member);
+  else if (Offset < AuxSize) {
+    PartialFieldOffset = Offset;
+    PartialFieldName = MemberName;
+  }
+}
+
+template <class T>
+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->printBinary(
+        "Raw data",
+        ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
+                              PartialFieldOffset,
+                          AuxSize - PartialFieldOffset));
+  } else if (sizeof(AuxHeader) < AuxSize)
+    Dumper->printBinary(
+        "Extra raw data",
+        ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
+                              sizeof(AuxHeader),
+                          AuxSize - sizeof(AuxHeader)));
+}
+
+void XCOFFDumper::printAuxiliaryHeader(
+    const XCOFFAuxiliaryHeader32 *AuxHeader) {
+  if (AuxHeader == nullptr)
+    return;
+  outs() << "\n---Auxiliary Header:\n";
+  uint16_t AuxSize = Obj.getOptionalHeaderSize();
+  uint16_t PartialFieldOffset = AuxSize;
+  const char *PartialFieldName = nullptr;
+
+  auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
+                            auto &Member) {
+    printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize,
+                         PartialFieldOffset, PartialFieldName, this);
+  };
+
+  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) {
+    printHex("Flag:", AuxHeader->getFlag());
+    printHex("Alignment of thread-local storage:",
+             AuxHeader->getTDataAlignment());
+  }
+
+  PrintAuxMember(Number,
+                 "Section number for .tdata:", AuxHeader->SecNumOfTData);
+  PrintAuxMember(Number, "Section number for .tbss:", AuxHeader->SecNumOfTBSS);
+
+  checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset,
+                                   AuxSize, *AuxHeader, this);
+}
+
+void XCOFFDumper::printAuxiliaryHeader(
+    const XCOFFAuxiliaryHeader64 *AuxHeader) {
+  if (AuxHeader == nullptr)
+    return;
+  uint16_t AuxSize = Obj.getOptionalHeaderSize();
+  outs() << "\n---Auxiliary Header:\n";
+  uint16_t PartialFieldOffset = AuxSize;
+  const char *PartialFieldName = nullptr;
+
+  auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
+                            auto &Member) {
+    printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize,
+                         PartialFieldOffset, PartialFieldName, this);
+  };
+
+  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) {
+    printHex("Flag:", AuxHeader->getFlag());
+    printHex("Alignment of thread-local storage:",
+             AuxHeader->getTDataAlignment());
+  }
+  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);
+}
+
 void XCOFFDumper::printFileHeader() {
   setWidth(20);
   outs() << "\n---File Header:\n";
@@ -112,7 +293,6 @@ void XCOFFDumper::printFileHeader() {
   printHex("OptionalHeaderSize:", Obj.getOptionalHeaderSize());
   printHex("Flags:", Obj.getFlags());
 }
-
 } // namespace
 
 std::unique_ptr<objdump::Dumper>

>From 935775cbf0de787865016a9fc0ba8037a49fb87f Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Thu, 22 Aug 2024 10:55:06 -0500
Subject: [PATCH 2/7] minor change

---
 llvm/tools/llvm-objdump/XCOFFDump.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 34718fedfc14b5..74cd832aba0a15 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -293,6 +293,7 @@ void XCOFFDumper::printFileHeader() {
   printHex("OptionalHeaderSize:", Obj.getOptionalHeaderSize());
   printHex("Flags:", Obj.getFlags());
 }
+
 } // namespace
 
 std::unique_ptr<objdump::Dumper>

>From e38e11ff4d5ef69c20dee17506990c3fee114d92 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Thu, 22 Aug 2024 12:20:00 -0500
Subject: [PATCH 3/7] add more FileCheck options

---
 .../XCOFF/private-header-auxiliary.test       | 136 +++++++++---------
 1 file changed, 69 insertions(+), 67 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
index 848b43b5db2d74..b6670f16743c72 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
@@ -1,83 +1,85 @@
 ## Test that `the llvm-objdump --private-headers` print out the auxiliary header of XCOFF object file.
 
 # RUN: yaml2obj %s -o %t1
-# RUN: llvm-objdump --private-headers %t1 | FileCheck %s --check-prefix=CHECK32
+# RUN: llvm-objdump --private-headers %t1 | \
+# RUN:   FileCheck %s --check-prefix=CHECK32 --match-full-lines --strict-whitespace
 # RUN: cp %t1 %t1_err1
 # RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45')"
 # RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(4); input.write(b'\x00')"
-# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1
+# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines
 # RUN: cp %t1 %t1_extra
 # RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(4); input.write(b'\x00')"
 # RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f')"
-# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA
+# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines
 # RUN: yaml2obj %s -DMAGIC=0x1F7 -DFLAG64=0x2 -o %t2
-# RUN: llvm-objdump --private-headers %t2 | FileCheck %s --check-prefix=CHECK64
+# RUN: llvm-objdump --private-headers %t2 | \
+# RUN:   FileCheck %s --check-prefix=CHECK64 --match-full-lines --strict-whitespace
 
 
-# CHECK32:      ---Auxiliary Header:
-# CHECK32-NEXT: Magic:                              0x10b
-# CHECK32-NEXT: Version:                            0x1
-# CHECK32-NEXT: Size of .text section:              0x8
-# CHECK32-NEXT: Size of .data section:              0x9
-# CHECK32-NEXT: Size of .bss section:               0x10
-# CHECK32-NEXT: Entry point address:                0x1111
-# CHECK32-NEXT: .text section start address:        0x2222
-# CHECK32-NEXT: .data section start address;        0x3333
-# CHECK32-NEXT: TOC anchor address:                 0x4444
-# CHECK32-NEXT: Section number of entryPoint:       1
-# CHECK32-NEXT: Section number of .text:            2
-# CHECK32-NEXT: Section number of .data:            3
-# CHECK32-NEXT: Section number of TOC:              4
-# CHECK32-NEXT: Section number of loader data:      5
-# CHECK32-NEXT: Section number of .bss:             6
-# CHECK32-NEXT: Maxium alignment of .text:          0x7
-# CHECK32-NEXT: Maxium alignment of .data:          0x3
-# CHECK32-NEXT: Module type;                        0x0
-# CHECK32-NEXT: CPU type of objects:                0x1
-# CHECK32-NEXT: (Reserved):                         0x0
-# CHECK32-NEXT: Maximum stack size:                 0x0
-# CHECK32-NEXT: Maximum data size:                  0x0
-# CHECK32-NEXT: Reserved for debugger:              0x0
-# CHECK32-NEXT: Text page size:                     0x1
-# CHECK32-NEXT: Data page size:                     0x1
-# CHECK32-NEXT: Stack page size:                    0x1
-# CHECK32-NEXT: Flag:                               0x0
-# CHECK32-NEXT: Alignment of thread-local storage:  0x1
-# CHECK32-NEXT: Section number for .tdata:          7
-# CHECK32-NEXT: Section number for .tbss:           8
+#      CHECK32:---Auxiliary Header:
+# CHECK32-NEXT:Magic:                              0x10b
+# CHECK32-NEXT:Version:                            0x1
+# CHECK32-NEXT:Size of .text section:              0x8
+# CHECK32-NEXT:Size of .data section:              0x9
+# CHECK32-NEXT:Size of .bss section:               0x10
+# CHECK32-NEXT:Entry point address:                0x1111
+# CHECK32-NEXT:.text section start address:        0x2222
+# CHECK32-NEXT:.data section start address;        0x3333
+# CHECK32-NEXT:TOC anchor address:                 0x4444
+# CHECK32-NEXT:Section number of entryPoint:       1
+# CHECK32-NEXT:Section number of .text:            2
+# CHECK32-NEXT:Section number of .data:            3
+# CHECK32-NEXT:Section number of TOC:              4
+# CHECK32-NEXT:Section number of loader data:      5
+# CHECK32-NEXT:Section number of .bss:             6
+# CHECK32-NEXT:Maxium alignment of .text:          0x7
+# CHECK32-NEXT:Maxium alignment of .data:          0x3
+# CHECK32-NEXT:Module type;                        0x0
+# CHECK32-NEXT:CPU type of objects:                0x1
+# CHECK32-NEXT:(Reserved):                         0x0
+# CHECK32-NEXT:Maximum stack size:                 0x0
+# CHECK32-NEXT:Maximum data size:                  0x0
+# CHECK32-NEXT:Reserved for debugger:              0x0
+# CHECK32-NEXT:Text page size:                     0x1
+# CHECK32-NEXT:Data page size:                     0x1
+# CHECK32-NEXT:Stack page size:                    0x1
+# CHECK32-NEXT:Flag:                               0x0
+# CHECK32-NEXT:Alignment of thread-local storage:  0x1
+# CHECK32-NEXT:Section number for .tdata:          7
+# CHECK32-NEXT:Section number for .tbss:           8
 
-# CHECK64:      ---Auxiliary Header:
-# CHECK64-NEXT: Magic:                              0x10b
-# CHECK64-NEXT: Version:                            0x1
-# CHECK64-NEXT: Reserved for debugger:              0x0
-# CHECK64-NEXT: .text section start address:        0x2222
-# CHECK64-NEXT: .data section start address:        0x3333
-# CHECK64-NEXT: TOC anchor address:                 0x4444
-# CHECK64-NEXT: Section number of entryPoint:       1
-# CHECK64-NEXT: Section number of .text:            2
-# CHECK64-NEXT: Section number of .data:            3
-# CHECK64-NEXT: Section number of TOC:              4
-# CHECK64-NEXT: Section number of loader data:      5
-# CHECK64-NEXT: Section number of .bss:             6
-# CHECK64-NEXT: Maxium alignment of .text:          0x7
-# CHECK64-NEXT: Maxium alignment of .data:          0x3
-# CHECK64-NEXT: Module type:                        0x0
-# CHECK64-NEXT: CPU type of objects:                0x1
-# CHECK64-NEXT: (Reserved):                         0x0
-# CHECK64-NEXT: Text page size:                     0x1
-# CHECK64-NEXT: Data page size:                     0x1
-# CHECK64-NEXT: Stack page size:                    0x1
-# CHECK64-NEXT: Flag:                               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
-# CHECK64-NEXT: Entry point address:                0x1111
-# CHECK64-NEXT: Maximum stack size:                 0x0
-# CHECK64-NEXT: Maximum data size:                  0x0
-# CHECK64-NEXT: Section number for .tdata:          7
-# CHECK64-NEXT: Section number for .tbss:           8
-# CHECK64-NEXT: Additional flags 64-bit XCOFF:      0x2
+#      CHECK64:---Auxiliary Header:
+# CHECK64-NEXT:Magic:                              0x10b
+# CHECK64-NEXT:Version:                            0x1
+# CHECK64-NEXT:Reserved for debugger:              0x0
+# CHECK64-NEXT:.text section start address:        0x2222
+# CHECK64-NEXT:.data section start address:        0x3333
+# CHECK64-NEXT:TOC anchor address:                 0x4444
+# CHECK64-NEXT:Section number of entryPoint:       1
+# CHECK64-NEXT:Section number of .text:            2
+# CHECK64-NEXT:Section number of .data:            3
+# CHECK64-NEXT:Section number of TOC:              4
+# CHECK64-NEXT:Section number of loader data:      5
+# CHECK64-NEXT:Section number of .bss:             6
+# CHECK64-NEXT:Maxium alignment of .text:          0x7
+# CHECK64-NEXT:Maxium alignment of .data:          0x3
+# CHECK64-NEXT:Module type:                        0x0
+# CHECK64-NEXT:CPU type of objects:                0x1
+# CHECK64-NEXT:(Reserved):                         0x0
+# CHECK64-NEXT:Text page size:                     0x1
+# CHECK64-NEXT:Data page size:                     0x1
+# CHECK64-NEXT:Stack page size:                    0x1
+# CHECK64-NEXT:Flag:                               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
+# CHECK64-NEXT:Entry point address:                0x1111
+# CHECK64-NEXT:Maximum stack size:                 0x0
+# CHECK64-NEXT:Maximum data size:                  0x0
+# CHECK64-NEXT:Section number for .tdata:          7
+# CHECK64-NEXT:Section number for .tbss:           8
+# CHECK64-NEXT:Additional flags 64-bit XCOFF:      0x2
 
 # WARN1:       {{.*}}: only partial field for Section number for .tdata: at offset (68)
 # WARN1-NEXT:  Raw data (00)

>From 8bfbee47527514d51f8e8afbe87a5d3d43171538 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 16 Sep 2024 19:11:56 +0000
Subject: [PATCH 4/7] address comment

---
 .../XCOFF/private-header-auxiliary.test       | 99 +++++++++----------
 llvm/tools/llvm-objdump/XCOFFDump.cpp         | 21 ++--
 2 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
index b6670f16743c72..3136a9d12e351b 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
@@ -4,17 +4,55 @@
 # RUN: llvm-objdump --private-headers %t1 | \
 # RUN:   FileCheck %s --check-prefix=CHECK32 --match-full-lines --strict-whitespace
 # RUN: cp %t1 %t1_err1
-# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45')"
-# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(4); input.write(b'\x00')"
-# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines
+# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45'); input.seek(4); input.write(b'\x00')"
+# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines --strict-whitespace
 # RUN: cp %t1 %t1_extra
-# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(4); input.write(b'\x00')"
-# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f')"
-# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines
+# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f'); input.seek(4); input.write(b'\x00')"
+# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines --strict-whitespace
 # RUN: yaml2obj %s -DMAGIC=0x1F7 -DFLAG64=0x2 -o %t2
 # RUN: llvm-objdump --private-headers %t2 | \
 # RUN:   FileCheck %s --check-prefix=CHECK64 --match-full-lines --strict-whitespace
 
+--- !XCOFF
+FileHeader:
+  MagicNumber: [[MAGIC=0x1DF]]
+AuxiliaryHeader:
+  Magic:                 0x10B
+  Version:               0x1
+  TextSectionSize:       0x8
+  DataSectionSize:       0x9
+  BssSectionSize:        0x10
+  EntryPointAddr:        0x1111
+  TextStartAddr:         0x2222
+  DataStartAddr:         0x3333
+  TOCAnchorAddr:         0x4444
+  SecNumOfEntryPoint:    1
+  SecNumOfText:          2
+  SecNumOfData:          3
+  SecNumOfTOC:           4
+  SecNumOfLoader:        5
+  SecNumOfBSS:           6
+  MaxAlignOfText:        0x7
+  MaxAlignOfData:        0x3
+  ModuleType:            0x1
+  TextPageSize:          0x1
+  DataPageSize:          0x1
+  StackPageSize:         0x1
+  SecNumOfTData:         7
+  SecNumOfTBSS:          8
+  FlagAndTDataAlignment: 0x1
+  Flag:                  [[FLAG64=<none>]]
+Sections:
+  - Flags:       [ STYP_TEXT ]
+    SectionData: "1232"
+  - Flags:       [ STYP_DATA ]
+    SectionData: "5678"
+  - Flags:       [ STYP_BSS ]
+    SectionData: "9101"
+  - Flags:       [ STYP_TDATA ]
+    SectionData: "1112"
+  - Flags:       [ STYP_TBSS ]
+    SectionData: "1314"
 
 #      CHECK32:---Auxiliary Header:
 # CHECK32-NEXT:Magic:                              0x10b
@@ -36,7 +74,6 @@
 # CHECK32-NEXT:Maxium alignment of .data:          0x3
 # CHECK32-NEXT:Module type;                        0x0
 # CHECK32-NEXT:CPU type of objects:                0x1
-# CHECK32-NEXT:(Reserved):                         0x0
 # CHECK32-NEXT:Maximum stack size:                 0x0
 # CHECK32-NEXT:Maximum data size:                  0x0
 # CHECK32-NEXT:Reserved for debugger:              0x0
@@ -65,7 +102,6 @@
 # CHECK64-NEXT:Maxium alignment of .data:          0x3
 # CHECK64-NEXT:Module type:                        0x0
 # CHECK64-NEXT:CPU type of objects:                0x1
-# CHECK64-NEXT:(Reserved):                         0x0
 # CHECK64-NEXT:Text page size:                     0x1
 # CHECK64-NEXT:Data page size:                     0x1
 # CHECK64-NEXT:Stack page size:                    0x1
@@ -81,48 +117,7 @@
 # CHECK64-NEXT:Section number for .tbss:           8
 # CHECK64-NEXT:Additional flags 64-bit XCOFF:      0x2
 
-# WARN1:       {{.*}}: only partial field for Section number for .tdata: at offset (68)
-# WARN1-NEXT:  Raw data (00)
-
-# EXTRA: Extra raw data (00000000 000000)
+#      WARN1:{{.*}}: only partial field for Section number for .tdata: at offset (68)
+# WARN1-NEXT:Raw data (00)
 
---- !XCOFF
-FileHeader:
-  MagicNumber: [[MAGIC=0x1DF]]
-AuxiliaryHeader:
-  Magic:                 0x10B
-  Version:               0x1
-  TextSectionSize:       0x8
-  DataSectionSize:       0x9
-  BssSectionSize:        0x10
-  EntryPointAddr:        0x1111
-  TextStartAddr:         0x2222
-  DataStartAddr:         0x3333
-  TOCAnchorAddr:         0x4444
-  SecNumOfEntryPoint:    1
-  SecNumOfText:          2
-  SecNumOfData:          3
-  SecNumOfTOC:           4
-  SecNumOfLoader:        5
-  SecNumOfBSS:           6
-  MaxAlignOfText:        0x7
-  MaxAlignOfData:        0x3
-  ModuleType:            0x1
-  TextPageSize:          0x1
-  DataPageSize:          0x1
-  StackPageSize:         0x1
-  SecNumOfTData:         7
-  SecNumOfTBSS:          8
-  FlagAndTDataAlignment: 0x1
-  Flag:                  [[FLAG64=<none>]]
-Sections:
-  - Flags:       [ STYP_TEXT ]
-    SectionData: "1232"
-  - Flags:       [ STYP_DATA ]
-    SectionData: "5678"
-  - Flags:       [ STYP_BSS ]
-    SectionData: "9101"
-  - Flags:       [ STYP_TDATA ]
-    SectionData: "1112"
-  - Flags:       [ STYP_TBSS ]
-    SectionData: "1314"
+# EXTRA:Extra raw data (00000000 000000)
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 74cd832aba0a15..6a8c17b39b6106 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -114,20 +114,25 @@ void checkAndPrintAuxHeaderParseError(const char *PartialFieldName,
                                       uint16_t AuxSize, T &AuxHeader,
                                       XCOFFDumper *Dumper) {
   if (PartialFieldOffset < AuxSize) {
+    std::string Buf;
+    raw_string_ostream OS(Buf);
+    OS.flush();
+    OS << FormattedString("Raw data", 0, FormattedString::JustifyLeft) << " ("
+       << format_bytes(
+              ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
+                                    PartialFieldOffset,
+                                AuxSize - PartialFieldOffset))
+       << ")\n";
     Dumper->reportUniqueWarning(Twine("only partial field for ") +
                                 PartialFieldName + " at offset (" +
-                                Twine(PartialFieldOffset) + ")");
-    Dumper->printBinary(
-        "Raw data",
-        ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
-                              PartialFieldOffset,
-                          AuxSize - PartialFieldOffset));
-  } else if (sizeof(AuxHeader) < AuxSize)
+                                Twine(PartialFieldOffset) + ")\n" + OS.str());
+  } else if (sizeof(AuxHeader) < AuxSize) {
     Dumper->printBinary(
         "Extra raw data",
         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
                               sizeof(AuxHeader),
                           AuxSize - sizeof(AuxHeader)));
+  }
 }
 
 void XCOFFDumper::printAuxiliaryHeader(
@@ -166,7 +171,6 @@ void XCOFFDumper::printAuxiliaryHeader(
   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);
@@ -222,7 +226,6 @@ void XCOFFDumper::printAuxiliaryHeader(
   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);

>From 4535a2f0d73faf67a1dcc237f753e90890f39f71 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 16 Sep 2024 19:20:02 +0000
Subject: [PATCH 5/7] reorder the run commands and add comments for test case

---
 .../llvm-objdump/XCOFF/private-header-auxiliary.test  | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
index 3136a9d12e351b..97cc4ca9661989 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
@@ -1,17 +1,20 @@
 ## Test that `the llvm-objdump --private-headers` print out the auxiliary header of XCOFF object file.
-
 # RUN: yaml2obj %s -o %t1
 # RUN: llvm-objdump --private-headers %t1 | \
 # RUN:   FileCheck %s --check-prefix=CHECK32 --match-full-lines --strict-whitespace
+# RUN: yaml2obj %s -DMAGIC=0x1F7 -DFLAG64=0x2 -o %t2
+# RUN: llvm-objdump --private-headers %t2 | \
+# RUN:   FileCheck %s --check-prefix=CHECK64 --match-full-lines --strict-whitespace
+
+## Test the auxiliary header of the XCOFF object file contains a partial field.
 # RUN: cp %t1 %t1_err1
 # RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45'); input.seek(4); input.write(b'\x00')"
 # RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines --strict-whitespace
+
+## Test the auxiliary header of the XCOFF object file contains extra data.
 # RUN: cp %t1 %t1_extra
 # RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f'); input.seek(4); input.write(b'\x00')"
 # RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines --strict-whitespace
-# RUN: yaml2obj %s -DMAGIC=0x1F7 -DFLAG64=0x2 -o %t2
-# RUN: llvm-objdump --private-headers %t2 | \
-# RUN:   FileCheck %s --check-prefix=CHECK64 --match-full-lines --strict-whitespace
 
 --- !XCOFF
 FileHeader:

>From de6dce5a78b0c22b50086f6d7f7144912fc5d055 Mon Sep 17 00:00:00 2001
From: Zhijian Lin <zhijian at kuat.aus.stglabs.ibm.com>
Date: Thu, 22 Aug 2024 10:33:59 -0500
Subject: [PATCH 6/7] implement decoding auxiliary header for xcoff with
 llvm-objdump --private-headers

---
 .../XCOFF/private-header-auxiliary.test       | 98 +++++++------------
 llvm/tools/llvm-objdump/XCOFFDump.cpp         | 66 ++++++++-----
 2 files changed, 76 insertions(+), 88 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
index 97cc4ca9661989..09a5bf1cdf5ba0 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
@@ -1,20 +1,10 @@
-## Test that `the llvm-objdump --private-headers` print out the auxiliary header of XCOFF object file.
+## Test that `the llvm-objdump --private-headers` prints out the auxiliary header of XCOFF object file.
 # RUN: yaml2obj %s -o %t1
 # RUN: llvm-objdump --private-headers %t1 | \
-# RUN:   FileCheck %s --check-prefix=CHECK32 --match-full-lines --strict-whitespace
+# RUN:   FileCheck %s --check-prefixes=CHECK32,COMMON --match-full-lines --strict-whitespace
 # RUN: yaml2obj %s -DMAGIC=0x1F7 -DFLAG64=0x2 -o %t2
 # RUN: llvm-objdump --private-headers %t2 | \
-# RUN:   FileCheck %s --check-prefix=CHECK64 --match-full-lines --strict-whitespace
-
-## Test the auxiliary header of the XCOFF object file contains a partial field.
-# RUN: cp %t1 %t1_err1
-# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45'); input.seek(4); input.write(b'\x00')"
-# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines --strict-whitespace
-
-## Test the auxiliary header of the XCOFF object file contains extra data.
-# RUN: cp %t1 %t1_extra
-# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f'); input.seek(4); input.write(b'\x00')"
-# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines --strict-whitespace
+# RUN:   FileCheck %s --check-prefixes=CHECK64,COMMON --match-full-lines --strict-whitespace
 
 --- !XCOFF
 FileHeader:
@@ -57,70 +47,56 @@ Sections:
   - Flags:       [ STYP_TBSS ]
     SectionData: "1314"
 
-#      CHECK32:---Auxiliary Header:
-# CHECK32-NEXT:Magic:                              0x10b
-# CHECK32-NEXT:Version:                            0x1
+#       COMMON:---Auxiliary Header:
+#  COMMON-NEXT:Magic:                              0x10b
+#  COMMON-NEXT:Version:                            0x1
 # CHECK32-NEXT:Size of .text section:              0x8
 # CHECK32-NEXT:Size of .data section:              0x9
 # CHECK32-NEXT:Size of .bss section:               0x10
 # CHECK32-NEXT:Entry point address:                0x1111
-# CHECK32-NEXT:.text section start address:        0x2222
-# CHECK32-NEXT:.data section start address;        0x3333
-# CHECK32-NEXT:TOC anchor address:                 0x4444
-# CHECK32-NEXT:Section number of entryPoint:       1
-# CHECK32-NEXT:Section number of .text:            2
-# CHECK32-NEXT:Section number of .data:            3
-# CHECK32-NEXT:Section number of TOC:              4
-# CHECK32-NEXT:Section number of loader data:      5
-# CHECK32-NEXT:Section number of .bss:             6
-# CHECK32-NEXT:Maxium alignment of .text:          0x7
-# CHECK32-NEXT:Maxium alignment of .data:          0x3
-# CHECK32-NEXT:Module type;                        0x0
-# CHECK32-NEXT:CPU type of objects:                0x1
+# CHECK64-NEXT:Reserved for debugger:              0x0
+#  COMMON-NEXT:.text section start address:        0x2222
+#  COMMON-NEXT:.data section start address:        0x3333
+#  COMMON-NEXT:TOC anchor address:                 0x4444
+#  COMMON-NEXT:Section number of entryPoint:       1
+#  COMMON-NEXT:Section number of .text:            2
+#  COMMON-NEXT:Section number of .data:            3
+#  COMMON-NEXT:Section number of TOC:              4
+#  COMMON-NEXT:Section number of loader data:      5
+#  COMMON-NEXT:Section number of .bss:             6
+#  COMMON-NEXT:Maxium alignment of .text:          0x7
+#  COMMON-NEXT:Maxium alignment of .data:          0x3
+#  COMMON-NEXT:Module type:                        0x0
+#  COMMON-NEXT:CPU type of objects:                0x1
 # CHECK32-NEXT:Maximum stack size:                 0x0
 # CHECK32-NEXT:Maximum data size:                  0x0
 # CHECK32-NEXT:Reserved for debugger:              0x0
-# CHECK32-NEXT:Text page size:                     0x1
-# CHECK32-NEXT:Data page size:                     0x1
-# CHECK32-NEXT:Stack page size:                    0x1
-# CHECK32-NEXT:Flag:                               0x0
-# CHECK32-NEXT:Alignment of thread-local storage:  0x1
-# CHECK32-NEXT:Section number for .tdata:          7
-# CHECK32-NEXT:Section number for .tbss:           8
-
-#      CHECK64:---Auxiliary Header:
-# CHECK64-NEXT:Magic:                              0x10b
-# CHECK64-NEXT:Version:                            0x1
-# CHECK64-NEXT:Reserved for debugger:              0x0
-# CHECK64-NEXT:.text section start address:        0x2222
-# CHECK64-NEXT:.data section start address:        0x3333
-# CHECK64-NEXT:TOC anchor address:                 0x4444
-# CHECK64-NEXT:Section number of entryPoint:       1
-# CHECK64-NEXT:Section number of .text:            2
-# CHECK64-NEXT:Section number of .data:            3
-# CHECK64-NEXT:Section number of TOC:              4
-# CHECK64-NEXT:Section number of loader data:      5
-# CHECK64-NEXT:Section number of .bss:             6
-# CHECK64-NEXT:Maxium alignment of .text:          0x7
-# CHECK64-NEXT:Maxium alignment of .data:          0x3
-# CHECK64-NEXT:Module type:                        0x0
-# CHECK64-NEXT:CPU type of objects:                0x1
-# CHECK64-NEXT:Text page size:                     0x1
-# CHECK64-NEXT:Data page size:                     0x1
-# CHECK64-NEXT:Stack page size:                    0x1
-# CHECK64-NEXT:Flag:                               0x0
-# CHECK64-NEXT:Alignment of thread-local storage:  0x1
+#  COMMON-NEXT:Text page size:                     0x1
+#  COMMON-NEXT:Data page size:                     0x1
+#  COMMON-NEXT:Stack page size:                    0x1
+#  COMMON-NEXT:Flag:                               0x0
+#  COMMON-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
 # CHECK64-NEXT:Entry point address:                0x1111
 # CHECK64-NEXT:Maximum stack size:                 0x0
 # CHECK64-NEXT:Maximum data size:                  0x0
-# CHECK64-NEXT:Section number for .tdata:          7
-# CHECK64-NEXT:Section number for .tbss:           8
+#  COMMON-NEXT:Section number for .tdata:          7
+#  COMMON-NEXT:Section number for .tbss:           8
 # CHECK64-NEXT:Additional flags 64-bit XCOFF:      0x2
 
+## Test how llvm-objdump behaves when the auxiliary header of the XCOFF object file contains a partial field.
+# RUN: cp %t1 %t1_err1
+# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45'); input.seek(4); input.write(b'\x00')"
+# RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines --strict-whitespace
+
 #      WARN1:{{.*}}: only partial field for Section number for .tdata: at offset (68)
 # WARN1-NEXT:Raw data (00)
 
+## Test how llvm-objdump behaves when the auxiliary header of the XCOFF object file contains extra data.
+# RUN: cp %t1 %t1_extra
+# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f'); input.seek(4); input.write(b'\x00')"
+# RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines --strict-whitespace
+
 # EXTRA:Extra raw data (00000000 000000)
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 6a8c17b39b6106..18a62037cffaa7 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -32,14 +32,12 @@ using namespace llvm::support;
 
 namespace {
 class XCOFFDumper : public objdump::Dumper {
+  enum PrintStyle { Hex, Number };
   const XCOFFObjectFile &Obj;
   unsigned Width;
 
 public:
   XCOFFDumper(const object::XCOFFObjectFile &O) : Dumper(O), Obj(O) {}
-  void printBinary(StringRef Name, ArrayRef<uint8_t> B);
-  void printHex(StringRef Name, uint64_t Value);
-  void printNumber(StringRef Name, uint64_t Value);
 
 private:
   void printPrivateHeaders() override;
@@ -47,6 +45,21 @@ class XCOFFDumper : public objdump::Dumper {
   void printAuxiliaryHeader();
   void printAuxiliaryHeader(const XCOFFAuxiliaryHeader32 *AuxHeader);
   void printAuxiliaryHeader(const XCOFFAuxiliaryHeader64 *AuxHeader);
+  template <typename MemberOfAuxiliaryHeader, typename XCOFFAuxiliaryHeader>
+  void printAuxMemberHelper(PrintStyle Style, const char *MemberName,
+                            const MemberOfAuxiliaryHeader &Member,
+                            const XCOFFAuxiliaryHeader *AuxHeader,
+                            uint16_t AuxSize, uint16_t &PartialFieldOffset,
+                            const char *&PartialFieldName);
+  template <typename XCOFFAuxiliaryHeader>
+  void checkAndPrintAuxHeaderParseError(const char *PartialFieldName,
+                                        uint16_t PartialFieldOffset,
+                                        uint16_t AuxSize,
+                                        XCOFFAuxiliaryHeader &AuxHeader);
+
+  void printBinary(StringRef Name, ArrayRef<uint8_t> B);
+  void printHex(StringRef Name, uint64_t Value);
+  void printNumber(StringRef Name, uint64_t Value);
   FormattedString formatName(StringRef Name);
   void printStrHex(StringRef Name, StringRef Str, uint64_t Value);
   void setWidth(unsigned W) { Width = W; };
@@ -90,29 +103,28 @@ void XCOFFDumper::printAuxiliaryHeader() {
     printAuxiliaryHeader(Obj.auxiliaryHeader32());
 }
 
-enum PrintStyle { Hex, Number };
-template <typename T, typename V>
-static void printAuxMemberHelper(PrintStyle Style, const char *MemberName,
-                                 const T &Member, const V *AuxHeader,
-                                 uint16_t AuxSize, uint16_t &PartialFieldOffset,
-                                 const char *&PartialFieldName,
-                                 XCOFFDumper *Dumper) {
+template <typename MemberOfAuxiliaryHeader, typename XCOFFAuxiliaryHeader>
+void XCOFFDumper::printAuxMemberHelper(PrintStyle Style, const char *MemberName,
+                                       const MemberOfAuxiliaryHeader &Member,
+                                       const XCOFFAuxiliaryHeader *AuxHeader,
+                                       uint16_t AuxSize,
+                                       uint16_t &PartialFieldOffset,
+                                       const char *&PartialFieldName) {
   ptrdiff_t Offset = reinterpret_cast<const char *>(&Member) -
                      reinterpret_cast<const char *>(AuxHeader);
   if (Offset + sizeof(Member) <= AuxSize)
-    Style == Hex ? Dumper->printHex(MemberName, Member)
-                 : Dumper->printNumber(MemberName, Member);
+    Style == Hex ? printHex(MemberName, Member)
+                 : printNumber(MemberName, Member);
   else if (Offset < AuxSize) {
     PartialFieldOffset = Offset;
     PartialFieldName = MemberName;
   }
 }
 
-template <class T>
-void checkAndPrintAuxHeaderParseError(const char *PartialFieldName,
-                                      uint16_t PartialFieldOffset,
-                                      uint16_t AuxSize, T &AuxHeader,
-                                      XCOFFDumper *Dumper) {
+template <typename XCOFFAuxiliaryHeader>
+void XCOFFDumper::checkAndPrintAuxHeaderParseError(
+    const char *PartialFieldName, uint16_t PartialFieldOffset, uint16_t AuxSize,
+    XCOFFAuxiliaryHeader &AuxHeader) {
   if (PartialFieldOffset < AuxSize) {
     std::string Buf;
     raw_string_ostream OS(Buf);
@@ -123,11 +135,11 @@ void checkAndPrintAuxHeaderParseError(const char *PartialFieldName,
                                     PartialFieldOffset,
                                 AuxSize - PartialFieldOffset))
        << ")\n";
-    Dumper->reportUniqueWarning(Twine("only partial field for ") +
-                                PartialFieldName + " at offset (" +
-                                Twine(PartialFieldOffset) + ")\n" + OS.str());
+    reportUniqueWarning(Twine("only partial field for ") + PartialFieldName +
+                        " at offset (" + Twine(PartialFieldOffset) + ")\n" +
+                        OS.str());
   } else if (sizeof(AuxHeader) < AuxSize) {
-    Dumper->printBinary(
+    printBinary(
         "Extra raw data",
         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&AuxHeader) +
                               sizeof(AuxHeader),
@@ -147,7 +159,7 @@ void XCOFFDumper::printAuxiliaryHeader(
   auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
                             auto &Member) {
     printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize,
-                         PartialFieldOffset, PartialFieldName, this);
+                         PartialFieldOffset, PartialFieldName);
   };
 
   PrintAuxMember(Hex, "Magic:", AuxHeader->AuxMagic);
@@ -157,7 +169,7 @@ void XCOFFDumper::printAuxiliaryHeader(
   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, ".data section start address:", AuxHeader->DataStartAddr);
   PrintAuxMember(Hex, "TOC anchor address:", AuxHeader->TOCAnchorAddr);
   PrintAuxMember(
       Number, "Section number of entryPoint:", AuxHeader->SecNumOfEntryPoint);
@@ -169,7 +181,7 @@ void XCOFFDumper::printAuxiliaryHeader(
   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, "Module type:", AuxHeader->ModuleType);
   PrintAuxMember(Hex, "CPU type of objects:", AuxHeader->CpuFlag);
   PrintAuxMember(Hex, "Maximum stack size:", AuxHeader->MaxStackSize);
   PrintAuxMember(Hex, "Maximum data size:", AuxHeader->MaxDataSize);
@@ -190,7 +202,7 @@ void XCOFFDumper::printAuxiliaryHeader(
   PrintAuxMember(Number, "Section number for .tbss:", AuxHeader->SecNumOfTBSS);
 
   checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset,
-                                   AuxSize, *AuxHeader, this);
+                                   AuxSize, *AuxHeader);
 }
 
 void XCOFFDumper::printAuxiliaryHeader(
@@ -205,7 +217,7 @@ void XCOFFDumper::printAuxiliaryHeader(
   auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
                             auto &Member) {
     printAuxMemberHelper(Style, MemberName, Member, AuxHeader, AuxSize,
-                         PartialFieldOffset, PartialFieldName, this);
+                         PartialFieldOffset, PartialFieldName);
   };
 
   PrintAuxMember(Hex, "Magic:", AuxHeader->AuxMagic);
@@ -248,7 +260,7 @@ void XCOFFDumper::printAuxiliaryHeader(
   PrintAuxMember(Hex, "Additional flags 64-bit XCOFF:", AuxHeader->XCOFF64Flag);
 
   checkAndPrintAuxHeaderParseError(PartialFieldName, PartialFieldOffset,
-                                   AuxSize, *AuxHeader, this);
+                                   AuxSize, *AuxHeader);
 }
 
 void XCOFFDumper::printFileHeader() {

>From 081f9175d587b58325ff3b19870bf8ad5d888b49 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 21 Oct 2024 18:12:55 +0000
Subject: [PATCH 7/7] change python to %python

---
 .../tools/llvm-objdump/XCOFF/private-header-auxiliary.test    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
index 09a5bf1cdf5ba0..c13f21d2c58920 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/private-header-auxiliary.test
@@ -88,7 +88,7 @@ Sections:
 
 ## Test how llvm-objdump behaves when the auxiliary header of the XCOFF object file contains a partial field.
 # RUN: cp %t1 %t1_err1
-# RUN: python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45'); input.seek(4); input.write(b'\x00')"
+# RUN: %python -c "with open(r'%t1_err1', 'r+b') as input: input.seek(17); input.write(b'\x45'); input.seek(4); input.write(b'\x00')"
 # RUN: llvm-objdump --private-headers %t1_err1 2>&1 | FileCheck %s --check-prefix=WARN1 --match-full-lines --strict-whitespace
 
 #      WARN1:{{.*}}: only partial field for Section number for .tdata: at offset (68)
@@ -96,7 +96,7 @@ Sections:
 
 ## Test how llvm-objdump behaves when the auxiliary header of the XCOFF object file contains extra data.
 # RUN: cp %t1 %t1_extra
-# RUN: python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f'); input.seek(4); input.write(b'\x00')"
+# RUN: %python -c "with open(r'%t1_extra', 'r+b') as input: input.seek(17); input.write(b'\x4f'); input.seek(4); input.write(b'\x00')"
 # RUN: llvm-objdump --private-headers %t1_extra 2>&1 | FileCheck %s --check-prefix=EXTRA --match-full-lines --strict-whitespace
 
 # EXTRA:Extra raw data (00000000 000000)



More information about the llvm-commits mailing list