[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