[PATCH v2] ld: Prevent `_tls_used` and `_load_config_used` from being garbage-collected

LIU Hao lh_mouse@126.com
Mon Jul 27 16:45:08 GMT 2026


在 2026-7-27 23:55, Jan Beulich 写道:
>> --- a/ld/emultempl/pe.em
>> +++ b/ld/emultempl/pe.em
>> @@ -1573,6 +1573,16 @@ gld${EMULATION_NAME}_after_open (void)
>>
>>      pe_output_file_set_long_section_names (link_info.output_bfd);
>>
>> +  /* The RVAs of these symbols will be written into the PE header, so they
>> +     must not be collected.  */
>> +#if defined (TARGET_IS_i386pe)
>> +  lang_add_gc_name ("__tls_used");
>> +  lang_add_gc_name ("__load_config_used");
>> +#else
>> +  lang_add_gc_name ("_tls_used");
>> +  lang_add_gc_name ("_load_config_used");
>> +#endif
> 
> The #ifdef here likely wants replacing by appropriate use of
> bfd_get_symbol_leading_char(). To play safe towards future uses, the
> same code could then also be used in pep.em.

An updated patch is attached.

I sincerely think this makes little sense for PE+. No known target for PE+ uses a symbol prefix; but 
there's `USE_MINGW64_LEADING_UNDERSCORES` so meh.



-- 
Best regards,
LIU Hao
-------------- next part --------------
From fd001e472847e0955c4f1e1bbfd684735567a028 Mon Sep 17 00:00:00 2001
From: LIU Hao <lh_mouse@126.com>
Date: Tue, 28 Jul 2026 00:05:24 +0800
Subject: [PATCH] ld: Prevent `_tls_used` and `_load_config_used` from being
 garbage-collected

Earlier today I pushed some patches to mingw-w64 to make `_tls_used` only
linked on demand, by referencing it indirectly through tentative definitions.
However, since the startup code no longer has strong references to `_tls_used`,
if LD is passed `--gc-sections`, it garbage-collects `_tls_used`, resulting in
a broken executable:

   $ objdump -p bin/test_thread_id_cpp.exe | grep -F .tls
   Entry 9 ffffffffc0000000 00000028 Thread Storage Directory [.tls]

This patch prevents `_tls_used` from being garbage-collected, and likewise for
`_load_config_used`.

Signed-off-by: LIU Hao <lh_mouse@126.com>
---
 ld/emultempl/pe.em  | 18 ++++++++++++++++++
 ld/emultempl/pep.em | 18 ++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 07ef2ca5953..fbf7398eb04 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -1573,6 +1573,24 @@ gld${EMULATION_NAME}_after_open (void)
 
   pe_output_file_set_long_section_names (link_info.output_bfd);
 
+  /* The RVAs of these symbols will be written into the PE header, so they
+     must not be collected.  */
+  char sym_prefix = bfd_get_symbol_leading_char (link_info.output_bfd);
+  if (sym_prefix == 0)
+    {
+      lang_add_gc_name ("_tls_used");
+      lang_add_gc_name ("_load_config_used");
+    }
+  else
+    {
+      char *sym = xstrdup ("__tls_used");
+      sym[0] = sym_prefix;
+      lang_add_gc_name (sym);
+      sym = xstrdup ("__load_config_used");
+      sym[0] = sym_prefix;
+      lang_add_gc_name (sym);
+    }
+
 #ifdef DLL_SUPPORT
   pe_process_import_defs (link_info.output_bfd, &link_info);
 
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 25ce3963b36..bf5e2c4665c 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -1582,6 +1582,24 @@ gld${EMULATION_NAME}_after_open (void)
 
   pep_output_file_set_long_section_names (link_info.output_bfd);
 
+  /* The RVAs of these symbols will be written into the PE header, so they
+     must not be collected.  */
+  char sym_prefix = bfd_get_symbol_leading_char (link_info.output_bfd);
+  if (sym_prefix == 0)
+    {
+      lang_add_gc_name ("_tls_used");
+      lang_add_gc_name ("_load_config_used");
+    }
+  else
+    {
+      char *sym = xstrdup ("__tls_used");
+      sym[0] = sym_prefix;
+      lang_add_gc_name (sym);
+      sym = xstrdup ("__load_config_used");
+      sym[0] = sym_prefix;
+      lang_add_gc_name (sym);
+    }
+
 #ifdef DLL_SUPPORT
   pep_process_import_defs (link_info.output_bfd, &link_info);
 
-- 
2.55.0

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/binutils/attachments/20260728/d6a0afaf/attachment-0001.sig>


More information about the Binutils mailing list