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>
* coff-rs6000.c: Convert to ISO-C. Remove PARAMS macro.

View file

@ -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

View file

@ -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:

View file

@ -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)

View file

@ -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 <ian@cygnus.com>, 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;
}

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>
* dwarf2.h (dwarf_line_number_hp_sfc_ops): New enum.

View file

@ -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.,

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>
* deffilep.y (def_aligncomm): Avoid duplets.

View file

@ -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)

View file

@ -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);
}