-
Notifications
You must be signed in to change notification settings - Fork 12.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ELF] Implement R_RISCV_TLSDESC for RISC-V
Support R_RISCV_TLSDESC_HI20/R_RISCV_TLSDESC_LOAD_LO12/R_RISCV_TLSDESC_ADD_LO12/R_RISCV_TLSDESC_CALL. LOAD_LO12/ADD_LO12/CALL relocations reference a label at the HI20 location, which requires special handling. We save the value of HI20 to be reused. Two interleaved TLSDESC code sequences, which compilers do not generate, are unsupported. For -no-pie/-pie links, TLSDESC to initial-exec or local-exec optimizations are eligible. Implement the relevant hooks (R_RELAX_TLS_GD_TO_LE, R_RELAX_TLS_GD_TO_IE): the first two instructions are converted to NOP while the latter two are converted to a GOT load or a lui+addi. The first two instructions, which would be converted to NOP, are removed instead in the presence of relaxation. Relaxation is eligible as long as the R_RISCV_TLSDESC_HI20 relocation has a pairing R_RISCV_RELAX, regardless of whether the following instructions have a R_RISCV_RELAX. In addition, for the TLSDESC to LE optimization (`lui a0,<hi20>; addi a0,a0,<lo12>`), `lui` can be removed (i.e. use the short form) if hi20 is 0. ``` // TLSDESC to LE/IE optimization .Ltlsdesc_hi2: auipc a4, %tlsdesc_hi(c) # if relax: remove; otherwise, NOP load a5, %tlsdesc_load_lo(.Ltlsdesc_hi2)(a4) # if relax: remove; otherwise, NOP addi a0, a4, %tlsdesc_add_lo(.Ltlsdesc_hi2) # if LE && !hi20 {if relax: remove; otherwise, NOP} jalr t0, 0(a5), %tlsdesc_call(.Ltlsdesc_hi2) add a0, a0, tp ``` The implementation carefully ensures that an instruction unrelated to the current TLSDESC code sequence, if immediately follows a removable instruction (HI20 or LOAD_LO12 OR (LE-specific) ADD_LO12), is not converted to NOP. * `riscv64-tlsdesc.s` is inspired by `i386-tlsdesc-gd.s` (https://reviews.llvm.org/D112582). * `riscv64-tlsdesc-relax.s` tests linker relaxation. * `riscv-tlsdesc-gd-mixed.s` is inspired by `x86-64-tlsdesc-gd-mixed.s` (https://reviews.llvm.org/D116900). Link: riscv-non-isa/riscv-elf-psabi-doc#373 Reviewed By: ilovepi Pull Request: #79239 (cherry picked from commit 1117fdd)
- Loading branch information
Showing
5 changed files
with
551 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# REQUIRES: riscv | ||
# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o | ||
# RUN: ld.lld -shared %t.o -o %t.so | ||
# RUN: llvm-readobj -r %t.so | FileCheck %s --check-prefix=RELA | ||
|
||
## Both TLSDESC and DTPMOD64/DTPREL64 should be present. | ||
# RELA: .rela.dyn { | ||
# RELA-NEXT: 0x[[#%X,ADDR:]] R_RISCV_TLSDESC a 0x0 | ||
# RELA-NEXT: 0x[[#ADDR+16]] R_RISCV_TLS_DTPMOD64 a 0x0 | ||
# RELA-NEXT: 0x[[#ADDR+24]] R_RISCV_TLS_DTPREL64 a 0x0 | ||
# RELA-NEXT: } | ||
|
||
la.tls.gd a0,a | ||
call __tls_get_addr@plt | ||
|
||
.Ltlsdesc_hi0: | ||
auipc a2, %tlsdesc_hi(a) | ||
ld a3, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a2) | ||
addi a0, a2, %tlsdesc_add_lo(.Ltlsdesc_hi0) | ||
jalr t0, 0(a3), %tlsdesc_call(.Ltlsdesc_hi0) | ||
|
||
.section .tbss,"awT",@nobits | ||
.globl a | ||
.zero 8 | ||
a: | ||
.zero 4 |
Oops, something went wrong.