[lld] b663287 - [PowerPC][llvm-objdump] enable --symbolize-operands for PowerPC ELF/XCOFF.
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 20 20:18:31 PST 2021
Author: Esme-Yi
Date: 2021-12-21T04:17:57Z
New Revision: b66328701a525d026a91b10df011712e5811319e
URL: https://github.com/llvm/llvm-project/commit/b66328701a525d026a91b10df011712e5811319e
DIFF: https://github.com/llvm/llvm-project/commit/b66328701a525d026a91b10df011712e5811319e.diff
LOG: [PowerPC][llvm-objdump] enable --symbolize-operands for PowerPC ELF/XCOFF.
Summary: When disassembling, symbolize a branch target operand
to print a label instead of a real address.
Reviewed By: shchenz
Differential Revision: https://reviews.llvm.org/D114492
Added:
llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll
llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
Modified:
lld/test/ELF/ppc64-toc-call-to-pcrel.s
llvm/docs/CommandGuide/llvm-objdump.rst
llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/lld/test/ELF/ppc64-toc-call-to-pcrel.s b/lld/test/ELF/ppc64-toc-call-to-pcrel.s
index 2013ba723d2ba..359870ecf2882 100644
--- a/lld/test/ELF/ppc64-toc-call-to-pcrel.s
+++ b/lld/test/ELF/ppc64-toc-call-to-pcrel.s
@@ -29,23 +29,22 @@
# SYMBOL: 10020020 0 NOTYPE LOCAL DEFAULT [<other: 0x60>] 2 caller_14
# SYMBOL: 10020040 8 FUNC LOCAL DEFAULT 2 __toc_save_callee
-# CHECK-LABEL: callee
+# CHECK-LABEL: <callee>:
# CHECK: blr
-# CHECK-LABEL: caller
-# CHECK: bl 0x10020040
+# CHECK-LABEL: <caller>:
+# CHECK: bl 0x10020040 <__toc_save_callee>
# CHECK-NEXT: ld 2, 24(1)
# CHECK-NEXT: blr
-# CHECK-LABEL: caller_14
-# CHECK: bfl 0, 0x10020040
+# CHECK-LABEL: <caller_14>:
+# CHECK: bfl 0, 0x10020040 <__toc_save_callee>
# CHECK-NEXT: ld 2, 24(1)
# CHECK-NEXT: blr
-# CHECK-LABEL: __toc_save_callee
+# CHECK-LABEL: <__toc_save_callee>:
# CHECK-NEXT: std 2, 24(1)
-# CHECK-NEXT: b 0x10010000
-
+# CHECK-NEXT: b 0x10010000 <callee>
.section .text_callee, "ax", %progbits
callee:
diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst
index 88bade71f6c60..bd4b77e52f243 100644
--- a/llvm/docs/CommandGuide/llvm-objdump.rst
+++ b/llvm/docs/CommandGuide/llvm-objdump.rst
@@ -226,7 +226,7 @@ OPTIONS
When printing a PC-relative global symbol reference, print it as an offset from the leading symbol.
- Only works with an X86 linked image.
+ Only works with PowerPC objects or X86 linked images.
Example:
A non-symbolized branch instruction with a local target and pc-relative memory access like
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 22b948a83c34a..d6e02d0d08628 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -28,6 +28,7 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
@@ -368,6 +369,31 @@ static MCInstPrinter *createPPCMCInstPrinter(const Triple &T,
return new PPCInstPrinter(MAI, MII, MRI, T);
}
+namespace {
+
+class PPCMCInstrAnalysis : public MCInstrAnalysis {
+public:
+ explicit PPCMCInstrAnalysis(const MCInstrInfo *Info)
+ : MCInstrAnalysis(Info) {}
+
+ bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
+ uint64_t &Target) const override {
+ unsigned NumOps = Inst.getNumOperands();
+ if (NumOps == 0 ||
+ Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType !=
+ MCOI::OPERAND_PCREL)
+ return false;
+ Target = Addr + Inst.getOperand(NumOps - 1).getImm() * Size;
+ return true;
+ }
+};
+
+} // end anonymous namespace
+
+static MCInstrAnalysis *createPPCMCInstrAnalysis(const MCInstrInfo *Info) {
+ return new PPCMCInstrAnalysis(Info);
+}
+
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
&getThePPC64Target(), &getThePPC64LETarget()}) {
@@ -383,6 +409,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo);
+ // Register the MC instruction analyzer.
+ TargetRegistry::RegisterMCInstrAnalysis(*T, createPPCMCInstrAnalysis);
+
// Register the MC Code Emitter
TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter);
diff --git a/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll b/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll
new file mode 100644
index 0000000000000..4d75a874d616d
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll
@@ -0,0 +1,59 @@
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu %s -filetype=obj -o %t
+; RUN: llvm-objdump %t -d --symbolize-operands --no-show-raw-insn \
+; RUN: | FileCheck %s
+
+;; Expect to find the branch labels.
+; CHECK-LABEL: <internal>:
+; CHECK: <L0>:
+; CHECK-NEXT: 20: addi 3, 3, 1
+; CHECK-NEXT: 24: bdnz 0x20 <L0>
+; CHECK-NEXT: 28: blr
+
+; CHECK-LABEL: <foo>:
+; CHECK: 6c: b 0x74 <L0>
+; CHECK-NEXT: <L2>:
+; CHECK-NEXT: 70: bf 8, 0x94 <L1>
+; CHECK-NEXT: <L0>:
+; CHECK-NEXT: 74: clrldi 3, 30, 32
+; CHECK-NEXT: 78: bl 0x0 <internal>
+; CHECK-NEXT: 7c: mr 30, 3
+; CHECK-NEXT: 80: cmplwi 30, 11
+; CHECK-NEXT: 84: bt 0, 0x70 <L2>
+; CHECK-NEXT: 88: bl 0x88 <foo+0x48>
+; CHECK-NEXT: 8c: nop
+; CHECK-NEXT: 90: b 0x70 <L2>
+; CHECK-NEXT: <L1>:
+; CHECK-NEXT: 94: ld 30, 32(1)
+
+define internal i32 @internal(i32 %a) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ 0, %entry ], [ %next, %for.body ]
+ %next = add nuw nsw i32 %i, 1
+ %cond = icmp eq i32 %next, %a
+ br i1 %cond, label %exit, label %for.body
+
+exit:
+ ret i32 %next
+}
+
+declare void @extern()
+
+define void @foo(i1 %breakcond) {
+entry:
+ br label %loop
+loop:
+ %tmp23phi = phi i32 [ %tmp23, %endif ], [ 0, %entry ]
+ %tmp23 = call i32 @internal(i32 %tmp23phi)
+ %tmp27 = icmp ult i32 10, %tmp23
+ br i1 %tmp27, label %then, label %endif
+then: ; preds = %bb
+ call void @extern()
+ br label %endif
+endif: ; preds = %bb28, %bb
+ br i1 %breakcond, label %loop, label %loopexit
+loopexit:
+ ret void
+}
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
new file mode 100644
index 0000000000000..a6742285a148e
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll
@@ -0,0 +1,63 @@
+; RUN: llc -mtriple=powerpc-ibm-aix-xcoff %s -filetype=obj -o %t
+; RUN: llvm-objdump %t -d --symbolize-operands --no-show-raw-insn \
+; RUN: | FileCheck %s
+
+;; Expect to find the branch labels.
+; CHECK-LABEL: <.text>:
+;; TODO: <.internal> should be printed instead of <.text>.
+; CHECK-NEXT: 0: mr 4, 3
+; CHECK-NEXT: 4: li 3, 0
+; CHECK-NEXT: 8: mtctr 4
+; CHECK-NEXT: <L0>:
+; CHECK-NEXT: c: addi 3, 3, 1
+; CHECK-NEXT: 10: bdnz 0xc <L0>
+; CHECK-NEXT: 14: blr
+
+; CHECK-LABEL: <.foo>:
+; CHECK: 5c: b 0x64 <L0>
+; CHECK-NEXT: <L2>:
+; CHECK-NEXT: 60: bf 8, 0x84 <L1>
+; CHECK-NEXT: <L0>:
+; CHECK-NEXT: 64: mr 3, 31
+; CHECK-NEXT: 68: bl 0x0 <.text>
+; CHECK-NEXT: 6c: mr 31, 3
+; CHECK-NEXT: 70: cmplwi 3, 11
+; CHECK-NEXT: 74: bt 0, 0x60 <L2>
+; CHECK-NEXT: 78: bl 0x0 <.text>
+; CHECK-NEXT: 7c: nop
+; CHECK-NEXT: 80: b 0x60 <L2>
+; CHECK-NEXT: <L1>:
+; CHECK-NEXT: 84: lwz 31, 60(1)
+
+define internal i32 @internal(i32 %a) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ 0, %entry ], [ %next, %for.body ]
+ %next = add nuw nsw i32 %i, 1
+ %cond = icmp eq i32 %next, %a
+ br i1 %cond, label %exit, label %for.body
+
+exit:
+ ret i32 %next
+}
+
+declare void @extern()
+
+define void @foo(i1 %breakcond) {
+entry:
+ br label %loop
+loop:
+ %tmp23phi = phi i32 [ %tmp23, %endif ], [ 0, %entry ]
+ %tmp23 = call i32 @internal(i32 %tmp23phi)
+ %tmp27 = icmp ult i32 10, %tmp23
+ br i1 %tmp27, label %then, label %endif
+then: ; preds = %bb
+ call void @extern()
+ br label %endif
+endif: ; preds = %bb28, %bb
+ br i1 %breakcond, label %loop, label %loopexit
+loopexit:
+ ret void
+}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 6f6f543f2f476..a16f760cd1cb4 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -978,8 +978,8 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, const MCInstrAnalysis *MIA,
const MCSubtargetInfo *STI, uint64_t SectionAddr,
uint64_t Start, uint64_t End,
std::unordered_map<uint64_t, std::string> &Labels) {
- // So far only supports X86.
- if (!STI->getTargetTriple().isX86())
+ // So far only supports PowerPC and X86.
+ if (!STI->getTargetTriple().isPPC() && !STI->getTargetTriple().isX86())
return;
Labels.clear();
@@ -999,8 +999,11 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, const MCInstrAnalysis *MIA,
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))
+ !Labels.count(Target) &&
+ !(STI->getTargetTriple().isPPC() && Target == Index))
Labels[Target] = ("L" + Twine(LabelCount++)).str();
}
More information about the llvm-commits
mailing list