Skip to content

Commit

Permalink
[llvm][ARM] Add Addend Checks for MOVT and MOVW instructions. (llvm#1…
Browse files Browse the repository at this point in the history
…11970)

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
  • Loading branch information
Stylie777 authored Oct 14, 2024
1 parent 851817b commit f3aebe6
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 16 deletions.
5 changes: 5 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ Changes to the ARM Backend
the required alignment space with a sequence of `0x0` bytes (the requested
fill value) rather than NOPs.

* When using the `MOVT` or `MOVW` instructions, the Assembler will now check to
ensure that any addend that is used is within a 16-bit signed value range. If the
addend falls outside of this range, the LLVM backend will emit an error like so
`Relocation Not In Range`.

Changes to the AVR Backend
--------------------------

Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

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

// For MOVW/MOVT Instructions, the fixup value must already be 16-bit aligned.
if ((Kind == ARM::fixup_arm_movw_lo16 || Kind == ARM::fixup_arm_movt_hi16 ||
Kind == ARM::fixup_t2_movw_lo16 || Kind == ARM::fixup_t2_movt_hi16) &&
(static_cast<int64_t>(Value) < minIntN(16) ||
static_cast<int64_t>(Value) > maxIntN(16))) {
Ctx.reportError(Fixup.getLoc(), "Relocation Not In Range");
return 0;
}

// MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
// and .word relocations they put the Thumb bit into the addend if possible.
// Other relocation types don't want this bit though (branches couldn't encode
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/MC/ARM/Windows/mov32t-range.s
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ truncation:

.section .rdata,"rd"
.Lbuffer:
.zero 65536
.zero 32767
.Lerange:
.asciz "-erange"

Expand All @@ -32,6 +32,6 @@ truncation:
@ CHECK-RELOCATIONS: }
@ CHECK-RELOCATIONS: ]

@ CHECK-ENCODING: 0: f240 0000
@ CHECK-ENCODING-NEXT: 4: f2c0 0001
@ CHECK-ENCODING: 0: f647 70ff
@ CHECK-ENCODING-NEXT: 4: f2c0 0000

13 changes: 13 additions & 0 deletions llvm/test/MC/ARM/arm-movt-movw-range-fail.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@RUN: not llvm-mc -triple armv7-eabi -filetype obj -o - %s 2>&1 | FileCheck %s

.global v
.text
movw r1, #:lower16:v + -65536
movt r1, #:upper16:v + 65536

@CHECK: error: Relocation Not In Range
@CHECK: movw r1, #:lower16:v + -65536
@CHECK: ^
@CHECK: error: Relocation Not In Range
@CHECK: movt r1, #:upper16:v + 65536
@CHECK: ^
13 changes: 13 additions & 0 deletions llvm/test/MC/ARM/arm-movt-movw-range-pass.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s 2>&1 | FileCheck %s

.global v
.text
movw r1, #:lower16:v + -20000
movt r1, #:upper16:v + 20000

@CHECK-NOT: error: Relocation Not In Range
@CHECK-NOT: movw r1, #:lower16:v + -20000
@CHECK-NOT: ^
@CHECK-NOT: error: Relocation Not In Range
@CHECK-NOT: movt r1, #:upper16:v + 20000
@CHECK-NOT: ^
16 changes: 8 additions & 8 deletions llvm/test/MC/ARM/macho-movwt.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
movw r0, :lower16:_x+4
movt r0, :upper16:_x+4

movw r0, :lower16:_x+0x10000
movt r0, :upper16:_x+0x10000
movw r0, :lower16:_x+0x1000
movt r0, :upper16:_x+0x1000

.arm
movw r0, :lower16:_x
Expand All @@ -18,8 +18,8 @@
movw r0, :lower16:_x+4
movt r0, :upper16:_x+4

movw r0, :lower16:_x+0x10000
movt r0, :upper16:_x+0x10000
movw r0, :lower16:_x+0x1000
movt r0, :upper16:_x+0x1000

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

@ CHECK: 0x2C 0 1 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 1 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x1000 0 1 0 ARM_RELOC_PAIR 0 -

@ CHECK: 0x28 0 0 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x1 0 0 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x0 0 0 0 ARM_RELOC_PAIR 0 -

@ CHECK: 0x24 0 1 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x4 0 1 0 ARM_RELOC_PAIR 0 -
Expand All @@ -48,10 +48,10 @@
@ CHECK: 0x0 0 0 0 ARM_RELOC_PAIR 0 -

@ CHECK: 0x14 0 3 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x0 0 3 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x1000 0 3 0 ARM_RELOC_PAIR 0 -

@ CHECK: 0x10 0 2 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x1 0 2 0 ARM_RELOC_PAIR 0 -
@ CHECK: 0x0 0 2 0 ARM_RELOC_PAIR 0 -

@ CHECK: 0xC 0 3 1 ARM_RELOC_HALF 0 _x
@ CHECK: 0x4 0 3 0 ARM_RELOC_PAIR 0 -
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
movt r2, :upper16:L1
movw r12, :lower16:L2
movt r12, :upper16:L2
.space 70000
.space 16382

.data
L1: .long 0
Expand All @@ -30,7 +30,7 @@ L2: .long 0
@ CHECK: Section: __data (2)
@ CHECK: }
@ CHECK: Relocation {
@ CHECK: Offset: 0x1184
@ CHECK: Offset: 0x4012
@ CHECK: PCRel: 0
@ CHECK: Length: 3
@ CHECK: Type: ARM_RELOC_PAIR (1)
Expand All @@ -44,7 +44,7 @@ L2: .long 0
@ CHECK: Section: __data (2)
@ CHECK: }
@ CHECK: Relocation {
@ CHECK: Offset: 0x1
@ CHECK: Offset: 0x0
@ CHECK: PCRel: 0
@ CHECK: Length: 2
@ CHECK: Type: ARM_RELOC_PAIR (1)
Expand All @@ -58,7 +58,7 @@ L2: .long 0
@ CHECK: Section: __data (2)
@ CHECK: }
@ CHECK: Relocation {
@ CHECK: Offset: 0x1180
@ CHECK: Offset: 0x400E
@ CHECK: PCRel: 0
@ CHECK: Length: 3
@ CHECK: Type: ARM_RELOC_PAIR (1)
Expand All @@ -72,7 +72,7 @@ L2: .long 0
@ CHECK: Section: __data (2)
@ CHECK: }
@ CHECK: Relocation {
@ CHECK: Offset: 0x1
@ CHECK: Offset: 0x0
@ CHECK: PCRel: 0
@ CHECK: Length: 2
@ CHECK: Type: ARM_RELOC_PAIR (1)
Expand Down

0 comments on commit f3aebe6

Please sign in to comment.