Skip to content

Commit a4d6fe5

Browse files
authored
Reland "[llvm][ARM] Add Addend Checks for MOVT and MOVW instructions. (PR #111970)" (#112877)
**Change relanded after feedback on failures and improvements to the check of the addend. Original PR #111970** Changes from original patch: - The value that is being checked has changed, it is now correctly checking any Addend for the instruction, rather than the Value. The addend is kept within the Target data structure from my investigation. - Removed changes to the following tests due to the original behaviour being correct, and my original patch causing unexpected errors - llvm/test/MC/ARM/Windows/mov32t-range.s - llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s As per the ARM ABI, the MOVT and MOVW instructions should have addends that fall within a 16bit signed range. LLVM does not check this so it is possible to use addends that are beyond the accepted range. These addends are silently truncated. A new check is added to ensure the addend falls within the expected range, rejecting an addend that falls outside with an error. 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 dc84337 commit a4d6fe5

File tree

5 files changed

+50
-8
lines changed

5 files changed

+50
-8
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ Changes to the ARM Backend
136136
in leaf functions by default. To eliminate the frame pointer in leaf functions,
137137
you must explicitly use the `-momit-leaf-frame-pointer` option.
138138

139+
* When using the `MOVT` or `MOVW` instructions, the Assembler will now check to
140+
ensure that any addend that is used is within a 16-bit signed value range. If the
141+
addend falls outside of this range, the LLVM backend will emit an error like so
142+
`Relocation Not In Range`.
143+
139144
Changes to the AVR Backend
140145
--------------------------
141146

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

Lines changed: 11 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

@@ -445,6 +446,16 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
445446
bool IsResolved, MCContext &Ctx,
446447
const MCSubtargetInfo* STI) const {
447448
unsigned Kind = Fixup.getKind();
449+
int64_t Addend = Target.getConstant();
450+
451+
// For MOVW/MOVT Instructions, the fixup value must already be within a
452+
// signed 16bit range.
453+
if ((Kind == ARM::fixup_arm_movw_lo16 || Kind == ARM::fixup_arm_movt_hi16 ||
454+
Kind == ARM::fixup_t2_movw_lo16 || Kind == ARM::fixup_t2_movt_hi16) &&
455+
(Addend < minIntN(16) || Addend > maxIntN(16))) {
456+
Ctx.reportError(Fixup.getLoc(), "Relocation Not In Range");
457+
return 0;
458+
}
448459

449460
// MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
450461
// and .word relocations they put the Thumb bit into the addend if possible.
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 -

0 commit comments

Comments
 (0)