Use the IR symbol table for the IR input object
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 20 Jun 2016 12:10:29 +0000 (05:10 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 20 Jun 2016 12:10:46 +0000 (05:10 -0700)
ELF linker shouldn't skip the IR object when searching the symbol table
of an archive element.  If linker doesn't know if the object file is an
IR object, it should give LTO plugin a chance to get the correct symbol
table and use the IR symbol table if the input is an IR object.

bfd/

PR ld/18250
PR ld/20267
* elflink.c: Include plugin.h if BFD_SUPPORTS_PLUGINS is
defined.
(elf_link_is_defined_archive_symbol): Call
bfd_link_plugin_object_p on unknown plugin object and use the
IR symbol table if the input is an IR object.
* plugin.c (bfd_link_plugin_object_p): New function.
* plugin.h (bfd_link_plugin_object_p): New prototype.

ld/

PR ld/20267
* testsuite/ld-plugin/lto.exp (lto_link_tests): Add test for
PR ld/20267.
(lto_run_tests): Likewise.
* testsuite/ld-plugin/pr20267a.c: New file.
* testsuite/ld-plugin/pr20267b.c: Likewise.

bfd/ChangeLog
bfd/elflink.c
bfd/plugin.c
bfd/plugin.h
ld/ChangeLog
ld/testsuite/ld-plugin/lto.exp
ld/testsuite/ld-plugin/pr20267a.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr20267b.c [new file with mode: 0644]

index 8ab9a1f3fb71b2ddf773058c15732eba4b51088a..85d2cea2eef905d99d51717fde73b9349f55d90e 100644 (file)
@@ -1,3 +1,15 @@
+2016-06-20  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/18250
+       PR ld/20267
+       * elflink.c: Include plugin.h if BFD_SUPPORTS_PLUGINS is
+       defined.
+       (elf_link_is_defined_archive_symbol): Call
+       bfd_link_plugin_object_p on unknown plugin object and use the
+       IR symbol table if the input is an IR object.
+       * plugin.c (bfd_link_plugin_object_p): New function.
+       * plugin.h (bfd_link_plugin_object_p): New prototype.
+
 2016-06-20  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/20276
index d4e8db67ea54e0ac49043ac8a35f97b4ab511c36..bb83854a275120cec34ae05d81293c01ef740f98 100644 (file)
@@ -28,6 +28,9 @@
 #include "safe-ctype.h"
 #include "libiberty.h"
 #include "objalloc.h"
+#ifdef BFD_SUPPORTS_PLUGINS
+#include "plugin.h"
+#endif
 
 /* This struct is used to pass information to routines called via
    elf_link_hash_traverse which must return failure.  */
@@ -3124,15 +3127,25 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
   if (abfd == NULL)
     return FALSE;
 
-  /* Return FALSE if the object has been claimed by plugin.  */
-  if (abfd->plugin_format == bfd_plugin_yes)
-    return FALSE;
-
   if (! bfd_check_format (abfd, bfd_object))
     return FALSE;
 
-  /* Select the appropriate symbol table.  */
-  if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
+  /* Select the appropriate symbol table.  If we don't know if the
+     object file is an IR object, give linker LTO plugin a chance to
+     get the correct symbol table.  */
+  if (abfd->plugin_format == bfd_plugin_yes
+#ifdef BFD_SUPPORTS_PLUGINS
+      || (abfd->plugin_format == bfd_plugin_unknown
+         && bfd_link_plugin_object_p (abfd))
+#endif
+      )
+    {
+      /* Use the IR symbol table if the object has been claimed by
+        plugin.  */
+      abfd = abfd->plugin_dummy_bfd;
+      hdr = &elf_tdata (abfd)->symtab_hdr;
+    }
+  else if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
     hdr = &elf_tdata (abfd)->symtab_hdr;
   else
     hdr = &elf_tdata (abfd)->dynsymtab_hdr;
index 2ab345216b4604e9b6a312c22b089e63f255f18a..c66d95eaffc049f68a2e38650e5baa25f4318b66 100644 (file)
@@ -287,6 +287,16 @@ bfd_plugin_specified_p (void)
   return has_plugin > 0;
 }
 
+/* Return TRUE if ABFD can be claimed by linker LTO plugin.  */
+
+bfd_boolean
+bfd_link_plugin_object_p (bfd *abfd)
+{
+  if (ld_plugin_object_p)
+    return ld_plugin_object_p (abfd) != NULL;
+  return FALSE;
+}
+
 extern const bfd_target plugin_vec;
 
 /* Return TRUE if TARGET is a pointer to plugin_vec.  */
index 0ad92fcfb484e68b1752852616c8533738016bb9..529f8c111fdddf4c7fcbe1045d58f733d92598e8 100644 (file)
@@ -27,6 +27,7 @@ void bfd_plugin_set_program_name (const char *);
 void bfd_plugin_set_plugin (const char *);
 bfd_boolean bfd_plugin_target_p (const bfd_target *);
 bfd_boolean bfd_plugin_specified_p (void);
+bfd_boolean bfd_link_plugin_object_p (bfd *);
 void register_ld_plugin_object_p (const bfd_target *(*object_p) (bfd *));
 
 typedef struct plugin_data_struct
index cd161ab16810657b6fea4f3995facb92221cc680..ca87628eb866e082b54fca178b8488259edc6e58 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-20  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20267
+       * testsuite/ld-plugin/lto.exp (lto_link_tests): Add test for
+       PR ld/20267.
+       (lto_run_tests): Likewise.
+       * testsuite/ld-plugin/pr20267a.c: New file.
+       * testsuite/ld-plugin/pr20267b.c: Likewise.
+
 2016-06-20  H.J. Lu  <hongjiu.lu@intel.com>
            Alan Modra  <amodra@gmail.com>
 
index 7743719e3f717d057c595da012c1f1f91144b9b1..80bc469e5993d87108b905a7a38bb2bff1961e06 100644 (file)
@@ -189,6 +189,15 @@ set lto_link_tests [list \
   [list "Build pr20276b.o" \
    "$plug_opt" "-flto $lto_no_fat" \
    {pr20276b.c}] \
+  [list "Build pr20267a.o" \
+   "" "" \
+   {pr20267a.c}] \
+  [list "Build libpr20267a.a" \
+   "$plug_opt" "-flto $lto_fat" \
+   {pr20267b.c} {} "libpr20267a.a"] \
+  [list "Build libpr20267b.a" \
+   "$plug_opt" "-flto $lto_no_fat" \
+   {pr20267b.c} {} "libpr20267b.a"] \
 ]
 
 if { [at_least_gcc_version 4 7] } {
@@ -341,6 +350,12 @@ set lto_run_tests [list \
   [list "Run pr20276" \
    "-O2 -flto tmpdir/pr20276a.o tmpdir/pr20276b.o" "" \
    {dummy.c} "pr20276" "pass.out" "-flto -O2" "c"] \
+  [list "Run pr20267a" \
+   "-O2 -flto tmpdir/pr20267a.o tmpdir/libpr20267a.a" "" \
+   {dummy.c} "pr20267a" "pass.out" "-flto -O2" "c"] \
+  [list "Run pr20267b" \
+   "-O2 -flto tmpdir/pr20267a.o tmpdir/libpr20267b.a" "" \
+   {dummy.c} "pr20267b" "pass.out" "-flto -O2" "c"] \
 ]
 
 if { [at_least_gcc_version 4 7] } {
diff --git a/ld/testsuite/ld-plugin/pr20267a.c b/ld/testsuite/ld-plugin/pr20267a.c
new file mode 100644 (file)
index 0000000..0b37bc7
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int global_var;
+extern void abort ();
+
+int main(void)
+{
+  if (global_var != 20)
+    abort ();
+  printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr20267b.c b/ld/testsuite/ld-plugin/pr20267b.c
new file mode 100644 (file)
index 0000000..2ecbc2c
--- /dev/null
@@ -0,0 +1 @@
+int global_var = 20;