Index: ELF/Arch/AArch64.cpp =================================================================== --- ELF/Arch/AArch64.cpp +++ ELF/Arch/AArch64.cpp @@ -90,6 +90,11 @@ case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: + case R_AARCH64_TLSLE_MOVW_TPREL_G0: + case R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: + case R_AARCH64_TLSLE_MOVW_TPREL_G1: + case R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: + case R_AARCH64_TLSLE_MOVW_TPREL_G2: return R_TLS; case R_AARCH64_CALL26: case R_AARCH64_CONDBR19: @@ -376,20 +381,25 @@ break; case R_AARCH64_MOVW_PREL_G0: case R_AARCH64_MOVW_SABS_G0: + case R_AARCH64_TLSLE_MOVW_TPREL_G0: checkInt(loc, val, 17, type); LLVM_FALLTHROUGH; case R_AARCH64_MOVW_PREL_G0_NC: + case R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: writeSMovWImm(loc, val); break; case R_AARCH64_MOVW_PREL_G1: case R_AARCH64_MOVW_SABS_G1: + case R_AARCH64_TLSLE_MOVW_TPREL_G1: checkInt(loc, val, 33, type); LLVM_FALLTHROUGH; case R_AARCH64_MOVW_PREL_G1_NC: + case R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: writeSMovWImm(loc, val >> 16); break; case R_AARCH64_MOVW_PREL_G2: case R_AARCH64_MOVW_SABS_G2: + case R_AARCH64_TLSLE_MOVW_TPREL_G2: checkInt(loc, val, 49, type); LLVM_FALLTHROUGH; case R_AARCH64_MOVW_PREL_G2_NC: Index: test/ELF/aarch64-movw-error.s =================================================================== --- test/ELF/aarch64-movw-error.s +++ test/ELF/aarch64-movw-error.s @@ -34,3 +34,22 @@ movn x0, #:prel_g1:.-0x100010000 # CHECK: relocation R_AARCH64_MOVW_PREL_G2 out of range: -281479271677952 is not in [-281474976710656, 281474976710655] movn x0, #:prel_g2:.-0x1000100000000 + +movz x0, #:tprel_g0: v1 +# CHECK: relocation R_AARCH64_TLSLE_MOVW_TPREL_G0 out of range: 65552 is not in [-65536, 65535] +movz x0, #:tprel_g1: v2 +# CHECK: relocation R_AARCH64_TLSLE_MOVW_TPREL_G1 out of range: 4295032848 is not in [-4294967296, 4294967295] +movz x0, #:tprel_g2: v3 +# CHECK: relocation R_AARCH64_TLSLE_MOVW_TPREL_G2 out of range: 281479271743496 is not in [-281474976710656, 281474976710655] + +.section .tbss,"awT",@nobits +.balign 16 +.space 0x10000 +v1: +.quad 0 +.space 0x100000000 - 8 +v2: +.quad 0 +.space 0x1000000000000 - 16 +v3: +.quad 0 Index: test/ELF/aarch64-movw-tprel.s =================================================================== --- /dev/null +++ test/ELF/aarch64-movw-tprel.s @@ -0,0 +1,65 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-objdump -d %t +# RUN: llvm-readobj --symbols %t +# RUN: llvm-objdump -d %t | FileCheck %s +# RUN: llvm-readobj --symbols %t | FileCheck --check-prefix=CHECK-SYM %s + +## Test the the local exec relocations that map to: +## R_AARCH64_TLSLE_MOVW_TPREL_G2 +## R_AARCH64_TLSLE_MOVW_TPREL_G1 +## R_AARCH64_TLSLE_MOVW_TPREL_G1_NC +## R_AARCH64_TLSLE_MOVW_TPREL_G0 +## R_AARCH64_TLSLE_MOVW_TPREL_G0_NC +## They calculate the same value as the other TPREL relocations, namely the +## offset from the thread pointer TP. The G0, G1 and G2 refer to partitions +## of the result with G2 bits [47:32], G1 bits [31:16] and G0 bits [15:0] +## the NC variant does not check for overflow. +## In AArch64 the structure of the TLS at runtime is: +## | TCB | Alignment Padding | TLS Block | +## With TP pointing to the start of the TCB. All offsets will be positive. + +.text +## Access variable in first partition +movz x0, #:tprel_g0:v0 +## TCB + 0 == 16 +# CHECK: 210000: 00 02 80 d2 mov x0, #16 + +# CHECK-SYM: Name: v0 +# CHECK-SYM-NEXT: Value: 0x0 + +## Access variable in second partition +movz x0, #:tprel_g1:v1 +movk x0, #:tprel_g0_nc:v1 + +## TCB + 65536 across movz and movk +# CHECK: 210004: 20 00 a0 d2 mov x0, #65536 +# CHECK-NEXT: 210008: 00 02 80 f2 movk x0, #16 + +# CHECK-SYM: Name: v1 +# CHECK-SYM-NEXT: Value: 0x10000 + +## Access variable in third partition +movz x0, #:tprel_g2:v2 +movk x0, #:tprel_g1_nc:v2 +movk x0, #:tprel_g0_nc:v2 + +## TCB + 65536 + 4294967296 across movz and 2 movk instructions +# CHECK: 21000c: 20 00 c0 d2 mov x0, #4294967296 +# CHECK-NEXT: 210010: 20 00 a0 f2 movk x0, #1, lsl #16 +# CHECK-NEXT: 210014: 00 02 80 f2 movk x0, #16 + +# CHECK-SYM: Name: v2 +# CHECK-SYM-NEXT: Value: 0x100010000 + +.section .tbss,"awT",@nobits +.balign 16 +v0: +.quad 0 +.space 0x10000 - 8 +v1: +.quad 0 +.space 0x100000000 - 8 +v2: +.quad 0