Use the IR symbol table for the IR input object

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.
This commit is contained in:
H.J. Lu 2016-06-20 05:10:29 -07:00
parent 9f99c22eb7
commit 7dc3990e40
8 changed files with 79 additions and 6 deletions

View 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

View 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;

View 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. */

View 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

View 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>

View 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] } {

View File

@ -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;
}

View File

@ -0,0 +1 @@
int global_var = 20;