]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Handle symbol defined in IR and referenced in DSO
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 20 Apr 2017 14:48:24 +0000 (07:48 -0700)
committerAlan Modra <amodra@gmail.com>
Wed, 27 Sep 2017 09:40:27 +0000 (19:10 +0930)
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)

bfd/ChangeLog
bfd/elflink.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/plugin.c
ld/testsuite/ld-plugin/lto.exp
ld/testsuite/ld-plugin/pr21382a.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr21382b.c [new file with mode: 0644]

index b736f883bf042f651aa3665d95318b2f593a04f8..e1c52ca7e7596585d8ecd722c34295593d94083c 100644 (file)
@@ -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
index f82bd8202bac6e87251576ae63102871b1dc7dc4..3e0d60c414b33b3d35c606957008f85396d96f3c 100644 (file)
@@ -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;
            }
        }
 
index dddecfb49b68f0a003bb7f477d133c235b8b11e9..f73ca4821bb9b0911b99f3e3ab2fd9b56ef36358 100644 (file)
@@ -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.
index 3835fcb0d3094d6f108424cf42b2596aca86d40f..b4528da9162666c897573dde9bdafe91d49d4a4d 100644 (file)
@@ -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;
index 7593a0891ed2bf17c1e3d198d465e89c1ac6166c..a29c2ca4d03efd835f2890e50e3cc88a2b822907 100644 (file)
@@ -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"...
index 03e2e69a639151285e9a06c41a722cdf87a03ca9..164b5db5d6d23a3daa527a49a88510796a75e78f 100644 (file)
@@ -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;
        }
 
index 49285b4d6c6b8e9dcd9901ec6c15141704b315af..3e6005da20d0f7ebf4797cda59d4246aebb178c2 100644 (file)
@@ -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 (file)
index 0000000..09b9d75
--- /dev/null
@@ -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 (file)
index 0000000..c5b74a9
--- /dev/null
@@ -0,0 +1,7 @@
+extern void x (void);
+
+void
+y (void)
+{
+  x ();
+}