[binutils-gdb] make ld -u symbols load --as-needed shared libraries

Alan Modra amodra@sourceware.org
Thu Sep 10 08:41:44 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5b57b7393a1e84aa6017e9e419b47e5f4f5ce4aa

commit 5b57b7393a1e84aa6017e9e419b47e5f4f5ce4aa
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Sep 10 18:01:45 2026 +0930

    make ld -u symbols load --as-needed shared libraries
    
    This makes --as-needed ELF shared libraries a little more like archives
    in that -u symbols on the command line will mark them as needed.  The
    pr26580-1 testcase that linked a library with a _start definition
    before linking an object defining _start needs the order fixing.
    Otherwise the library will be found needed to satisfy _start,
    destroying the whole purpose of the testcase which was to verify a
    library found not needed would leave common symbol size unchanged.
    I made the same change to pr25680-2 for consistency.
    
            PR 32816
            * ldlang.h (ldlang_ref): Declare.
            * ldlang.c (ldlang_ref): New function.
            (insert_undefined): Use ldlang_ref.
            * ldexp.c (exp_fold_tree_1): Use ldlang_ref.
            * testsuite/ld-elf/comm-data.exp (pr26580-1, pr26580-2): Link
            shared library after pr26580-a.o.

Diff:
---
 ld/ldexp.c                        |  2 +-
 ld/ldlang.c                       | 15 ++++++++++++++-
 ld/ldlang.h                       |  2 ++
 ld/testsuite/ld-elf/comm-data.exp |  4 ++--
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/ld/ldexp.c b/ld/ldexp.c
index 19542ad99c6..60145d635c2 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1301,7 +1301,7 @@ exp_fold_tree_1 (etree_type *tree)
 			{
 			  bfd_copy_link_hash_symbol_type (link_info.output_bfd,
 							  h, expld.assign_src);
-			  expld.assign_src->non_ir_ref_regular = true;
+			  ldlang_ref (expld.assign_src);
 			}
 		    }
 		}
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 8c7ab3eea72..f78c9000149 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -4252,6 +4252,19 @@ ldlang_add_undef (const char *const name, bool cmdline ATTRIBUTE_UNUSED)
     insert_undefined (new_undef->name);
 }
 
+/* Mark symbol as referenced.  */
+
+void
+ldlang_ref (struct bfd_link_hash_entry *h)
+{
+  h->non_ir_ref_regular = 1;
+  if (is_elf_hash_table (link_info.hash))
+    {
+      ((struct elf_link_hash_entry *) h)->ref_regular = 1;
+      ((struct elf_link_hash_entry *) h)->ref_regular_nonweak = 1;
+    }
+}
+
 /* Insert NAME as undefined in the symbol table.  */
 
 static void
@@ -4266,7 +4279,7 @@ insert_undefined (const char *name)
     {
       h->type = bfd_link_hash_undefined;
       h->u.undef.abfd = NULL;
-      h->non_ir_ref_regular = true;
+      ldlang_ref (h);
       bfd_link_add_undef (link_info.hash, h);
     }
 }
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 2f0bae2beab..dd10ecdfead 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -654,6 +654,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen
   (lang_output_section_statement_type *, int);
 extern void ldlang_add_undef
   (const char *const, bool);
+extern void ldlang_ref
+  (struct bfd_link_hash_entry *h);
 extern void ldlang_add_require_defined
   (const char *const);
 extern void lang_add_output_format
diff --git a/ld/testsuite/ld-elf/comm-data.exp b/ld/testsuite/ld-elf/comm-data.exp
index 07090f63769..2b1f2e60591 100644
--- a/ld/testsuite/ld-elf/comm-data.exp
+++ b/ld/testsuite/ld-elf/comm-data.exp
@@ -122,7 +122,7 @@ run_ld_link_tests [list \
     ] \
     [list \
 	"pr26580-1" \
-	"$LFLAGS --as-needed -Ltmpdir -lpr26580-1" "" \
+	"$LFLAGS --as-needed -Ltmpdir" "-lpr26580-1" \
 	"$AFLAGS" \
 	{ pr26580-a.s } \
 	{ {readelf -s pr26580-1.sd} } \
@@ -130,7 +130,7 @@ run_ld_link_tests [list \
     ] \
     [list \
 	"pr26580-2" \
-	"$LFLAGS --no-as-needed -Ltmpdir -lpr26580-1" "" \
+	"$LFLAGS --no-as-needed -Ltmpdir" "-lpr26580-1" \
 	"$AFLAGS" \
 	{ pr26580-a.s } \
 	{ {readelf -s pr26580-2.sd} } \


More information about the Binutils-cvs mailing list