[llvm] Add Addend Checks for MOVT and MOVW instructions. (PR #111970)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 11 02:30:20 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mc

Author: Jack Styles (Stylie777)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/111970.diff


7 Files Affected:

- (modified) llvm/docs/ReleaseNotes.md (+5) 
- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (+11) 
- (modified) llvm/test/MC/ARM/Windows/mov32t-range.s (+3-3) 
- (added) llvm/test/MC/ARM/arm-movt-movw-range-fail.s (+13) 
- (added) llvm/test/MC/ARM/arm-movt-movw-range-pass.s (+13) 
- (modified) llvm/test/MC/ARM/macho-movwt.s (+8-8) 
- (modified) llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s (+5-5) 


``````````diff
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 8ac5900a7e532e..e5b1e1a37a1b91 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -123,6 +123,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 16bit 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
 --------------------------
 
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 1223210a76f6e3..4d643d001d7541 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -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;
 
@@ -446,6 +447,16 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
                                          const MCSubtargetInfo* STI) const {
   unsigned Kind = Fixup.getKind();
 
+  // For MOVW/MOVT Instructions, the Fixup Value needs to be 16 bit aligned.
+  // If this is not the case, we should reject compilation.
+  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) &&
+      (!(minIntN(16) <= static_cast<int64_t>(Value) &&
+    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
diff --git a/llvm/test/MC/ARM/Windows/mov32t-range.s b/llvm/test/MC/ARM/Windows/mov32t-range.s
index 7e16105cddc6f3..386893a078de40 100644
--- a/llvm/test/MC/ARM/Windows/mov32t-range.s
+++ b/llvm/test/MC/ARM/Windows/mov32t-range.s
@@ -21,7 +21,7 @@ truncation:
 
 	.section .rdata,"rd"
 .Lbuffer:
-	.zero 65536
+	.zero 32767
 .Lerange:
 	.asciz "-erange"
 
@@ -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
 
diff --git a/llvm/test/MC/ARM/arm-movt-movw-range-fail.s b/llvm/test/MC/ARM/arm-movt-movw-range-fail.s
new file mode 100644
index 00000000000000..2961b9bfcb64d2
--- /dev/null
+++ b/llvm/test/MC/ARM/arm-movt-movw-range-fail.s
@@ -0,0 +1,13 @@
+ at 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
+
+ at CHECK: error: Relocation Not In Range
+ at CHECK: movw    r1, #:lower16:v + -65536
+ at CHECK: ^
+ at CHECK: error: Relocation Not In Range
+ at CHECK: movt    r1, #:upper16:v + 65536
+ at CHECK: ^
diff --git a/llvm/test/MC/ARM/arm-movt-movw-range-pass.s b/llvm/test/MC/ARM/arm-movt-movw-range-pass.s
new file mode 100644
index 00000000000000..41f19565a46c4a
--- /dev/null
+++ b/llvm/test/MC/ARM/arm-movt-movw-range-pass.s
@@ -0,0 +1,13 @@
+ at 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
+
+ at CHECK-NOT: error: Relocation Not In Range
+ at CHECK-NOT: movw    r1, #:lower16:v + -20000
+ at CHECK-NOT: ^
+ at CHECK-NOT: error: Relocation Not In Range
+ at CHECK-NOT: movt    r1, #:upper16:v + 20000
+ at CHECK-NOT: ^
diff --git a/llvm/test/MC/ARM/macho-movwt.s b/llvm/test/MC/ARM/macho-movwt.s
index 6f067cd86dc15d..b2c0587ca7fe59 100644
--- a/llvm/test/MC/ARM/macho-movwt.s
+++ b/llvm/test/MC/ARM/macho-movwt.s
@@ -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
@@ -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
@@ -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 -
@@ -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 -
diff --git a/llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s b/llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s
index 18182d1affb063..0d6f38325b1d3c 100644
--- a/llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s
+++ b/llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s
@@ -11,7 +11,7 @@
 	movt	r2, :upper16:L1
   movw	r12, :lower16:L2
 	movt	r12, :upper16:L2
-  .space 70000
+  .space 16382
   
   .data
 L1: .long 0
@@ -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)
@@ -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)
@@ -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)
@@ -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)

``````````

</details>


https://github.com/llvm/llvm-project/pull/111970


More information about the llvm-commits mailing list