[binutils-gdb] ld/pe-dll: Don't auto-export symbols from .tls section

Jan Beulich jbeulich@sourceware.org
Fri Dec 12 14:03:14 GMT 2025


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

commit 8297edc90abc66b8c347afafa062ff9ba9895e4c
Author: LIU Hao <lh_mouse@126.com>
Date:   Fri Dec 12 15:00:15 2025 +0100

    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$$<symbol> when -fdata-sections is specified.
    
    Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80881
    Signed-off-by: LIU Hao <lh_mouse@126.com>

Diff:
---
 ld/pe-dll.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

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)


More information about the Binutils-cvs mailing list