summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-06-18 14:54:09 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-06-18 18:48:36 -0700
commit8735960c85e04dc5ed5e71f894b452936ecd3607 (patch)
tree95c8bd632a87484acc8c996dd959cdf0e1510ffa
parent6614e881c6420aecbf83dff9e5d2ba3495ea9027 (diff)
downloadbinutils-gdb-users/hjl/pr18250.tar.gz
Use the IR symbol table for the IR input objectusers/hjl/pr18250
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 an 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.
-rw-r--r--bfd/elflink.c25
-rw-r--r--bfd/plugin.c10
-rw-r--r--bfd/plugin.h1
-rw-r--r--ld/testsuite/ld-plugin/lto.exp15
-rw-r--r--ld/testsuite/ld-plugin/pr20267a.c12
-rw-r--r--ld/testsuite/ld-plugin/pr20267b.c1
6 files changed, 58 insertions, 6 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d4e8db67ea5..3aa7ddfe7b9 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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 an 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;
diff --git a/bfd/plugin.c b/bfd/plugin.c
index 2ab345216b4..c66d95eaffc 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -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. */
diff --git a/bfd/plugin.h b/bfd/plugin.h
index 0ad92fcfb48..529f8c111fd 100644
--- a/bfd/plugin.h
+++ b/bfd/plugin.h
@@ -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
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 9fa73e19cad..893eb7f2396 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -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] } {
@@ -344,6 +353,12 @@ set lto_run_tests [list \
[list "Run pr20276" \
"-O2 -flto tmpdir/pr20276a.o tmpdir/pr20267b.o" "" \
{dummy.c} "pr20267" "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
index 00000000000..0b37bc7d309
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr20267a.c
@@ -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
index 00000000000..2ecbc2ca908
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr20267b.c
@@ -0,0 +1 @@
+int global_var = 20;