[PATCH] D50998: [LLD] [COFF] Check the instructions in ARM MOV32T relocations

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 20 14:38:30 PDT 2018


mstorsjo created this revision.
mstorsjo added reviewers: ruiu, peter.smith, efriedma, rnk, pcc.
Herald added a reviewer: javed.absar.
Herald added subscribers: chrib, kristof.beyls.

For this relocation, which applies to two consecutive instructions, it's possible that the second instruction might not actually be the right one.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D50998

Files:
  COFF/Chunks.cpp
  test/COFF/broken-arm-reloc.s


Index: test/COFF/broken-arm-reloc.s
===================================================================
--- /dev/null
+++ test/COFF/broken-arm-reloc.s
@@ -0,0 +1,20 @@
+# REQUIRES: arm
+
+# RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: not lld-link -out:%t.exe -entry:main %t.obj 2>&1 | FileCheck %s
+
+# CHECK: error: Unexpected instruction in MOVT instruction in MOV32T relocation
+
+    .global main
+    .global variable
+    .text
+    .thumb
+main:
+    movw r0, :lower16:variable
+    nop
+    movt r0, :upper16:variable
+    ldr  r0, [r0]
+    bx   lr
+    .data
+variable:
+    .long 42
Index: COFF/Chunks.cpp
===================================================================
--- COFF/Chunks.cpp
+++ COFF/Chunks.cpp
@@ -131,16 +131,22 @@
   write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
 }
 
-static uint16_t readMOV(uint8_t *Off) {
+static uint16_t readMOV(uint8_t *Off, bool MOVT) {
   uint16_t Op1 = read16le(Off);
+  if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
+    error("Unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
+          " instruction in MOV32T relocation");
   uint16_t Op2 = read16le(Off + 2);
+  if ((Op2 & 0x8000) != 0)
+    error("Unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
+          " instruction in MOV32T relocation");
   return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
          ((Op1 & 0x000f) << 12);
 }
 
 void applyMOV32T(uint8_t *Off, uint32_t V) {
-  uint16_t ImmW = readMOV(Off);     // read MOVW operand
-  uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
+  uint16_t ImmW = readMOV(Off, false);    // read MOVW operand
+  uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
   uint32_t Imm = ImmW | (ImmT << 16);
   V += Imm;                         // add the immediate offset
   applyMOV(Off, V);           // set MOVW operand


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50998.161565.patch
Type: text/x-patch
Size: 1916 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180820/786be9e9/attachment.bin>


More information about the llvm-commits mailing list