diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst index 5e5eaccecd2b7..c9f0379694287 100644 --- a/llvm/docs/CommandGuide/llvm-objdump.rst +++ b/llvm/docs/CommandGuide/llvm-objdump.rst @@ -278,7 +278,7 @@ OPTIONS any analysis with a special representation (i.e. BlockFrequency, BranchProbability, etc) are printed as raw hex values. - Only works with PowerPC objects or X86 linked images. + Only supported for AArch64, BPF, PowerPC, and X86. Example: A non-symbolized branch instruction with a local target and pc-relative memory access like diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp index bbe83821eca8e..3c8b5712c1f0c 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -1784,6 +1784,10 @@ void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, uint64_t Address, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { + // Do not print the numeric target address when symbolizing. + if (SymbolizeOperands) + return; + const MCOperand &Op = MI->getOperand(OpNum); // If the label has already been resolved to an immediate offset (say, when @@ -1813,6 +1817,12 @@ void AArch64InstPrinter::printAdrAdrpLabel(const MCInst *MI, uint64_t Address, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { + // Do not print the numeric target address when symbolizing. + // However, do print for ADRP, as this is typically used together with an ADD + // or an immediate-offset ldr/str and the label is likely at the wrong point. + if (SymbolizeOperands && MI->getOpcode() != AArch64::ADRP) + return; + const MCOperand &Op = MI->getOperand(OpNum); // If the label has already been resolved to an immediate offset (say, when diff --git a/llvm/test/tools/llvm-objdump/ELF/AArch64/symbolize-operands-executable.yaml b/llvm/test/tools/llvm-objdump/ELF/AArch64/symbolize-operands-executable.yaml new file mode 100644 index 0000000000000..d318ea01b4c30 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ELF/AArch64/symbolize-operands-executable.yaml @@ -0,0 +1,67 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-objdump %t -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \ +# RUN: FileCheck %s --match-full-lines -DABS_ADRP_VAL=0x6000 +# RUN: llvm-objdump %t -d --symbolize-operands --no-show-raw-insn --no-leading-addr --adjust-vma=0x2000 | \ +# RUN: FileCheck %s --match-full-lines -DABS_ADRP_VAL=0x8000 + +## Expect to find the branch labels and global variable name. +# CHECK: <_start>: +# CHECK-NEXT: ldr x0, +# CHECK-NEXT: : +# CHECK-NEXT: adrp x1, [[ABS_ADRP_VAL]] +# CHECK-NEXT: adr x2, +# CHECK-NEXT: cmp x1, x2 +# CHECK-NEXT: b.eq +# CHECK-NEXT: b +# CHECK-NEXT: : +# CHECK-NEXT: cbz x2, +# CHECK-NEXT: ret + +## Machine code generated with: +# llvm-mc --arch=aarch64 --filetype=obj -o tmp.o <: +# CHECK-NEXT: b +# CHECK-NEXT: tbz x0, #0x2c, +# CHECK-NEXT: : +# CHECK-NEXT: b.eq +# CHECK-NEXT: : +# CHECK-NEXT: cbz x1, +# CHECK-NEXT: : +# CHECK-NEXT: nop +# CHECK-NEXT: : +# CHECK-NEXT: bl +# CHECK-NEXT: R_AARCH64_CALL26 fn2 +# CHECK-NEXT: bl +# CHECK-NEXT: adr x0, +# CHECK-NEXT: : +# CHECK-NEXT: adr x1, +# CHECK-NEXT: R_AARCH64_ADR_PREL_LO21 fn2 +# CHECK-NEXT: adr x2, +# CHECK-NEXT: ldr w0, +# CHECK-NEXT: : +# CHECK-NEXT: ldr w0, +# CHECK-NEXT: R_AARCH64_LD_PREL_LO19 fn2 +# CHECK-NEXT: ret +# CHECK-NEXT: nop +# CHECK-NEXT: nop +# CHECK-NEXT: nop +# CHECK-EMPTY: +# CHECK-NEXT: : +# CHECK-NEXT: bl +# CHECK-NEXT: adrp x3, 0x0 +# CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 fn2 +# CHECK-NEXT: add x3, x3, #0x0 +# CHECK-NEXT: R_AARCH64_ADD_ABS_LO12_NC fn2 +# CHECK-NEXT: adrp x3, 0x0 +# CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 fn2 +# CHECK-NEXT: ldr x0, [x3] +# CHECK-NEXT: R_AARCH64_LDST64_ABS_LO12_NC fn2 +# CHECK-NEXT: ret +# CHECK-NEXT: nop +# CHECK-NEXT: nop +# CHECK-NEXT: : +# CHECK-NEXT: ret + + .p2align 4 + .global fn1 +fn1: + b 0f + tbz x0, 44, 2f +0: b.eq 1f +1: cbz x1, 0b +2: nop + bl fn2 + bl .Lfn2 + adr x0, 2b + adr x1, fn2 + adr x2, .Lfn2 + ldr w0, 2b + ldr w0, fn2 + ret + + .p2align 4 + .global fn2 +fn2: +.Lfn2: ## Local label for non-interposable call. + bl .Lfn3 + ## In future, we might identify the pairs and symbolize the operands properly. + adrp x3, fn2 + add x3, x3, :lo12:fn2 + adrp x3, fn2 + ldr x0, [x3, :lo12:fn2] + ret + + .p2align 4 +.Lfn3: ## Private function + ret diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 5ecb33375943f..c5967cd090eec 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1495,8 +1495,9 @@ collectLocalBranchTargets(ArrayRef Bytes, MCInstrAnalysis *MIA, // Supported by certain targets. const bool isPPC = STI->getTargetTriple().isPPC(); const bool isX86 = STI->getTargetTriple().isX86(); + const bool isAArch64 = STI->getTargetTriple().isAArch64(); const bool isBPF = STI->getTargetTriple().isBPF(); - if (!isPPC && !isX86 && !isBPF) + if (!isPPC && !isX86 && !isAArch64 && !isBPF) return; if (MIA)