Bug 28387 - ld: Move R_*_TLSDESC to .rela.dyn
Summary: ld: Move R_*_TLSDESC to .rela.dyn
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.46
: P2 normal
Target Milestone: 2.46
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-09-25 20:26 UTC by Fangrui Song
Modified: 2026-03-15 21:10 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2025-08-24 00:00:00
Project(s) to access:
ssh public key:


Attachments
A patch (6.19 KB, patch)
2025-08-24 16:58 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2021-09-25 20:26:35 UTC
Lazy R_*_TLSDESC resolving has several problems (e.g. data race) and glibc has eagerly resolved R_*_TLSDESC for all(?) supported ports: arm (PR18572)/aarch64 (PR18034)/x86 (PR27137).

It is also odd to overload .rela.plt (PLT) with TLSDESC which have quite different semantics.

Currently GNU ld still uses .rela.plt, but it probably makes sense to switch to .rela.dyn instead.

% cat x.c
extern __thread int tlsdesc;
int get(void) { return tlsdesc; }

% gcc -fpic -mtls-dialect=gnu2 -shared x.c && readelf -r a.out
...
Relocation section '.rela.plt' at offset 0x440 contains 1 entry:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000004018  000200000024 R_X86_64_TLSDESC  0000000000000000 tlsdesc + 0

% aarch64-linux-gnu-gcc -fpic -shared x.c && readelf -r a.out                                                 
...

Relocation section '.rela.plt' at offset 0x400 contains 3 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000011000  000300000402 R_AARCH64_JUMP_SL 0000000000000000 __cxa_finalize + 0
000000011008  000700000402 R_AARCH64_JUMP_SL 0000000000000000 __gmon_start__ + 0
000000011010  000400000407 R_AARCH64_TLSDESC 0000000000000000 tlsdesc + 0

% arm-linux-gnueabi-gcc -fpic -mtls-dialect=gnu2 -fuse-ld=bfd -shared x.c && readelf -r a.out
...
Relocation section '.rel.plt' at offset 0x264 contains 3 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0001100c  00000316 R_ARM_JUMP_SLOT   00000000   __cxa_finalize
00011010  00000716 R_ARM_JUMP_SLOT   00000000   __gmon_start__
00011014  0000040d R_ARM_TLS_DESC    00000000   tlsdesc
Comment 1 H.J. Lu 2025-08-24 16:58:29 UTC
Created attachment 16281 [details]
A patch

I am testing this patch with GCC configured with --with-tls=gnu2.
Comment 2 Sourceware Commits 2025-08-27 04:04:07 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d5faa503bbd97015f7c9685322ace81211f5eb04

commit d5faa503bbd97015f7c9685322ace81211f5eb04
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sun Aug 24 14:43:44 2025 -0700

    x86: Don't put R_386_TLS_DESC/R_X86_64_TLSDESC in .rel.plt/.rela.plt
    
    Since lazy tlsdesc relocation has data races:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=27137
    
    put R_386_TLS_DESC and R_X86_64_TLSDESC relocation in .rela.tls/.rel.tls
    section, instead of .rel.plt/.rela.plt section.
    
    Tested with glibc/i686 and glibc/x86-64 compiled with -mtls-dialect=gnu2
    as well as GCC 16 configured with --with-tls=gnu2.
    
    bfd/
    
            PR ld/28387
            * elf32-i386.c (elf_i386_relocate_section): Put R_386_TLS_DESC
            in rel_tls_desc instead of elf.srelplt.
            * elf64-x86-64.c (elf_x86_64_relocate_section): Put
            R_X86_64_TLSDESC in rel_tls_desc instead of elf.srelplt.
            * elfxx-x86.c (elf_x86_allocate_dynrelocs): Use rel_tls_desc,
            instead of elf.srelplt, for GOT_TLS_GDESC_P.
            (_bfd_elf_x86_get_reloc_section): New function.
            (_bfd_x86_elf_late_size_sections): Use rel_tls_desc, instead of
            elf.srelplt, for GOT_TLS_GDESC_P.  Remove next_tls_desc_index.
            (_bfd_x86_elf_link_setup_gnu_properties): Allocate
            .rela.tls/.rel.tls section for rel_tls_desc.
            * elfxx-x86.h (elf_x86_link_hash_table): Add rel_tls_desc.
            Remove next_tls_desc_index.
            (_bfd_elf_x86_get_reloc_section): New.
            (elf_backend_get_reloc_section): Likewise.
    
    ld/
    
            PR ld/28387
            * emulparams/elf32_x86_64.sh (OTHER_GOT_RELOC_SECTIONS): New.
            * emulparams/elf_i386.sh (OTHER_GOT_RELOC_SECTIONS): Likewise.
            * emulparams/elf_x86_64.sh (OTHER_GOT_RELOC_SECTIONS): Likewise.
            * testsuite/ld-i386/i386.exp: Run pr28387.
            * testsuite/ld-i386/pr17057.d: Adjusted
            * testsuite/ld-i386/tlsdesc.rd: Likewise.
            * testsuite/ld-i386/tlsdesc2.d: Likewise.
            * testsuite/ld-i386/tlsgdesc.rd: Likewise.
            * testsuite/ld-x86-64/tlsdesc.pd: Likewise.
            * testsuite/ld-x86-64/tlsdesc.rd: Likewise.
            * testsuite/ld-x86-64/tlsdesc2.d: Likewise.
            * testsuite/ld-x86-64/tlsgdesc.rd: Likewise.
            * testsuite/ld-i386/pr28387.d: New file.
            * testsuite/ld-i386/pr28387.s: Likewise.
            * testsuite/ld-x86-64/pr28387-x32.d: Likewise.
            * testsuite/ld-x86-64/pr28387.d: Likewise.
            * testsuite/ld-x86-64/pr28387.s: Likewise.
            * testsuite/ld-x86-64/x86-64.exp: Run pr28387 and pr28387-x32.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Comment 3 H.J. Lu 2025-08-27 13:31:53 UTC
Fixed for x86 so far.