[2.45] x86: Copy non_got_ref_without_indirect_extern_access

Message ID CAMe9rOp+BdKxvuHOxWZFePE6Zu=R6ExnwazZcKWcJQj84QmMWg@mail.gmail.com
State New
Headers
Series [2.45] x86: Copy non_got_ref_without_indirect_extern_access |

Commit Message

H.J. Lu Sept. 13, 2025, 3:57 p.m. UTC
  Hi Nick,

I am backporting this patch to 2.45 branch.
  

Patch

From 4c56e00c0e0025733bfd102fe932cdd122a9f0cd Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 9 Sep 2025 18:38:49 -0700
Subject: [PATCH] x86: Copy non_got_ref_without_indirect_extern_access

Copy non_got_ref_without_indirect_extern_access when copying indirect
symbol for weak alias so that _bfd_x86_elf_adjust_dynamic_symbol will
properly handle GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.

bfd/

	PR ld/33409
	* elfxx-x86.c (_bfd_x86_elf_copy_indirect_symbol): Copy
	non_got_ref_without_indirect_extern_access.

ld/

	PR ld/33409
	* testsuite/config/default.exp (DIRECT_EXTERN_ACCESS_CFLAGS): New.
	(NO_DIRECT_EXTERN_ACCESS_CFLAGS): Likewise.
	* testsuite/ld-elf/shared.exp: Run PR ld/33409 tests.
	* testsuite/ld-elf/pr33409a.c: New file.
	* testsuite/ld-elf/pr33409b.c: Likewise.
	* testsuite/ld-elf/pr33409c.c: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit 59ada1f6d61bfc7b119f0ae6edcc23dc569e70ad)
---
 bfd/elfxx-x86.c                 |  6 ++++++
 ld/testsuite/config/default.exp | 12 ++++++++++++
 ld/testsuite/ld-elf/pr33409a.c  | 20 ++++++++++++++++++++
 ld/testsuite/ld-elf/pr33409b.c  |  9 +++++++++
 ld/testsuite/ld-elf/pr33409c.c  |  4 ++++
 ld/testsuite/ld-elf/shared.exp  | 25 +++++++++++++++++++++++++
 6 files changed, 76 insertions(+)
 create mode 100644 ld/testsuite/ld-elf/pr33409a.c
 create mode 100644 ld/testsuite/ld-elf/pr33409b.c
 create mode 100644 ld/testsuite/ld-elf/pr33409c.c

diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 3dc00956eef..79baa217524 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -3144,6 +3144,12 @@  _bfd_x86_elf_copy_indirect_symbol (struct bfd_link_info *info,
      generate a R_386_COPY reloc.  */
   edir->gotoff_ref |= eind->gotoff_ref;
 
+  /* Copy non_got_ref_without_indirect_extern_access so that
+     _bfd_x86_elf_adjust_dynamic_symbol will handle
+     GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS properly.  */
+  edir->non_got_ref_without_indirect_extern_access
+    |= eind->non_got_ref_without_indirect_extern_access;
+
   edir->zero_undefweak |= eind->zero_undefweak;
 
   if (ELIMINATE_COPY_RELOCS
diff --git a/ld/testsuite/config/default.exp b/ld/testsuite/config/default.exp
index 1d696811e8e..c10257ba7f3 100644
--- a/ld/testsuite/config/default.exp
+++ b/ld/testsuite/config/default.exp
@@ -447,6 +447,18 @@  if { ![info exists NOPIE_CFLAGS] || ![info exists NOPIE_LDFLAGS] } then {
     }
 }
 
+if { ![info exists DIRECT_EXTERN_ACCESS_CFLAGS] } then {
+    set DIRECT_EXTERN_ACCESS_CFLAGS ""
+    set NO_DIRECT_EXTERN_ACCESS_CFLAGS ""
+    if [compiler_supports "-mdirect-extern-access"] {
+	set DIRECT_EXTERN_ACCESS_CFLAGS "-mdirect-extern-access"
+	set NO_DIRECT_EXTERN_ACCESS_CFLAGS "-mno-direct-extern-access"
+    } elseif [compiler_supports "-fdirect-access-external-data"] {
+	set DIRECT_EXTERN_ACCESS_CFLAGS "-fdirect-access-external-data"
+	set NO_DIRECT_EXTERN_ACCESS_CFLAGS "-fno-direct-access-external-data"
+    }
+}
+
 if { ![info exists NOCF_PROTECTION_CFLAGS] } then {
     set NOCF_PROTECTION_CFLAGS ""
     if [compiler_supports "-fcf-protection=none"] {
diff --git a/ld/testsuite/ld-elf/pr33409a.c b/ld/testsuite/ld-elf/pr33409a.c
new file mode 100644
index 00000000000..c37a5e6aebf
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr33409a.c
@@ -0,0 +1,20 @@ 
+#include <stdio.h>
+
+extern char *array[];
+
+char **
+foo (void)
+{
+  return array;
+}
+
+extern void bar (void);
+
+int
+main()
+{
+  char **p = foo ();
+  bar ();
+  printf ("%s\n", p[0]);
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/pr33409b.c b/ld/testsuite/ld-elf/pr33409b.c
new file mode 100644
index 00000000000..db64e1342c4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr33409b.c
@@ -0,0 +1,9 @@ 
+#include <stdio.h>
+
+char *__array [] =
+{
+  "PASS",
+  NULL
+};
+
+extern __typeof (__array) array __attribute__ ((weak, alias ("__array")));
diff --git a/ld/testsuite/ld-elf/pr33409c.c b/ld/testsuite/ld-elf/pr33409c.c
new file mode 100644
index 00000000000..7de81b31a47
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr33409c.c
@@ -0,0 +1,4 @@ 
+void
+bar (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 09669b5483c..7d44c5468e3 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -1011,6 +1011,20 @@  run_cc_link_tests [list \
 	 {nm {-u -D --with-symbol-versions} pr26302.nd}} \
 	"pr26302b.so" \
     ] \
+    [list \
+	"Build pr33409a.o" \
+	"" \
+	"$DIRECT_EXTERN_ACCESS_CFLAGS" \
+	{pr33409a.c} \
+    ] \
+    [list \
+	"Build pr33409.so" \
+	"-shared" \
+	"-fPIC" \
+	{pr33409b.c} \
+	{} \
+	"pr33409.so" \
+    ] \
 ]
 
 run_ld_link_tests [list \
@@ -1201,6 +1215,17 @@  set run_tests [list \
      "tmpdir/pr31482b-no-lto.so tmpdir/pr31482c-no-lto.a \
       tmpdir/pr31482d-no-lto.a" \
     ] \
+    [list "Run pr33409" \
+     "-Wl,-z,text" \
+     "" \
+     {pr33409c.c} \
+     "pr33409" \
+     "pass.out" \
+     "$NO_DIRECT_EXTERN_ACCESS_CFLAGS" \
+     "c" \
+     "" \
+     "tmpdir/pr33409a.o tmpdir/pr33409.so" \
+    ] \
 ]
 
 # NetBSD ELF systems do not currently support the .*_array sections.
-- 
2.51.0