x86: Copy non_got_ref_without_indirect_extern_access
Commit Message
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 (NO_DIRECT_EXTERN_ACCESS_CFLAGS):
New.
* 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>
---
bfd/elfxx-x86.c | 6 ++++++
ld/testsuite/config/default.exp | 3 +++
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 | 26 ++++++++++++++++++++++++++
6 files changed, 68 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
Comments
On Tue, Sep 9, 2025 at 6:44 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> 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 (NO_DIRECT_EXTERN_ACCESS_CFLAGS):
> New.
> * 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>
This is the patch I am checking in.
Hi,
The test case added by this patch fails on LoongArch:
FAIL: Run pr33409.
This is because LoongArch's `-mdirect-extern-access` is only suitable
for environments where no dynamic link is performed, like firmwares, OS
kernels, and executables linked with `-static` or `-static-pie`.
On 9/10/25 9:44 AM, H.J. Lu wrote:
> 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 (NO_DIRECT_EXTERN_ACCESS_CFLAGS):
> New.
> * 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>
> ---
> bfd/elfxx-x86.c | 6 ++++++
> ld/testsuite/config/default.exp | 3 +++
> 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 | 26 ++++++++++++++++++++++++++
> 6 files changed, 68 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 58a83173827..06265ee4e15 100644
> --- a/bfd/elfxx-x86.c
> +++ b/bfd/elfxx-x86.c
> @@ -3155,6 +3155,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 3619f523762..fae7d72d7e0 100644
> --- a/ld/testsuite/config/default.exp
> +++ b/ld/testsuite/config/default.exp
> @@ -458,10 +458,13 @@ 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"
> }
> }
>
> diff --git a/ld/testsuite/ld-elf/pr33409a.c b/ld/testsuite/ld-elf/pr33409a.c
> new file mode 100644
> index 00000000000..1c8642ccc0b
> --- /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..3d26efbb983
> --- /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"))) __attribute__ ((__copy__ (__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 a24525a2ff8..228e58f7ae3 100644
> --- a/ld/testsuite/ld-elf/shared.exp
> +++ b/ld/testsuite/ld-elf/shared.exp
> @@ -1016,6 +1016,21 @@ 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 \
> @@ -1206,6 +1221,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.
On Thu, Sep 18, 2025 at 12:03 AM Lulu Cai <cailulu@loongson.cn> wrote:
>
> Hi,
> The test case added by this patch fails on LoongArch:
> FAIL: Run pr33409.
> This is because LoongArch's `-mdirect-extern-access` is only suitable
> for environments where no dynamic link is performed, like firmwares, OS
> kernels, and executables linked with `-static` or `-static-pie`.
Please try the enclosed patch.
> On 9/10/25 9:44 AM, H.J. Lu wrote:
> > 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 (NO_DIRECT_EXTERN_ACCESS_CFLAGS):
> > New.
> > * 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.
> >
--
H.J.
On 9/18/25 8:00 PM, H.J. Lu wrote:
> On Thu, Sep 18, 2025 at 12:03 AM Lulu Cai <cailulu@loongson.cn> wrote:
>> Hi,
>> The test case added by this patch fails on LoongArch:
>> FAIL: Run pr33409.
>> This is because LoongArch's `-mdirect-extern-access` is only suitable
>> for environments where no dynamic link is performed, like firmwares, OS
>> kernels, and executables linked with `-static` or `-static-pie`.
> Please try the enclosed patch.
It works, thank you.
>> On 9/10/25 9:44 AM, H.J. Lu wrote:
>>> 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 (NO_DIRECT_EXTERN_ACCESS_CFLAGS):
>>> New.
>>> * 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.
>>>
>
> --
> H.J.
@@ -3155,6 +3155,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
@@ -458,10 +458,13 @@ 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"
}
}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+char *__array [] =
+{
+ "PASS",
+ NULL
+};
+
+extern __typeof (__array) array __attribute__ ((weak, alias ("__array"))) __attribute__ ((__copy__ (__array)));
new file mode 100644
@@ -0,0 +1,4 @@
+void
+bar (void)
+{
+}
@@ -1016,6 +1016,21 @@ 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 \
@@ -1206,6 +1221,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.