Skip to content

Commit ceb7f60

Browse files
committed
[ELF][RISCV] Support linking CHERI TGOT TLS objects
1 parent ccb207f commit ceb7f60

File tree

4 files changed

+228
-1
lines changed

4 files changed

+228
-1
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ RISCV::RISCV() {
112112
relativeRel = R_RISCV_RELATIVE;
113113
iRelativeRel = R_RISCV_IRELATIVE;
114114
cheriCapRel = R_RISCV_CHERI_CAPABILITY;
115+
tgotRel = R_RISCV_CHERI_TLS_TGOT_SLOT;
116+
tgotGotRel = R_RISCV_CHERI_TLS_TGOTREL;
115117
if (config->is64) {
116118
symbolicRel = R_RISCV_64;
117119
tlsModuleIndexRel = R_RISCV_TLS_DTPMOD64;
@@ -355,10 +357,18 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
355357
return R_RELAX_HINT;
356358
case R_RISCV_TPREL_ADD:
357359
case R_RISCV_CHERI_TPREL_CINCOFFSET:
360+
case R_RISCV_CHERI_TLS_TGOT_ADD:
358361
case R_RISCV_RELAX:
359362
return config->relax ? R_RELAX_HINT : R_NONE;
360363
case R_RISCV_CHERI_CAPABILITY:
361364
return R_CHERI_CAPABILITY;
365+
case R_RISCV_CHERI_TLS_TGOT_HI20:
366+
case R_RISCV_CHERI_TLS_TGOT_LO12_I:
367+
return R_TGOT_TP;
368+
case R_RISCV_CHERI_TLS_TGOT_GOT_HI20:
369+
return R_TGOT_GOT_PC;
370+
case R_RISCV_CHERI_TLS_TGOT_GD_HI20:
371+
return R_TGOT_TLSGD_PC;
362372
// TODO: Deprecate and eventually remove these
363373
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
364374
return R_GOT_PC;
@@ -478,6 +488,9 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
478488
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
479489
case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
480490
case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
491+
case R_RISCV_CHERI_TLS_TGOT_GOT_HI20:
492+
case R_RISCV_CHERI_TLS_TGOT_GD_HI20:
493+
case R_RISCV_CHERI_TLS_TGOT_HI20:
481494
case R_RISCV_GOT_HI20:
482495
case R_RISCV_PCREL_HI20:
483496
case R_RISCV_TLS_GD_HI20:
@@ -490,6 +503,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
490503
return;
491504
}
492505

506+
case R_RISCV_CHERI_TLS_TGOT_LO12_I:
493507
case R_RISCV_PCREL_LO12_I:
494508
case R_RISCV_TPREL_LO12_I:
495509
case R_RISCV_LO12_I: {
@@ -577,6 +591,13 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
577591
write64le(loc, val - dtpOffset);
578592
break;
579593

594+
case R_RISCV_CHERI_TLS_TGOTREL:
595+
if (config->is64)
596+
write64le(loc, val);
597+
else
598+
write32le(loc, val);
599+
break;
600+
580601
case R_RISCV_RELAX:
581602
return; // Ignored (for now)
582603

lld/ELF/InputSection.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,9 @@ static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
590590
it->type == R_RISCV_TLS_GD_HI20 || it->type == R_RISCV_TLS_GOT_HI20 ||
591591
it->type == R_RISCV_CHERI_CAPTAB_PCREL_HI20 ||
592592
it->type == R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20 ||
593-
it->type == R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20)
593+
it->type == R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20 ||
594+
it->type == R_RISCV_CHERI_TLS_TGOT_GOT_HI20 ||
595+
it->type == R_RISCV_CHERI_TLS_TGOT_GD_HI20)
594596
return &*it;
595597

596598
errorOrWarn("R_RISCV_PCREL_LO12 relocation points to " +

lld/ELF/SyntheticSections.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,10 @@ DynamicSection<ELFT>::computeContents() {
16761676
addInSec(DT_RISCV_CHERI___CAPRELOCS, *in.capRelocs);
16771677
addInt(DT_RISCV_CHERI___CAPRELOCSSZ, in.capRelocs->getParent()->size);
16781678
}
1679+
if (in.tgotCapRelocs && in.tgotCapRelocs->isNeeded()) {
1680+
addInSec(DT_RISCV_CHERI___TGOTCAPRELOCS, *in.tgotCapRelocs);
1681+
addInt(DT_RISCV_CHERI___TGOTCAPRELOCSSZ, in.tgotCapRelocs->getParent()->size);
1682+
}
16791683
}
16801684

16811685
// DT_PPC_GOT indicates to glibc Secure PLT is used. If DT_PPC_GOT is absent,

lld/test/ELF/cheri/riscv/tgot-tls.s

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# REQUIRES: riscv
2+
# RUN: echo '.tbss; .globl evar; evar: .zero 4' > %t.s
3+
4+
# RUN: %riscv32_cheri_purecap_llvm-mc -cheri-tgot-tls -filetype=obj %t.s -o %t1.32.o
5+
# RUN: ld.lld -shared -soname=t1.so %t1.32.o -o %t1.32.so
6+
7+
# RUN: %riscv32_cheri_purecap_llvm-mc --defsym PIC=0 -cheri-tgot-tls -filetype=obj %s -o %t.32.o
8+
# RUN: ld.lld %t.32.o %t1.32.so -o %t.32
9+
# RUN: llvm-readobj -r --cap-relocs %t.32 | FileCheck --check-prefix=RV32-REL %s
10+
# RUN: llvm-readelf -x .got -x .tgot %t.32 | FileCheck --check-prefix=RV32-GOT %s
11+
# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefix=RV32-DIS %s
12+
13+
# RUN: %riscv32_cheri_purecap_llvm-mc --defsym PIC=1 -cheri-tgot-tls -filetype=obj %s -o %t.32.pico
14+
# RUN: ld.lld -shared %t.32.pico %t1.32.so -o %t.32.so
15+
# RUN: llvm-readobj -r --cap-relocs %t.32.so | FileCheck --check-prefix=RV32-SO-REL %s
16+
# RUN: llvm-readelf -x .got -x .tgot %t.32.so | FileCheck --check-prefix=RV32-SO-GOT %s
17+
# RUN: llvm-objdump -d --no-show-raw-insn %t.32.so | FileCheck --check-prefix=RV32-SO-DIS %s
18+
19+
# RUN: %riscv64_cheri_purecap_llvm-mc -cheri-tgot-tls -filetype=obj %t.s -o %t1.64.o
20+
# RUN: ld.lld -shared -soname=t1.so %t1.64.o -o %t1.64.so
21+
22+
# RUN: %riscv64_cheri_purecap_llvm-mc --defsym PIC=0 -cheri-tgot-tls -filetype=obj %s -o %t.64.o
23+
# RUN: ld.lld %t.64.o %t1.64.so -o %t.64
24+
# RUN: llvm-readobj -r --cap-relocs %t.64 | FileCheck --check-prefix=RV64-REL %s
25+
# RUN: llvm-readelf -x .got -x .tgot %t.64 | FileCheck --check-prefix=RV64-GOT %s
26+
# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefix=RV64-DIS %s
27+
28+
# RUN: %riscv64_cheri_purecap_llvm-mc --defsym PIC=1 -cheri-tgot-tls -filetype=obj %s -o %t.64.pico
29+
# RUN: ld.lld -shared %t.64.pico %t1.64.so -o %t.64.so
30+
# RUN: llvm-readobj -r --cap-relocs %t.64.so | FileCheck --check-prefix=RV64-SO-REL %s
31+
# RUN: llvm-readelf -x .got -x .tgot %t.64.so | FileCheck --check-prefix=RV64-SO-GOT %s
32+
# RUN: llvm-objdump -d --no-show-raw-insn %t.64.so | FileCheck --check-prefix=RV64-SO-DIS %s
33+
34+
# RV32-REL: .rela.tgot {
35+
# RV32-REL-NEXT: 0x132B8 R_RISCV_CHERI_TLS_TGOT_SLOT evar 0x0
36+
# RV32-REL-NEXT: }
37+
# RV32-REL: CHERI __tgot_cap_relocs [
38+
# RV32-REL-NEXT: 0x0132c0 Base: 0x4 (lvar+0) Length: 4 Perms: Object
39+
# RV32-REL-NEXT: ]
40+
41+
# RV32-SO-REL: .rela.dyn {
42+
# RV32-SO-REL-NEXT: 0x22F8 R_RISCV_CHERI_TLS_TGOTREL - 0x0
43+
# RV32-SO-REL-NEXT: 0x2300 R_RISCV_TLS_DTPMOD32 - 0x0
44+
# RV32-SO-REL-NEXT: 0x2308 R_RISCV_CHERI_TLS_TGOTREL - 0x8
45+
# RV32-SO-REL-NEXT: 0x2310 R_RISCV_TLS_DTPMOD32 - 0x0
46+
# RV32-SO-REL-NEXT: }
47+
# RV32-SO-REL: .rela.tgot {
48+
# RV32-SO-REL-NEXT: 0x3318 R_RISCV_CHERI_TLS_TGOT_SLOT evar 0x0
49+
# RV32-SO-REL-NEXT: }
50+
# RV32-SO-REL: CHERI __tgot_cap_relocs [
51+
# RV32-SO-REL-NEXT: 0x003320 Base: 0x4 (lvar+0) Length: 4 Perms: Object
52+
# RV32-SO-REL-NEXT: ]
53+
54+
# RV32-GOT: section '.got':
55+
# RV32-GOT-NEXT: 0x00012290 1c220100 00000000 00000000 00000000
56+
# RV32-GOT-NEXT: 0x000122a0 01000000 00000000 08000000 00000000
57+
# RV32-GOT-NEXT: 0x000122b0 01000000 08000000
58+
# RV32-GOT: section '.tgot':
59+
# RV32-GOT-NEXT: 0x000132b8 00000000 00000000 00000000 00000000
60+
61+
# RV32-SO-GOT: section '.got':
62+
# RV32-SO-GOT-NEXT: 0x000022f0 64220000 00000000 00000000 00000000
63+
# RV32-SO-GOT-NEXT: 0x00002300 00000000 00000000 00000000 00000000
64+
# RV32-SO-GOT-NEXT: 0x00002310 00000000 08000000
65+
# RV32-SO-GOT: section '.tgot':
66+
# RV32-SO-GOT-NEXT: 0x00003318 00000000 00000000 00000000 00000000
67+
68+
# 0x122a0 - 0x111f0 = 0x10b0 (GD evar)
69+
# RV32-DIS: 111f0: auipcc ca0, 1
70+
# RV32-DIS-NEXT: cincoffset ca0, ca0, 176
71+
72+
# 0x12298 - 0x111f8 = 0x10a0 (IE evar)
73+
# RV32-DIS: 111f8: auipcc ca0, 1
74+
# RV32-DIS-NEXT: lw a0, 160(ca0)
75+
76+
# 0x122b0 - 0x11200 = 0x10b0 (GD lvar)
77+
# RV32-DIS: 11200: auipcc ca0, 1
78+
# RV32-DIS-NEXT: cincoffset ca0, ca0, 176
79+
80+
# 0x122a8 - 0x11208 = 0x10a0 (IE lvar)
81+
# RV32-DIS: 11208: auipcc ca0, 1
82+
# RV32-DIS-NEXT: lw a0, 160(ca0)
83+
84+
# RV32-DIS: 11210: lui a0, 0
85+
# RV32-DIS-NEXT: cincoffset ca0, ctp, a0
86+
# RV32-DIS-NEXT: lc ca0, 8(ca0)
87+
88+
# 0x2300 - 0x1244 = 0x10bc (GD evar)
89+
# RV32-SO-DIS: 1244: auipcc ca0, 1
90+
# RV32-SO-DIS-NEXT: cincoffset ca0, ca0, 188
91+
92+
# 0x22f8 - 0x124c = 0x10ac (IE evar)
93+
# RV32-SO-DIS: 124c: auipcc ca0, 1
94+
# RV32-SO-DIS-NEXT: lw a0, 172(ca0)
95+
96+
# 0x2310 - 0x1254 = 0x10bc (GD lvar)
97+
# RV32-SO-DIS: 1254: auipcc ca0, 1
98+
# RV32-SO-DIS-NEXT: cincoffset ca0, ca0, 188
99+
100+
# 0x2308 - 0x125c = 0x10ac (IE lvar)
101+
# RV32-SO-DIS: 125c: auipcc ca0, 1
102+
# RV32-SO-DIS-NEXT: lw a0, 172(ca0)
103+
104+
# RV64-REL: .rela.tgot {
105+
# RV64-REL-NEXT: 0x13480 R_RISCV_CHERI_TLS_TGOT_SLOT evar 0x0
106+
# RV64-REL-NEXT: }
107+
# RV64-REL: CHERI __tgot_cap_relocs [
108+
# RV64-REL-NEXT: 0x013490 Base: 0x4 (lvar+0) Length: 4 Perms: Object
109+
# RV64-REL-NEXT: ]
110+
111+
# RV64-SO-REL: .rela.dyn {
112+
# RV64-SO-REL-NEXT: 0x24F0 R_RISCV_CHERI_TLS_TGOTREL - 0x0
113+
# RV64-SO-REL-NEXT: 0x2500 R_RISCV_TLS_DTPMOD64 - 0x0
114+
# RV64-SO-REL-NEXT: 0x2510 R_RISCV_CHERI_TLS_TGOTREL - 0x10
115+
# RV64-SO-REL-NEXT: 0x2520 R_RISCV_TLS_DTPMOD64 - 0x0
116+
# RV64-SO-REL-NEXT: }
117+
# RV64-SO-REL: .rela.tgot {
118+
# RV64-SO-REL-NEXT: 0x3530 R_RISCV_CHERI_TLS_TGOT_SLOT evar 0x0
119+
# RV64-SO-REL-NEXT: }
120+
# RV64-SO-REL: CHERI __tgot_cap_relocs [
121+
# RV64-SO-REL-NEXT: 0x003540 Base: 0x4 (lvar+0) Length: 4 Perms: Object
122+
# RV64-SO-REL-NEXT: ]
123+
124+
# RV64-GOT: section '.got':
125+
# RV64-GOT-NEXT: 0x00012430 50230100 00000000 00000000 00000000
126+
# RV64-GOT-NEXT: 0x00012440 00000000 00000000 00000000 00000000
127+
# RV64-GOT-NEXT: 0x00012450 01000000 00000000 00000000 00000000
128+
# RV64-GOT-NEXT: 0x00012460 10000000 00000000 00000000 00000000
129+
# RV64-GOT-NEXT: 0x00012470 01000000 00000000 10000000 00000000
130+
# RV64-GOT: section '.tgot':
131+
# RV64-GOT-NEXT: 0x00013480 00000000 00000000 00000000 00000000
132+
# RV64-GOT-NEXT: 0x00013490 00000000 00000000 00000000 00000000
133+
134+
# RV64-SO-GOT: section '.got':
135+
# RV64-SO-GOT-NEXT: 0x000024e0 d0230000 00000000 00000000 00000000
136+
# RV64-SO-GOT-NEXT: 0x000024f0 00000000 00000000 00000000 00000000
137+
# RV64-SO-GOT-NEXT: 0x00002500 00000000 00000000 00000000 00000000
138+
# RV64-SO-GOT-NEXT: 0x00002510 00000000 00000000 00000000 00000000
139+
# RV64-SO-GOT-NEXT: 0x00002520 00000000 00000000 10000000 00000000
140+
# RV64-SO-GOT: section '.tgot':
141+
# RV64-SO-GOT-NEXT: 0x00003530 00000000 00000000 00000000 00000000
142+
# RV64-SO-GOT-NEXT: 0x00003540 00000000 00000000 00000000 00000000
143+
144+
# 0x12450 - 0x11320 = 0x1130 (GD evar)
145+
# RV64-DIS: 11320: auipcc ca0, 1
146+
# RV64-DIS-NEXT: cincoffset ca0, ca0, 304
147+
148+
# 0x12440 - 0x11328 = 0x1118 (IE evar)
149+
# RV64-DIS: 11328: auipcc ca0, 1
150+
# RV64-DIS-NEXT: ld a0, 280(ca0)
151+
152+
# 0x12470 - 0x11330 = 0x1140 (GD lvar)
153+
# RV64-DIS: 11330: auipcc ca0, 1
154+
# RV64-DIS-NEXT: cincoffset ca0, ca0, 320
155+
156+
# 0x12460 - 0x11338 = 0x1128 (IE lvar)
157+
# RV64-DIS: 11338: auipcc ca0, 1
158+
# RV64-DIS-NEXT: ld a0, 296(ca0)
159+
160+
# RV64-DIS: 11340: lui a0, 0
161+
# RV64-DIS-NEXT: cincoffset ca0, ctp, a0
162+
# RV64-DIS-NEXT: lc ca0, 16(ca0)
163+
164+
# 0x2500 - 0x13b0 = 0x1150 (GD evar)
165+
# RV64-SO-DIS: 13b0: auipcc ca0, 1
166+
# RV64-SO-DIS-NEXT: cincoffset ca0, ca0, 336
167+
168+
# 0x24f0 - 0x13b8 = 0x1138 (IE evar)
169+
# RV64-SO-DIS: 13b8: auipcc ca0, 1
170+
# RV64-SO-DIS-NEXT: ld a0, 312(ca0)
171+
172+
# 0x2520 - 0x13c0 = 0x1160 (GD lvar)
173+
# RV64-SO-DIS: 13c0: auipcc ca0, 1
174+
# RV64-SO-DIS-NEXT: cincoffset ca0, ca0, 352
175+
176+
# 0x2510 - 0x13c8 = 0x1148 (IE lvar)
177+
# RV64-SO-DIS: 13c8: auipcc ca0, 1
178+
# RV64-SO-DIS-NEXT: ld a0, 328(ca0)
179+
180+
.global _start
181+
_start:
182+
clc.tls.gd ca0, evar
183+
184+
cla.tls.ie a0, evar
185+
186+
clc.tls.gd ca0, lvar
187+
188+
cla.tls.ie a0, lvar
189+
190+
.if PIC == 0
191+
lui a0, %tgot_tprel_hi(lvar)
192+
cincoffset ca0, ctp, a0, %tgot_tprel_add(lvar)
193+
clc ca0, %tgot_tprel_lo(lvar)(ca0)
194+
.endif
195+
196+
.tbss
197+
.zero 4
198+
lvar:
199+
.zero 4
200+
.size lvar, . - lvar

0 commit comments

Comments
 (0)