[LLD][ELF] Symbol/Relocation manipulation.

I’d like to convert the following
call A@GDPLT //R_HEX_GD_PLT_B22_PCREL

to
call __tls_get_addr //R_HEX_B22_PCREL

“A” is a TLS variable and preceding code has prepared for the call.

When the R_HEX_GD_PLT_B22_PCREL is found it will initially point to the TLS variable so at that point I’d like to define a __tls_get_addr symbol and update the relocation’s type and symbol to point to it.

Is there an existing mechanism to do this? It would happen during relaxation I guess.

Thanks,

For newer psABI, it is recommended implementing TLSDESC directly. It is
strictly superior to the traditional General Dynamic and Local Dynamic
TLS models. This applies to RISC-V
Support Thread-Local Storage Descriptors (TLSDESC) · Issue #94 · riscv-non-isa/riscv-elf-psabi-doc · GitHub as well, which
seems to copy from ARM or MIPS.

If you have to implement the traditional General Dynamic and Local Dynamic TLS models (__tls_get_addr):

call A@GDPLT //R_HEX_GD_PLT_B22_PCREL
->
call __tls_get_addr //R_HEX_B22_PCREL

IMO the generated assembly should mention __tls_get_addr directly, i.e.
the assembler should create an undefined symbol __tls_get_addr and
create call-typed relocations which reference it.

The linker should not be responsible for synthesizing a symbol called
__tls_get_addr. No existing architecture (AFAIK) does this.

Fangrui,

Thanks for the info. I had made a change to llvm to emit the call to __tls_get_addr but wanted to see if lld could accommodate the current baseline. I will revisit the llvm change.

>>I'd like to convert the following
>>call A@GDPLT //R_HEX_GD_PLT_B22_PCREL
>>
>>to
>>call __tls_get_addr //R_HEX_B22_PCREL
>>
>>"A" is a TLS variable and preceding code has prepared for the call.
>>
>>When the R_HEX_GD_PLT_B22_PCREL is found it will initially point to the TLS
>>variable so at that point I'd like to define a __tls_get_addr symbol and
>update
>>the relocation's type and symbol to point to it.
>>
>>Is there an existing mechanism to do this? It would happen during relaxation
>I
>>guess.
>>
>>Thanks,
>
>For newer psABI, it is recommended implementing TLSDESC directly. It is
>strictly superior to the traditional General Dynamic and Local Dynamic
>TLS models. This applies to RISC-V
>Support Thread-Local Storage Descriptors (TLSDESC) · Issue #94 · riscv-non-isa/riscv-elf-psabi-doc · GitHub as well, which
>seems to copy from ARM or MIPS.
>
>If you have to implement the traditional General Dynamic and Local Dynamic TLS
>models (__tls_get_addr):
>
>call A@GDPLT //R_HEX_GD_PLT_B22_PCREL
>->
>call __tls_get_addr //R_HEX_B22_PCREL
>
>IMO the generated assembly should mention __tls_get_addr directly, i.e.
>the assembler should create an undefined symbol __tls_get_addr and
>create call-typed relocations which reference it.
>
>The linker should not be responsible for synthesizing a symbol called
>__tls_get_addr. No existing architecture (AFAIK) does this.

> Fangrui,
> > Thanks for the info. I had made a change to llvm to emit the call to
> __tls_get_addr but wanted to see if lld could accommodate the current
> baseline. I will revisit the llvm change.

Hi Sid,

I do not follow Hexagon toolchain development and am not clear what the
current status is. If traditional General Dynamic and Local Dynamic TLS
models have not been fully implemented in the LLVM codegen yet, I
recommend that Hexagon uses TLSDESC instead. TLSDESC is strictly
superior, largely due to its custom calling convention. A __tls_get_addr
call, following the psABI, may clobber many registers. TLSDESC can avoid
the register saving cost.

lld/test/ELF tests that may be useful:

aarch64-tlsdesc.s
invalid/x86-64-tlsdesc-gd.s
x86-64-tlsdesc-gd.s
x86-64-tlsdesc-ld.s

AArch64 ABI uses TLSDESC. I implemented TLSDESC for x86 in ⚙ D62512 [X86] Fix x86-64 call *foo@tlsdesc(reg) and support R_386_TLSGOTDESC R_386_TLS_DESC_CALL

Hope you may find the information above helpful.