From: LIU Hao Date: Fri, 12 Dec 2025 14:00:15 +0000 (+0100) Subject: ld/pe-dll: Don't auto-export symbols from .tls section X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8297edc90abc66b8c347afafa062ff9ba9895e4c;p=thirdparty%2Fbinutils-gdb.git ld/pe-dll: Don't auto-export symbols from .tls section The .tls section of an image contains template data that will be duplicated for each new thread to be created. Accessing thread-local data involves an image-specific global variable, _tls_used, for calculation. Therefore, it is impossible to export thread-local variables from a DLL. The only symbol that exists in the .tls input section is _tls_start, but it's a CRT symbol and is never auto-exported. It's only necessary to check for user symbols, which are always generated in the subsection .tls$ by default, or in subsections like .tls$$ when -fdata-sections is specified. Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80881 Signed-off-by: LIU Hao --- diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 853425dc287..37b32dc69a7 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -806,9 +806,17 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info * { /* We should export symbols which are either global or not anything at all. (.bss data is the latter) - We should not export undefined symbols. */ + We should not export undefined symbols. + Compilers may generate template data (initializers) for + thread-local variables in .tls$* sections, but they are only + used by the DLL loader. Symbols in those sections are used + to access thread-local variables, but only via offsets to the + beginning of the .tls output section. These offsets can't be + exported. PE targets not using BSF_THREAD_LOCAL, we need to + go by section name for now. */ bool would_export = (symbols[j]->section != bfd_und_section_ptr + && !startswith (symbols[j]->section->name, ".tls$") && ((symbols[j]->flags & BSF_GLOBAL) || (symbols[j]->flags == 0))); if (link_info.version_info && would_export)