[lld] r312637 - [ELF][AArch64] Add alignment checks for the LDST<N>_ABS_LO12_NC relocations

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 6 07:23:07 PDT 2017


Author: psmith
Date: Wed Sep  6 07:23:06 2017
New Revision: 312637

URL: http://llvm.org/viewvc/llvm-project?rev=312637&view=rev
Log:
[ELF][AArch64] Add alignment checks for the LDST<N>_ABS_LO12_NC relocations

The R_AARCH64_LDST<N>_ABS LO12_NC relocations where N is 8, 16, 32, 64 or
128 have a scaled immediate. For example R_AARCH64_LDST32_ABS_LO12_NC
shifts the calculated value right by 4. If the target symbol + relocation
addend is not aligned properly then bits of the answer will be lost.

This change adds an alignment check to the relocations to make sure the
target of the relocation is aligned properly. This matches the behavior of
GNU ld. The motivation is to catch ODR violations such as a declaration of
extern int foo, but a definition of bool foo as the compiler may use
R_AARCH64_LDST32_ABS_LO12_NC for the former, but not align the destination.

Differential Revision: https://reviews.llvm.org/D37444


Added:
    lld/trunk/test/ELF/aarch64-lo12-alignment.s
Modified:
    lld/trunk/ELF/Arch/AArch64.cpp

Modified: lld/trunk/ELF/Arch/AArch64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AArch64.cpp?rev=312637&r1=312636&r2=312637&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AArch64.cpp (original)
+++ lld/trunk/ELF/Arch/AArch64.cpp Wed Sep  6 07:23:06 2017
@@ -251,15 +251,19 @@ void AArch64::relocateOne(uint8_t *Loc,
     or32AArch64Imm(Loc, getBits(Val, 0, 11));
     break;
   case R_AARCH64_LDST16_ABS_LO12_NC:
+    checkAlignment<2>(Loc, Val, Type);
     or32AArch64Imm(Loc, getBits(Val, 1, 11));
     break;
   case R_AARCH64_LDST32_ABS_LO12_NC:
+    checkAlignment<4>(Loc, Val, Type);
     or32AArch64Imm(Loc, getBits(Val, 2, 11));
     break;
   case R_AARCH64_LDST64_ABS_LO12_NC:
+    checkAlignment<8>(Loc, Val, Type);
     or32AArch64Imm(Loc, getBits(Val, 3, 11));
     break;
   case R_AARCH64_LDST128_ABS_LO12_NC:
+    checkAlignment<16>(Loc, Val, Type);
     or32AArch64Imm(Loc, getBits(Val, 4, 11));
     break;
   case R_AARCH64_MOVW_UABS_G0_NC:

Added: lld/trunk/test/ELF/aarch64-lo12-alignment.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-lo12-alignment.s?rev=312637&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-lo12-alignment.s (added)
+++ lld/trunk/test/ELF/aarch64-lo12-alignment.s Wed Sep  6 07:23:06 2017
@@ -0,0 +1,45 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t
+// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
+        
+// Test derived from a typical ODR violation where a global is declared
+// extern int but defined as a half or byte sized type.
+ .section .text
+ .globl _start
+ .type _start, %function
+// Access foo2 as if it were an aligned 32-bit int, expect an error as
+// foo is not aligned
+
+_start:
+ ldrb w2, [x0, #:lo12:foo1]  // Ok as no shift involved
+ ldrh w2, [x0, #:lo12:foo1]  // Error foo1 is not 2-byte aligned
+ ldrh w2, [x0, #:lo12:foo2]  // Ok as foo2 is 2-byte aligned
+ ldr  w2, [x0, #:lo12:foo2]  // Error foo2 is not 4-byte aligned
+ ldr  w2, [x0, #:lo12:foo4]  // Ok as foo4 is 4-byte aligned
+ ldr  x3, [x0, #:lo12:foo4]  // Error foo4 is not 8-byte aligned
+ ldr  x3, [x0, #:lo12:foo8]  // Ok as foo8 is 8-byte aligned
+ ldr  q0, [x0, #:lo12:foo8]  // Error foo8 is not 16-byte aligned
+ ldr  q0, [x0, #:lo12:foo16] // Ok as foo16 is 16-byte aligned
+
+ .section .data.bool, "a", @nobits
+ .balign 16
+ .globl foo16
+ .globl foo1
+ .globl foo2
+ .globl foo4
+ .globl foo8
+foo16:
+ .space 1
+foo1:
+ .space 1
+foo2:
+ .space 2
+foo4:
+ .space 4
+foo8:
+ .space 8
+
+// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC
+// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC
+// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC
+// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC




More information about the llvm-commits mailing list