This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_28-branch] Handle symbol defined in IR and referenced in DSO


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

commit b805037cf0061e86b1a71cba26fdaff52a46844d
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Apr 20 07:48:24 2017 -0700

    Handle symbol defined in IR and referenced in DSO
    
    We need to make an IR symbol visible if it is defined in an IR object
    and referenced in a dynamic object.  When --as-needed is used, since
    linker removes the IR symbol reference of the dynamic object if the
    dynamic object isn't needed in the first pass, the IR definition isn't
    visible to the dynamic object even if the dynamic object becomes needed
    in the second pass.  Add dynamic_ref_after_ir_def to bfd_link_hash_entry
    to track IR symbol which is defined in an IR object and later referenced
    in a dynamic object.  dynamic_ref_after_ir_def is preserved when restoring
    the symbol table for unneeded dynamic object.
    
    bfd/
    
    	PR ld/21382
    	* elflink.c (elf_link_add_object_symbols): Preserve
    	dynamic_ref_after_ir_def when restoring the symbol table for
    	unneeded dynamic object.
    
    include/
    
    	PR ld/21382
    	* bfdlink.h (bfd_link_hash_entry): Add dynamic_ref_after_ir_def.
    
    ld/
    
    	PR ld/21382
    	* plugin.c (is_visible_from_outside): Symbol may be visible
    	from outside if dynamic_ref_after_ir_def is set.
    	(plugin_notice): Set dynamic_ref_after_ir_def if the symbol is
    	defined in an IR object and referenced in a dynamic object.
    	* testsuite/ld-plugin/lto.exp: Run PR ld/21382 tests.
    	* testsuite/ld-plugin/pr21382a.c: New file.
    	* testsuite/ld-plugin/pr21382b.c: Likewise.
    
    (cherry picked from commit 59fa66c53823dc695f78669f40ec2eebab3aec42)

Diff:
---
 bfd/ChangeLog                     |  9 +++++++++
 bfd/elflink.c                     |  6 ++++++
 include/ChangeLog                 |  7 +++++++
 include/bfdlink.h                 |  4 ++++
 ld/ChangeLog                      | 10 ++++++++++
 ld/plugin.c                       | 23 +++++++++++++++++------
 ld/testsuite/ld-plugin/lto.exp    |  9 +++++++++
 ld/testsuite/ld-plugin/pr21382a.c | 17 +++++++++++++++++
 ld/testsuite/ld-plugin/pr21382b.c |  7 +++++++
 9 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b736f88..e1c52ca 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2017-09-27  Alan Modra  <amodra@gmail.com>
+
+	Apply from master
+	2017-04-20  H.J. Lu  <hongjiu.lu@intel.com>
+	PR ld/21382
+	* elflink.c (elf_link_add_object_symbols): Preserve
+	dynamic_ref_after_ir_def when restoring the symbol table for
+	unneeded dynamic object.
+
 2017-08-30  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* elfxx-mips.c (mips_elf_perform_relocation): Correct microMIPS
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f82bd82..3e0d60c 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4886,6 +4886,7 @@ error_free_dyn:
 	  struct elf_link_hash_entry *h;
 	  bfd_size_type size;
 	  unsigned int alignment_power;
+	  unsigned int dynamic_ref_after_ir_def;
 
 	  for (p = htab->root.table.table[i]; p != NULL; p = p->next)
 	    {
@@ -4907,6 +4908,10 @@ error_free_dyn:
 		  size = 0;
 		  alignment_power = 0;
 		}
+	      /* Preserve dynamic_ref_after_ir_def so that this symbol
+		 will be exported when the dynamic lib becomes needed
+		 in the second pass.  */
+	      dynamic_ref_after_ir_def = h->root.dynamic_ref_after_ir_def;
 	      memcpy (p, old_ent, htab->root.table.entsize);
 	      old_ent = (char *) old_ent + htab->root.table.entsize;
 	      h = (struct elf_link_hash_entry *) p;
@@ -4923,6 +4928,7 @@ error_free_dyn:
 		  if (alignment_power > h->root.u.c.p->alignment_power)
 		    h->root.u.c.p->alignment_power = alignment_power;
 		}
+	      h->root.dynamic_ref_after_ir_def = dynamic_ref_after_ir_def;
 	    }
 	}
 
diff --git a/include/ChangeLog b/include/ChangeLog
index dddecfb..f73ca48 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,10 @@
+2017-09-27  Alan Modra  <amodra@gmail.com>
+
+	Apply from master
+	2017-04-20  H.J. Lu  <hongjiu.lu@intel.com>
+	PR ld/21382
+	* bfdlink.h (bfd_link_hash_entry): Add dynamic_ref_after_ir_def.
+
 2017-04-03  Palmer Dabbelt  <palmer@dabbelt.com>
 
 	* elf/riscv.h (RISCV_GP_SYMBOL): New define.
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 3835fcb..b4528da 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -104,6 +104,10 @@ struct bfd_link_hash_entry
      IR object file.  */
   unsigned int non_ir_ref : 1;
 
+  /* Symbol is referenced in a dynamic object after it has been defined
+     in an IR object.  */
+  unsigned int dynamic_ref_after_ir_def : 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/ChangeLog b/ld/ChangeLog
index 7593a08..a29c2ca 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,6 +1,16 @@
 2017-09-27  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
+	2017-04-20  H.J. Lu  <hongjiu.lu@intel.com>
+	PR ld/21382
+	* plugin.c (is_visible_from_outside): Symbol may be visible
+	from outside if dynamic_ref_after_ir_def is set.
+	(plugin_notice): Set dynamic_ref_after_ir_def if the symbol is
+	defined in an IR object and referenced in a dynamic object.
+	* testsuite/ld-plugin/lto.exp: Run PR ld/21382 tests.
+	* testsuite/ld-plugin/pr21382a.c: New file.
+	* testsuite/ld-plugin/pr21382b.c: Likewise.
+
 	2017-01-24  Jiong Wang  <jiong.wang@arm.com>
 	* testsuite/ld-plugin/lto.exp (lto_link_elf_tests): Move "Compile 7",
 	"Compile 8a", "Compile 8b"...
diff --git a/ld/plugin.c b/ld/plugin.c
index 03e2e69..164b5db 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -629,7 +629,9 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym,
 
   if (bfd_link_relocatable (&link_info))
     return TRUE;
-  if (link_info.export_dynamic || bfd_link_dll (&link_info))
+  if (blhe->dynamic_ref_after_ir_def
+      || link_info.export_dynamic
+      || bfd_link_dll (&link_info))
     {
       /* Check if symbol is hidden by version script.  */
       if (bfd_hide_sym_by_version (link_info.version_info,
@@ -1316,12 +1318,21 @@ plugin_notice (struct bfd_link_info *info,
       /* If this is a ref, set non_ir_ref.  */
       else if (bfd_is_und_section (section))
 	{
+	   if (h->type == bfd_link_hash_defweak
+	       || h->type == bfd_link_hash_defined)
+	     {
+	       /* Check if the symbol is referenced in a dynamic object
+		  after it has been defined in an IR object.  */
+	       if ((abfd->flags & DYNAMIC) != 0
+		   && is_ir_dummy_bfd (h->u.def.section->owner))
+		 h->dynamic_ref_after_ir_def = TRUE;
+	     }
 	  /* Replace the undefined dummy bfd with the real one.  */
-	  if ((h->type == bfd_link_hash_undefined
-	       || h->type == bfd_link_hash_undefweak)
-	      && (h->u.undef.abfd == NULL
-		  || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
-	    h->u.undef.abfd = abfd;
+	   else if ((h->type == bfd_link_hash_undefined
+		     || h->type == bfd_link_hash_undefweak)
+		    && (h->u.undef.abfd == NULL
+			|| (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
+	     h->u.undef.abfd = abfd;
 	  h->non_ir_ref = TRUE;
 	}
 
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 49285b4..3e6005d 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -282,6 +282,12 @@ set lto_link_elf_tests [list \
   [list "PR ld/14918" \
    "-flto" "-flto" \
    {pr14918.c} {{"readelf" {-d --wide} "pr14918.d"}} "pr14918.exe" "c"] \
+  [list "Build pr21382a.o" \
+   "" "-O2 -flto" \
+   {pr21382a.c} {} "" "c"] \
+  [list "Build pr21382.so" \
+   "-shared" "-O2 -fpic" \
+   {pr21382b.c} {} "pr21382.so" "c"] \
 ]
 
 # Check final symbols in executables.
@@ -380,6 +386,9 @@ set lto_run_elf_shared_tests [list \
   [list "LTO 7" \
    "-O2 -flto -fuse-linker-plugin tmpdir/lto-7b.o tmpdir/lto-7c.o tmpdir/lto-7a.o -Wl,--no-as-needed tmpdir/liblto-7.so" "" \
    {dummy.c} "lto-7.exe" "lto-7.out" "" "c"] \
+  [list "Run pr21382" \
+   "-O2 -flto -fuse-linker-plugin -Wl,--as-needed tmpdir/pr21382a.o tmpdir/pr21382.so" "" \
+   {dummy.c} "pr21382.exe" "pass.out" "" "c"] \
 ]
 
 # LTO run-time tests for ELF
diff --git a/ld/testsuite/ld-plugin/pr21382a.c b/ld/testsuite/ld-plugin/pr21382a.c
new file mode 100644
index 0000000..09b9d75
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr21382a.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+extern void y (void);
+
+void
+x (void)
+{
+  printf ("PASS\n");
+}
+
+
+int
+main (void)
+{
+  y ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr21382b.c b/ld/testsuite/ld-plugin/pr21382b.c
new file mode 100644
index 0000000..c5b74a9
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr21382b.c
@@ -0,0 +1,7 @@
+extern void x (void);
+
+void
+y (void)
+{
+  x ();
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]