diff options
author | Alan Modra <amodra@gmail.com> | 2011-04-20 00:11:33 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2011-04-20 00:11:33 +0000 |
commit | 24f58f47de96a6c061fc6eeb37a699c03dde970a (patch) | |
tree | 6d218f4096841f46c906ecab5f7090df8723161e /ld | |
parent | 43a8278ee9e14776343b7b3692650b130c301363 (diff) | |
download | gdb-24f58f47de96a6c061fc6eeb37a699c03dde970a.zip gdb-24f58f47de96a6c061fc6eeb37a699c03dde970a.tar.gz gdb-24f58f47de96a6c061fc6eeb37a699c03dde970a.tar.bz2 |
PR ld/12365
include/
* bfdlink.h (struct bfd_link_callbacks): Modify multiple_definition
and multiple_common parameters to pass in a bfd_link_hash_entry
pointer rather than name,bfd etc. found in the hash entry.
bfd/
* elflink.c (_bfd_elf_merge_symbol): Update multiple_common calls.
* linker.c (_bfd_generic_link_add_one_symbol): Likewise. Call
multiple_definition regardless of allow_multiple_definition.
* simple.c (simple_dummy_multiple_definition): Update.
* xcofflink.c (xcoff_link_add_symbols): Update multiple_definition
calls.
ld/
* ldmain.c (multiple_definition): Take a bfd_link_hash_entry
pointer arg rather than "name", "obfd", "osec", "oval". Add code
removed from linker.c. Hack around xcofflink.c oddity in
passing NULL nbfd.
(multiple_common): Similarly.
* plugin.c (orig_allow_multiple_defs): Delete.
(plugin_call_all_symbols_read): Don't twiddle allow_multiple_definition.
(plugin_multiple_definition): Update.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 12 | ||||
-rw-r--r-- | ld/ldmain.c | 87 | ||||
-rw-r--r-- | ld/plugin.c | 39 |
3 files changed, 96 insertions, 42 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 26164a9..ab16c69 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2011-04-20 Alan Modra <amodra@gmail.com> + + PR ld/12365 + * ldmain.c (multiple_definition): Take a bfd_link_hash_entry + pointer arg rather than "name", "obfd", "osec", "oval". Add code + removed from linker.c. Hack around xcofflink.c oddity in + passing NULL nbfd. + (multiple_common): Similarly. + * plugin.c (orig_allow_multiple_defs): Delete. + (plugin_call_all_symbols_read): Don't twiddle allow_multiple_definition. + (plugin_multiple_definition): Update. + 2011-04-18 Kai Tietz <ktietz@redhat.com> * deffilep.y (def_aligncomm): Avoid duplets. diff --git a/ld/ldmain.c b/ld/ldmain.c index 52a4b04..b7e725b 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -123,11 +123,11 @@ static char *get_emulation static bfd_boolean add_archive_element (struct bfd_link_info *, bfd *, const char *, bfd **); static bfd_boolean multiple_definition - (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma, + (struct bfd_link_info *, struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma); static bfd_boolean multiple_common - (struct bfd_link_info *, const char *, bfd *, enum bfd_link_hash_type, - bfd_vma, bfd *, enum bfd_link_hash_type, bfd_vma); + (struct bfd_link_info *, struct bfd_link_hash_entry *, + bfd *, enum bfd_link_hash_type, bfd_vma); static bfd_boolean add_to_set (struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_reloc_code_real_type, bfd *, asection *, bfd_vma); @@ -937,15 +937,44 @@ add_archive_element (struct bfd_link_info *info, multiple times. */ static bfd_boolean -multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, - const char *name, - bfd *obfd, - asection *osec, - bfd_vma oval, +multiple_definition (struct bfd_link_info *info, + struct bfd_link_hash_entry *h, bfd *nbfd, asection *nsec, bfd_vma nval) { + const char *name; + bfd *obfd; + asection *osec; + bfd_vma oval; + + if (info->allow_multiple_definition) + return TRUE; + + switch (h->type) + { + case bfd_link_hash_defined: + osec = h->u.def.section; + oval = h->u.def.value; + obfd = h->u.def.section->owner; + break; + case bfd_link_hash_indirect: + osec = bfd_ind_section_ptr; + oval = 0; + obfd = NULL; + break; + default: + abort (); + } + + /* Ignore a redefinition of an absolute symbol to the + same value; it's harmless. */ + if (h->type == bfd_link_hash_defined + && bfd_is_abs_section (osec) + && bfd_is_abs_section (nsec) + && nval == oval) + return TRUE; + /* If either section has the output_section field set to bfd_abs_section_ptr, it means that the section is being discarded, and this is not really a multiple definition at all. @@ -959,6 +988,14 @@ multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, && bfd_is_abs_section (nsec->output_section))) return TRUE; + name = h->root.string; + if (nbfd == NULL) + { + nbfd = obfd; + nsec = osec; + nval = oval; + obfd = NULL; + } einfo (_("%X%C: multiple definition of `%T'\n"), nbfd, nsec, nval, name); if (obfd != NULL) @@ -980,17 +1017,41 @@ multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, static bfd_boolean multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED, - const char *name, - bfd *obfd, - enum bfd_link_hash_type otype, - bfd_vma osize, + struct bfd_link_hash_entry *h, bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize) { - if (! config.warn_common) + const char *name; + bfd *obfd; + enum bfd_link_hash_type otype; + bfd_vma osize; + + if (!config.warn_common) return TRUE; + name = h->root.string; + otype = h->type; + if (otype == bfd_link_hash_common) + { + obfd = h->u.c.p->section->owner; + osize = h->u.c.size; + } + else if (otype == bfd_link_hash_defined + || otype == bfd_link_hash_defweak) + { + obfd = h->u.def.section->owner; + osize = 0; + } + else + { + /* FIXME: It would nice if we could report the BFD which defined + an indirect symbol, but we don't have anywhere to store the + information. */ + obfd = NULL; + osize = 0; + } + if (ntype == bfd_link_hash_defined || ntype == bfd_link_hash_defweak || ntype == bfd_link_hash_indirect) diff --git a/ld/plugin.c b/ld/plugin.c index 07f3afe..b363bc1 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -97,10 +97,8 @@ static const char *error_plugin = NULL; cases when establishing symbol resolutions. */ static struct bfd_hash_table *non_ironly_hash = NULL; -/* State of linker "notice" and "multiple_definition" interfaces - before we poked at them. */ +/* State of linker "notice" interface before we poked at it. */ static bfd_boolean orig_notice_all; -static bfd_boolean orig_allow_multiple_defs; /* Original linker callbacks, and the plugin version. */ static const struct bfd_link_callbacks *orig_callbacks; @@ -138,9 +136,8 @@ static bfd_boolean plugin_notice (struct bfd_link_info *info, const char *name, bfd *abfd, asection *section, bfd_vma value); static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info, - const char *name, - bfd *obfd, asection *osec, - bfd_vma oval, bfd *nbfd, + struct bfd_link_hash_entry *h, + bfd *nbfd, asection *nsec, bfd_vma nval); @@ -847,12 +844,6 @@ plugin_call_all_symbols_read (void) /* Disable any further file-claiming. */ no_more_claiming = TRUE; - /* If --allow-multiple-definition is in effect, we need to disable it, - as the plugin infrastructure relies on the multiple_definition - callback to swap out the dummy IR-only BFDs for new real ones - when it starts opening the files added during this callback. */ - orig_allow_multiple_defs = link_info.allow_multiple_definition; - link_info.allow_multiple_definition = FALSE; plugin_callbacks.multiple_definition = &plugin_multiple_definition; while (curplug) @@ -949,28 +940,18 @@ plugin_notice (struct bfd_link_info *info, we've fixed it up, or anyway if --allow-multiple-definition was in effect (before we disabled it to ensure we got called back). */ static bfd_boolean -plugin_multiple_definition (struct bfd_link_info *info, const char *name, - bfd *obfd, asection *osec, bfd_vma oval, +plugin_multiple_definition (struct bfd_link_info *info, + struct bfd_link_hash_entry *h, bfd *nbfd, asection *nsec, bfd_vma nval) { - if (is_ir_dummy_bfd (obfd)) + if (h->type == bfd_link_hash_defined + && is_ir_dummy_bfd (h->u.def.section->owner)) { - struct bfd_link_hash_entry *blhe - = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE); - if (!blhe) - einfo (_("%P%X: %s: can't find IR symbol '%s'\n"), nbfd->filename, - name); - else if (blhe->type != bfd_link_hash_defined) - einfo (_("%P%x: %s: bad IR symbol type %d\n"), name, blhe->type); /* Replace it with new details. */ - blhe->u.def.section = nsec; - blhe->u.def.value = nval; + h->u.def.section = nsec; + h->u.def.value = nval; return TRUE; } - if (orig_allow_multiple_defs) - return TRUE; - - return (*orig_callbacks->multiple_definition) (info, name, obfd, osec, oval, - nbfd, nsec, nval); + return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval); } |