diff options
author | Alan Modra <amodra@gmail.com> | 2011-04-20 00:22:08 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2011-04-20 00:22:08 +0000 |
commit | 02d002477b60cff9f0f5abbd5fc27e2889b13421 (patch) | |
tree | ddb5245de932bf699df9cd2dda541ad9c96eef26 /ld/plugin.c | |
parent | 24f58f47de96a6c061fc6eeb37a699c03dde970a (diff) | |
download | gdb-02d002477b60cff9f0f5abbd5fc27e2889b13421.zip gdb-02d002477b60cff9f0f5abbd5fc27e2889b13421.tar.gz gdb-02d002477b60cff9f0f5abbd5fc27e2889b13421.tar.bz2 |
PR ld/12365
bfd/
* elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols
in their own common section.
* elflink.c (elf_link_add_object_symbols): Likewise.
* linker.c (generic_link_check_archive_element): Don't lose flags
if common section is pre-existing.
(_bfd_generic_link_add_one_symbol): Likewise.
ld/
* ldfile.c (ldfile_try_open_bfd): Move code creating and switching
to plugin IR BFD..
* ldmain.c (add_archive_element): ..and similar code here..
* plugin.c (plugin_maybe_claim): ..to here. New function.
(plugin_call_claim_file): Make static.
(asymbol_from_plugin_symbol): Set ELF st_shndx for common syms.
(plugin_multiple_common): New function.
(plugin_call_all_symbols_read): Hook in plugin_multiple_common.
* plugin.h (plugin_call_claim_file): Don't declare.
(plugin_maybe_claim): Declare.
Diffstat (limited to 'ld/plugin.c')
-rw-r--r-- | ld/plugin.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/ld/plugin.c b/ld/plugin.c index b363bc1..f45064e 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -140,6 +140,11 @@ static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info, bfd *nbfd, asection *nsec, bfd_vma nval); +static bfd_boolean plugin_multiple_common (struct bfd_link_info *info, + struct bfd_link_hash_entry *h, + bfd *nbfd, + enum bfd_link_hash_type ntype, + bfd_vma nsize); #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) @@ -312,7 +317,10 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym, asym->value = ldsym->size; /* For ELF targets, set alignment of common symbol to 1. */ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1; + { + ((elf_symbol_type *) asym)->internal_elf_sym.st_shndx = SHN_COMMON; + ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1; + } break; default: @@ -812,7 +820,7 @@ plugin_load_plugins (void) } /* Call 'claim file' hook for all plugins. */ -int +static int plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed) { plugin_t *curplug = plugins_list; @@ -835,6 +843,42 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed) return plugin_error_p () ? -1 : 0; } +void +plugin_maybe_claim (struct ld_plugin_input_file *file, + lang_input_statement_type *entry) +{ + int claimed = 0; + + /* We create a dummy BFD, initially empty, to house whatever symbols + the plugin may want to add. */ + file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename, + entry->the_bfd); + if (plugin_call_claim_file (file, &claimed)) + einfo (_("%P%F: %s: plugin reported error claiming file\n"), + plugin_error_plugin ()); + /* fd belongs to us, not the plugin; but we don't need it. */ + close (file->fd); + if (claimed) + { + /* Discard the real file's BFD and substitute the dummy one. */ + + /* BFD archive handling caches elements so we can't call + bfd_close for archives. */ + if (entry->the_bfd->my_archive == NULL) + bfd_close (entry->the_bfd); + entry->the_bfd = file->handle; + entry->claimed = TRUE; + bfd_make_readable (entry->the_bfd); + } + else + { + /* If plugin didn't claim the file, we don't need the dummy bfd. + Can't avoid speculatively creating it, alas. */ + bfd_close_all_done (file->handle); + entry->claimed = FALSE; + } +} + /* Call 'all symbols read' hook for all plugins. */ int plugin_call_all_symbols_read (void) @@ -845,6 +889,7 @@ plugin_call_all_symbols_read (void) no_more_claiming = TRUE; plugin_callbacks.multiple_definition = &plugin_multiple_definition; + plugin_callbacks.multiple_common = &plugin_multiple_common; while (curplug) { @@ -955,3 +1000,22 @@ plugin_multiple_definition (struct bfd_link_info *info, return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval); } + +static bfd_boolean +plugin_multiple_common (struct bfd_link_info *info, + struct bfd_link_hash_entry *h, + bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize) +{ + if (h->type == bfd_link_hash_common + && is_ir_dummy_bfd (h->u.c.p->section->owner) + && ntype == bfd_link_hash_common + && !is_ir_dummy_bfd (nbfd)) + { + /* Arrange to have it replaced. */ + ASSERT (nsize != 0); + h->u.c.size = 0; + return TRUE; + } + + return (*orig_callbacks->multiple_common) (info, h, nbfd, ntype, nsize); +} |