commit: e2e29fbc91c3fff57c973a0eec733effe482bb37 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Wed Aug 20 22:15:44 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Wed Aug 20 22:15:44 2025 +0000 URL: https://gitweb.gentoo.org/proj/toolchain/binutils-patches.git/commit/?id=e2e29fbc
9999: drop merged TLS patches Signed-off-by: Sam James <sam <AT> gentoo.org> ...Add-GLIBC_ABI_GNU2_TLS-version-dependency.patch | 1353 -------------------- ...GLIBC_ABI_DT_X86_64_PLT-version-dependenc.patch | 160 --- ...-Add-GLIBC_ABI_GNU_TLS-version-dependency.patch | 470 ------- 3 files changed, 1983 deletions(-) diff --git a/9999/0007-x86-Add-GLIBC_ABI_GNU2_TLS-version-dependency.patch b/9999/0007-x86-Add-GLIBC_ABI_GNU2_TLS-version-dependency.patch deleted file mode 100644 index b459a36..0000000 --- a/9999/0007-x86-Add-GLIBC_ABI_GNU2_TLS-version-dependency.patch +++ /dev/null @@ -1,1353 +0,0 @@ -From b6b200c936241a908de6d0c9e8c13db8cf16a31f Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" <[email protected]> -Date: Fri, 4 Jul 2025 08:39:03 +0800 -Subject: [PATCH] x86: Add GLIBC_ABI_GNU2_TLS version dependency - -On Linux/x86, programs and shared libraries compiled with --mtls-dialect=gnu2 may fail silently at run-time against glibc without -the GNU2 TLS run-time fixes for: - -https://sourceware.org/bugzilla/show_bug.cgi?id=31501 -https://sourceware.org/bugzilla/show_bug.cgi?id=31372 - -A version tag, GLIBC_ABI_GNU2_TLS, has been added to glibc to indicate -that glibc has the working GNU2 TLS run-time. Add the --gnu2-tls-tag -option to i386/x86-64 ELF linker to add the GLIBC_ABI_GNU2_TLS version -dependency in output programs and shared libraries when linking against -glibc if input relocatable object files have R_386_TLS_DESC_CALL or -R_X86_64_TLSDESC_CALL relocation. The output will fail to load and run -at run-time against glibc which doesn't define the GLIBC_ABI_GNU2_TLS -version. - -Add the --enable-gnu2-tls-tag configure option to enable --gnu2-tls-tag -by default. If unspecified, linker will add the GLIBC_ABI_GNU2_TLS -version dependency if input object files have R_386_TLS_DESC_CALL or -R_X86_64_TLSDESC_CALL relocation and libc.so defines the GLIBC_ABI_GNU2_TLS -version. - -Update elf_link_add_glibc_verneed to properly add the GLIBC_2.36 version -dependency when -z mark-plt -z nopack-relative-relocs passed to x86-64 -ELF linker. - -bfd/ - - PR ld/33130 - * elf-bfd.h (_bfd_elf_link_add_glibc_version_dependency): Add - a pointer to bool argument. - * elf-linker-x86.h (elf_linker_x86_params): Add - gnu2_tls_version_tag. - * elf32-i386.c (elf_i386_scan_relocs): Set has_tls_desc_call to - 1 for R_386_TLS_DESC_CALL. - (elf_i386_add_glibc_version_dependency): New. Undef before - FreeBSD support. - * elf64-x86-64.c (elf_x86_64_scan_relocs): Set has_tls_desc_call - to 1 for R_X86_64_TLSDESC_CALL. - (elf_x86_64_add_glibc_version_dependency): Add GLIBC_ABI_GNU2_TLS - version dependency if GLIBC_ABI_GNU2_TLS dependency isn't disabled - and has_tlsdesc_call isn't 0. - (elf_backend_add_glibc_version_dependency): Undef before CloudABI - support and redefine for elf32-x86-64. - * elflink.c (elf_link_add_glibc_verneed): Changed to return bool. - Remove the pointer to elf_find_verdep_info argument. Add a - pointer to bool argument, auto_version. Return true if linked - against glibc. Otherwise return false. If the version dependency - is added, set *auto_version to true. If *auto_version is true, - add the version dependency only if libc.so defines the version. - (_bfd_elf_link_add_glibc_version_dependency): Add a pointer to - bool argument and pass it to elf_link_add_glibc_verneed. - (_bfd_elf_link_add_dt_relr_dependency): Pass NULL to - _bfd_elf_link_add_glibc_version_dependency. - * elfxx-x86.h (elf_x86_link_hash_table): Add has_tls_desc_call. - -ld/ - - PR ld/33130 - * NEWS: Mention --gnu2-tls-tag, --no-gnu2-tls-tag and - --enable-gnu2-tls-tag. - * config.in: Regenerated. - * configure: Likewise. - * configure.ac: Add --enable-gnu2-tls-tag. - * ld.texi: Document --gnu2-tls-tag/--no-gnu2-tls-tag. - * ldlex.h (option_values): Add OPTION_GNU2_TLS_VERSION_TAG and - OPTION_NO_GNU2_TLS_VERSION_TAG. - * emulparams/elf32_x86_64.sh (EXTRA_EM_FILE): Changed to - "elf-x86-64-glibc". - * emulparams/elf_i386.sh (EXTRA_EM_FILE): Set to "elf-i386-glibc". - * emulparams/elf_i386_fbsd.sh (EXTRA_EM_FILE): New. Set to - "elf-x86". - * emulparams/elf_i386_haiku.sh (EXTRA_EM_FILE): Likewise. - * emulparams/elf_x86_64.sh (EXTRA_EM_FILE): Likewise. - * emulparams/elf_x86_64_cloudabi.sh (EXTRA_EM_FILE): New. Set - to "elf-x86-64". - * emulparams/elf_x86_64_fbsd.sh (EXTRA_EM_FILE): Likewise. - * emulparams/elf_x86_64_haiku.sh (EXTRA_EM_FILE): Likewise. - * (EXTRA_EM_FILE): Likewise. - * (EXTRA_EM_FILE): Likewise. - * emultempl/elf-i386-glibc.em: New file. - * emultempl/elf-x86-64-glibc.em: Likewise. - * emultempl/elf-x86-64.em: Likewise. - * emultempl/elf-x86-glibc.em: Likewise. - * emultempl/elf-x86.em (elf_x86_64_before_parse): Removed. - (LDEMUL_BEFORE_PARSE): Likewise. - (elf_x86_64_before_allocation): Likewise. - (LDEMUL_BEFORE_ALLOCATION): Likewise. - * emultempl/solaris2-x86-64.em: New file. - * testsuite/ld-i386/gnu2-tls-1.s: Likewise. - * testsuite/ld-i386/gnu2-tls-1a.rd: Likewise. - * testsuite/ld-i386/gnu2-tls-1b.rd: Likewise. - * testsuite/ld-x86-64/gnu2-tls-1.s: Likewise. - * testsuite/ld-x86-64/gnu2-tls-1a.rd: Likewise. - * testsuite/ld-x86-64/gnu2-tls-1b.rd: Likewise. - * testsuite/ld-x86-64/mark-plt-2.rd: Likewise. - * testsuite/ld-x86-64/mark-plt-2.s: Likewise. - * testsuite/ld-i386/i386.exp: Run GLIBC_ABI_GNU2_TLS tests. - * testsuite/ld-x86-64/x86-64.exp: Likewise. - -Signed-off-by: H.J. Lu <[email protected]> ---- - bfd/elf-bfd.h | 2 +- - bfd/elf-linker-x86.h | 8 ++ - bfd/elf32-i386.c | 44 ++++++++- - bfd/elf64-x86-64.c | 36 +++++-- - bfd/elflink.c | 130 +++++++++++++++----------- - bfd/elfxx-x86.h | 4 + - ld/NEWS | 6 ++ - ld/config.in | 4 + - ld/configure | 29 +++++- - ld/configure.ac | 19 ++++ - ld/emulparams/elf32_x86_64.sh | 2 +- - ld/emulparams/elf_i386.sh | 2 +- - ld/emulparams/elf_i386_fbsd.sh | 1 + - ld/emulparams/elf_i386_haiku.sh | 1 + - ld/emulparams/elf_x86_64.sh | 2 +- - ld/emulparams/elf_x86_64_fbsd.sh | 1 + - ld/emulparams/elf_x86_64_haiku.sh | 1 + - ld/emultempl/elf-i386-glibc.em | 41 ++++++++ - ld/emultempl/elf-x86-64-glibc.em | 37 ++++++++ - ld/emultempl/elf-x86-64.em | 68 ++++++++++++++ - ld/emultempl/elf-x86-glibc.em | 70 ++++++++++++++ - ld/emultempl/elf-x86.em | 58 ------------ - ld/emultempl/solaris2-x86-64.em | 23 +++++ - ld/ld.texi | 15 +++ - ld/ldlex.h | 3 + - ld/testsuite/ld-i386/gnu2-tls-1.s | 11 +++ - ld/testsuite/ld-i386/gnu2-tls-1a.rd | 7 ++ - ld/testsuite/ld-i386/gnu2-tls-1b.rd | 4 + - ld/testsuite/ld-i386/i386.exp | 23 +++++ - ld/testsuite/ld-x86-64/gnu2-tls-1.s | 11 +++ - ld/testsuite/ld-x86-64/gnu2-tls-1a.rd | 7 ++ - ld/testsuite/ld-x86-64/gnu2-tls-1b.rd | 4 + - ld/testsuite/ld-x86-64/mark-plt-2.rd | 7 ++ - ld/testsuite/ld-x86-64/mark-plt-2.s | 13 +++ - ld/testsuite/ld-x86-64/x86-64.exp | 26 +++++- - 36 files changed, 596 insertions(+), 125 deletions(-) - create mode 100644 ld/emultempl/elf-i386-glibc.em - create mode 100644 ld/emultempl/elf-x86-64-glibc.em - create mode 100644 ld/emultempl/elf-x86-64.em - create mode 100644 ld/emultempl/elf-x86-glibc.em - create mode 100644 ld/emultempl/solaris2-x86-64.em - create mode 100644 ld/testsuite/ld-i386/gnu2-tls-1.s - create mode 100644 ld/testsuite/ld-i386/gnu2-tls-1a.rd - create mode 100644 ld/testsuite/ld-i386/gnu2-tls-1b.rd - create mode 100644 ld/testsuite/ld-x86-64/gnu2-tls-1.s - create mode 100644 ld/testsuite/ld-x86-64/gnu2-tls-1a.rd - create mode 100644 ld/testsuite/ld-x86-64/gnu2-tls-1b.rd - create mode 100644 ld/testsuite/ld-x86-64/mark-plt-2.rd - create mode 100644 ld/testsuite/ld-x86-64/mark-plt-2.s - -diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h -index accdd6d41a8..feb470fc477 100644 ---- a/bfd/elf-bfd.h -+++ b/bfd/elf-bfd.h -@@ -2632,7 +2632,7 @@ extern bool _bfd_elf_link_output_relocs - struct elf_link_hash_entry **); - - extern void _bfd_elf_link_add_glibc_version_dependency -- (struct elf_find_verdep_info *, const char *const []); -+ (struct elf_find_verdep_info *, const char *const [], bool *); - - extern void _bfd_elf_link_add_dt_relr_dependency - (struct elf_find_verdep_info *); -diff --git a/bfd/elf-linker-x86.h b/bfd/elf-linker-x86.h -index 2c98257038f..fe322152e14 100644 ---- a/bfd/elf-linker-x86.h -+++ b/bfd/elf-linker-x86.h -@@ -72,6 +72,14 @@ struct elf_linker_x86_params - /* Mark PLT with dynamic tags. */ - unsigned int mark_plt : 1; - -+ /* Add the GLIBC_ABI_GNU2_TLS version dependency if input object files -+ have R_386_TLS_DESC_CALL or R_X86_64_TLSDESC_CALL relocation: -+ 0: Disable. -+ 1: Enable. -+ 2: Auto. Enable if libc.so has the GLIBC_ABI_GNU2_TLS version. -+ */ -+ unsigned int gnu2_tls_version_tag : 2; -+ - /* X86-64 ISA level needed. */ - unsigned int isa_level; - -diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c -index b755b39ab55..9d06f1494cf 100644 ---- a/bfd/elf32-i386.c -+++ b/bfd/elf32-i386.c -@@ -1687,6 +1687,10 @@ elf_i386_scan_relocs (bfd *abfd, - size_reloc = true; - goto do_size; - -+ case R_386_TLS_DESC_CALL: -+ htab->has_tls_desc_call = 1; -+ goto need_got; -+ - case R_386_TLS_IE_32: - case R_386_TLS_IE: - case R_386_TLS_GOTIE: -@@ -1698,7 +1702,7 @@ elf_i386_scan_relocs (bfd *abfd, - case R_386_GOT32X: - case R_386_TLS_GD: - case R_386_TLS_GOTDESC: -- case R_386_TLS_DESC_CALL: -+ need_got: - /* This symbol requires a global offset table entry. */ - { - int tls_type, old_tls_type; -@@ -4492,6 +4496,40 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) - return _bfd_x86_elf_link_setup_gnu_properties (info, &init_table); - } - -+static void -+elf_i386_add_glibc_version_dependency -+ (struct elf_find_verdep_info *rinfo) -+{ -+ int i = 0; -+ const char *version[3] = { NULL, NULL, NULL }; -+ bool auto_version[3] = { false, false, false }; -+ struct elf_x86_link_hash_table *htab; -+ -+ if (rinfo->info->enable_dt_relr) -+ { -+ version[i] = "GLIBC_ABI_DT_RELR"; -+ i++; -+ } -+ -+ htab = elf_x86_hash_table (rinfo->info, I386_ELF_DATA); -+ if (htab != NULL) -+ { -+ if (htab->params->gnu2_tls_version_tag && htab->has_tls_desc_call) -+ { -+ version[i] = "GLIBC_ABI_GNU2_TLS"; -+ /* 2 == auto, enable if libc.so defines the GLIBC_ABI_GNU2_TLS -+ version. */ -+ if (htab->params->gnu2_tls_version_tag == 2) -+ auto_version[i] = true; -+ i++; -+ } -+ } -+ -+ if (i != 0) -+ _bfd_elf_link_add_glibc_version_dependency (rinfo, version, -+ auto_version); -+} -+ - #define TARGET_LITTLE_SYM i386_elf32_vec - #define TARGET_LITTLE_NAME "elf32-i386" - #define ELF_ARCH bfd_arch_i386 -@@ -4532,6 +4570,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) - #define elf_backend_relocate_section elf_i386_relocate_section - #define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties - #define elf_backend_hide_symbol _bfd_x86_elf_hide_symbol -+#define elf_backend_add_glibc_version_dependency \ -+ elf_i386_add_glibc_version_dependency - - #define elf_backend_linux_prpsinfo32_ugid16 true - -@@ -4539,6 +4579,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) - - #include "elf32-target.h" - -+#undef elf_backend_add_glibc_version_dependency -+ - /* FreeBSD support. */ - - #undef TARGET_LITTLE_SYM -diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c -index b6fd466178e..1edce6e8703 100644 ---- a/bfd/elf64-x86-64.c -+++ b/bfd/elf64-x86-64.c -@@ -2694,6 +2694,10 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, - eh->zero_undefweak &= 0x2; - break; - -+ case R_X86_64_TLSDESC_CALL: -+ htab->has_tls_desc_call = 1; -+ goto need_got; -+ - case R_X86_64_GOTTPOFF: - case R_X86_64_CODE_4_GOTTPOFF: - case R_X86_64_CODE_5_GOTTPOFF: -@@ -2715,7 +2719,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, - case R_X86_64_GOTPLT64: - case R_X86_64_GOTPC32_TLSDESC: - case R_X86_64_CODE_4_GOTPC32_TLSDESC: -- case R_X86_64_TLSDESC_CALL: -+need_got: - /* This symbol requires a global offset table entry. */ - { - int tls_type, old_tls_type; -@@ -6243,7 +6247,8 @@ elf_x86_64_add_glibc_version_dependency - (struct elf_find_verdep_info *rinfo) - { - unsigned int i = 0; -- const char *version[3] = { NULL, NULL, NULL }; -+ const char *version[4] = { NULL, NULL, NULL, NULL }; -+ bool auto_version[4] = { false, false, false, false }; - struct elf_x86_link_hash_table *htab; - - if (rinfo->info->enable_dt_relr) -@@ -6253,14 +6258,27 @@ elf_x86_64_add_glibc_version_dependency - } - - htab = elf_x86_hash_table (rinfo->info, X86_64_ELF_DATA); -- if (htab != NULL && htab->params->mark_plt) -+ if (htab != NULL) - { -- version[i] = "GLIBC_2.36"; -- i++; -+ if (htab->params->gnu2_tls_version_tag && htab->has_tls_desc_call) -+ { -+ version[i] = "GLIBC_ABI_GNU2_TLS"; -+ /* 2 == auto, enable if libc.so defines the GLIBC_ABI_GNU2_TLS -+ version. */ -+ if (htab->params->gnu2_tls_version_tag == 2) -+ auto_version[i] = true; -+ i++; -+ } -+ if (htab->params->mark_plt) -+ { -+ version[i] = "GLIBC_2.36"; -+ i++; -+ } - } - - if (i != 0) -- _bfd_elf_link_add_glibc_version_dependency (rinfo, version); -+ _bfd_elf_link_add_glibc_version_dependency (rinfo, version, -+ auto_version); - } - - static const struct bfd_elf_special_section -@@ -6479,6 +6499,10 @@ elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUS - #define elf_backend_bfd_from_remote_memory \ - _bfd_elf32_bfd_from_remote_memory - -+#undef elf_backend_add_glibc_version_dependency -+#define elf_backend_add_glibc_version_dependency \ -+ elf_x86_64_add_glibc_version_dependency -+ - #undef elf_backend_size_info - #define elf_backend_size_info \ - _bfd_elf32_size_info -diff --git a/bfd/elflink.c b/bfd/elflink.c -index f6c0c04e82e..d2c43f31bf5 100644 ---- a/bfd/elflink.c -+++ b/bfd/elflink.c -@@ -2281,68 +2281,85 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) - return true; - } - --/* Return the glibc version reference if VERSION_DEP is added to the -- list of glibc version dependencies successfully. VERSION_DEP will -- be put into the .gnu.version_r section. GLIBC_MINOR_BASE is the -- pointer to the glibc minor base version. */ -+/* Return true if linked against glibc. Otherwise return false. If -+ linked against glibc, add VERSION_DEP to the list of glibc version -+ dependencies and set *AUTO_VERSION to true. If *AUTO_VERSION is -+ true, add VERSION_DEP to the version dependency list only if libc.so -+ defines VERSION_DEP. GLIBC_MINOR_BASE is the pointer to the glibc -+ minor base version. */ - --static Elf_Internal_Verneed * -+static bool - elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo, -- Elf_Internal_Verneed *glibc_verref, - const char *version_dep, -- int *glibc_minor_base) -+ int *glibc_minor_base, -+ bool *auto_version) - { - Elf_Internal_Verneed *t; - Elf_Internal_Vernaux *a; - size_t amt; - int minor_version = -1; -+ bool added = false; -+ bool glibc = false; - -- if (glibc_verref != NULL) -+ for (t = elf_tdata (rinfo->info->output_bfd)->verref; -+ t != NULL; -+ t = t->vn_nextref) - { -- t = glibc_verref; -+ const char *soname = bfd_elf_get_dt_soname (t->vn_bfd); -+ if (soname != NULL && startswith (soname, "libc.so.")) -+ break; -+ } - -- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) -+ /* Skip the shared library if it isn't libc.so. */ -+ if (t == NULL) -+ goto update_auto_version_and_return; -+ -+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) -+ { -+ /* Return if VERSION_DEP dependency has been added. */ -+ if (a->vna_nodename == version_dep -+ || strcmp (a->vna_nodename, version_dep) == 0) - { -- /* Return if VERSION_DEP dependency has been added. */ -- if (a->vna_nodename == version_dep -- || strcmp (a->vna_nodename, version_dep) == 0) -- return t; -+ glibc = true; -+ goto update_auto_version_and_return; - } -- } -- else -- { -- for (t = elf_tdata (rinfo->info->output_bfd)->verref; -- t != NULL; -- t = t->vn_nextref) -+ -+ /* Check if libc.so provides GLIBC_2.XX version. */ -+ if (startswith (a->vna_nodename, "GLIBC_2.")) - { -- const char *soname = bfd_elf_get_dt_soname (t->vn_bfd); -- if (soname != NULL && startswith (soname, "libc.so.")) -- break; -+ minor_version = strtol (a->vna_nodename + 8, NULL, 10); -+ if (minor_version < *glibc_minor_base) -+ *glibc_minor_base = minor_version; - } -+ } - -- /* Skip the shared library if it isn't libc.so. */ -- if (t == NULL) -- return t; -+ /* Skip if it isn't linked against glibc. */ -+ if (minor_version < 0) -+ goto update_auto_version_and_return; - -- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) -- { -- /* Return if VERSION_DEP dependency has been added. */ -- if (a->vna_nodename == version_dep -- || strcmp (a->vna_nodename, version_dep) == 0) -- return t; -+ glibc = true; - -- /* Check if libc.so provides GLIBC_2.XX version. */ -- if (startswith (a->vna_nodename, "GLIBC_2.")) -- { -- minor_version = strtol (a->vna_nodename + 8, NULL, 10); -- if (minor_version < *glibc_minor_base) -- *glibc_minor_base = minor_version; -- } -- } -+ if (auto_version && *auto_version) -+ { -+ /* Add VERSION_DEP to the version dependency list only if -+ libc.so defines VERSION_DEP. */ - -- /* Skip if it isn't linked against glibc. */ -- if (minor_version < 0) -- return NULL; -+ bool defined = false; -+ Elf_Internal_Verdef *d; -+ -+ for (d = elf_tdata (t->vn_bfd)->verdef; -+ d != NULL; -+ d = d->vd_nextdef) -+ if (strcmp (d->vd_nodename, version_dep) == 0) -+ { -+ defined = true; -+ break; -+ } -+ -+ /* Set *AUTO_VERSION to false and return true to indicate that -+ libc.so doesn't define VERSION_DEP. */ -+ if (!defined) -+ goto update_auto_version_and_return; - } - - /* Skip if 2.GLIBC_MINOR_BASE includes VERSION_DEP. */ -@@ -2350,7 +2367,7 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo, - { - minor_version = strtol (version_dep + 8, NULL, 10); - if (minor_version <= *glibc_minor_base) -- return NULL; -+ goto update_auto_version_and_return; - } - - amt = sizeof *a; -@@ -2358,7 +2375,8 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo, - if (a == NULL) - { - rinfo->failed = true; -- return NULL; -+ glibc = false; -+ goto update_auto_version_and_return; - } - - a->vna_nodename = version_dep; -@@ -2369,7 +2387,13 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo, - - t->vn_auxptr = a; - -- return t; -+ added = true; -+ -+ update_auto_version_and_return: -+ if (auto_version) -+ *auto_version = added; -+ -+ return glibc; - } - - /* Add VERSION_DEP to the list of version dependencies when linked -@@ -2378,19 +2402,19 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo, - void - _bfd_elf_link_add_glibc_version_dependency - (struct elf_find_verdep_info *rinfo, -- const char *const version_dep[]) -+ const char *const version_dep[], -+ bool *auto_version) - { -- Elf_Internal_Verneed *t = NULL; - int glibc_minor_base = INT_MAX; - - do - { -- t = elf_link_add_glibc_verneed (rinfo, t, *version_dep, -- &glibc_minor_base); -- /* Return if there is no glibc version reference. */ -- if (t == NULL) -+ /* Return if not linked against glibc. */ -+ if (!elf_link_add_glibc_verneed (rinfo, *version_dep, -+ &glibc_minor_base, auto_version)) - return; - version_dep++; -+ auto_version++; - } - while (*version_dep != NULL); - } -@@ -2408,7 +2432,7 @@ _bfd_elf_link_add_dt_relr_dependency (struct elf_find_verdep_info *rinfo) - "GLIBC_ABI_DT_RELR", - NULL - }; -- _bfd_elf_link_add_glibc_version_dependency (rinfo, version); -+ _bfd_elf_link_add_glibc_version_dependency (rinfo, version, NULL); - } - } - -diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h -index f6ee6a65356..791a2a2592f 100644 ---- a/bfd/elfxx-x86.h -+++ b/bfd/elfxx-x86.h -@@ -670,6 +670,10 @@ struct elf_x86_link_hash_table - /* Number of relative reloc generation pass. */ - unsigned int generate_relative_reloc_pass; - -+ /* TRUE if inputs have R_386_TLS_DESC_CALL or R_X86_64_TLSDESC_CALL -+ relocation. */ -+ unsigned int has_tls_desc_call : 1; -+ - /* Value used to fill the unused bytes of the first PLT entry. This - is only used for i386. */ - bfd_byte plt0_pad_byte; -diff --git a/ld/NEWS b/ld/NEWS -index 54c1df5aadf..bacabc8440e 100644 ---- a/ld/NEWS -+++ b/ld/NEWS -@@ -1,5 +1,11 @@ - -*- text -*- - -+* Add --gnu2-tls-tag/--no-gnu2-tls-tag options to i386 and x86-64 ELF -+ linkers to add the GLIBC_ABI_GNU2_TLS version dependency in output if -+ input object files have R_386_TLS_DESC_CALL or R_X86_64_TLSDESC_CALL -+ relocation. Also added --enable-gnu2-tls-tag configure option to -+ enable --gnu2-tls-tag by default. -+ - * NaCl target support is removed. - - Changes in 2.45: -diff --git a/ld/config.in b/ld/config.in -index 37812241bd9..64dbc3e0c88 100644 ---- a/ld/config.in -+++ b/ld/config.in -@@ -31,6 +31,10 @@ - when a .note-GNU-stack section is missing. */ - #undef DEFAULT_LD_EXECSTACK - -+/* Define to 1 if you want to enable --gnu2-tls-tag in ELF i386/x86-64 linker -+ by default. */ -+#undef DEFAULT_LD_GNU2_TLS_TAG -+ - /* Define to 1 if you want to enable --rosegment in the ELF linker by default. - */ - #undef DEFAULT_LD_ROSEGMENT -diff --git a/ld/configure b/ld/configure -index 124b44182bc..6f1a3559964 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -851,6 +851,7 @@ enable_textrel_check - enable_separate_code - enable_rosegment - enable_mark_plt -+enable_gnu2_tls_tag - enable_memory_seal - enable_warn_execstack - enable_error_execstack -@@ -1548,6 +1549,8 @@ Optional Features: - --enable-separate-code enable -z separate-code in ELF linker by default - --enable-rosegment enable --rosegment in the ELF linker by default - --enable-mark-plt enable -z mark-plt in ELF x86-64 linker by default -+ --enable-gnu2-tls-tag enable --gnu2-tls-tag in ELF i386/x86-64 linker by -+ default - --enable-memory-seal enable -z memory-seal in ELF linker by default - --enable-warn-execstack enable warnings when creating an executable stack - --enable-error-execstack -@@ -11514,7 +11517,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11517 "configure" -+#line 11520 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11620,7 +11623,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11623 "configure" -+#line 11626 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -15507,6 +15510,18 @@ esac - fi - - -+# Decide if --gnu2-tls-tag should be enabled in ELF i386 and x86-64 -+# linkers by default. -+ac_default_ld_enable_gnu2_tls_tag=unset -+# Check whether --enable-gnu2-tls-tag was given. -+if test "${enable_gnu2_tls_tag+set}" = set; then : -+ enableval=$enable_gnu2_tls_tag; case "${enableval}" in -+ yes) ac_default_ld_enable_gnu2_tls_tag=1 ;; -+ no) ac_default_ld_enable_gnu2_tls_tag=0 ;; -+esac -+fi -+ -+ - # Decide if -z memory-seal should be enabled in ELF linker by default. - ac_default_ld_z_memory_seal=unset - # Check whether --enable-memory-seal was given. -@@ -18981,6 +18996,16 @@ cat >>confdefs.h <<_ACEOF - _ACEOF - - -+if test "${ac_default_ld_enable_gnu2_tls_tag}" = unset; then -+ # Default to enable --gnu2-tls-tag if libc.so has the GLIBC_ABI_GNU2_TLS -+ # version. -+ ac_default_ld_enable_gnu2_tls_tag=2 -+fi -+ -+cat >>confdefs.h <<_ACEOF -+#define DEFAULT_LD_GNU2_TLS_TAG $ac_default_ld_enable_gnu2_tls_tag -+_ACEOF -+ - - - cat >>confdefs.h <<_ACEOF -diff --git a/ld/configure.ac b/ld/configure.ac -index e306c1ded4a..4b9068a415e 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -245,6 +245,17 @@ AC_ARG_ENABLE(mark-plt, - no) ac_default_ld_z_mark_plt=0 ;; - esac]) - -+# Decide if --gnu2-tls-tag should be enabled in ELF i386 and x86-64 -+# linkers by default. -+ac_default_ld_enable_gnu2_tls_tag=unset -+AC_ARG_ENABLE(gnu2-tls-tag, -+ AS_HELP_STRING([--enable-gnu2-tls-tag], -+ [enable --gnu2-tls-tag in ELF i386/x86-64 linker by default]), -+[case "${enableval}" in -+ yes) ac_default_ld_enable_gnu2_tls_tag=1 ;; -+ no) ac_default_ld_enable_gnu2_tls_tag=0 ;; -+esac]) -+ - # Decide if -z memory-seal should be enabled in ELF linker by default. - ac_default_ld_z_memory_seal=unset - AC_ARG_ENABLE(memory-seal, -@@ -646,6 +657,14 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_MEMORY_SEAL, - $ac_default_ld_z_memory_seal, - [Define to 1 if you want to enable -z memory_seal in ELF linker by default.]) - -+if test "${ac_default_ld_enable_gnu2_tls_tag}" = unset; then -+ # Default to enable --gnu2-tls-tag if libc.so has the GLIBC_ABI_GNU2_TLS -+ # version. -+ ac_default_ld_enable_gnu2_tls_tag=2 -+fi -+AC_DEFINE_UNQUOTED(DEFAULT_LD_GNU2_TLS_TAG, -+ $ac_default_ld_enable_gnu2_tls_tag, -+ [Define to 1 if you want to enable --gnu2-tls-tag in ELF i386/x86-64 linker by default.]) - - AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_EXECSTACK, - $ac_default_ld_warn_execstack, -diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh -index 6a92eec129d..4db1a979058 100644 ---- a/ld/emulparams/elf32_x86_64.sh -+++ b/ld/emulparams/elf32_x86_64.sh -@@ -20,7 +20,7 @@ COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" - ARCH="i386:x64-32" - MACHINE= - TEMPLATE_NAME=elf --EXTRA_EM_FILE="elf-x86" -+EXTRA_EM_FILE="elf-x86-64-glibc" - GENERATE_SHLIB_SCRIPT=yes - GENERATE_PIE_SCRIPT=yes - NO_SMALL_DATA=yes -diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh -index 6f698bb0b06..51a650f692e 100644 ---- a/ld/emulparams/elf_i386.sh -+++ b/ld/emulparams/elf_i386.sh -@@ -17,7 +17,7 @@ COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" - ARCH=i386 - MACHINE= - TEMPLATE_NAME=elf --EXTRA_EM_FILE="elf-x86" -+EXTRA_EM_FILE="elf-i386-glibc" - GENERATE_SHLIB_SCRIPT=yes - GENERATE_PIE_SCRIPT=yes - NO_SMALL_DATA=yes -diff --git a/ld/emulparams/elf_i386_fbsd.sh b/ld/emulparams/elf_i386_fbsd.sh -index d1d6604504a..d39a5cf882f 100644 ---- a/ld/emulparams/elf_i386_fbsd.sh -+++ b/ld/emulparams/elf_i386_fbsd.sh -@@ -1,3 +1,4 @@ - source_sh ${srcdir}/emulparams/elf_i386.sh - source_sh ${srcdir}/emulparams/elf_fbsd.sh -+EXTRA_EM_FILE="elf-x86" - OUTPUT_FORMAT="elf32-i386-freebsd" -diff --git a/ld/emulparams/elf_i386_haiku.sh b/ld/emulparams/elf_i386_haiku.sh -index 6c4001e4e05..c931c0e3f91 100644 ---- a/ld/emulparams/elf_i386_haiku.sh -+++ b/ld/emulparams/elf_i386_haiku.sh -@@ -1,5 +1,6 @@ - source_sh ${srcdir}/emulparams/elf_i386.sh - source_sh ${srcdir}/emulparams/elf_haiku.sh -+EXTRA_EM_FILE="elf-x86" - TEXT_START_ADDR=0x200000 - NONPAGED_TEXT_START_ADDR=0x200000 - MAXPAGESIZE=0x1000 -diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh -index 92449745c7a..6e66f2e1035 100644 ---- a/ld/emulparams/elf_x86_64.sh -+++ b/ld/emulparams/elf_x86_64.sh -@@ -21,7 +21,7 @@ COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" - ARCH="i386:x86-64" - MACHINE= - TEMPLATE_NAME=elf --EXTRA_EM_FILE="elf-x86" -+EXTRA_EM_FILE="elf-x86-64-glibc" - GENERATE_SHLIB_SCRIPT=yes - GENERATE_PIE_SCRIPT=yes - NO_SMALL_DATA=yes -diff --git a/ld/emulparams/elf_x86_64_fbsd.sh b/ld/emulparams/elf_x86_64_fbsd.sh -index 7ef974addca..17fdc83b075 100644 ---- a/ld/emulparams/elf_x86_64_fbsd.sh -+++ b/ld/emulparams/elf_x86_64_fbsd.sh -@@ -1,3 +1,4 @@ - source_sh ${srcdir}/emulparams/elf_x86_64.sh - source_sh ${srcdir}/emulparams/elf_fbsd.sh -+EXTRA_EM_FILE="elf-x86-64" - OUTPUT_FORMAT="elf64-x86-64-freebsd" -diff --git a/ld/emulparams/elf_x86_64_haiku.sh b/ld/emulparams/elf_x86_64_haiku.sh -index e6231cdfb15..7b033840fb6 100644 ---- a/ld/emulparams/elf_x86_64_haiku.sh -+++ b/ld/emulparams/elf_x86_64_haiku.sh -@@ -1,2 +1,3 @@ - source_sh ${srcdir}/emulparams/elf_x86_64.sh - source_sh ${srcdir}/emulparams/elf_haiku.sh -+EXTRA_EM_FILE="elf-x86-64" -diff --git a/ld/emultempl/elf-i386-glibc.em b/ld/emultempl/elf-i386-glibc.em -new file mode 100644 -index 00000000000..547823750a4 ---- /dev/null -+++ b/ld/emultempl/elf-i386-glibc.em -@@ -0,0 +1,41 @@ -+# This shell script emits a C file. -*- C -*- -+# Copyright (C) 2025 Free Software Foundation, Inc. -+# -+# This file is part of the GNU Binutils. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3 of the license, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; see the file COPYING3. If not, -+# see <http://www.gnu.org/licenses/>. -+# -+ -+# This file is sourced from elf.em, and defines i386 glibc specific -+# routines. -+# -+ -+source_em ${srcdir}/emultempl/elf-x86.em -+source_em ${srcdir}/emultempl/elf-x86-glibc.em -+ -+# Define some shell vars to insert bits of code into the standard elf -+# parse_args and list_options functions. -+# -+ -+fragment <<EOF -+static void -+elf_i386_glibc_before_parse (void) -+{ -+ elf_x86_before_parse (); -+ elf_x86_glibc_before_parse (); -+} -+EOF -+ -+LDEMUL_BEFORE_PARSE=elf_i386_glibc_before_parse -diff --git a/ld/emultempl/elf-x86-64-glibc.em b/ld/emultempl/elf-x86-64-glibc.em -new file mode 100644 -index 00000000000..1e62d4f48bc ---- /dev/null -+++ b/ld/emultempl/elf-x86-64-glibc.em -@@ -0,0 +1,37 @@ -+# This shell script emits a C file. -*- C -*- -+# Copyright (C) 2025 Free Software Foundation, Inc. -+# -+# This file is part of the GNU Binutils. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3 of the license, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; see the file COPYING3. If not, -+# see <http://www.gnu.org/licenses/>. -+# -+ -+# This file is sourced from elf.em, and defines x86-64 glibc specific -+# routines. -+# -+ -+source_em ${srcdir}/emultempl/elf-x86-64.em -+source_em ${srcdir}/emultempl/elf-x86-glibc.em -+ -+fragment <<EOF -+static void -+elf_x86_64_glibc_before_parse (void) -+{ -+ elf_x86_64_before_parse (); -+ elf_x86_glibc_before_parse (); -+} -+EOF -+ -+LDEMUL_BEFORE_PARSE=elf_x86_64_glibc_before_parse -diff --git a/ld/emultempl/elf-x86-64.em b/ld/emultempl/elf-x86-64.em -new file mode 100644 -index 00000000000..ca7ccc0f478 ---- /dev/null -+++ b/ld/emultempl/elf-x86-64.em -@@ -0,0 +1,68 @@ -+# This shell script emits a C file. -*- C -*- -+# Copyright (C) 2025 Free Software Foundation, Inc. -+# -+# This file is part of the GNU Binutils. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3 of the license, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; see the file COPYING3. If not, -+# see <http://www.gnu.org/licenses/>. -+# -+ -+# This file is sourced from elf.em, and defines x86-64 specific routines. -+# -+ -+source_em ${srcdir}/emultempl/elf-x86.em -+ -+fragment <<EOF -+static void -+elf_x86_64_before_parse (void) -+{ -+ params.mark_plt = DEFAULT_LD_Z_MARK_PLT; -+ -+ elf_x86_before_parse (); -+} -+ -+static void -+elf_x86_64_before_allocation (void) -+{ -+ if (!bfd_link_relocatable (&link_info) -+ && is_elf_hash_table (link_info.hash) -+ && expld.phase != lang_mark_phase_enum) -+ { -+ struct elf_link_hash_table *htab = elf_hash_table (&link_info); -+ /* Run one_lang_size_sections_pass to estimate the output section -+ layout before sizing dynamic sections. */ -+ expld.dataseg.phase = exp_seg_none; -+ expld.phase = lang_mark_phase_enum; -+ /* NB: Exclude linker created GOT setions when estimating output -+ section layout as sizing dynamic sections may change linker -+ created GOT sections. */ -+ if (htab->sgot != NULL) -+ htab->sgot->flags |= SEC_EXCLUDE; -+ if (htab->sgotplt != NULL) -+ htab->sgotplt->flags |= SEC_EXCLUDE; -+ one_lang_size_sections_pass (NULL, false); -+ /* Restore linker created GOT setions. */ -+ if (htab->sgot != NULL) -+ htab->sgot->flags &= ~SEC_EXCLUDE; -+ if (htab->sgotplt != NULL) -+ htab->sgotplt->flags &= ~SEC_EXCLUDE; -+ lang_reset_memory_regions (); -+ } -+ -+ gld${EMULATION_NAME}_before_allocation (); -+} -+EOF -+ -+LDEMUL_BEFORE_PARSE=elf_x86_64_before_parse -+LDEMUL_BEFORE_ALLOCATION=elf_x86_64_before_allocation -diff --git a/ld/emultempl/elf-x86-glibc.em b/ld/emultempl/elf-x86-glibc.em -new file mode 100644 -index 00000000000..0fc37a6b59c ---- /dev/null -+++ b/ld/emultempl/elf-x86-glibc.em -@@ -0,0 +1,70 @@ -+# This shell script emits a C file. -*- C -*- -+# Copyright (C) 2025 Free Software Foundation, Inc. -+# -+# This file is part of the GNU Binutils. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3 of the license, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; see the file COPYING3. If not, -+# see <http://www.gnu.org/licenses/>. -+# -+ -+# This file is sourced from elf.em, and defines x86 glibc specific -+# routines. -+# -+ -+fragment <<EOF -+static void -+elf_x86_glibc_before_parse (void) -+{ -+ params.gnu2_tls_version_tag = DEFAULT_LD_GNU2_TLS_TAG; -+} -+EOF -+ -+# Define some shell vars to insert bits of code into the standard elf -+# parse_args and list_options functions. -+# -+ -+PARSE_AND_LIST_LONGOPTS_X86=' -+ { "gnu2-tls-tag", no_argument, NULL, OPTION_GNU2_TLS_VERSION_TAG }, -+ { "no-gnu2-tls-tag", no_argument, NULL, OPTION_NO_GNU2_TLS_VERSION_TAG }, -+' -+ -+PARSE_AND_LIST_OPTIONS_X86=' -+ if (DEFAULT_LD_GNU2_TLS_TAG == 0) -+ fprintf (file, _("\ -+ --gnu2-tls-tag Add GNU2_ABI_GNU2_TLS dependency\n\ -+ --no-gnu2-tls-tag Do not add GNU2_ABI_GNU2_TLS dependency (default)\n")); -+ else if (DEFAULT_LD_GNU2_TLS_TAG == 1) -+ fprintf (file, _("\ -+ --gnu2-tls-tag Add GNU2_ABI_GNU2_TLS dependency (default)\n\ -+ --no-gnu2-tls-tag Do not add GNU2_ABI_GNU2_TLS dependency\n")); -+ else -+ fprintf (file, _("\ -+ --gnu2-tls-tag Add GNU2_ABI_GNU2_TLS dependency (auto)\n\ -+ when no options are specified (default)\n\ -+ --no-gnu2-tls-tag Do not add GNU2_ABI_GNU2_TLS dependency\n")); -+' -+ -+PARSE_AND_LIST_ARGS_CASES_X86=' -+ case OPTION_GNU2_TLS_VERSION_TAG: -+ params.gnu2_tls_version_tag = 1; -+ break; -+ -+ case OPTION_NO_GNU2_TLS_VERSION_TAG: -+ params.gnu2_tls_version_tag = 0; -+ break; -+' -+ -+PARSE_AND_LIST_LONGOPTS="$PARSE_AND_LIST_LONGOPTS $PARSE_AND_LIST_LONGOPTS_X86" -+PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_X86" -+PARSE_AND_LIST_ARGS_CASES="$PARSE_AND_LIST_ARGS_CASES $PARSE_AND_LIST_ARGS_CASES_X86" -diff --git a/ld/emultempl/elf-x86.em b/ld/emultempl/elf-x86.em -index f72a0cd0d4a..411a4d62294 100644 ---- a/ld/emultempl/elf-x86.em -+++ b/ld/emultempl/elf-x86.em -@@ -56,61 +56,3 @@ EOF - - LDEMUL_BEFORE_PARSE=elf_x86_before_parse - fi -- --case x${OUTPUT_FORMAT}${CALL_NOP_BYTE} in -- x*x86-64*0x67) --fragment <<EOF -- --static void --elf_x86_64_before_parse (void) --{ -- params.mark_plt = DEFAULT_LD_Z_MARK_PLT; -- -- elf_x86_before_parse (); --} --EOF -- -- LDEMUL_BEFORE_PARSE=elf_x86_64_before_parse -- ;; --esac -- --case x${OUTPUT_FORMAT} in -- x*x86-64*) --fragment <<EOF -- --static void --elf_x86_64_before_allocation (void) --{ -- if (!bfd_link_relocatable (&link_info) -- && is_elf_hash_table (link_info.hash) -- && expld.phase != lang_mark_phase_enum) -- { -- struct elf_link_hash_table *htab = elf_hash_table (&link_info); -- /* Run one_lang_size_sections_pass to estimate the output section -- layout before sizing dynamic sections. */ -- expld.dataseg.phase = exp_seg_none; -- expld.phase = lang_mark_phase_enum; -- /* NB: Exclude linker created GOT setions when estimating output -- section layout as sizing dynamic sections may change linker -- created GOT sections. */ -- if (htab->sgot != NULL) -- htab->sgot->flags |= SEC_EXCLUDE; -- if (htab->sgotplt != NULL) -- htab->sgotplt->flags |= SEC_EXCLUDE; -- one_lang_size_sections_pass (NULL, false); -- /* Restore linker created GOT setions. */ -- if (htab->sgot != NULL) -- htab->sgot->flags &= ~SEC_EXCLUDE; -- if (htab->sgotplt != NULL) -- htab->sgotplt->flags &= ~SEC_EXCLUDE; -- lang_reset_memory_regions (); -- } -- -- gld${EMULATION_NAME}_before_allocation (); --} -- --EOF -- --LDEMUL_BEFORE_ALLOCATION=elf_x86_64_before_allocation -- ;; --esac -diff --git a/ld/emultempl/solaris2-x86-64.em b/ld/emultempl/solaris2-x86-64.em -new file mode 100644 -index 00000000000..788b3cf4800 ---- /dev/null -+++ b/ld/emultempl/solaris2-x86-64.em -@@ -0,0 +1,23 @@ -+# This shell script emits a C file. -*- C -*- -+# Copyright (C) 2025 Free Software Foundation, Inc. -+# -+# This file is part of the GNU Binutils. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 3 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, -+# MA 02110-1301, USA. -+# -+ -+source_em "${srcdir}/emultempl/elf-x86-64.em" -+source_em "${srcdir}/emultempl/solaris2.em" -diff --git a/ld/ld.texi b/ld/ld.texi -index 413335ad765..0e13f7d8e35 100644 ---- a/ld/ld.texi -+++ b/ld/ld.texi -@@ -1745,6 +1745,21 @@ Supported for Linux/i386 and Linux/x86_64. - - Other keywords are ignored for Solaris compatibility. - -+@item --gnu2-tls-tag -+@itemx --no-gnu2-tls-tag -+Add @code{GLIBC_ABI_GNU2_TLS} version tag dependency in output programs -+and shared libraries when linking against glibc if input relocatable -+object files have @code{R_386_TLS_DESC_CALL} or -+@code{R_X86_64_TLSDESC_CALL} relocation. The output will fail to load -+and run at run-time against glibc which doesn't define the -+@code{GLIBC_ABI_GNU2_TLS} version tag. Unless disabled by the -+@option{--disable-gnu2-tls-tag} configure option at the linker build -+time, when no options are specified, linker will add the -+@code{GLIBC_ABI_GNU2_TLS} version tag dependency if inputs have -+@code{R_386_TLS_DESC_CALL} or @code{R_X86_64_TLSDESC_CALL} relocation -+and libc.so defines the @code{GLIBC_ABI_GNU2_TLS} version tag. -+Supported for Linux/i386 and Linux/x86_64. -+ - @kindex -( - @cindex groups of archives - @item -( @var{archives} -) -diff --git a/ld/ldlex.h b/ld/ldlex.h -index d0c2e5d6db8..020712df0e7 100644 ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -469,6 +469,9 @@ enum option_values - OPTION_NO_LITERAL_MOVEMENT, - OPTION_ABI_WINDOWED, - OPTION_ABI_CALL0, -+ /* Used by emultempl/elf-x86-glibc.em. */ -+ OPTION_GNU2_TLS_VERSION_TAG, -+ OPTION_NO_GNU2_TLS_VERSION_TAG, - }; - - /* The initial parser states. */ -diff --git a/ld/testsuite/ld-i386/gnu2-tls-1.s b/ld/testsuite/ld-i386/gnu2-tls-1.s -new file mode 100644 -index 00000000000..e3841c71653 ---- /dev/null -+++ b/ld/testsuite/ld-i386/gnu2-tls-1.s -@@ -0,0 +1,11 @@ -+ .section .text.startup,"ax",@progbits -+ .p2align 4 -+ .globl main -+ .type main, @function -+main: -+ leal ld@TLSDESC(%ebx), %eax -+ call *ld@TLSCALL(%eax) -+ addl %gs:0, %eax -+ ret -+ .size main, .-main -+ .section .note.GNU-stack,"",@progbits -diff --git a/ld/testsuite/ld-i386/gnu2-tls-1a.rd b/ld/testsuite/ld-i386/gnu2-tls-1a.rd -new file mode 100644 -index 00000000000..3eb926a227c ---- /dev/null -+++ b/ld/testsuite/ld-i386/gnu2-tls-1a.rd -@@ -0,0 +1,7 @@ -+#... -+Version needs section '.gnu.version_r' contains 1 entry: -+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\) -+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+ -+#... -+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+ -+#pass -diff --git a/ld/testsuite/ld-i386/gnu2-tls-1b.rd b/ld/testsuite/ld-i386/gnu2-tls-1b.rd -new file mode 100644 -index 00000000000..33ef8acb232 ---- /dev/null -+++ b/ld/testsuite/ld-i386/gnu2-tls-1b.rd -@@ -0,0 +1,4 @@ -+#failif -+#... -+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+ -+#... -diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp -index 86748b1a494..74ef1672f86 100644 ---- a/ld/testsuite/ld-i386/i386.exp -+++ b/ld/testsuite/ld-i386/i386.exp -@@ -1516,6 +1516,29 @@ run_ld_link_tests [list \ - ] \ - ] - -+# The musl C library does not support --gnu2-tls-tag. -+if { ![istarget *-*-musl] -+ && [check_compiler_available] } { -+ run_cc_link_tests [list \ -+ [list \ -+ "Build gnu2-tls-1a.so" \ -+ "-shared -Wl,--no-as-needed,--gnu2-tls-tag" \ -+ "-fPIC" \ -+ { gnu2-tls-1.s } \ -+ {{readelf {-W --version-info} gnu2-tls-1a.rd}} \ -+ "gnu2-tls-1a.so" \ -+ ] \ -+ [list \ -+ "Build gnu2-tls-1b.so" \ -+ "-shared -Wl,--no-as-needed,--no-gnu2-tls-tag" \ -+ "-fPIC" \ -+ { gnu2-tls-1.s } \ -+ {{readelf {-W --version-info} gnu2-tls-1b.rd}} \ -+ "gnu2-tls-1b.so" \ -+ ] \ -+ ] -+} -+ - # Linux only tests - run_dump_test "pltgot-1" - run_dump_test "pltgot-2" -diff --git a/ld/testsuite/ld-x86-64/gnu2-tls-1.s b/ld/testsuite/ld-x86-64/gnu2-tls-1.s -new file mode 100644 -index 00000000000..eca788c9ca2 ---- /dev/null -+++ b/ld/testsuite/ld-x86-64/gnu2-tls-1.s -@@ -0,0 +1,11 @@ -+ .section .text.startup,"ax",@progbits -+ .p2align 4 -+ .globl main -+ .type main, @function -+main: -+ leaq foo@TLSDESC(%rip), %rax -+ call *foo@TLSCALL(%rax) -+ movl %fs:(%rax), %eax -+ ret -+ .size main, .-main -+ .section .note.GNU-stack,"",@progbits -diff --git a/ld/testsuite/ld-x86-64/gnu2-tls-1a.rd b/ld/testsuite/ld-x86-64/gnu2-tls-1a.rd -new file mode 100644 -index 00000000000..3eb926a227c ---- /dev/null -+++ b/ld/testsuite/ld-x86-64/gnu2-tls-1a.rd -@@ -0,0 +1,7 @@ -+#... -+Version needs section '.gnu.version_r' contains 1 entry: -+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\) -+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+ -+#... -+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+ -+#pass -diff --git a/ld/testsuite/ld-x86-64/gnu2-tls-1b.rd b/ld/testsuite/ld-x86-64/gnu2-tls-1b.rd -new file mode 100644 -index 00000000000..33ef8acb232 ---- /dev/null -+++ b/ld/testsuite/ld-x86-64/gnu2-tls-1b.rd -@@ -0,0 +1,4 @@ -+#failif -+#... -+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+ -+#... -diff --git a/ld/testsuite/ld-x86-64/mark-plt-2.rd b/ld/testsuite/ld-x86-64/mark-plt-2.rd -new file mode 100644 -index 00000000000..b0ed7024420 ---- /dev/null -+++ b/ld/testsuite/ld-x86-64/mark-plt-2.rd -@@ -0,0 +1,7 @@ -+#... -+Version needs section '.gnu.version_r' contains 1 entry: -+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\) -+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+ -+#... -+ 0x[a-f0-9]+: Name: (GLIBC_2.36|GLIBC_ABI_DT_X86_64_PLT) Flags: none Version: [0-9]+ -+#pass -diff --git a/ld/testsuite/ld-x86-64/mark-plt-2.s b/ld/testsuite/ld-x86-64/mark-plt-2.s -new file mode 100644 -index 00000000000..c816567c204 ---- /dev/null -+++ b/ld/testsuite/ld-x86-64/mark-plt-2.s -@@ -0,0 +1,13 @@ -+ .text -+ .globl foo -+ .type foo, @function -+foo: -+ subq $8, %rsp -+ leaq xxx@TLSDESC(%rip), %rax -+ .nops 10 -+ call *xxx@TLSCALL(%rax) -+ movl %fs:(%rax), %eax -+ addq $8, %rsp -+ call bar -+ ret -+ .section .note.GNU-stack,"",@progbits -diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp -index a72a7da12c1..25480f70185 100644 ---- a/ld/testsuite/ld-x86-64/x86-64.exp -+++ b/ld/testsuite/ld-x86-64/x86-64.exp -@@ -2360,7 +2360,7 @@ run_dump_test "ibt-plt-3b-x32" - run_dump_test "ibt-plt-3c-x32" - run_dump_test "ibt-plt-3d-x32" - --# Skip -z mark-plt tests on MUSL. -+# Skip -z mark-plt and --gnu2-tls-tag tests on MUSL. - if { [istarget "x86_64-*-musl*"]} { - set ASFLAGS "$saved_ASFLAGS" - return -@@ -2386,6 +2386,30 @@ if { [check_compiler_available] } { - {readelf {-W --version-info} mark-plt-1b.rd}} \ - "mark-plt-1.so" \ - ] \ -+ [list \ -+ "Build mark-plt-2.so" \ -+ "-shared -Wl,--no-as-needed,-z,mark-plt,-z,nopack-relative-relocs" \ -+ "-fPIC" \ -+ { mark-plt-2.s } \ -+ {{readelf {-W --version-info} mark-plt-2.rd}} \ -+ "mark-plt-2.so" \ -+ ] \ -+ [list \ -+ "Build gnu2-tls-1a.so" \ -+ "-shared -Wl,--no-as-needed,--gnu2-tls-tag" \ -+ "-fPIC" \ -+ { gnu2-tls-1.s } \ -+ {{readelf {-W --version-info} gnu2-tls-1a.rd}} \ -+ "gnu2-tls-1a.so" \ -+ ] \ -+ [list \ -+ "Build gnu2-tls-1b.so" \ -+ "-shared -Wl,--no-as-needed,--no-gnu2-tls-tag" \ -+ "-fPIC" \ -+ { gnu2-tls-1.s } \ -+ {{readelf {-W --version-info} gnu2-tls-1b.rd}} \ -+ "gnu2-tls-1b.so" \ -+ ] \ - ] - } - --- -2.50.1 - diff --git a/9999/0008-x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-version-dependenc.patch b/9999/0008-x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-version-dependenc.patch deleted file mode 100644 index c9c7175..0000000 --- a/9999/0008-x86-64-Add-GLIBC_ABI_DT_X86_64_PLT-version-dependenc.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 9269afaad66f2d88126768e4c647ba711117bcca Mon Sep 17 00:00:00 2001 -Message-ID: <9269afaad66f2d88126768e4c647ba711117bcca.1755548203.git....@gentoo.org> -In-Reply-To: <40fd19259a3b9a576bedba9f9ce236d2f1b42da9.1755548203.git....@gentoo.org> -References: <40fd19259a3b9a576bedba9f9ce236d2f1b42da9.1755548203.git....@gentoo.org> -From: "H.J. Lu" <[email protected]> -Date: Mon, 18 Aug 2025 13:13:21 -0700 -Subject: [PATCH 2/3] x86-64: Add GLIBC_ABI_DT_X86_64_PLT version dependency - -On Linux/x86-64, programs and shared libraries created with -z mark-plt -have the GLIBC_2.36 version tag dependency since -z mark-plt uses the -r_addend field of the R_X86_64_JUMP_SLOT relocation to store the offset -of the indirect branch instruction. Glibc versions which don't have the -commit added to glibc 2.36: - -commit f8587a61892cbafd98ce599131bf4f103466f084 -Author: H.J. Lu <[email protected]> -Date: Fri May 20 19:21:48 2022 -0700 - - x86-64: Ignore r_addend for R_X86_64_GLOB_DAT/R_X86_64_JUMP_SLOT - -won't ignore the r_addend value in the R_X86_64_JUMP_SLOT relocation. If -glibc versions defines GLIBC_ABI_DT_X86_64_PLT version tag with - -commit 399384e0c8193e31aea014220ccfa24300ae5938 -Author: H.J. Lu <[email protected]> -Date: Thu Aug 14 07:03:20 2025 -0700 - - x86-64: Add GLIBC_ABI_DT_X86_64_PLT [BZ #33212] - -to indicate inclusion of the commit: - -commit f8587a61892cbafd98ce599131bf4f103466f084 -Author: H.J. Lu <[email protected]> -Date: Fri May 20 19:21:48 2022 -0700 - - x86-64: Ignore r_addend for R_X86_64_GLOB_DAT/R_X86_64_JUMP_SLOT - -we can add GLIBC_ABI_DT_X86_64_PLT version tag dependency, instead of -GLIBC_2.36 version tag dependency. - - PR ld/33213 - * elf-bfd.h (_bfd_elf_link_add_glibc_version_dependency): Change - return type to bool. - * elf64-x86-64.c (elf_x86_64_add_glibc_version_dependency): Add - GLIBC_ABI_DT_X86_64_PLT version tag dependency, instead of, - GLIBC_2.36 version tag dependency, for -z mark-plt if libc.so - defines GLIBC_ABI_DT_X86_64_PLT version tag. - * elflink.c (_bfd_elf_link_add_glibc_version_dependency): Change - return type to bool. Return false if elf_link_add_glibc_verneed - returns false. - -Signed-off-by: H.J. Lu <[email protected]> ---- - bfd/elf-bfd.h | 2 +- - bfd/elf64-x86-64.c | 24 +++++++++++++++++++----- - bfd/elflink.c | 6 ++++-- - ld/testsuite/ld-x86-64/mark-plt-1a.rd | 2 +- - 4 files changed, 25 insertions(+), 9 deletions(-) - -diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h -index feb470fc477..de7cc410a99 100644 ---- a/bfd/elf-bfd.h -+++ b/bfd/elf-bfd.h -@@ -2631,7 +2631,7 @@ extern bool _bfd_elf_link_output_relocs - (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, - struct elf_link_hash_entry **); - --extern void _bfd_elf_link_add_glibc_version_dependency -+extern bool _bfd_elf_link_add_glibc_version_dependency - (struct elf_find_verdep_info *, const char *const [], bool *); - - extern void _bfd_elf_link_add_dt_relr_dependency -diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c -index edfa608d2d7..31a4b0ce489 100644 ---- a/bfd/elf64-x86-64.c -+++ b/bfd/elf64-x86-64.c -@@ -6246,7 +6246,7 @@ static void - elf_x86_64_add_glibc_version_dependency - (struct elf_find_verdep_info *rinfo) - { -- unsigned int i = 0; -+ int i = 0, mark_plt = -1; - const char *version[4] = { NULL, NULL, NULL, NULL }; - bool auto_version[4] = { false, false, false, false }; - struct elf_x86_link_hash_table *htab; -@@ -6271,14 +6271,28 @@ elf_x86_64_add_glibc_version_dependency - } - if (htab->params->mark_plt) - { -- version[i] = "GLIBC_2.36"; -+ mark_plt = i; -+ auto_version[i] = true; -+ version[i] = "GLIBC_ABI_DT_X86_64_PLT"; - i++; - } - } - -- if (i != 0) -- _bfd_elf_link_add_glibc_version_dependency (rinfo, version, -- auto_version); -+ if (i == 0 -+ || !_bfd_elf_link_add_glibc_version_dependency (rinfo, version, -+ auto_version)) -+ return; -+ -+ if (mark_plt < 0 || auto_version[mark_plt]) -+ return; -+ -+ /* Add the GLIBC_2.36 version dependency if libc.so doesn't have -+ GLIBC_ABI_DT_X86_64_PLT. */ -+ version[0] = "GLIBC_2.36"; -+ auto_version[0] = false; -+ version[1] = NULL; -+ _bfd_elf_link_add_glibc_version_dependency (rinfo, version, -+ auto_version); - } - - static const struct bfd_elf_special_section -diff --git a/bfd/elflink.c b/bfd/elflink.c -index ac40423751f..98759a3dec6 100644 ---- a/bfd/elflink.c -+++ b/bfd/elflink.c -@@ -2401,7 +2401,7 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo, - /* Add VERSION_DEP to the list of version dependencies when linked - against glibc. */ - --void -+bool - _bfd_elf_link_add_glibc_version_dependency - (struct elf_find_verdep_info *rinfo, - const char *const version_dep[], -@@ -2414,11 +2414,13 @@ _bfd_elf_link_add_glibc_version_dependency - /* Return if not linked against glibc. */ - if (!elf_link_add_glibc_verneed (rinfo, *version_dep, - &glibc_minor_base, auto_version)) -- return; -+ return false; - version_dep++; - auto_version++; - } - while (*version_dep != NULL); -+ -+ return true; - } - - /* Add GLIBC_ABI_DT_RELR to the list of version dependencies when -diff --git a/ld/testsuite/ld-x86-64/mark-plt-1a.rd b/ld/testsuite/ld-x86-64/mark-plt-1a.rd -index 1234fbe038c..b0ed7024420 100644 ---- a/ld/testsuite/ld-x86-64/mark-plt-1a.rd -+++ b/ld/testsuite/ld-x86-64/mark-plt-1a.rd -@@ -3,5 +3,5 @@ Version needs section '.gnu.version_r' contains 1 entry: - Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\) - +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+ - #... -- 0x[a-f0-9]+: Name: GLIBC_2.36 Flags: none Version: [0-9]+ -+ 0x[a-f0-9]+: Name: (GLIBC_2.36|GLIBC_ABI_DT_X86_64_PLT) Flags: none Version: [0-9]+ - #pass --- -2.50.1 - diff --git a/9999/0009-i386-Add-GLIBC_ABI_GNU_TLS-version-dependency.patch b/9999/0009-i386-Add-GLIBC_ABI_GNU_TLS-version-dependency.patch deleted file mode 100644 index 8a758c8..0000000 --- a/9999/0009-i386-Add-GLIBC_ABI_GNU_TLS-version-dependency.patch +++ /dev/null @@ -1,470 +0,0 @@ -From 7a3c2c05795a290a1436e0ca0f21514325c8ef44 Mon Sep 17 00:00:00 2001 -Message-ID: <7a3c2c05795a290a1436e0ca0f21514325c8ef44.1755548203.git....@gentoo.org> -In-Reply-To: <40fd19259a3b9a576bedba9f9ce236d2f1b42da9.1755548203.git....@gentoo.org> -References: <40fd19259a3b9a576bedba9f9ce236d2f1b42da9.1755548203.git....@gentoo.org> -From: "H.J. Lu" <[email protected]> -Date: Mon, 18 Aug 2025 13:13:22 -0700 -Subject: [PATCH 3/3] i386: Add GLIBC_ABI_GNU_TLS version dependency - -On Linux/i386, programs and shared libraries compiled with --mtls-dialect=gnu may fail silently at run-time against glibc without -the GNU TLS run-time fix for: - -https://sourceware.org/bugzilla/show_bug.cgi?id=32996 - -The glibc version tag, GLIBC_ABI_GNU_TLS, has been added to indicate -that glibc has the working GNU TLS run-time: - -commit ed1b7a5a489ab555a27fad9c101ebe2e1c1ba881 -Author: H.J. Lu <[email protected]> -Date: Mon Jul 28 12:16:11 2025 -0700 - - i386: Add GLIBC_ABI_GNU_TLS version [BZ #33221] - -Add the --gnu-tls-tag option to x86-64 ELF linker to add the -GLIBC_ABI_GNU_TLS version dependency in output programs and shared -libraries when linking against glibc if input relocatable object files -call ___tls_get_addr. The output will fail to load and run at run-time -against glibc which doesn't define the GLIBC_ABI_GNU_TLS version. - -Add the --enable-gnu-tls-tag configure option to enable --gnu-tls-tag -by default. If unspecified, linker will add the GLIBC_ABI_GNU_TLS -version dependency if input call ___tls_get_addr and libc.so defines -the GLIBC_ABI_GNU2_TLS version. - -bfd/ - - PR ld/33287 - * elf-linker-x86.h (elf_linker_x86_params): Add - gnu_tls_version_tag. - * elf32-i386.c (elf_backend_add_glibc_version_dependency): Add - GLIBC_ABI_GNU_TLS support. - * elfxx-x86.c (_bfd_x86_elf_link_check_relocs): Set - has_tls_get_addr_call to 1 if ___tls_get_addr is used. - * elfxx-x86.h (elf_x86_link_hash_table): Add has_tls_get_addr_call. - -ld/ - - PR ld/33287 - * Mention --gnu-tls-tag, --no-gnu-tls-tag and --enable-gnu-tls-tag. - * config.in: Regenerated. - * configure: Likewise. - * configure.ac: Add --enable-gnu-tls-tag. - * ld.texi: Document --gnu-tls-tag and --enable-gnu-tls-tag. - * ldlex.h (option_values): Add OPTION_GNU_TLS_VERSION_TAG and - OPTION_NO_GNU_TLS_VERSION_TAG. - * emultempl/elf-i386-glibc.em (elf_i386_glibc_before_parse): - Initialize params.gnu_tls_version_tag. - (PARSE_AND_LIST_LONGOPTS_386): New. - (PARSE_AND_LIST_OPTIONS_386): Likewise. - (PARSE_AND_LIST_ARGS_CASES_386): Likewise. - (PARSE_AND_LIST_LONGOPTS): Append $PARSE_AND_LIST_LONGOPTS_386. - (PARSE_AND_LIST_OPTIONS): Append $PARSE_AND_LIST_OPTIONS_386. - (PARSE_AND_LIST_ARGS_CASES): Append - $PARSE_AND_LIST_ARGS_CASES_386. - * testsuite/ld-i386/gnu-tls-1.s: Likewise. - * testsuite/ld-i386/gnu-tls-1a.rd: Likewise. - * testsuite/ld-i386/gnu-tls-1b.rd: Likewise. - * testsuite/ld-i386/i386.exp: Run PR ld/33287 tests. - -Signed-off-by: H.J. Lu <[email protected]> ---- - bfd/elf-linker-x86.h | 9 ++++++++ - bfd/elf32-i386.c | 14 ++++++++++-- - bfd/elfxx-x86.c | 2 ++ - bfd/elfxx-x86.h | 3 +++ - ld/NEWS | 5 +++++ - ld/config.in | 4 ++++ - ld/configure | 28 +++++++++++++++++++++-- - ld/configure.ac | 19 ++++++++++++++++ - ld/emultempl/elf-i386-glibc.em | 36 ++++++++++++++++++++++++++++++ - ld/ld.texi | 13 +++++++++++ - ld/ldlex.h | 3 +++ - ld/testsuite/ld-i386/gnu-tls-1.s | 9 ++++++++ - ld/testsuite/ld-i386/gnu-tls-1a.rd | 7 ++++++ - ld/testsuite/ld-i386/gnu-tls-1b.rd | 4 ++++ - ld/testsuite/ld-i386/i386.exp | 18 ++++++++++++++- - 15 files changed, 169 insertions(+), 5 deletions(-) - create mode 100644 ld/testsuite/ld-i386/gnu-tls-1.s - create mode 100644 ld/testsuite/ld-i386/gnu-tls-1a.rd - create mode 100644 ld/testsuite/ld-i386/gnu-tls-1b.rd - -diff --git a/bfd/elf-linker-x86.h b/bfd/elf-linker-x86.h -index fe322152e14..cdd739e572a 100644 ---- a/bfd/elf-linker-x86.h -+++ b/bfd/elf-linker-x86.h -@@ -80,6 +80,15 @@ struct elf_linker_x86_params - */ - unsigned int gnu2_tls_version_tag : 2; - -+ /* Add the GLIBC_ABI_GNU_TLS version dependency if input object files -+ call ___tls_get_addr: -+ 0: Disable. -+ 1: Enable. -+ 2: Auto. Enable if libc.so has the GLIBC_ABI_GNU_TLS version. -+ This is only used by i386. -+ */ -+ unsigned int gnu_tls_version_tag : 2; -+ - /* X86-64 ISA level needed. */ - unsigned int isa_level; - -diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c -index c1115a52d1b..3f1a0b14577 100644 ---- a/bfd/elf32-i386.c -+++ b/bfd/elf32-i386.c -@@ -4501,8 +4501,8 @@ elf_i386_add_glibc_version_dependency - (struct elf_find_verdep_info *rinfo) - { - int i = 0; -- const char *version[3] = { NULL, NULL, NULL }; -- bool auto_version[3] = { false, false, false }; -+ const char *version[4] = { NULL, NULL, NULL, NULL }; -+ bool auto_version[4] = { false, false, false, false }; - struct elf_x86_link_hash_table *htab; - - if (rinfo->info->enable_dt_relr) -@@ -4523,6 +4523,16 @@ elf_i386_add_glibc_version_dependency - auto_version[i] = true; - i++; - } -+ if (htab->params->gnu_tls_version_tag -+ && htab->has_tls_get_addr_call) -+ { -+ version[i] = "GLIBC_ABI_GNU_TLS"; -+ /* 2 == auto, enable if libc.so defines the GLIBC_ABI_GNU_TLS -+ version. */ -+ if (htab->params->gnu_tls_version_tag == 2) -+ auto_version[i] = true; -+ i++; -+ } - } - - if (i != 0) -diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c -index e2c61b85fc6..3de48397e78 100644 ---- a/bfd/elfxx-x86.c -+++ b/bfd/elfxx-x86.c -@@ -882,6 +882,8 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - elf_x86_hash_entry (h)->tls_get_addr = 1; - } -+ -+ htab->has_tls_get_addr_call = 1; - } - - /* Pass NULL for __ehdr_start which will be defined by -diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h -index 791a2a2592f..2a28987f208 100644 ---- a/bfd/elfxx-x86.h -+++ b/bfd/elfxx-x86.h -@@ -674,6 +674,9 @@ struct elf_x86_link_hash_table - relocation. */ - unsigned int has_tls_desc_call : 1; - -+ /* TRUE if inputs call ___tls_get_addr. This is only used for i386. */ -+ unsigned int has_tls_get_addr_call : 1; -+ - /* Value used to fill the unused bytes of the first PLT entry. This - is only used for i386. */ - bfd_byte plt0_pad_byte; -diff --git a/ld/NEWS b/ld/NEWS -index bacabc8440e..8794e883522 100644 ---- a/ld/NEWS -+++ b/ld/NEWS -@@ -1,5 +1,10 @@ - -*- text -*- - -+* Add --gnu-tls-tag/--no-gnu-tls-tag options to i386 ELF linker to add -+ the GLIBC_ABI_GNU_TLS version dependency in output if input object -+ files call ___tls_get_addr. Also added --enable-gnu-tls-tag configure -+ option to enable --gnu-tls-tag by default. -+ - * Add --gnu2-tls-tag/--no-gnu2-tls-tag options to i386 and x86-64 ELF - linkers to add the GLIBC_ABI_GNU2_TLS version dependency in output if - input object files have R_386_TLS_DESC_CALL or R_X86_64_TLSDESC_CALL -diff --git a/ld/config.in b/ld/config.in -index 64dbc3e0c88..790efd336be 100644 ---- a/ld/config.in -+++ b/ld/config.in -@@ -35,6 +35,10 @@ - by default. */ - #undef DEFAULT_LD_GNU2_TLS_TAG - -+/* Define to 1 if you want to enable --gnu-tls-tag in ELF i386 linker by -+ default. */ -+#undef DEFAULT_LD_GNU_TLS_TAG -+ - /* Define to 1 if you want to enable --rosegment in the ELF linker by default. - */ - #undef DEFAULT_LD_ROSEGMENT -diff --git a/ld/configure b/ld/configure -index 6f1a3559964..fe23178cd29 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -852,6 +852,7 @@ enable_separate_code - enable_rosegment - enable_mark_plt - enable_gnu2_tls_tag -+enable_gnu_tls_tag - enable_memory_seal - enable_warn_execstack - enable_error_execstack -@@ -1551,6 +1552,7 @@ Optional Features: - --enable-mark-plt enable -z mark-plt in ELF x86-64 linker by default - --enable-gnu2-tls-tag enable --gnu2-tls-tag in ELF i386/x86-64 linker by - default -+ --enable-gnu-tls-tag enable --gnu-tls-tag in ELF i386 linker by default - --enable-memory-seal enable -z memory-seal in ELF linker by default - --enable-warn-execstack enable warnings when creating an executable stack - --enable-error-execstack -@@ -11517,7 +11519,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11520 "configure" -+#line 11522 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11623,7 +11625,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11626 "configure" -+#line 11628 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -15522,6 +15524,17 @@ esac - fi - - -+# Decide if --gnu-tls-tag should be enabled in ELF i386 linker by default. -+ac_default_ld_enable_gnu_tls_tag=unset -+# Check whether --enable-gnu-tls-tag was given. -+if test "${enable_gnu_tls_tag+set}" = set; then : -+ enableval=$enable_gnu_tls_tag; case "${enableval}" in -+ yes) ac_default_ld_enable_gnu_tls_tag=1 ;; -+ no) ac_default_ld_enable_gnu_tls_tag=0 ;; -+esac -+fi -+ -+ - # Decide if -z memory-seal should be enabled in ELF linker by default. - ac_default_ld_z_memory_seal=unset - # Check whether --enable-memory-seal was given. -@@ -19007,6 +19020,17 @@ cat >>confdefs.h <<_ACEOF - _ACEOF - - -+if test "${ac_default_ld_enable_gnu_tls_tag}" = unset; then -+ # Default to enable --gnu-tls-tag if libc.so has the GLIBC_ABI_GNU_TLS -+ # version. -+ ac_default_ld_enable_gnu_tls_tag=2 -+fi -+ -+cat >>confdefs.h <<_ACEOF -+#define DEFAULT_LD_GNU_TLS_TAG $ac_default_ld_enable_gnu_tls_tag -+_ACEOF -+ -+ - - cat >>confdefs.h <<_ACEOF - #define DEFAULT_LD_WARN_EXECSTACK $ac_default_ld_warn_execstack -diff --git a/ld/configure.ac b/ld/configure.ac -index 4b9068a415e..3e44e3361ef 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -256,6 +256,16 @@ AC_ARG_ENABLE(gnu2-tls-tag, - no) ac_default_ld_enable_gnu2_tls_tag=0 ;; - esac]) - -+# Decide if --gnu-tls-tag should be enabled in ELF i386 linker by default. -+ac_default_ld_enable_gnu_tls_tag=unset -+AC_ARG_ENABLE(gnu-tls-tag, -+ AS_HELP_STRING([--enable-gnu-tls-tag], -+ [enable --gnu-tls-tag in ELF i386 linker by default]), -+[case "${enableval}" in -+ yes) ac_default_ld_enable_gnu_tls_tag=1 ;; -+ no) ac_default_ld_enable_gnu_tls_tag=0 ;; -+esac]) -+ - # Decide if -z memory-seal should be enabled in ELF linker by default. - ac_default_ld_z_memory_seal=unset - AC_ARG_ENABLE(memory-seal, -@@ -666,6 +676,15 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_GNU2_TLS_TAG, - $ac_default_ld_enable_gnu2_tls_tag, - [Define to 1 if you want to enable --gnu2-tls-tag in ELF i386/x86-64 linker by default.]) - -+if test "${ac_default_ld_enable_gnu_tls_tag}" = unset; then -+ # Default to enable --gnu-tls-tag if libc.so has the GLIBC_ABI_GNU_TLS -+ # version. -+ ac_default_ld_enable_gnu_tls_tag=2 -+fi -+AC_DEFINE_UNQUOTED(DEFAULT_LD_GNU_TLS_TAG, -+ $ac_default_ld_enable_gnu_tls_tag, -+ [Define to 1 if you want to enable --gnu-tls-tag in ELF i386 linker by default.]) -+ - AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_EXECSTACK, - $ac_default_ld_warn_execstack, - [Define to 1 if you want to enable --warn-execstack in ELF linker by default.]) -diff --git a/ld/emultempl/elf-i386-glibc.em b/ld/emultempl/elf-i386-glibc.em -index 547823750a4..26a7296cf76 100644 ---- a/ld/emultempl/elf-i386-glibc.em -+++ b/ld/emultempl/elf-i386-glibc.em -@@ -35,7 +35,43 @@ elf_i386_glibc_before_parse (void) - { - elf_x86_before_parse (); - elf_x86_glibc_before_parse (); -+ params.gnu_tls_version_tag = DEFAULT_LD_GNU_TLS_TAG; - } - EOF - - LDEMUL_BEFORE_PARSE=elf_i386_glibc_before_parse -+ -+PARSE_AND_LIST_LONGOPTS_386=' -+ { "gnu-tls-tag", no_argument, NULL, OPTION_GNU_TLS_VERSION_TAG }, -+ { "no-gnu-tls-tag", no_argument, NULL, OPTION_NO_GNU_TLS_VERSION_TAG }, -+' -+ -+PARSE_AND_LIST_OPTIONS_386=' -+ if (DEFAULT_LD_GNU_TLS_TAG == 0) -+ fprintf (file, _("\ -+ --gnu-tls-tag Add GLIBC_ABI_GNU_TLS dependency\n\ -+ --no-gnu-tls-tag Do not add GLIBC_ABI_GNU_TLS dependency (default)\n")); -+ else if (DEFAULT_LD_GNU_TLS_TAG == 1) -+ fprintf (file, _("\ -+ --gnu-tls-tag Add GLIBC_ABI_GNU_TLS dependency (default)\n\ -+ --no-gnu-tls-tag Do not add GLIBC_ABI_GNU_TLS dependency\n")); -+ else -+ fprintf (file, _("\ -+ --gnu-tls-tag Add GLIBC_ABI_GNU_TLS dependency (auto)\n\ -+ when no options are specified (default)\n\ -+ --no-gnu-tls-tag Do not add GLIBC_ABI_GNU_TLS dependency\n")); -+' -+ -+PARSE_AND_LIST_ARGS_CASES_386=' -+ case OPTION_GNU_TLS_VERSION_TAG: -+ params.gnu_tls_version_tag = 1; -+ break; -+ -+ case OPTION_NO_GNU_TLS_VERSION_TAG: -+ params.gnu_tls_version_tag = 0; -+ break; -+' -+ -+PARSE_AND_LIST_LONGOPTS="$PARSE_AND_LIST_LONGOPTS $PARSE_AND_LIST_LONGOPTS_386" -+PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_386" -+PARSE_AND_LIST_ARGS_CASES="$PARSE_AND_LIST_ARGS_CASES $PARSE_AND_LIST_ARGS_CASES_386" -diff --git a/ld/ld.texi b/ld/ld.texi -index 0e13f7d8e35..cf750d15259 100644 ---- a/ld/ld.texi -+++ b/ld/ld.texi -@@ -1745,6 +1745,19 @@ Supported for Linux/i386 and Linux/x86_64. - - Other keywords are ignored for Solaris compatibility. - -+@item --gnu-tls-tag -+@itemx --no-gnu-tls-tag -+Add @code{GLIBC_ABI_GNU_TLS} version tag dependency in output programs -+and shared libraries when linking against glibc if input relocatable -+object files call @code{___tls_get_addr}. The output will fail to load -+and run at run-time against glibc which doesn't define the -+@code{GLIBC_ABI_GNU_TLS} version tag. Unless disabled by the -+@option{--disable-gnu-tls-tag} configure option at the linker build -+time, when no options are specified, linker will add the -+@code{GLIBC_ABI_GNU_TLS} version tag dependency if inputs have -+@code{___tls_get_addr} call and libc.so defines the -+@code{GLIBC_ABI_GNU_TLS} version tag. Supported for Linux/i386. -+ - @item --gnu2-tls-tag - @itemx --no-gnu2-tls-tag - Add @code{GLIBC_ABI_GNU2_TLS} version tag dependency in output programs -diff --git a/ld/ldlex.h b/ld/ldlex.h -index 286ab0ba6d1..c8d61478c60 100644 ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -474,6 +474,9 @@ enum option_values - /* Used by emultempl/elf-x86-glibc.em. */ - OPTION_GNU2_TLS_VERSION_TAG, - OPTION_NO_GNU2_TLS_VERSION_TAG, -+ /* Used by emultempl/elf-i386-glibc.em. */ -+ OPTION_GNU_TLS_VERSION_TAG, -+ OPTION_NO_GNU_TLS_VERSION_TAG, - }; - - /* The initial parser states. */ -diff --git a/ld/testsuite/ld-i386/gnu-tls-1.s b/ld/testsuite/ld-i386/gnu-tls-1.s -new file mode 100644 -index 00000000000..02ae207a9b5 ---- /dev/null -+++ b/ld/testsuite/ld-i386/gnu-tls-1.s -@@ -0,0 +1,9 @@ -+ .text -+ .p2align 4 -+ .globl func -+ .type func, @function -+func: -+ leal foo@tlsgd(,%ebx,1), %eax -+ call ___tls_get_addr@PLT -+ ret -+ .section .note.GNU-stack,"",@progbits -diff --git a/ld/testsuite/ld-i386/gnu-tls-1a.rd b/ld/testsuite/ld-i386/gnu-tls-1a.rd -new file mode 100644 -index 00000000000..65d889de7d9 ---- /dev/null -+++ b/ld/testsuite/ld-i386/gnu-tls-1a.rd -@@ -0,0 +1,7 @@ -+#... -+Version needs section '.gnu.version_r' contains [0-9]+ entries: -+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\) -+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+ -+#... -+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU_TLS Flags: none Version: [0-9]+ -+#pass -diff --git a/ld/testsuite/ld-i386/gnu-tls-1b.rd b/ld/testsuite/ld-i386/gnu-tls-1b.rd -new file mode 100644 -index 00000000000..02006e47da1 ---- /dev/null -+++ b/ld/testsuite/ld-i386/gnu-tls-1b.rd -@@ -0,0 +1,4 @@ -+#failif -+#... -+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU_TLS Flags: none Version: [0-9]+ -+#... -diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp -index 74ef1672f86..2b6a36e63f8 100644 ---- a/ld/testsuite/ld-i386/i386.exp -+++ b/ld/testsuite/ld-i386/i386.exp -@@ -1516,10 +1516,26 @@ run_ld_link_tests [list \ - ] \ - ] - --# The musl C library does not support --gnu2-tls-tag. -+# The musl C library does not support --gnu-tls-tag nor --gnu2-tls-tag. - if { ![istarget *-*-musl] - && [check_compiler_available] } { - run_cc_link_tests [list \ -+ [list \ -+ "Build gnu-tls-1a.so" \ -+ "-shared -Wl,--no-as-needed,--gnu-tls-tag" \ -+ "-fPIC" \ -+ { gnu-tls-1.s } \ -+ {{readelf {-W --version-info} gnu-tls-1a.rd}} \ -+ "gnu-tls-1a.so" \ -+ ] \ -+ [list \ -+ "Build gnu-tls-1b.so" \ -+ "-shared -Wl,--no-as-needed,--no-gnu-tls-tag" \ -+ "-fPIC" \ -+ { gnu-tls-1.s } \ -+ {{readelf {-W --version-info} gnu-tls-1b.rd}} \ -+ "gnu-tls-1b.so" \ -+ ] \ - [list \ - "Build gnu2-tls-1a.so" \ - "-shared -Wl,--no-as-needed,--gnu2-tls-tag" \ --- -2.50.1 -
