[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
Fri Oct 18 09:05:57 PDT 2024


================
@@ -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) {
----------------
diggerlin wrote:

We prefer to print the fields in their order. Although the implementation cannot share the code, the output will provide users with the information about the field order.

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


More information about the llvm-commits mailing list