[llvm] [llvm-objdump] Implement decoding auxiliary header for xcoff with llvm-objdump --private-headers (PR #105682)
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 11 02:38:59 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) {
----------------
jh7370 wrote:
(Note for posterity: diggerlin edited my previous comment, rather than replying to it, for some reason)
> we need to print out the fields by the order of structure XCOFFAuxiliaryHeader32 and XCOFFAuxiliaryHeader64.
Do you actually need to do that? Could you instead print all the common stuff, then print the stuff that is specific to the individual formats?
https://github.com/llvm/llvm-project/pull/105682
More information about the llvm-commits
mailing list