ld: Prevent `_tls_used` and `_load_config_used` from being garbage-collected
Jan Beulich
jbeulich@suse.com
Mon Jul 27 15:55:57 GMT 2026
On 27.07.2026 17:38, LIU Hao wrote:
> From: LIU Hao <lh_mouse@126.com>
>
> 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`.
But it does so not knowing what environment the executable targets. Aiui
both names aren't exactly "reserved" in the PE world, they're more like
reserved in combination with certain C or other runtime libraries, I
suppose. In an EFI application, for example, they may exist but have an
entirely different purpose.
Then again I realize that bfd/peXXigen.c already makes a similar
assumption.
> --- 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.
Jan
More information about the Binutils
mailing list