From 24f58f47de96a6c061fc6eeb37a699c03dde970a Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 20 Apr 2011 00:11:33 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 10 +++++++ bfd/elflink.c | 8 ++--- bfd/linker.c | 71 ++++++++------------------------------------- bfd/simple.c | 7 ++--- bfd/xcofflink.c | 12 ++------ include/ChangeLog | 13 +++++++-- include/bfdlink.h | 24 +++++---------- ld/ChangeLog | 12 ++++++++ ld/ldmain.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++--------- ld/plugin.c | 39 +++++++------------------ 10 files changed, 144 insertions(+), 139 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ecd1f03..0d532e8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2011-04-20 Alan Modra + + PR ld/12365 + * 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. + 2011-04-18 Tristan Gingold * coff-rs6000.c: Convert to ISO-C. Remove PARAMS macro. diff --git a/bfd/elflink.c b/bfd/elflink.c index 2275503..f0ad579 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1,6 +1,6 @@ /* ELF linking support for BFD. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010 + 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -1361,8 +1361,7 @@ _bfd_elf_merge_symbol (bfd *abfd, symbols defined in dynamic objects. */ if (! ((*info->callbacks->multiple_common) - (info, h->root.root.string, oldbfd, bfd_link_hash_common, - h->size, abfd, bfd_link_hash_common, sym->st_size))) + (info, &h->root, abfd, bfd_link_hash_common, sym->st_size))) return FALSE; if (sym->st_size > h->size) @@ -1513,8 +1512,7 @@ _bfd_elf_merge_symbol (bfd *abfd, common symbol, but we don't know what to use for the section or the alignment. */ if (! ((*info->callbacks->multiple_common) - (info, h->root.root.string, oldbfd, bfd_link_hash_common, - h->size, abfd, bfd_link_hash_common, sym->st_size))) + (info, &h->root, abfd, bfd_link_hash_common, sym->st_size))) return FALSE; /* If the presumed common symbol in the dynamic object is diff --git a/bfd/linker.c b/bfd/linker.c index 2b52ba9..8c577f2 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1,6 +1,6 @@ /* linker.c -- BFD linker routines Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support @@ -1651,9 +1651,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, previously common. */ BFD_ASSERT (h->type == bfd_link_hash_common); if (! ((*info->callbacks->multiple_common) - (info, h->root.string, - h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_defined, 0))) + (info, h, abfd, bfd_link_hash_defined, 0))) return FALSE; /* Fall through. */ case DEF: @@ -1782,9 +1780,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, two sizes, and use the section required by the larger symbol. */ BFD_ASSERT (h->type == bfd_link_hash_common); if (! ((*info->callbacks->multiple_common) - (info, h->root.string, - h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_common, value))) + (info, h, abfd, bfd_link_hash_common, value))) return FALSE; if (value > h->u.c.size) { @@ -1821,23 +1817,11 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, break; case CREF: - { - bfd *obfd; - - /* We have found a common definition for a symbol which - was already defined. 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. */ - if (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak) - obfd = h->u.def.section->owner; - else - obfd = NULL; - if (! ((*info->callbacks->multiple_common) - (info, h->root.string, obfd, h->type, 0, - abfd, bfd_link_hash_common, value))) - return FALSE; - } + /* We have found a common definition for a symbol which + was already defined. */ + if (! ((*info->callbacks->multiple_common) + (info, h, abfd, bfd_link_hash_common, value))) + return FALSE; break; case MIND: @@ -1848,47 +1832,16 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, /* Fall through. */ case MDEF: /* Handle a multiple definition. */ - if (!info->allow_multiple_definition) - { - asection *msec = NULL; - bfd_vma mval = 0; - - switch (h->type) - { - case bfd_link_hash_defined: - msec = h->u.def.section; - mval = h->u.def.value; - break; - case bfd_link_hash_indirect: - msec = bfd_ind_section_ptr; - mval = 0; - 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 (msec) - && bfd_is_abs_section (section) - && value == mval) - break; - - if (! ((*info->callbacks->multiple_definition) - (info, h->root.string, msec->owner, msec, mval, - abfd, section, value))) - return FALSE; - } + if (! ((*info->callbacks->multiple_definition) + (info, h, abfd, section, value))) + return FALSE; break; case CIND: /* Create an indirect symbol from an existing common symbol. */ BFD_ASSERT (h->type == bfd_link_hash_common); if (! ((*info->callbacks->multiple_common) - (info, h->root.string, - h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_indirect, 0))) + (info, h, abfd, bfd_link_hash_indirect, 0))) return FALSE; /* Fall through. */ case IND: diff --git a/bfd/simple.c b/bfd/simple.c index 03d1a15..e5a5b58 100644 --- a/bfd/simple.c +++ b/bfd/simple.c @@ -1,5 +1,5 @@ /* simple.c -- BFD simple client routines - Copyright 2002, 2003, 2004, 2005, 2007, 2008, 2009 + Copyright 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by MontaVista Software, Inc. @@ -82,10 +82,7 @@ simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, static bfd_boolean simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - bfd *obfd ATTRIBUTE_UNUSED, - asection *osec ATTRIBUTE_UNUSED, - bfd_vma oval ATTRIBUTE_UNUSED, + struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED, bfd *nbfd ATTRIBUTE_UNUSED, asection *nsec ATTRIBUTE_UNUSED, bfd_vma nval ATTRIBUTE_UNUSED) diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 7ff920a..47e094e 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -1,6 +1,6 @@ /* POWER/PowerPC XCOFF linker support. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Written by Ian Lance Taylor , Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -1996,11 +1996,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) handle them, and that would only be a warning, not an error. */ if (! ((*info->callbacks->multiple_definition) - (info, (*sym_hash)->root.root.string, - NULL, NULL, (bfd_vma) 0, - (*sym_hash)->root.u.def.section->owner, - (*sym_hash)->root.u.def.section, - (*sym_hash)->root.u.def.value))) + (info, &(*sym_hash)->root, NULL, NULL, (bfd_vma) 0))) goto error_return; /* Try not to give this error too many times. */ (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED; @@ -3119,9 +3115,7 @@ bfd_xcoff_import_symbol (bfd *output_bfd, || h->root.u.def.value != val)) { if (! ((*info->callbacks->multiple_definition) - (info, h->root.root.string, h->root.u.def.section->owner, - h->root.u.def.section, h->root.u.def.value, - output_bfd, bfd_abs_section_ptr, val))) + (info, &h->root, output_bfd, bfd_abs_section_ptr, val))) return FALSE; } diff --git a/include/ChangeLog b/include/ChangeLog index 7c18850..bf7128f 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2011-04-20 Alan Modra + + PR ld/12365 + * 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. + 2011-03-31 Tristan Gingold * dwarf2.h (dwarf_line_number_hp_sfc_ops): New enum. @@ -64,19 +71,19 @@ * simple-object.h: New file. -2010-10-15 Dave Korn +2010-10-15 Dave Korn Sync LD plugin patch series (part 1/6) with src/include/. * plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member. -2010-10-14 Dave Korn +2010-10-14 Dave Korn Apply LD plugin patch series (part 6/6). * bfdlink.h (struct_bfd_link_callbacks): Document new argument to add_archive_element callback used to return a replacement bfd which is to be added to the hash table in place of the original element. -2010-10-14 Dave Korn +2010-10-14 Dave Korn Apply LD plugin patch series (part 1/6). * plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member. diff --git a/include/bfdlink.h b/include/bfdlink.h index 0d6e9f8..7cfaea0 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -1,6 +1,7 @@ /* bfdlink.h -- header file for BFD link routines Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -487,29 +488,20 @@ struct bfd_link_callbacks bfd_boolean (*add_archive_element) (struct bfd_link_info *, bfd *abfd, const char *name, bfd **subsbfd); /* A function which is called when a symbol is found with multiple - definitions. NAME is the symbol which is defined multiple times. - OBFD is the old BFD, OSEC is the old section, OVAL is the old - value, NBFD is the new BFD, NSEC is the new section, and NVAL is - the new value. OBFD may be NULL. OSEC and NSEC may be - bfd_com_section or bfd_ind_section. */ + definitions. H is the symbol which is defined multiple times. + NBFD is the new BFD, NSEC is the new section, and NVAL is the new + value. NSEC may be bfd_com_section or bfd_ind_section. */ bfd_boolean (*multiple_definition) - (struct bfd_link_info *, const char *name, - bfd *obfd, asection *osec, bfd_vma oval, + (struct bfd_link_info *, struct bfd_link_hash_entry *h, bfd *nbfd, asection *nsec, bfd_vma nval); /* A function which is called when a common symbol is defined - multiple times. NAME is the symbol appearing multiple times. - OBFD is the BFD of the existing symbol; it may be NULL if this is - not known. OTYPE is the type of the existing symbol, which may - be bfd_link_hash_defined, bfd_link_hash_defweak, - bfd_link_hash_common, or bfd_link_hash_indirect. If OTYPE is - bfd_link_hash_common, OSIZE is the size of the existing symbol. + multiple times. H is the symbol appearing multiple times. NBFD is the BFD of the new symbol. NTYPE is the type of the new symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or bfd_link_hash_indirect. If NTYPE is bfd_link_hash_common, NSIZE is the size of the new symbol. */ bfd_boolean (*multiple_common) - (struct bfd_link_info *, const char *name, - bfd *obfd, enum bfd_link_hash_type otype, bfd_vma osize, + (struct bfd_link_info *, struct bfd_link_hash_entry *h, bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize); /* A function which is called to add a symbol to a set. ENTRY is the link hash table entry for the set itself (e.g., 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 + + 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 * 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); } -- 2.7.4