diff --git a/llvm/test/tools/llvm-readobj/XCOFF/relocations.test b/llvm/test/tools/llvm-readobj/XCOFF/relocations.test --- a/llvm/test/tools/llvm-readobj/XCOFF/relocations.test +++ b/llvm/test/tools/llvm-readobj/XCOFF/relocations.test @@ -3,40 +3,50 @@ # RUN: yaml2obj %s -o %t # RUN: llvm-readobj --relocs --expand-relocs %t | \ # RUN: FileCheck %s --strict-whitespace --match-full-lines --check-prefix=RELOCSEXP - -## TODO: Output of relocations not aligned. +# RUN: llvm-readobj --relocs %t | \ +# RUN: FileCheck %s --strict-whitespace --match-full-lines --check-prefix=RELOCS # RELOCSEXP:Relocations [ # RELOCSEXP-NEXT: Section (index: 1) .text { -# RELOCSEXP-NEXT: Relocation { -# RELOCSEXP-NEXT: Virtual Address: 0x80 -# RELOCSEXP-NEXT: Symbol: foo (0) -# RELOCSEXP-NEXT: IsSigned: No -# RELOCSEXP-NEXT: FixupBitValue: 0 -# RELOCSEXP-NEXT: Length: 22 -# RELOCSEXP-NEXT: Type: R_POS (0x0) +# RELOCSEXP-NEXT: Relocation { +# RELOCSEXP-NEXT: Virtual Address: 0x80 +# RELOCSEXP-NEXT: Symbol: foo (0) +# RELOCSEXP-NEXT: IsSigned: No +# RELOCSEXP-NEXT: FixupBitValue: 0 +# RELOCSEXP-NEXT: Length: 22 +# RELOCSEXP-NEXT: Type: R_POS (0x0) +# RELOCSEXP-NEXT: } +# RELOCSEXP-NEXT: Relocation { +# RELOCSEXP-NEXT: Virtual Address: 0x100 +# RELOCSEXP-NEXT: Symbol: foo (0) +# RELOCSEXP-NEXT: IsSigned: No +# RELOCSEXP-NEXT: FixupBitValue: 0 +# RELOCSEXP-NEXT: Length: 21 +# RELOCSEXP-NEXT: Type: R_REL (0x2) +# RELOCSEXP-NEXT: } # RELOCSEXP-NEXT: } -# RELOCSEXP-NEXT: Relocation { -# RELOCSEXP-NEXT: Virtual Address: 0x100 -# RELOCSEXP-NEXT: Symbol: foo (0) -# RELOCSEXP-NEXT: IsSigned: No -# RELOCSEXP-NEXT: FixupBitValue: 0 -# RELOCSEXP-NEXT: Length: 21 -# RELOCSEXP-NEXT: Type: R_REL (0x2) +# RELOCSEXP-NEXT: Section (index: 2) .data { +# RELOCSEXP-NEXT: Relocation { +# RELOCSEXP-NEXT: Virtual Address: 0x200 +# RELOCSEXP-NEXT: Symbol: bar (1) +# RELOCSEXP-NEXT: IsSigned: No +# RELOCSEXP-NEXT: FixupBitValue: 0 +# RELOCSEXP-NEXT: Length: 20 +# RELOCSEXP-NEXT: Type: R_TOC (0x3) +# RELOCSEXP-NEXT: } # RELOCSEXP-NEXT: } -# RELOCSEXP-NEXT:} -# RELOCSEXP-NEXT:Section (index: 2) .data { -# RELOCSEXP-NEXT:Relocation { -# RELOCSEXP-NEXT: Virtual Address: 0x200 -# RELOCSEXP-NEXT: Symbol: bar (1) -# RELOCSEXP-NEXT: IsSigned: No -# RELOCSEXP-NEXT: FixupBitValue: 0 -# RELOCSEXP-NEXT: Length: 20 -# RELOCSEXP-NEXT: Type: R_TOC (0x3) -# RELOCSEXP-NEXT:} -# RELOCSEXP-NEXT:} # RELOCSEXP-NEXT:] +# RELOCS:Relocations [ +# RELOCS-NEXT: Section (index: 1) .text { +# RELOCS-NEXT: 0x80 R_POS foo(0) 0x15 +# RELOCS-NEXT: 0x100 R_REL foo(0) 0x14 +# RELOCS-NEXT: } +# RELOCS-NEXT: Section (index: 2) .data { +# RELOCS-NEXT: 0x200 R_TOC bar(1) 0x13 +# RELOCS-NEXT: } +# RELOCS-NEXT:] + --- !XCOFF FileHeader: MagicNumber: 0x01DF 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 @@ -48,6 +48,7 @@ void printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef); void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr); void printSymbol(const SymbolRef &); + template void printRelocation(RelTy Reloc); template void printRelocations(ArrayRef Sections); void printAuxiliaryHeader(const XCOFFAuxiliaryHeader32 *AuxHeader); @@ -136,11 +137,33 @@ #undef ECase }; +template void XCOFFDumper::printRelocation(RelTy Reloc) { + Expected ErrOrSymbolName = + Obj.getSymbolNameByIndex(Reloc.SymbolIndex); + if (Error E = ErrOrSymbolName.takeError()) { + reportUniqueWarning(std::move(E)); + return; + } + StringRef SymbolName = *ErrOrSymbolName; + StringRef RelocName = XCOFF::getRelocationTypeString(Reloc.Type); + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Virtual Address", Reloc.VirtualAddress); + W.printNumber("Symbol", SymbolName, Reloc.SymbolIndex); + W.printString("IsSigned", Reloc.isRelocationSigned() ? "Yes" : "No"); + W.printNumber("FixupBitValue", Reloc.isFixupIndicated() ? 1 : 0); + W.printNumber("Length", Reloc.getRelocatedLength()); + W.printEnum("Type", (uint8_t)Reloc.Type, + makeArrayRef(RelocationTypeNameclass)); + } else { + raw_ostream &OS = W.startLine(); + OS << W.hex(Reloc.VirtualAddress) << " " << RelocName << " " << SymbolName + << "(" << Reloc.SymbolIndex << ") " << W.hex(Reloc.Info) << "\n"; + } +} + template void XCOFFDumper::printRelocations(ArrayRef Sections) { - if (!opts::ExpandRelocs) - report_fatal_error("Unexpanded relocation output not implemented."); - ListScope LS(W, "Relocations"); uint16_t Index = 0; for (const Shdr &Sec : Sections) { @@ -161,24 +184,11 @@ W.startLine() << "Section (index: " << Index << ") " << Sec.getName() << " {\n"; - for (const RelTy Reloc : Relocations) { - Expected ErrOrSymbolName = - Obj.getSymbolNameByIndex(Reloc.SymbolIndex); - if (Error E = ErrOrSymbolName.takeError()) { - reportUniqueWarning(std::move(E)); - continue; - } + W.indent(); + + for (const RelTy Reloc : Relocations) + printRelocation(Reloc); - StringRef SymbolName = *ErrOrSymbolName; - DictScope RelocScope(W, "Relocation"); - W.printHex("Virtual Address", Reloc.VirtualAddress); - W.printNumber("Symbol", SymbolName, Reloc.SymbolIndex); - W.printString("IsSigned", Reloc.isRelocationSigned() ? "Yes" : "No"); - W.printNumber("FixupBitValue", Reloc.isFixupIndicated() ? 1 : 0); - W.printNumber("Length", Reloc.getRelocatedLength()); - W.printEnum("Type", (uint8_t)Reloc.Type, - makeArrayRef(RelocationTypeNameclass)); - } W.unindent(); W.startLine() << "}\n"; }