[llvm] a4d6fe5 - Reland "[llvm][ARM] Add Addend Checks for MOVT and MOVW instructions. (PR #111970)" (#112877)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 22 00:18:12 PDT 2024
Author: Jack Styles
Date: 2024-10-22T08:18:09+01:00
New Revision: a4d6fe54a7c3c967d88862e51660a5cdabc080bb
URL: https://github.com/llvm/llvm-project/commit/a4d6fe54a7c3c967d88862e51660a5cdabc080bb
DIFF: https://github.com/llvm/llvm-project/commit/a4d6fe54a7c3c967d88862e51660a5cdabc080bb.diff
LOG: 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
Added:
llvm/test/MC/ARM/arm-movt-movw-range-fail.s
llvm/test/MC/ARM/arm-movt-movw-range-pass.s
Modified:
llvm/docs/ReleaseNotes.md
llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
llvm/test/MC/ARM/macho-movwt.s
Removed:
################################################################################
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index e5853789c78b63..0c4cd437dac0b4 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -136,6 +136,11 @@ Changes to the ARM Backend
in leaf functions by default. To eliminate the frame pointer in leaf functions,
you must explicitly use the `-momit-leaf-frame-pointer` option.
+* 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
--------------------------
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 1223210a76f6e3..1f07e646e43885 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;
@@ -445,6 +446,16 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
bool IsResolved, MCContext &Ctx,
const MCSubtargetInfo* STI) const {
unsigned Kind = Fixup.getKind();
+ int64_t Addend = Target.getConstant();
+
+ // For MOVW/MOVT Instructions, the fixup value must already be within a
+ // signed 16bit range.
+ 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) &&
+ (Addend < minIntN(16) || Addend > 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.
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 -
More information about the llvm-commits
mailing list