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.
This commit is contained in:
Alan Modra 2011-04-20 00:11:33 +00:00
parent 43a8278ee9
commit 24f58f47de
10 changed files with 144 additions and 139 deletions

View file

@ -1,3 +1,13 @@
2011-04-20 Alan Modra <amodra@gmail.com>
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 <gingold@adacore.com> 2011-04-18 Tristan Gingold <gingold@adacore.com>
* coff-rs6000.c: Convert to ISO-C. Remove PARAMS macro. * coff-rs6000.c: Convert to ISO-C. Remove PARAMS macro.

View file

@ -1,6 +1,6 @@
/* ELF linking support for BFD. /* ELF linking support for BFD.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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. Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library. 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. */ symbols defined in dynamic objects. */
if (! ((*info->callbacks->multiple_common) if (! ((*info->callbacks->multiple_common)
(info, h->root.root.string, oldbfd, bfd_link_hash_common, (info, &h->root, abfd, bfd_link_hash_common, sym->st_size)))
h->size, abfd, bfd_link_hash_common, sym->st_size)))
return FALSE; return FALSE;
if (sym->st_size > h->size) 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 common symbol, but we don't know what to use for the section
or the alignment. */ or the alignment. */
if (! ((*info->callbacks->multiple_common) if (! ((*info->callbacks->multiple_common)
(info, h->root.root.string, oldbfd, bfd_link_hash_common, (info, &h->root, abfd, bfd_link_hash_common, sym->st_size)))
h->size, abfd, bfd_link_hash_common, sym->st_size)))
return FALSE; return FALSE;
/* If the presumed common symbol in the dynamic object is /* If the presumed common symbol in the dynamic object is

View file

@ -1,6 +1,6 @@
/* linker.c -- BFD linker routines /* linker.c -- BFD linker routines
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 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. Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support 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. */ previously common. */
BFD_ASSERT (h->type == bfd_link_hash_common); BFD_ASSERT (h->type == bfd_link_hash_common);
if (! ((*info->callbacks->multiple_common) if (! ((*info->callbacks->multiple_common)
(info, h->root.string, (info, h, abfd, bfd_link_hash_defined, 0)))
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
abfd, bfd_link_hash_defined, 0)))
return FALSE; return FALSE;
/* Fall through. */ /* Fall through. */
case DEF: 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. */ two sizes, and use the section required by the larger symbol. */
BFD_ASSERT (h->type == bfd_link_hash_common); BFD_ASSERT (h->type == bfd_link_hash_common);
if (! ((*info->callbacks->multiple_common) if (! ((*info->callbacks->multiple_common)
(info, h->root.string, (info, h, abfd, bfd_link_hash_common, value)))
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
abfd, bfd_link_hash_common, value)))
return FALSE; return FALSE;
if (value > h->u.c.size) if (value > h->u.c.size)
{ {
@ -1821,23 +1817,11 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
break; break;
case CREF: case CREF:
{ /* We have found a common definition for a symbol which
bfd *obfd; was already defined. */
if (! ((*info->callbacks->multiple_common)
/* We have found a common definition for a symbol which (info, h, abfd, bfd_link_hash_common, value)))
was already defined. FIXME: It would nice if we could return FALSE;
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;
}
break; break;
case MIND: case MIND:
@ -1848,47 +1832,16 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
/* Fall through. */ /* Fall through. */
case MDEF: case MDEF:
/* Handle a multiple definition. */ /* Handle a multiple definition. */
if (!info->allow_multiple_definition) if (! ((*info->callbacks->multiple_definition)
{ (info, h, abfd, section, value)))
asection *msec = NULL; return FALSE;
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;
}
break; break;
case CIND: case CIND:
/* Create an indirect symbol from an existing common symbol. */ /* Create an indirect symbol from an existing common symbol. */
BFD_ASSERT (h->type == bfd_link_hash_common); BFD_ASSERT (h->type == bfd_link_hash_common);
if (! ((*info->callbacks->multiple_common) if (! ((*info->callbacks->multiple_common)
(info, h->root.string, (info, h, abfd, bfd_link_hash_indirect, 0)))
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
abfd, bfd_link_hash_indirect, 0)))
return FALSE; return FALSE;
/* Fall through. */ /* Fall through. */
case IND: case IND:

View file

@ -1,5 +1,5 @@
/* simple.c -- BFD simple client routines /* 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. Free Software Foundation, Inc.
Contributed by MontaVista Software, 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 static bfd_boolean
simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
const char *name ATTRIBUTE_UNUSED, struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
bfd *obfd ATTRIBUTE_UNUSED,
asection *osec ATTRIBUTE_UNUSED,
bfd_vma oval ATTRIBUTE_UNUSED,
bfd *nbfd ATTRIBUTE_UNUSED, bfd *nbfd ATTRIBUTE_UNUSED,
asection *nsec ATTRIBUTE_UNUSED, asection *nsec ATTRIBUTE_UNUSED,
bfd_vma nval ATTRIBUTE_UNUSED) bfd_vma nval ATTRIBUTE_UNUSED)

View file

@ -1,6 +1,6 @@
/* POWER/PowerPC XCOFF linker support. /* POWER/PowerPC XCOFF linker support.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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 <ian@cygnus.com>, Cygnus Support. Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library. 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, handle them, and that would only be a warning,
not an error. */ not an error. */
if (! ((*info->callbacks->multiple_definition) if (! ((*info->callbacks->multiple_definition)
(info, (*sym_hash)->root.root.string, (info, &(*sym_hash)->root, NULL, NULL, (bfd_vma) 0)))
NULL, NULL, (bfd_vma) 0,
(*sym_hash)->root.u.def.section->owner,
(*sym_hash)->root.u.def.section,
(*sym_hash)->root.u.def.value)))
goto error_return; goto error_return;
/* Try not to give this error too many times. */ /* Try not to give this error too many times. */
(*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED; (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
@ -3119,9 +3115,7 @@ bfd_xcoff_import_symbol (bfd *output_bfd,
|| h->root.u.def.value != val)) || h->root.u.def.value != val))
{ {
if (! ((*info->callbacks->multiple_definition) if (! ((*info->callbacks->multiple_definition)
(info, h->root.root.string, h->root.u.def.section->owner, (info, &h->root, output_bfd, bfd_abs_section_ptr, val)))
h->root.u.def.section, h->root.u.def.value,
output_bfd, bfd_abs_section_ptr, val)))
return FALSE; return FALSE;
} }

View file

@ -1,3 +1,10 @@
2011-04-20 Alan Modra <amodra@gmail.com>
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 <gingold@adacore.com> 2011-03-31 Tristan Gingold <gingold@adacore.com>
* dwarf2.h (dwarf_line_number_hp_sfc_ops): New enum. * dwarf2.h (dwarf_line_number_hp_sfc_ops): New enum.
@ -64,19 +71,19 @@
* simple-object.h: New file. * simple-object.h: New file.
2010-10-15 Dave Korn <dave.korn.cygwin@gmail.com> 2010-10-15 Dave Korn <dave.korn.cygwin@gmail.com>
Sync LD plugin patch series (part 1/6) with src/include/. Sync LD plugin patch series (part 1/6) with src/include/.
* plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member. * plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member.
2010-10-14 Dave Korn <dave.korn.cygwin@gmail.com> 2010-10-14 Dave Korn <dave.korn.cygwin@gmail.com>
Apply LD plugin patch series (part 6/6). Apply LD plugin patch series (part 6/6).
* bfdlink.h (struct_bfd_link_callbacks): Document new argument * bfdlink.h (struct_bfd_link_callbacks): Document new argument
to add_archive_element callback used to return a replacement bfd which 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. is to be added to the hash table in place of the original element.
2010-10-14 Dave Korn <dave.korn.cygwin@gmail.com> 2010-10-14 Dave Korn <dave.korn.cygwin@gmail.com>
Apply LD plugin patch series (part 1/6). Apply LD plugin patch series (part 1/6).
* plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member. * plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member.

View file

@ -1,6 +1,7 @@
/* bfdlink.h -- header file for BFD link routines /* bfdlink.h -- header file for BFD link routines
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 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. Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library. This file is part of BFD, the Binary File Descriptor library.
@ -487,29 +488,20 @@ struct bfd_link_callbacks
bfd_boolean (*add_archive_element) bfd_boolean (*add_archive_element)
(struct bfd_link_info *, bfd *abfd, const char *name, bfd **subsbfd); (struct bfd_link_info *, bfd *abfd, const char *name, bfd **subsbfd);
/* A function which is called when a symbol is found with multiple /* A function which is called when a symbol is found with multiple
definitions. NAME is the symbol which is defined multiple times. definitions. H is the symbol which is defined multiple times.
OBFD is the old BFD, OSEC is the old section, OVAL is the old NBFD is the new BFD, NSEC is the new section, and NVAL is the new
value, NBFD is the new BFD, NSEC is the new section, and NVAL is value. NSEC may be bfd_com_section or bfd_ind_section. */
the new value. OBFD may be NULL. OSEC and NSEC may be
bfd_com_section or bfd_ind_section. */
bfd_boolean (*multiple_definition) bfd_boolean (*multiple_definition)
(struct bfd_link_info *, const char *name, (struct bfd_link_info *, struct bfd_link_hash_entry *h,
bfd *obfd, asection *osec, bfd_vma oval,
bfd *nbfd, asection *nsec, bfd_vma nval); bfd *nbfd, asection *nsec, bfd_vma nval);
/* A function which is called when a common symbol is defined /* A function which is called when a common symbol is defined
multiple times. NAME is the symbol appearing multiple times. multiple times. H 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.
NBFD is the BFD of the new symbol. NTYPE is the type of the new 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 symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or
bfd_link_hash_indirect. If NTYPE is bfd_link_hash_common, NSIZE bfd_link_hash_indirect. If NTYPE is bfd_link_hash_common, NSIZE
is the size of the new symbol. */ is the size of the new symbol. */
bfd_boolean (*multiple_common) bfd_boolean (*multiple_common)
(struct bfd_link_info *, const char *name, (struct bfd_link_info *, struct bfd_link_hash_entry *h,
bfd *obfd, enum bfd_link_hash_type otype, bfd_vma osize,
bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize); 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 /* 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., the link hash table entry for the set itself (e.g.,

View file

@ -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> 2011-04-18 Kai Tietz <ktietz@redhat.com>
* deffilep.y (def_aligncomm): Avoid duplets. * deffilep.y (def_aligncomm): Avoid duplets.

View file

@ -123,11 +123,11 @@ static char *get_emulation
static bfd_boolean add_archive_element static bfd_boolean add_archive_element
(struct bfd_link_info *, bfd *, const char *, bfd **); (struct bfd_link_info *, bfd *, const char *, bfd **);
static bfd_boolean multiple_definition 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); bfd *, asection *, bfd_vma);
static bfd_boolean multiple_common static bfd_boolean multiple_common
(struct bfd_link_info *, const char *, bfd *, enum bfd_link_hash_type, (struct bfd_link_info *, struct bfd_link_hash_entry *,
bfd_vma, bfd *, enum bfd_link_hash_type, bfd_vma); bfd *, enum bfd_link_hash_type, bfd_vma);
static bfd_boolean add_to_set static bfd_boolean add_to_set
(struct bfd_link_info *, struct bfd_link_hash_entry *, (struct bfd_link_info *, struct bfd_link_hash_entry *,
bfd_reloc_code_real_type, bfd *, asection *, bfd_vma); bfd_reloc_code_real_type, bfd *, asection *, bfd_vma);
@ -937,15 +937,44 @@ add_archive_element (struct bfd_link_info *info,
multiple times. */ multiple times. */
static bfd_boolean static bfd_boolean
multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, multiple_definition (struct bfd_link_info *info,
const char *name, struct bfd_link_hash_entry *h,
bfd *obfd,
asection *osec,
bfd_vma oval,
bfd *nbfd, bfd *nbfd,
asection *nsec, asection *nsec,
bfd_vma nval) 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 /* If either section has the output_section field set to
bfd_abs_section_ptr, it means that the section is being bfd_abs_section_ptr, it means that the section is being
discarded, and this is not really a multiple definition at all. 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))) && bfd_is_abs_section (nsec->output_section)))
return TRUE; 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"), einfo (_("%X%C: multiple definition of `%T'\n"),
nbfd, nsec, nval, name); nbfd, nsec, nval, name);
if (obfd != NULL) if (obfd != NULL)
@ -980,17 +1017,41 @@ multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED,
static bfd_boolean static bfd_boolean
multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED, multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
const char *name, struct bfd_link_hash_entry *h,
bfd *obfd,
enum bfd_link_hash_type otype,
bfd_vma osize,
bfd *nbfd, bfd *nbfd,
enum bfd_link_hash_type ntype, enum bfd_link_hash_type ntype,
bfd_vma nsize) 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; 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 if (ntype == bfd_link_hash_defined
|| ntype == bfd_link_hash_defweak || ntype == bfd_link_hash_defweak
|| ntype == bfd_link_hash_indirect) || ntype == bfd_link_hash_indirect)

View file

@ -97,10 +97,8 @@ static const char *error_plugin = NULL;
cases when establishing symbol resolutions. */ cases when establishing symbol resolutions. */
static struct bfd_hash_table *non_ironly_hash = NULL; static struct bfd_hash_table *non_ironly_hash = NULL;
/* State of linker "notice" and "multiple_definition" interfaces /* State of linker "notice" interface before we poked at it. */
before we poked at them. */
static bfd_boolean orig_notice_all; static bfd_boolean orig_notice_all;
static bfd_boolean orig_allow_multiple_defs;
/* Original linker callbacks, and the plugin version. */ /* Original linker callbacks, and the plugin version. */
static const struct bfd_link_callbacks *orig_callbacks; 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, const char *name, bfd *abfd,
asection *section, bfd_vma value); asection *section, bfd_vma value);
static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info, static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
const char *name, struct bfd_link_hash_entry *h,
bfd *obfd, asection *osec, bfd *nbfd,
bfd_vma oval, bfd *nbfd,
asection *nsec, asection *nsec,
bfd_vma nval); bfd_vma nval);
@ -847,12 +844,6 @@ plugin_call_all_symbols_read (void)
/* Disable any further file-claiming. */ /* Disable any further file-claiming. */
no_more_claiming = TRUE; 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; plugin_callbacks.multiple_definition = &plugin_multiple_definition;
while (curplug) 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 we've fixed it up, or anyway if --allow-multiple-definition was in
effect (before we disabled it to ensure we got called back). */ effect (before we disabled it to ensure we got called back). */
static bfd_boolean static bfd_boolean
plugin_multiple_definition (struct bfd_link_info *info, const char *name, plugin_multiple_definition (struct bfd_link_info *info,
bfd *obfd, asection *osec, bfd_vma oval, struct bfd_link_hash_entry *h,
bfd *nbfd, asection *nsec, bfd_vma nval) 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. */ /* Replace it with new details. */
blhe->u.def.section = nsec; h->u.def.section = nsec;
blhe->u.def.value = nval; h->u.def.value = nval;
return TRUE; return TRUE;
} }
if (orig_allow_multiple_defs) return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval);
return TRUE;
return (*orig_callbacks->multiple_definition) (info, name, obfd, osec, oval,
nbfd, nsec, nval);
} }