diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 12 | ||||
-rw-r--r-- | bfd/elflink.c | 25 | ||||
-rw-r--r-- | bfd/plugin.c | 10 | ||||
-rw-r--r-- | bfd/plugin.h | 1 |
4 files changed, 42 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8ab9a1f..85d2cea 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,17 @@ 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 * elflink.c (elf_link_add_object_symbols): Don't check alignment on symbol from plugin dummy input. diff --git a/bfd/elflink.c b/bfd/elflink.c index d4e8db6..bb83854 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 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; diff --git a/bfd/plugin.c b/bfd/plugin.c index 2ab3452..c66d95e 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 0ad92fc..529f8c1 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 |