Skip to content

Commit adbe144

Browse files
jcohen-applejroelofs
authored andcommitted
[ARMAsmBackend] Add range and alignment checks for armv7 branches
Currently we will silently truncate and round the relocation values input to the assembler, and produce branch instructions with a bad offset. After this change, the assembler will fail if the relocation value cannot be encoded into the instruction.
1 parent 9835aa0 commit adbe144

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
Value = Value - 4;
591605
if (!isInt<25>(Value)) {
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)