Skip to content

Commit a1bc3e6

Browse files
authored
[ARMAsmBackend] Add checks for relocation addends in assembler (#109969)
This PR adds checks that any addends attached to branch instructions are valid, and can be properly encoded in the branch instruction. Before this fix, the assembler would silently truncate or round invalid addend values, creating incorrect branch instructions.
1 parent b43e003 commit a1bc3e6

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,13 +579,27 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
579579
case ARM::fixup_arm_uncondbl:
580580
case ARM::fixup_arm_condbl:
581581
case ARM::fixup_arm_blx:
582+
// Check that the relocation value is legal.
583+
Value -= 8;
584+
if (!isInt<26>(Value)) {
585+
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
586+
return 0;
587+
}
588+
// Alignment differs for blx. Because we are switching to thumb ISA, we use
589+
// 16-bit alignment. Otherwise, use 32-bit.
590+
if ((Kind == ARM::fixup_arm_blx && Value % 2 != 0) ||
591+
(Kind != ARM::fixup_arm_blx && Value % 4 != 0)) {
592+
Ctx.reportError(Fixup.getLoc(), "Relocation not aligned");
593+
return 0;
594+
}
595+
582596
// These values don't encode the low two bits since they're always zero.
583597
// Offset by 8 just as above.
584598
if (const MCSymbolRefExpr *SRE =
585599
dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
586600
if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
587601
return 0;
588-
return 0xffffff & ((Value - 8) >> 2);
602+
return 0xffffff & (Value >> 2);
589603
case ARM::fixup_t2_uncondbranch: {
590604
if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
591605
Value != 4) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// RUN: not llvm-mc -triple armv7-apple-darwin -filetype=obj %s 2>&1 | FileCheck %s
2+
3+
// Check that the relocation size is valid.
4+
// Check lower bound of edge case.
5+
_foo1_valid:
6+
// CHECK-NOT: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
7+
b _foo1_valid+0x2000004
8+
// Check outside of range of the largest accepted positive number
9+
_foo1:
10+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
11+
b _foo1+0x2000008
12+
13+
// Check Same as above, for smallest negative value
14+
_foo2_valid:
15+
// CHECK-NOT: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
16+
b _foo2_valid-0x1FFFFF8
17+
_foo2:
18+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
19+
b _foo2-0x1FFFFFC
20+
21+
// Edge case - subtracting positive number
22+
_foo3:
23+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
24+
b _foo3-0x2000010
25+
26+
// Edge case - adding negative number
27+
_foo4:
28+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
29+
b _foo4+0x2000008
30+
31+
_foo5:
32+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
33+
bl _foo5+0x2000008
34+
35+
_foo6:
36+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
37+
blx _foo6+0x2000008
38+
39+
// blx instruction is aligned to 16-bits.
40+
_foo7_blx:
41+
// CHECK-NOT:[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
42+
blx _foo7_blx+0x1FFFFFE
43+
44+
// Other branch instructions require 32-bit alignment.
45+
_foo7:
46+
// CHECK:[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
47+
bl _foo7_blx+0x1FFFFFE
48+
49+
_foo8:
50+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
51+
ble _foo8+0x2000008
52+
53+
_foo9:
54+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
55+
beq _foo9+0x2000008
56+
57+
// Check that the relocation alignment is valid.
58+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
59+
bl _foo1+0x101
60+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
61+
blx _foo1+0x101
62+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
63+
b _foo1+0x101
64+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
65+
ble _foo1+0x101
66+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
67+
beq _foo1+0x101

llvm/test/MC/ARM/macho-relocs-with-addend.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ _with_thumb:
1515
.globl _with_arm
1616
.arm
1717
_with_arm:
18-
bl _dest+10
18+
bl _dest+12
1919
blx _dest+20
20-
bne _dest+30
20+
bne _dest+32
2121
b _dest+40
2222

2323
.data

0 commit comments

Comments
 (0)