Skip to content

Commit f3aebe6

Browse files
authored
[llvm][ARM] Add Addend Checks for MOVT and MOVW instructions. (llvm#111970)
Previously, any value could be used for the MOVT and MOVW instructions, however the ARM ABI dictates that the addend should be a signed 16 bit value. To ensure this is followed, the Assembler will now check that when using these instructions, the addend is a 16bit signed value, and throw an error if this is not the case. Information relating to the ABI requirements can be found here: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#addends-and-pc-bias-compensation
1 parent 851817b commit f3aebe6

File tree

7 files changed

+57
-16
lines changed

7 files changed

+57
-16
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ Changes to the ARM Backend
125125
the required alignment space with a sequence of `0x0` bytes (the requested
126126
fill value) rather than NOPs.
127127

128+
* When using the `MOVT` or `MOVW` instructions, the Assembler will now check to
129+
ensure that any addend that is used is within a 16-bit signed value range. If the
130+
addend falls outside of this range, the LLVM backend will emit an error like so
131+
`Relocation Not In Range`.
132+
128133
Changes to the AVR Backend
129134
--------------------------
130135

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "llvm/Support/EndianStream.h"
3535
#include "llvm/Support/ErrorHandling.h"
3636
#include "llvm/Support/Format.h"
37+
#include "llvm/Support/MathExtras.h"
3738
#include "llvm/Support/raw_ostream.h"
3839
using namespace llvm;
3940

@@ -446,6 +447,15 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
446447
const MCSubtargetInfo* STI) const {
447448
unsigned Kind = Fixup.getKind();
448449

450+
// For MOVW/MOVT Instructions, the fixup value must already be 16-bit aligned.
451+
if ((Kind == ARM::fixup_arm_movw_lo16 || Kind == ARM::fixup_arm_movt_hi16 ||
452+
Kind == ARM::fixup_t2_movw_lo16 || Kind == ARM::fixup_t2_movt_hi16) &&
453+
(static_cast<int64_t>(Value) < minIntN(16) ||
454+
static_cast<int64_t>(Value) > maxIntN(16))) {
455+
Ctx.reportError(Fixup.getLoc(), "Relocation Not In Range");
456+
return 0;
457+
}
458+
449459
// MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
450460
// and .word relocations they put the Thumb bit into the addend if possible.
451461
// Other relocation types don't want this bit though (branches couldn't encode

llvm/test/MC/ARM/Windows/mov32t-range.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ truncation:
2121

2222
.section .rdata,"rd"
2323
.Lbuffer:
24-
.zero 65536
24+
.zero 32767
2525
.Lerange:
2626
.asciz "-erange"
2727

@@ -32,6 +32,6 @@ truncation:
3232
@ CHECK-RELOCATIONS: }
3333
@ CHECK-RELOCATIONS: ]
3434

35-
@ CHECK-ENCODING: 0: f240 0000
36-
@ CHECK-ENCODING-NEXT: 4: f2c0 0001
35+
@ CHECK-ENCODING: 0: f647 70ff
36+
@ CHECK-ENCODING-NEXT: 4: f2c0 0000
3737

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@RUN: not llvm-mc -triple armv7-eabi -filetype obj -o - %s 2>&1 | FileCheck %s
2+
3+
.global v
4+
.text
5+
movw r1, #:lower16:v + -65536
6+
movt r1, #:upper16:v + 65536
7+
8+
@CHECK: error: Relocation Not In Range
9+
@CHECK: movw r1, #:lower16:v + -65536
10+
@CHECK: ^
11+
@CHECK: error: Relocation Not In Range
12+
@CHECK: movt r1, #:upper16:v + 65536
13+
@CHECK: ^
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s 2>&1 | FileCheck %s
2+
3+
.global v
4+
.text
5+
movw r1, #:lower16:v + -20000
6+
movt r1, #:upper16:v + 20000
7+
8+
@CHECK-NOT: error: Relocation Not In Range
9+
@CHECK-NOT: movw r1, #:lower16:v + -20000
10+
@CHECK-NOT: ^
11+
@CHECK-NOT: error: Relocation Not In Range
12+
@CHECK-NOT: movt r1, #:upper16:v + 20000
13+
@CHECK-NOT: ^

llvm/test/MC/ARM/macho-movwt.s

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
movw r0, :lower16:_x+4
99
movt r0, :upper16:_x+4
1010

11-
movw r0, :lower16:_x+0x10000
12-
movt r0, :upper16:_x+0x10000
11+
movw r0, :lower16:_x+0x1000
12+
movt r0, :upper16:_x+0x1000
1313

1414
.arm
1515
movw r0, :lower16:_x
@@ -18,8 +18,8 @@
1818
movw r0, :lower16:_x+4
1919
movt r0, :upper16:_x+4
2020

21-
movw r0, :lower16:_x+0x10000
22-
movt r0, :upper16:_x+0x10000
21+
movw r0, :lower16:_x+0x1000
22+
movt r0, :upper16:_x+0x1000
2323

2424
@ Enter the bizarre world of MachO relocations. First, they're in reverse order
2525
@ to the actual instructions
@@ -30,10 +30,10 @@
3030
@ Third column identifies ARM/Thumb & HI/LO.
3131

3232
@ CHECK: 0x2C 0 1 1 ARM_RELOC_HALF 0 _x
33-
@ CHECK: 0x0 0 1 0 ARM_RELOC_PAIR 0 -
33+
@ CHECK: 0x1000 0 1 0 ARM_RELOC_PAIR 0 -
3434

3535
@ CHECK: 0x28 0 0 1 ARM_RELOC_HALF 0 _x
36-
@ CHECK: 0x1 0 0 0 ARM_RELOC_PAIR 0 -
36+
@ CHECK: 0x0 0 0 0 ARM_RELOC_PAIR 0 -
3737

3838
@ CHECK: 0x24 0 1 1 ARM_RELOC_HALF 0 _x
3939
@ CHECK: 0x4 0 1 0 ARM_RELOC_PAIR 0 -
@@ -48,10 +48,10 @@
4848
@ CHECK: 0x0 0 0 0 ARM_RELOC_PAIR 0 -
4949

5050
@ CHECK: 0x14 0 3 1 ARM_RELOC_HALF 0 _x
51-
@ CHECK: 0x0 0 3 0 ARM_RELOC_PAIR 0 -
51+
@ CHECK: 0x1000 0 3 0 ARM_RELOC_PAIR 0 -
5252

5353
@ CHECK: 0x10 0 2 1 ARM_RELOC_HALF 0 _x
54-
@ CHECK: 0x1 0 2 0 ARM_RELOC_PAIR 0 -
54+
@ CHECK: 0x0 0 2 0 ARM_RELOC_PAIR 0 -
5555

5656
@ CHECK: 0xC 0 3 1 ARM_RELOC_HALF 0 _x
5757
@ CHECK: 0x4 0 3 0 ARM_RELOC_PAIR 0 -

llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
movt r2, :upper16:L1
1212
movw r12, :lower16:L2
1313
movt r12, :upper16:L2
14-
.space 70000
14+
.space 16382
1515

1616
.data
1717
L1: .long 0
@@ -30,7 +30,7 @@ L2: .long 0
3030
@ CHECK: Section: __data (2)
3131
@ CHECK: }
3232
@ CHECK: Relocation {
33-
@ CHECK: Offset: 0x1184
33+
@ CHECK: Offset: 0x4012
3434
@ CHECK: PCRel: 0
3535
@ CHECK: Length: 3
3636
@ CHECK: Type: ARM_RELOC_PAIR (1)
@@ -44,7 +44,7 @@ L2: .long 0
4444
@ CHECK: Section: __data (2)
4545
@ CHECK: }
4646
@ CHECK: Relocation {
47-
@ CHECK: Offset: 0x1
47+
@ CHECK: Offset: 0x0
4848
@ CHECK: PCRel: 0
4949
@ CHECK: Length: 2
5050
@ CHECK: Type: ARM_RELOC_PAIR (1)
@@ -58,7 +58,7 @@ L2: .long 0
5858
@ CHECK: Section: __data (2)
5959
@ CHECK: }
6060
@ CHECK: Relocation {
61-
@ CHECK: Offset: 0x1180
61+
@ CHECK: Offset: 0x400E
6262
@ CHECK: PCRel: 0
6363
@ CHECK: Length: 3
6464
@ CHECK: Type: ARM_RELOC_PAIR (1)
@@ -72,7 +72,7 @@ L2: .long 0
7272
@ CHECK: Section: __data (2)
7373
@ CHECK: }
7474
@ CHECK: Relocation {
75-
@ CHECK: Offset: 0x1
75+
@ CHECK: Offset: 0x0
7676
@ CHECK: PCRel: 0
7777
@ CHECK: Length: 2
7878
@ CHECK: Type: ARM_RELOC_PAIR (1)

0 commit comments

Comments
 (0)