[llvm] 7026086 - [XCOFF] Use RLDs to print branches even without -r (#74342)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 21 06:17:36 PST 2023
Author: stephenpeckham
Date: 2023-12-21T08:17:32-06:00
New Revision: 70260860739fcbea2a5bee9a0d5e1d1d32ac6603
URL: https://github.com/llvm/llvm-project/commit/70260860739fcbea2a5bee9a0d5e1d1d32ac6603
DIFF: https://github.com/llvm/llvm-project/commit/70260860739fcbea2a5bee9a0d5e1d1d32ac6603.diff
LOG: [XCOFF] Use RLDs to print branches even without -r (#74342)
This presents misleading and confusing output. If you have a function
defined at the beginning of an XCOFF object file, and you have a
function call to an external function, the function call disassembles as
a branch to the local function. That is,
`void f() { f(); g();}`
disassembles as
>00000000 <.f>:
0: 7c 08 02 a6 mflr 0
4: 94 21 ff c0 stwu 1, -64(1)
8: 90 01 00 48 stw 0, 72(1)
c: 4b ff ff f5 bl 0x0 <.f>
10: 4b ff ff f1 bl 0x0 <.f>
With this PR, the second call will display:
`10: 4b ff ff f1 bl 0x0 <.g> `
Using -r can help, but you still get the confusing output:
>10: 4b ff ff f1 bl 0x0 <.f>
00000010: R_RBR .g
Added:
llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands2.ll
Modified:
llvm/test/CodeGen/PowerPC/aix-return55.ll
llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll
llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll
llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
llvm/tools/llvm-objdump/XCOFFDump.cpp
llvm/tools/llvm-objdump/XCOFFDump.h
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/llvm/test/CodeGen/PowerPC/aix-return55.ll b/llvm/test/CodeGen/PowerPC/aix-return55.ll
index c7d481ced140ef..a36deda9c14694 100644
--- a/llvm/test/CodeGen/PowerPC/aix-return55.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-return55.ll
@@ -39,7 +39,7 @@ entry:
;CHECKOBJ-NEXT: 1c: 67 8a bc de oris 10, 28, 48350{{[[:space:]] *}}
;CHECKOBJ32-NEXT: 00000020 <d>:
;CHECKOBJ64-NEXT: 0000000000000020 <d>:
-;CHECKOBJ-NEXT: 20: 40 14 00 00 bdnzf 20, 0x20
+;CHECKOBJ-NEXT: 20: 40 14 00 00 bdnzf 20, 0x20 <d>
;CHECKOBJ-NEXT: 24: 00 00 00 00 <unknown>{{[[:space:]] *}}
;CHECKOBJ32-NEXT: 00000028 <foo>:
;CHECKOBJ32-NEXT: 28: 00 00 00 00 <unknown>
diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll
index a5056d407b76f8..a557b6f4f17198 100644
--- a/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll
@@ -189,7 +189,7 @@ entry:
; DIS32-NEXT: 40: 7c 08 02 a6 mflr 0
; DIS32-NEXT: 44: 94 21 ff c0 stwu 1, -64(1)
; DIS32-NEXT: 48: 90 01 00 48 stw 0, 72(1)
-; DIS32-NEXT: 4c: 4b ff ff b5 bl 0x0 <.alias_foo>
+; DIS32-NEXT: 4c: 4b ff ff b5 bl 0x0 <.foo>
; DIS32-NEXT: 0000004c: R_RBR (idx: 7) .foo[PR]
; DIS32-NEXT: 50: 60 00 00 00 nop
; DIS32-NEXT: 54: 48 00 00 6d bl 0xc0 <.static_overalign_foo>
@@ -198,7 +198,7 @@ entry:
; DIS32-NEXT: 5c: 4b ff ff a5 bl 0x0 <.alias_foo>
; DIS32-NEXT: 0000005c: R_RBR (idx: 9) .alias_foo
; DIS32-NEXT: 60: 60 00 00 00 nop
-; DIS32-NEXT: 64: 4b ff ff 9d bl 0x0 <.alias_foo>
+; DIS32-NEXT: 64: 4b ff ff 9d bl 0x0 <.extern_foo>
; DIS32-NEXT: 00000064: R_RBR (idx: 1) .extern_foo[PR]
; DIS32-NEXT: 68: 60 00 00 00 nop
; DIS32-NEXT: 6c: 4b ff ff b5 bl 0x20 <.hidden_foo>
@@ -212,7 +212,7 @@ entry:
; DIS64-NEXT: 40: 7c 08 02 a6 mflr 0
; DIS64-NEXT: 44: f8 21 ff 91 stdu 1, -112(1)
; DIS64-NEXT: 48: f8 01 00 80 std 0, 128(1)
-; DIS64-NEXT: 4c: 4b ff ff b5 bl 0x0 <.alias_foo>
+; DIS64-NEXT: 4c: 4b ff ff b5 bl 0x0 <.foo>
; DIS64-NEXT: 000000000000004c: R_RBR (idx: 7) .foo[PR]
; DIS64-NEXT: 50: 60 00 00 00 nop
; DIS64-NEXT: 54: 48 00 00 6d bl 0xc0 <.static_overalign_foo>
@@ -221,7 +221,7 @@ entry:
; DIS64-NEXT: 5c: 4b ff ff a5 bl 0x0 <.alias_foo>
; DIS64-NEXT: 000000000000005c: R_RBR (idx: 9) .alias_foo
; DIS64-NEXT: 60: 60 00 00 00 nop
-; DIS64-NEXT: 64: 4b ff ff 9d bl 0x0 <.alias_foo>
+; DIS64-NEXT: 64: 4b ff ff 9d bl 0x0 <.extern_foo>
; DIS64-NEXT: 0000000000000064: R_RBR (idx: 1) .extern_foo[PR]
; DIS64-NEXT: 68: 60 00 00 00 nop
; DIS64-NEXT: 6c: 4b ff ff b5 bl 0x20 <.hidden_foo>
diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll
index 97a5fbcf78f5d4..5ac6a7af0db268 100644
--- a/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll
@@ -456,7 +456,7 @@ declare i32 @bar(i32)
; SYM-NEXT: ]
-; DIS: {{.*}}aix-xcoff-reloc.ll.tmp.o: file format aixcoff-rs6000
+; DIS: : file format aixcoff-rs6000
; DIS: Disassembly of section .text:
; DIS: 00000000 <.foo>:
; DIS-NEXT: 0: 7c 08 02 a6 mflr 0
@@ -495,7 +495,7 @@ declare i32 @bar(i32)
; DIS: 00000084 <globalB>:
; DIS-NEXT: 84: 00 00 00 44 <unknown>
-; DIS_REL: {{.*}}aix-xcoff-reloc.ll.tmp.o: file format aixcoff-rs6000
+; DIS_REL: : file format aixcoff-rs6000
; DIS_REL: RELOCATION RECORDS FOR [.text]:
; DIS_REL-NEXT: OFFSET TYPE VALUE
; DIS_REL-NEXT: 00000010 R_RBR .bar
@@ -515,7 +515,7 @@ declare i32 @bar(i32)
; DIS64-NEXT: 4: f8 21 ff 91 stdu 1, -112(1)
; DIS64-NEXT: 8: 38 60 00 01 li 3, 1
; DIS64-NEXT: c: f8 01 00 80 std 0, 128(1)
-; DIS64-NEXT: 10: 4b ff ff f1 bl 0x0 <.foo>
+; DIS64-NEXT: 10: 4b ff ff f1 bl 0x0 <.bar>
; DIS64-NEXT: 14: 60 00 00 00 nop
; DIS64-NEXT: 18: e8 82 00 00 ld 4, 0(2)
; DIS64-NEXT: 1c: e8 a2 00 08 ld 5, 8(2)
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
index adedb6b7a5abf8..2b4d6806292cef 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
+++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
@@ -21,7 +21,7 @@
; CHECK-NEXT: 68: cmplwi 3, 11
; CHECK-NEXT: 6c: bt 0, 0x60 <L2>
; CHECK-NEXT: 70: mr 31, 3
-; CHECK-NEXT: 74: bl 0x0 <.internal>
+; CHECK-NEXT: 74: bl 0x0 <.extern>
; CHECK-NEXT: 78: nop
; CHECK-NEXT: 7c: mr 3, 31
; CHECK-NEXT: 80: b 0x60 <L2>
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands2.ll b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands2.ll
new file mode 100644
index 00000000000000..a9cee924845f8b
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands2.ll
@@ -0,0 +1,65 @@
+; RUN: llc -mtriple=powerpc-ibm-aix-xcoff %s -filetype=obj -o %t
+; RUN: llvm-objdump %t -r -d --symbolize-operands --no-show-raw-insn \
+; RUN: | FileCheck %s
+
+; CHECK-LABEL: <.a>:
+;; No <L0> should appear
+; CHECK-NEXT: 0: mflr 0
+; CHECK-NEXT: 4: stwu 1, -64(1)
+; CHECK-NEXT: 8: lwz 3, 0(2)
+; CHECK-NEXT:0000000a: R_TOC var
+; CHECK-NEXT: c: stw 0, 72(1)
+; CHECK-NEXT: 10: lwz 3, 0(3)
+; CHECK-NEXT: 14: bl 0x4c <.b>
+; CHECK-NEXT: 18: nop
+; CHECK-NEXT: 1c: li 3, 1
+; CHECK-NEXT: 20: bl 0x0 <.c>
+; CHECK-NEXT:00000020: R_RBR .c
+
+; CHECK-LABEL: <.b>:
+; CHECK-NEXT: 4c: mflr 0
+; CHECK-NEXT: 50: stwu 1, -64(1)
+; CHECK-NEXT: 54: cmplwi 3, 1
+; CHECK-NEXT: 58: stw 0, 72(1)
+; CHECK-NEXT: 5c: stw 3, 60(1)
+; CHECK-NEXT: 60: bf 2, 0x6c <L0>
+; CHECK-NEXT: 64: bl 0x0 <.a>
+; CHECK-NEXT: 68: nop
+; CHECK-NEXT:<L0>:
+; CHECK-NEXT: 6c: li 3, 2
+; CHECK-NEXT: 70: bl 0x0 <.c>
+; CHECK-NEXT:00000070: R_RBR .c
+
+target triple = "powerpc-ibm-aix7.2.0.0"
+
+ at var = external global i32, align 4
+
+; Function Attrs: noinline nounwind optnone
+define i32 @a() {
+entry:
+ %0 = load i32, ptr @var, align 4
+ %call = call i32 @b(i32 noundef %0)
+ %call1 = call i32 @c(i32 noundef 1)
+ ret i32 %call1
+}
+
+; Function Attrs: noinline nounwind optnone
+define i32 @b(i32 noundef %x) {
+entry:
+ %x.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ %0 = load i32, ptr %x.addr, align 4
+ %cmp = icmp eq i32 %0, 1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %call = call i32 @a()
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %call1 = call i32 @c(i32 noundef 2)
+ ret i32 %call1
+}
+
+declare i32 @c(i32 noundef)
+
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 0f6147924f8a1a..d9c00c09620983 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -43,6 +43,7 @@ objdump::createXCOFFDumper(const object::XCOFFObjectFile &Obj) {
Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile &Obj,
const RelocationRef &Rel,
+ bool SymbolDescription,
SmallVectorImpl<char> &Result) {
symbol_iterator SymI = Rel.getSymbol();
if (SymI == Obj.symbol_end())
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.h b/llvm/tools/llvm-objdump/XCOFFDump.h
index cf5b19f910ea84..0ba6ba4cdaaad0 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.h
+++ b/llvm/tools/llvm-objdump/XCOFFDump.h
@@ -33,6 +33,7 @@ std::string getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
Error getXCOFFRelocationValueString(const object::XCOFFObjectFile &Obj,
const object::RelocationRef &RelRef,
+ bool SymbolDescription,
llvm::SmallVectorImpl<char> &Result);
void dumpTracebackTable(ArrayRef<uint8_t> Bytes, uint64_t Address,
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 463d73e73ef82a..7467a6062b5a8b 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -424,6 +424,7 @@ bool objdump::isRelocAddressLess(RelocationRef A, RelocationRef B) {
}
static Error getRelocationValueString(const RelocationRef &Rel,
+ bool SymbolDescription,
SmallVectorImpl<char> &Result) {
const ObjectFile *Obj = Rel.getObject();
if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
@@ -435,7 +436,8 @@ static Error getRelocationValueString(const RelocationRef &Rel,
if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
return getMachORelocationValueString(MachO, Rel, Result);
if (auto *XCOFF = dyn_cast<XCOFFObjectFile>(Obj))
- return getXCOFFRelocationValueString(*XCOFF, Rel, Result);
+ return getXCOFFRelocationValueString(*XCOFF, Rel, SymbolDescription,
+ Result);
llvm_unreachable("unknown object file format");
}
@@ -527,7 +529,7 @@ static void printRelocation(formatted_raw_ostream &OS, StringRef FileName,
SmallString<16> Name;
SmallString<32> Val;
Rel.getTypeName(Name);
- if (Error E = getRelocationValueString(Rel, Val))
+ if (Error E = getRelocationValueString(Rel, SymbolDescription, Val))
reportError(std::move(E), FileName);
OS << (Is64Bits || !LeadingAddr ? "\t\t" : "\t\t\t");
if (LeadingAddr)
@@ -1289,7 +1291,8 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, MCInstrAnalysis *MIA,
uint64_t Start, uint64_t End,
std::unordered_map<uint64_t, std::string> &Labels) {
// So far only supports PowerPC and X86.
- if (!STI->getTargetTriple().isPPC() && !STI->getTargetTriple().isX86())
+ const bool isPPC = STI->getTargetTriple().isPPC();
+ if (!isPPC && !STI->getTargetTriple().isX86())
return;
if (MIA)
@@ -1299,8 +1302,8 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, MCInstrAnalysis *MIA,
unsigned LabelCount = 0;
Start += SectionAddr;
End += SectionAddr;
- uint64_t Index = Start;
- while (Index < End) {
+ const bool isXCOFF = STI->getTargetTriple().isOSBinFormatXCOFF();
+ for (uint64_t Index = Start; Index < End;) {
// Disassemble a real instruction and record function-local branch labels.
MCInst Inst;
uint64_t Size;
@@ -1311,18 +1314,22 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, MCInstrAnalysis *MIA,
Size = std::min<uint64_t>(ThisBytes.size(),
DisAsm->suggestBytesToSkip(ThisBytes, Index));
- if (Disassembled && MIA) {
- uint64_t Target;
- bool TargetKnown = MIA->evaluateBranch(Inst, Index, Size, Target);
- // On PowerPC, if the address of a branch is the same as the target, it
- // means that it's a function call. Do not mark the label for this case.
- if (TargetKnown && (Target >= Start && Target < End) &&
- !Labels.count(Target) &&
- !(STI->getTargetTriple().isPPC() && Target == Index))
- Labels[Target] = ("L" + Twine(LabelCount++)).str();
- MIA->updateState(Inst, Index);
- } else if (!Disassembled && MIA) {
- MIA->resetState();
+ if (MIA) {
+ if (Disassembled) {
+ uint64_t Target;
+ bool TargetKnown = MIA->evaluateBranch(Inst, Index, Size, Target);
+ if (TargetKnown && (Target >= Start && Target < End) &&
+ !Labels.count(Target)) {
+ // On PowerPC and AIX, a function call is encoded as a branch to 0.
+ // On other PowerPC platforms (ELF), a function call is encoded as
+ // a branch to self. Do not add a label for these cases.
+ if (!(isPPC &&
+ ((Target == 0 && isXCOFF) || (Target == Index && !isXCOFF))))
+ Labels[Target] = ("L" + Twine(LabelCount++)).str();
+ }
+ MIA->updateState(Inst, Index);
+ } else
+ MIA->resetState();
}
Index += Size;
}
@@ -1486,7 +1493,7 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
}
std::map<SectionRef, std::vector<RelocationRef>> RelocMap;
- if (InlineRelocs)
+ if (InlineRelocs || Obj.isXCOFF())
RelocMap = getRelocsMap(Obj);
bool Is64Bits = Obj.getBytesInAddress() > 4;
@@ -1985,6 +1992,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
DT->InstrAnalysis->resetState();
while (Index < End) {
+ uint64_t RelOffset;
+
// ARM and AArch64 ELF binaries can interleave data and text in the
// same section. We rely on the markers introduced to understand what
// we need to dump. If the data marker is within a function, it is
@@ -2019,6 +2028,26 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
}
}
+ auto findRel = [&]() {
+ while (RelCur != RelEnd) {
+ RelOffset = RelCur->getOffset() - RelAdjustment;
+ // If this relocation is hidden, skip it.
+ if (getHidden(*RelCur) || SectionAddr + RelOffset < StartAddress) {
+ ++RelCur;
+ continue;
+ }
+
+ // Stop when RelCur's offset is past the disassembled
+ // instruction/data.
+ if (RelOffset >= Index + Size)
+ return false;
+ if (RelOffset >= Index)
+ return true;
+ ++RelCur;
+ }
+ return false;
+ };
+
if (DumpARMELFData) {
Size = dumpARMELFData(SectionAddr, Index, End, Obj, Bytes,
MappingSymbols, *DT->SubtargetInfo, FOS);
@@ -2029,7 +2058,7 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
uint64_t MaxOffset = End - Index;
// For --reloc: print zero blocks patched by relocations, so that
// relocations can be shown in the dump.
- if (RelCur != RelEnd)
+ if (InlineRelocs && RelCur != RelEnd)
MaxOffset = std::min(RelCur->getOffset() - RelAdjustment - Index,
MaxOffset);
@@ -2087,17 +2116,19 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
DT->InstPrinter->setCommentStream(llvm::nulls());
- // If disassembly has failed, avoid analysing invalid/incomplete
- // instruction information. Otherwise, try to resolve the target
- // address (jump target or memory operand address) and print it on the
+ // If disassembly succeeds, we try to resolve the target address
+ // (jump target or memory operand address) and print it to the
// right of the instruction.
+ //
+ // Otherwise, we don't print anything else so that we avoid
+ // analyzing invalid or incomplete instruction information.
if (Disassembled && DT->InstrAnalysis) {
- // Branch targets are printed just after the instructions.
llvm::raw_ostream *TargetOS = &FOS;
uint64_t Target;
bool PrintTarget = DT->InstrAnalysis->evaluateBranch(
Inst, SectionAddr + Index, Size, Target);
- if (!PrintTarget)
+
+ if (!PrintTarget) {
if (std::optional<uint64_t> MaybeTarget =
DT->InstrAnalysis->evaluateMemoryOperandAddress(
Inst, DT->SubtargetInfo.get(), SectionAddr + Index,
@@ -2111,6 +2142,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
*TargetOS << "0x" << Twine::utohexstr(Target);
}
}
+ }
+
if (PrintTarget) {
// In a relocatable object, the target's section must reside in
// the same section as the call instruction or it is accessed
@@ -2120,7 +2153,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
// In that case, locate the section(s) containing the target
// address and find the symbol in one of those, if possible.
//
- // N.B. We don't walk the relocations in the relocatable case yet.
+ // N.B. Except for XCOFF, we don't walk the relocations in the
+ // relocatable case yet.
std::vector<const SectionSymbolsTy *> TargetSectionSymbols;
if (!Obj.isRelocatableObject()) {
auto It = llvm::partition_point(
@@ -2166,19 +2200,65 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
break;
}
+ // Branch targets are printed just after the instructions.
// Print the labels corresponding to the target if there's any.
bool BBAddrMapLabelAvailable = BBAddrMapLabels.count(Target);
bool LabelAvailable = AllLabels.count(Target);
+
if (TargetSym != nullptr) {
uint64_t TargetAddress = TargetSym->Addr;
uint64_t Disp = Target - TargetAddress;
std::string TargetName = Demangle ? demangle(TargetSym->Name)
: TargetSym->Name.str();
+ bool RelFixedUp = false;
+ SmallString<32> Val;
*TargetOS << " <";
- if (!Disp) {
- // Always Print the binary symbol precisely corresponding to
- // the target address.
+ // On XCOFF, we use relocations, even without -r, so we
+ // can print the correct name for an extern function call.
+ if (Obj.isXCOFF() && findRel()) {
+ // Check for possible branch relocations and
+ // branches to fixup code.
+ bool BranchRelocationType = true;
+ XCOFF::RelocationType RelocType;
+ if (Obj.is64Bit()) {
+ const XCOFFRelocation64 *Reloc =
+ reinterpret_cast<XCOFFRelocation64 *>(
+ RelCur->getRawDataRefImpl().p);
+ RelFixedUp = Reloc->isFixupIndicated();
+ RelocType = Reloc->Type;
+ } else {
+ const XCOFFRelocation32 *Reloc =
+ reinterpret_cast<XCOFFRelocation32 *>(
+ RelCur->getRawDataRefImpl().p);
+ RelFixedUp = Reloc->isFixupIndicated();
+ RelocType = Reloc->Type;
+ }
+ BranchRelocationType =
+ RelocType == XCOFF::R_BA || RelocType == XCOFF::R_BR ||
+ RelocType == XCOFF::R_RBA || RelocType == XCOFF::R_RBR;
+
+ // If we have a valid relocation, try to print its
+ // corresponding symbol name. Multiple relocations on the
+ // same instruction are not handled.
+ // Branches to fixup code will have the RelFixedUp flag set in
+ // the RLD. For these instructions, we print the correct
+ // branch target, but print the referenced symbol as a
+ // comment.
+ if (Error E = getRelocationValueString(*RelCur, false, Val)) {
+ // If -r was used, this error will be printed later.
+ // Otherwise, we ignore the error and print what
+ // would have been printed without using relocations.
+ consumeError(std::move(E));
+ *TargetOS << TargetName;
+ RelFixedUp = false; // Suppress comment for RLD sym name
+ } else if (BranchRelocationType && !RelFixedUp)
+ *TargetOS << Val;
+ else
+ *TargetOS << TargetName;
+ if (Disp)
+ *TargetOS << "+0x" << Twine::utohexstr(Disp);
+ } else if (!Disp) {
*TargetOS << TargetName;
} else if (BBAddrMapLabelAvailable) {
*TargetOS << BBAddrMapLabels[Target].front();
@@ -2190,6 +2270,12 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
*TargetOS << TargetName << "+0x" << Twine::utohexstr(Disp);
}
*TargetOS << ">";
+ if (RelFixedUp && !InlineRelocs) {
+ // We have fixup code for a relocation. We print the
+ // referenced symbol as a comment.
+ *TargetOS << "\t# " << Val;
+ }
+
} else if (BBAddrMapLabelAvailable) {
*TargetOS << " <" << BBAddrMapLabels[Target].front() << ">";
} else if (LabelAvailable) {
@@ -2215,36 +2301,20 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
if (BTF)
printBTFRelocation(FOS, *BTF, {Index, Section.getIndex()}, LVP);
- // Hexagon does this in pretty printer
- if (Obj.getArch() != Triple::hexagon) {
- // Print relocation for instruction and data.
- while (RelCur != RelEnd) {
- uint64_t Offset = RelCur->getOffset() - RelAdjustment;
- // If this relocation is hidden, skip it.
- if (getHidden(*RelCur)) {
- ++RelCur;
- continue;
- }
-
- // Stop when RelCur's offset is past the disassembled
- // instruction/data. Note that it's possible the disassembled data
- // is not the complete data: we might see the relocation printed in
- // the middle of the data, but this matches the binutils objdump
- // output.
- if (Offset >= Index + Size)
- break;
-
+ // Hexagon handles relocs in pretty printer
+ if (InlineRelocs && Obj.getArch() != Triple::hexagon) {
+ while (findRel()) {
// When --adjust-vma is used, update the address printed.
if (RelCur->getSymbol() != Obj.symbol_end()) {
Expected<section_iterator> SymSI =
RelCur->getSymbol()->getSection();
if (SymSI && *SymSI != Obj.section_end() &&
shouldAdjustVA(**SymSI))
- Offset += AdjustVMA;
+ RelOffset += AdjustVMA;
}
printRelocation(FOS, Obj.getFileName(), *RelCur,
- SectionAddr + Offset, Is64Bits);
+ SectionAddr + RelOffset, Is64Bits);
LVP.printAfterOtherLine(FOS, true);
++RelCur;
}
@@ -2428,7 +2498,8 @@ void Dumper::printRelocations() {
if (Address < StartAddress || Address > StopAddress || getHidden(Reloc))
continue;
Reloc.getTypeName(RelocName);
- if (Error E = getRelocationValueString(Reloc, ValueStr))
+ if (Error E =
+ getRelocationValueString(Reloc, SymbolDescription, ValueStr))
reportUniqueWarning(std::move(E));
outs() << format(Fmt.data(), Address) << " "
More information about the llvm-commits
mailing list