Skip to content

Commit cdd29f5

Browse files
authored
[ELF,RISCV] Fix TLSDESC=>IE when there is no TLS section
See the comment in handleTlsRelocation. For TLSDESC=>IE (the TLS symbol is defined in another DSO), R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} referencing a non-preemptible label uses the `R_RELAX_TLS_GD_TO_LE` code path. If there is no TLS section, `getTlsTpOffset` will be called with null `Out::tlsPhdr`, leading to a null pointer dereference. Since the return value is used by `RISCV::relocateAlloc` and ignored there, just return 0. LoongArch TLSDESC doesn't use STT_NOTYPE labels. The `if (..) return 0;` is a no-op for LoongArch. This patch is a follow-up to llvm#79239 and fixes some comments. Pull Request: llvm#98569
1 parent db3d337 commit cdd29f5

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,8 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
631631
continue;
632632
case R_RELAX_TLS_GD_TO_LE:
633633
// See the comment in handleTlsRelocation. For TLSDESC=>IE,
634-
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12,CALL} also reach here. If isToIe is
635-
// true, this is actually TLSDESC=>IE optimization.
634+
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12,CALL} also reach here. If isToLe is
635+
// false, this is actually TLSDESC=>IE optimization.
636636
if (rel.type == R_RISCV_TLSDESC_HI20) {
637637
tlsdescVal = val;
638638
isToLe = true;

lld/ELF/InputSection.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,11 @@ static int64_t getTlsTpOffset(const Symbol &s) {
660660
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1)) - 0x7000;
661661
case EM_LOONGARCH:
662662
case EM_RISCV:
663+
// See the comment in handleTlsRelocation. For TLSDESC=>IE,
664+
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} also reach here. While
665+
// `tls` may be null, the return value is ignored.
666+
if (s.type != STT_TLS)
667+
return 0;
663668
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1));
664669

665670
// Variant 2.

lld/ELF/Relocations.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,8 +1399,8 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13991399
// depending on the symbol being locally defined or not.
14001400
//
14011401
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a non-preemptible
1402-
// label, so the LE optimization will be categorized as
1403-
// R_RELAX_TLS_GD_TO_LE. We fix the categorization in RISCV::relocateAlloc.
1402+
// label, so TLSDESC=>IE will be categorized as R_RELAX_TLS_GD_TO_LE. We fix
1403+
// the categorization in RISCV::relocateAlloc.
14041404
if (sym.isPreemptible) {
14051405
sym.setFlags(NEEDS_TLSGD_TO_IE);
14061406
c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type,

lld/test/ELF/riscv-tlsdesc.s

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
# RUN: llvm-mc -triple=riscv32 -filetype=obj d.s -o d.32.o --defsym ELF32=1
3838
# RUN: ld.lld -shared -soname=d.32.so -o d.32.so d.32.o --fatal-warnings
3939

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+
4045
# GD64-RELA: .rela.dyn {
4146
# GD64-RELA-NEXT: 0x2408 R_RISCV_TLSDESC - 0x7FF
4247
# GD64-RELA-NEXT: 0x23E8 R_RISCV_TLSDESC a 0x0
@@ -164,6 +169,17 @@
164169
# IE32-NEXT: lw a0, 0x80(a0)
165170
# IE32-NEXT: add a0, a0, tp
166171

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+
167183
#--- a.s
168184
.macro load dst, src
169185
.ifdef ELF32
@@ -202,6 +218,15 @@ a:
202218
b:
203219
.zero 1
204220

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+
205230
#--- c.s
206231
.tbss
207232
.globl c

0 commit comments

Comments
 (0)