Skip to content

Commit 415ac86

Browse files
committed
[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 1714b11 commit 415ac86

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,19 @@ 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+
if (!isInt<26>(Value)) {
584+
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
585+
return 0;
586+
}
587+
// Alignment differs for blx. Because we are switching to thumb ISA, we use
588+
// 16-bit alignment. Otherwise, use 32-bit.
589+
if ((Kind == ARM::fixup_arm_blx && Value % 2 != 0) ||
590+
(Kind != ARM::fixup_arm_blx && Value % 4 != 0)) {
591+
Ctx.reportError(Fixup.getLoc(), "Relocation not aligned");
592+
return 0;
593+
}
594+
582595
// These values don't encode the low two bits since they're always zero.
583596
// Offset by 8 just as above.
584597
if (const MCSymbolRefExpr *SRE =
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 outside of range of the largest accepted positive number
5+
_foo1:
6+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
7+
b _foo1+33554432
8+
9+
// Check Same as above, for smallest negative value
10+
_foo2:
11+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
12+
b _foo2-33554436
13+
14+
// Edge case - subtracting positive number
15+
_foo3:
16+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
17+
b _foo3-0x2000010
18+
19+
// Edge case - adding negative number
20+
_foo4:
21+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
22+
b _foo4+0x2000008
23+
24+
_foo5:
25+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
26+
bl _foo5+33554432
27+
28+
_foo6:
29+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
30+
blx _foo6+33554432
31+
32+
// blx instruction is aligned to 16-bits.
33+
_foo7:
34+
// CHECK-NOT:[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
35+
blx _foo6+33554430
36+
37+
_foo8:
38+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
39+
ble _foo8+33554432
40+
41+
_foo9:
42+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
43+
beq _foo9+33554432
44+
45+
// Check that the relocation alignment is valid.
46+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
47+
bl _foo1+0x101
48+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
49+
blx _foo1+0x101
50+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
51+
b _foo1+0x101
52+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
53+
ble _foo1+0x101
54+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
55+
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)