[objdump][ARM] Fix evaluating the target address of a Thumb BLX(i)

The instruction can be 16-bit aligned while targeting 32-bit aligned
code. To calculate the target address correctly, the address of the
instruction has to be adjusted.

Differential Revision: https://reviews.llvm.org/D104446
This commit is contained in:
Igor Kudrin 2021-06-18 10:40:55 +07:00
parent a10aeb3b32
commit 85ec210751
2 changed files with 34 additions and 0 deletions

View File

@ -429,6 +429,14 @@ public:
// is 4 bytes.
uint64_t Offset = ((Desc.TSFlags & ARMII::FormMask) == ARMII::ThumbFrm) ? 4 : 8;
// A Thumb instruction BLX(i) can be 16-bit aligned while targets Arm code
// which is 32-bit aligned. The target address for the case is calculated as
// targetAddress = Align(PC,4) + imm32;
// where
// Align(x, y) = y * (x DIV y);
if (Inst.getOpcode() == ARM::tBLXi)
Addr &= ~0x3;
Target = Addr + Imm + Offset;
return true;
}

View File

@ -0,0 +1,26 @@
## Check that the disassembler reports the target address of a Thumb BLX(i)
## instruction correctly even if the instruction is not 32-bit aligned.
# RUN: llvm-mc %s --triple=armv8a -filetype=obj | \
# RUN: llvm-objdump -dr - --triple armv8a --no-show-raw-insn | \
# RUN: FileCheck %s
# CHECK: <test>:
# CHECK-NEXT: 4: nop
# CHECK-NEXT: 6: blx #-8 <foo>
# CHECK-NEXT: a: blx #4 <bar>
.arm
foo:
nop
.thumb
test:
nop
blx #-8
blx #4
.arm
.p2align 2
bar:
nop