xref: /llvm-project/lld/test/ELF/riscv-tlsdesc.s (revision cdd29f5bd2f5e55ae116be1a912f0b036d7c98e7)
1# REQUIRES: riscv
2# RUN: rm -rf %t && split-file %s %t && cd %t
3# RUN: llvm-mc -filetype=obj -triple=riscv64 a.s -o a.64.o
4# RUN: llvm-mc -filetype=obj -triple=riscv64 c.s -o c.64.o
5# RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so
6# RUN: llvm-mc -filetype=obj -triple=riscv32 --defsym ELF32=1 a.s -o a.32.o
7# RUN: llvm-mc -filetype=obj -triple=riscv32 --defsym ELF32=1 c.s -o c.32.o
8# RUN: ld.lld -shared -soname=c.32.so c.32.o -o c.32.so
9
10# RUN: ld.lld -shared -z now a.64.o c.64.o -o a.64.so
11# RUN: llvm-readobj -r -x .got a.64.so | FileCheck --check-prefix=GD64-RELA %s
12# RUN: llvm-objdump --no-show-raw-insn -M no-aliases -h -d a.64.so | FileCheck %s --check-prefix=GD64
13
14# RUN: ld.lld -shared -z now a.64.o c.64.o -o rel.64.so -z rel
15# RUN: llvm-readobj -r -x .got rel.64.so | FileCheck --check-prefix=GD64-REL %s
16
17# RUN: ld.lld -e 0 -z now a.64.o c.64.o -o a.64.le
18# RUN: llvm-readelf -r a.64.le | FileCheck --check-prefix=NOREL %s
19# RUN: llvm-objdump --no-show-raw-insn -M no-aliases -h -d a.64.le | FileCheck %s --check-prefix=LE64
20
21# RUN: ld.lld -e 0 -z now a.64.o c.64.so -o a.64.ie
22# RUN: llvm-readobj -r a.64.ie | FileCheck --check-prefix=IE64-RELA %s
23# RUN: llvm-objdump --no-show-raw-insn -M no-aliases -h -d a.64.ie | FileCheck %s --check-prefix=IE64
24
25## 32-bit code is mostly the same. We only test a few variants. The IE optimization uses the LW instruction.
26
27# RUN: ld.lld -shared -z now a.32.o c.32.o -o rel.32.so -z rel
28# RUN: llvm-readobj -r -x .got rel.32.so | FileCheck --check-prefix=GD32-REL %s
29# RUN: ld.lld -e 0 -z now a.32.o c.32.so -o a.32.ie
30# RUN: llvm-objdump --no-show-raw-insn -M no-aliases -h -d a.32.ie | FileCheck %s --check-prefix=IE32
31
32## Prior to https://github.com/llvm/llvm-project/pull/85817 the local TLSDESC
33## labels would be marked STT_TLS, resulting in an error "has an STT_TLS symbol but doesn't have an SHF_TLS section"
34
35# RUN: llvm-mc -triple=riscv64 -filetype=obj d.s -o d.64.o
36# RUN: ld.lld -shared -soname=d.64.so -o d.64.so d.64.o --fatal-warnings
37# RUN: llvm-mc -triple=riscv32 -filetype=obj d.s -o d.32.o --defsym ELF32=1
38# RUN: ld.lld -shared -soname=d.32.so -o d.32.so d.32.o --fatal-warnings
39
40## The output has a TLS reference but no TLS section.
41# RUN: llvm-mc -filetype=obj -triple=riscv64 a1.s -o a1.64.o
42# RUN: ld.lld -pie a1.64.o c.64.so -o a1.64
43# RUN: llvm-objdump --no-show-raw-insn -M no-aliases -Rd a1.64 | FileCheck %s --check-prefix=IE64A
44
45# GD64-RELA:      .rela.dyn {
46# GD64-RELA-NEXT:   0x2408 R_RISCV_TLSDESC - 0x7FF
47# GD64-RELA-NEXT:   0x23E8 R_RISCV_TLSDESC a 0x0
48# GD64-RELA-NEXT:   0x23F8 R_RISCV_TLSDESC c 0x0
49# GD64-RELA-NEXT: }
50# GD64-RELA:      Hex dump of section '.got':
51# GD64-RELA-NEXT: 0x000023e0 20230000 00000000 00000000 00000000 #
52# GD64-RELA-NEXT: 0x000023f0 00000000 00000000 00000000 00000000 .
53
54# GD64-REL:      .rel.dyn {
55# GD64-REL-NEXT:   0x23F0 R_RISCV_TLSDESC -
56# GD64-REL-NEXT:   0x23D0 R_RISCV_TLSDESC a
57# GD64-REL-NEXT:   0x23E0 R_RISCV_TLSDESC c
58# GD64-REL-NEXT: }
59# GD64-REL:      Hex dump of section '.got':
60# GD64-REL-NEXT: 0x000023c8 08230000 00000000 00000000 00000000 .
61# GD64-REL-NEXT: 0x000023d8 00000000 00000000 00000000 00000000 .
62# GD64-REL-NEXT: 0x000023e8 00000000 00000000 00000000 00000000 .
63# GD64-REL-NEXT: 0x000023f8 ff070000 00000000                   .
64
65# GD32-REL:      .rel.dyn {
66# GD32-REL-NEXT:   0x2274 R_RISCV_TLSDESC -
67# GD32-REL-NEXT:   0x2264 R_RISCV_TLSDESC a
68# GD32-REL-NEXT:   0x226C R_RISCV_TLSDESC c
69# GD32-REL-NEXT: }
70# GD32-REL:      Hex dump of section '.got':
71# GD32-REL-NEXT: 0x00002260 00220000 00000000 00000000 00000000 .
72# GD32-REL-NEXT: 0x00002270 00000000 00000000 ff070000          .
73
74# GD64:      .got     00000038 00000000000023e0
75
76## &.got[a]-. = 0x23e0+8 - 0x12e0 = 0x1108
77# GD64:        12e0: auipc   a0, 0x1
78# GD64-NEXT:         ld      a1, 0x108(a0)
79# GD64-NEXT:         addi    a0, a0, 0x108
80# GD64-NEXT:         jalr    t0, 0x0(a1)
81# GD64-NEXT:         add     a0, a0, tp
82
83## &.got[b]-. = 0x23e0+40 - 0x12f4 = 0x1114
84# GD64:        12f4: auipc   a2, 0x1
85# GD64-NEXT:         ld      a3, 0x114(a2)
86# GD64-NEXT:         addi    a0, a2, 0x114
87# GD64-NEXT:         jalr    t0, 0x0(a3)
88# GD64-NEXT:         add     a0, a0, tp
89
90## &.got[c]-. = 0x23e0+24 - 0x1308 = 0x10f0
91# GD64:        1308: auipc   a4, 0x1
92# GD64-NEXT:         ld      a5, 0xf0(a4)
93# GD64-NEXT:         addi    a0, a4, 0xf0
94# GD64-NEXT:         jalr    t0, 0x0(a5)
95# GD64-NEXT:         add     a0, a0, tp
96
97# NOREL: no relocations
98
99# LE64-LABEL: <.Ltlsdesc_hi0>:
100## st_value(a) = 8
101# LE64-NEXT:         addi    zero, zero, 0x0
102# LE64-NEXT:         addi    zero, zero, 0x0
103# LE64-NEXT:         addi    zero, zero, 0x0
104# LE64-NEXT:         addi    a0, zero, 0x8
105# LE64-NEXT:         add     a0, a0, tp
106## st_value(b) = 2047
107# LE64-LABEL: <.Ltlsdesc_hi1>:
108# LE64-NEXT:         addi    zero, zero, 0x0
109# LE64-NEXT:         addi    zero, zero, 0x0
110# LE64-NEXT:         addi    zero, zero, 0x0
111# LE64-NEXT:         addi    a0, zero, 0x7ff
112# LE64-NEXT:         add     a0, a0, tp
113## st_value(c) = 2048
114# LE64-LABEL: <.Ltlsdesc_hi2>:
115# LE64-NEXT:         addi    zero, zero, 0x0
116# LE64-NEXT:         addi    zero, zero, 0x0
117# LE64-NEXT:         lui     a0, 0x1
118# LE64-NEXT:         addi    a0, a0, -0x800
119# LE64-NEXT:         add     a0, a0, tp
120
121# IE64-RELA:      .rela.dyn {
122# IE64-RELA-NEXT:   0x123B0 R_RISCV_TLS_TPREL64 c 0x0
123# IE64-RELA-NEXT: }
124
125# IE64:       .got     00000010 00000000000123a8
126
127## a and b are optimized to use LE. c is optimized to IE.
128# IE64-LABEL: <.Ltlsdesc_hi0>:
129# IE64-NEXT:         addi    zero, zero, 0x0
130# IE64-NEXT:         addi    zero, zero, 0x0
131# IE64-NEXT:         addi    zero, zero, 0x0
132# IE64-NEXT:         addi    a0, zero, 0x8
133# IE64-NEXT:         add     a0, a0, tp
134# IE64-LABEL: <.Ltlsdesc_hi1>:
135# IE64-NEXT:         addi    zero, zero, 0x0
136# IE64-NEXT:         addi    zero, zero, 0x0
137# IE64-NEXT:         addi    zero, zero, 0x0
138# IE64-NEXT:         addi    a0, zero, 0x7ff
139# IE64-NEXT:         add     a0, a0, tp
140## &.got[c]-. = 0x123a8+8 - 0x112b8 = 0x10f8
141# IE64-LABEL: <.Ltlsdesc_hi2>:
142# IE64-NEXT:         addi    zero, zero, 0x0
143# IE64-NEXT:         addi    zero, zero, 0x0
144# IE64-NEXT:  112b8: auipc   a0, 0x1
145# IE64-NEXT:         ld      a0, 0xf8(a0)
146# IE64-NEXT:         add     a0, a0, tp
147
148# IE32:       .got     00000008 00012248
149
150# IE32-LABEL: <.Ltlsdesc_hi0>:
151## st_value(a) = 8
152# IE32-NEXT:         addi    zero, zero, 0x0
153# IE32-NEXT:         addi    zero, zero, 0x0
154# IE32-NEXT:         addi    zero, zero, 0x0
155# IE32-NEXT:         addi    a0, zero, 0x8
156# IE32-NEXT:         add     a0, a0, tp
157## st_value(b) = 2047
158# IE32-LABEL: <.Ltlsdesc_hi1>:
159# IE32-NEXT:         addi    zero, zero, 0x0
160# IE32-NEXT:         addi    zero, zero, 0x0
161# IE32-NEXT:         addi    zero, zero, 0x0
162# IE32-NEXT:         addi    a0, zero, 0x7ff
163# IE32-NEXT:         add     a0, a0, tp
164## &.got[c]-. = 0x12248+4 - 0x111cc = 0x1080
165# IE32-LABEL: <.Ltlsdesc_hi2>:
166# IE32-NEXT:         addi    zero, zero, 0x0
167# IE32-NEXT:         addi    zero, zero, 0x0
168# IE32-NEXT:  111cc: auipc   a0, 0x1
169# IE32-NEXT:         lw      a0, 0x80(a0)
170# IE32-NEXT:         add     a0, a0, tp
171
172# IE64A:       OFFSET           TYPE                     VALUE
173# IE64A-NEXT:  0000000000002340 R_RISCV_TLS_TPREL64      c
174# IE64A-EMPTY:
175## &.got[c]-. = 0x2340 - 0x1258 = 0x10e8
176# IE64A-LABEL: <.Ltlsdesc_hi2>:
177# IE64A-NEXT:         addi    zero, zero, 0x0
178# IE64A-NEXT:         addi    zero, zero, 0x0
179# IE64A-NEXT:   1258: auipc   a0, 0x1
180# IE64A-NEXT:         ld      a0, 0xe8(a0)
181# IE64A-NEXT:         add     a0, a0, tp
182
183#--- a.s
184.macro load dst, src
185.ifdef ELF32
186lw \dst, \src
187.else
188ld \dst, \src
189.endif
190.endm
191
192.Ltlsdesc_hi0:
193  auipc a0, %tlsdesc_hi(a)
194  load  a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
195  addi  a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
196  jalr  t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
197  add   a0, a0, tp
198
199.Ltlsdesc_hi1:
200  auipc a2, %tlsdesc_hi(b)
201  load  a3, %tlsdesc_load_lo(.Ltlsdesc_hi1)(a2)
202  addi  a0, a2, %tlsdesc_add_lo(.Ltlsdesc_hi1)
203  jalr  t0, 0(a3), %tlsdesc_call(.Ltlsdesc_hi1)
204  add   a0, a0, tp
205
206.Ltlsdesc_hi2:
207  auipc a4, %tlsdesc_hi(c)
208  load  a5, %tlsdesc_load_lo(.Ltlsdesc_hi2)(a4)
209  addi  a0, a4, %tlsdesc_add_lo(.Ltlsdesc_hi2)
210  jalr  t0, 0(a5), %tlsdesc_call(.Ltlsdesc_hi2)
211  add   a0, a0, tp
212
213.section .tbss
214.globl a
215.zero 8
216a:
217.zero 2039  ## Place b at 0x7ff
218b:
219.zero 1
220
221#--- a1.s
222## a.s without TLS definitions.
223.Ltlsdesc_hi2:
224  auipc a4, %tlsdesc_hi(c)
225  ld    a5, %tlsdesc_load_lo(.Ltlsdesc_hi2)(a4)
226  addi  a0, a4, %tlsdesc_add_lo(.Ltlsdesc_hi2)
227  jalr  t0, 0(a5), %tlsdesc_call(.Ltlsdesc_hi2)
228  add   a0, a0, tp
229
230#--- c.s
231.tbss
232.globl c
233c: .zero 4
234
235#--- d.s
236.macro load dst, src
237.ifdef ELF32
238lw \dst, \src
239.else
240ld \dst, \src
241.endif
242.endm
243
244.Ltlsdesc_hi0:
245  auipc	a0, %tlsdesc_hi(foo)
246  load	a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
247  addi	a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
248  jalr	t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
249  add	a1, a0, tp
250