public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] elf: Don't load archive element after DT_NEEDED dynamic definition
@ 2020-09-07 16:06 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2020-09-07 16:06 UTC (permalink / raw)
  To: binutils

Don't load the archive element after seeing a definition in a DT_NEEDED
shared object.

bfd/

	PR ld/26530
	* elflink.c (elf_link_add_object_symbols): Also preserve the
	as_needed_def_dynamic bit for --as-needed.
	(elf_link_add_archive_symbols): Don't load the archive element
	after seeing a definition in a DT_NEEDED shared object.

include/

	PR ld/26530
	* bfdlink.h (bfd_link_hash_entry): Add as_needed_def_dynamic.

ld/

	PR ld/26530
	* plugin.c (get_symbols): Check as_needed_def_dynamic for
	undefined IR symbol.
	* testsuite/ld-plugin/lto.exp: Run PR ld/26530 tests.
	* testsuite/ld-plugin/pr26530a.c: New file.
	* testsuite/ld-plugin/pr26530b.c: Likewise.
	* testsuite/ld-plugin/pr26530c.c: Likewise.
---
 bfd/elflink.c                     | 20 ++++++++++++++------
 include/bfdlink.h                 |  3 +++
 ld/plugin.c                       |  3 ++-
 ld/testsuite/ld-plugin/lto.exp    | 22 ++++++++++++++++++++++
 ld/testsuite/ld-plugin/pr26530a.c |  5 +++++
 ld/testsuite/ld-plugin/pr26530b.c |  7 +++++++
 ld/testsuite/ld-plugin/pr26530c.c | 12 ++++++++++++
 7 files changed, 65 insertions(+), 7 deletions(-)
 create mode 100644 ld/testsuite/ld-plugin/pr26530a.c
 create mode 100644 ld/testsuite/ld-plugin/pr26530b.c
 create mode 100644 ld/testsuite/ld-plugin/pr26530c.c

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 5c085b14b7..562a3f9924 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5347,7 +5347,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 	  struct elf_link_hash_entry *h;
 	  bfd_size_type size;
 	  unsigned int alignment_power;
-	  unsigned int non_ir_ref_dynamic;
+	  struct elf_link_hash_entry preserved_h;
 
 	  for (p = htab->root.table.table[i]; p != NULL; p = p->next)
 	    {
@@ -5369,10 +5369,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 		  size = 0;
 		  alignment_power = 0;
 		}
-	      /* Preserve non_ir_ref_dynamic so that this symbol
-		 will be exported when the dynamic lib becomes needed
-		 in the second pass.  */
-	      non_ir_ref_dynamic = h->root.non_ir_ref_dynamic;
+	      /* Preserve some bits so that this symbol will be exported
+		 when the dynamic lib becomes needed in the second pass.
+		 and to avoid linking in an archive after the dynamic
+		 lib.  */
+	      preserved_h = *h;
 	      memcpy (p, old_ent, htab->root.table.entsize);
 	      old_ent = (char *) old_ent + htab->root.table.entsize;
 	      h = (struct elf_link_hash_entry *) p;
@@ -5389,7 +5390,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 		  if (alignment_power > h->root.u.c.p->alignment_power)
 		    h->root.u.c.p->alignment_power = alignment_power;
 		}
-	      h->root.non_ir_ref_dynamic = non_ir_ref_dynamic;
+	      h->root.non_ir_ref_dynamic
+		= preserved_h.root.non_ir_ref_dynamic;
+	      h->root.as_needed_def_dynamic |= preserved_h.dynamic_def;
 	    }
 	}
 
@@ -5826,6 +5829,11 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	  if (h == NULL)
 	    continue;
 
+	  /* Don't load the archive element after seeing a definition
+	     in a DT_NEEDED shared object.  */
+	  if (h->root.as_needed_def_dynamic)
+	    continue;
+
 	  if (h->root.type == bfd_link_hash_undefined)
 	    {
 	      /* If the archive element has already been loaded then one
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 3badfbdb19..f5517ee5dd 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -114,6 +114,9 @@ struct bfd_link_hash_entry
      as distinct from a LTO IR object file.  */
   unsigned int non_ir_ref_dynamic : 1;
 
+  /* Symbol is defined in a DT_NEEDED dynamic object file.  */
+  unsigned int as_needed_def_dynamic : 1;
+
   /* Symbol is a built-in define.  These will be overridden by PROVIDE
      in a linker script.  */
   unsigned int linker_def : 1;
diff --git a/ld/plugin.c b/ld/plugin.c
index d709ee10fe..ee8948e40c 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -794,7 +794,8 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
       if (blhe->type == bfd_link_hash_undefined
 	  || blhe->type == bfd_link_hash_undefweak)
 	{
-	  res = LDPR_UNDEF;
+	  res = (blhe->as_needed_def_dynamic
+		 ? LDPR_RESOLVED_DYN : LDPR_UNDEF);
 	  goto report_symbol;
 	}
       if (blhe->type != bfd_link_hash_defined
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index adad1e4895..8ccf4b8deb 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -419,6 +419,18 @@ set lto_link_elf_tests [list \
    "-shared -Wl,--exclude-libs,ALL tmpdir/pr25618a.o tmpdir/pr25618.a" \
    "-fpic" \
    {dummy.c} {{readelf {--dyn-syms --wide} pr25618.d}} "pr25618.so" "c++"] \
+  [list "Build pr26530a.so" \
+   "-shared" "-O2 -fpic $no_lto" \
+   {pr26530a.c} {} "pr26530a.so" "c"] \
+  [list "Build pr26530b.so" \
+   "-shared" "-O2 -fpic $no_lto" \
+   {pr26530b.c} {} "pr26530b.so" "c"] \
+  [list "Build pr26530a.a" \
+   "" "-O2 $no_lto" \
+   {pr26530a.c} {} "pr26530a.a" "c"] \
+  [list "Build pr26530b.a" \
+   "" "-O2 $no_lto" \
+   {pr26530b.c} {} "pr26530b.a" "c"] \
 ]
 
 # PR 14918 checks that libgcc is not spuriously included in a shared link of
@@ -584,6 +596,16 @@ set lto_run_elf_shared_tests [list \
   [list {pr22220b} \
    {-flto -fuse-linker-plugin -Wl,--no-as-needed tmpdir/pr22220lib.so tmpdir/pr22220main.o} {} \
    {dummy.c} {pr22220b.exe} {pass.out} {} {c++}] \
+  [list "pr26530a" \
+   "-O2 -flto -fuse-linker-plugin -Wl,--verbose=2" "" \
+   {pr26530c.c} "pr26530a.exe" "pass.out" "-O2 -flto" "c" \
+   {.*: symbol `lrealpath' definition: UNDEF, visibility: DEFAULT, resolution: RESOLVED_DYN.*} \
+   "-Wl,--as-needed tmpdir/pr26530a.so tmpdir/pr26530b.a"] \
+  [list "pr26530b" \
+   "-O2 -flto -fuse-linker-plugin -Wl,--verbose=2" "" \
+   {pr26530c.c} "pr26530b.exe" "pass.out" "-O2 -flto" "c" \
+   {.*: symbol `lrealpath' definition: UNDEF, visibility: DEFAULT, resolution: RESOLVED_EXEC.*} \
+   "-Wl,--as-needed tmpdir/pr26530a.a tmpdir/pr26530b.so"] \
 ]
 
 # LTO run-time tests for ELF
diff --git a/ld/testsuite/ld-plugin/pr26530a.c b/ld/testsuite/ld-plugin/pr26530a.c
new file mode 100644
index 0000000000..08e746911e
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26530a.c
@@ -0,0 +1,5 @@
+const char *
+lrealpath (const char *a)
+{
+  return a;
+}
diff --git a/ld/testsuite/ld-plugin/pr26530b.c b/ld/testsuite/ld-plugin/pr26530b.c
new file mode 100644
index 0000000000..0eb003f470
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26530b.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+
+void
+lrealpath (void)
+{
+  abort ();
+}
diff --git a/ld/testsuite/ld-plugin/pr26530c.c b/ld/testsuite/ld-plugin/pr26530c.c
new file mode 100644
index 0000000000..c8ef23675e
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26530c.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+const char *lrealpath(const char *a);
+
+int
+main(int argc, char **argv)
+{
+  const char *path = lrealpath (argv[0]);
+  if (path[0] != '\0')
+    printf ("PASS\n");
+  return 0;
+}
-- 
2.26.2


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-07 16:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-07 16:06 [PATCH] elf: Don't load archive element after DT_NEEDED dynamic definition H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).