PR ld/12762

bfd/
	* bfd-in.h (struct bfd_section_already_linked): Forward declare.
	(_bfd_handle_already_linked): Declare.
	* coff-alpha.c (_bfd_ecoff_section_already_linked): Define as
	_bfd_coff_section_already_linked.
	* coff-mips.c (_bfd_ecoff_section_already_linked): Likewise.
	* coffcode.h (coff_section_already_linked): Likewise.
	* cofflink.c (coff_link_add_symbols): Revert 2011-07-09 changes.
	* elf-bfd.h: Likewise.
	* libbfd-in.h: Likewise.
	* targets.c: Likewise.
	* linker.c (bfd_section_already_linked): Likewise.
	(bfd_section_already_linked_table_lookup): Likewise.
	(bfd_section_already_linked_table_insert): Likewise.
	(_bfd_generic_section_already_linked): Likewise.  Call
	_bfd_handle_already_linked.
	(_bfd_handle_already_linked): New function, split out from..
	* elflink.c (_bfd_elf_section_already_linked): ..here.  Revert
	2011-07-09 changes.  Avoid unnecessary strcmp when matching
	already_linked_list entries.  Match plugin linkonce section.
	(section_signature): Delete.
	* coffgen.c (_bfd_coff_section_already_linked): New function.
	* libcoff-in.h (_bfd_coff_section_already_linked): Declare.
	* libbfd.h: Regenerate.
	* libcoff.h: Regenerate.
	* bfd-in2.h: Regenerate.
ld/
	* ldlang.c (section_already_linked): Revert 2011-07-09 changes.
	* plugin.c: Likewise.
	(asymbol_from_plugin_symbol): Create linkonce section for syms
	with comdat_key.
This commit is contained in:
Alan Modra
2011-08-17 00:39:41 +00:00
parent 142a8c5dcf
commit c77ec72614
19 changed files with 395 additions and 484 deletions

View File

@@ -2399,3 +2399,70 @@ bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec)
else
return NULL;
}
bfd_boolean
_bfd_coff_section_already_linked (bfd *abfd,
asection *sec,
struct bfd_link_info *info)
{
flagword flags;
const char *name, *key;
struct bfd_section_already_linked *l;
struct bfd_section_already_linked_hash_entry *already_linked_list;
struct coff_comdat_info *s_comdat;
flags = sec->flags;
if ((flags & SEC_LINK_ONCE) == 0)
return FALSE;
/* The COFF backend linker doesn't support group sections. */
if ((flags & SEC_GROUP) != 0)
return FALSE;
name = bfd_get_section_name (abfd, sec);
s_comdat = bfd_coff_get_comdat_section (abfd, sec);
if (s_comdat != NULL)
key = s_comdat->name;
else
{
if (CONST_STRNEQ (name, ".gnu.linkonce.")
&& (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
key++;
else
/* FIXME: gcc as of 2011-09 emits sections like .text$<key>,
.xdata$<key> and .pdata$<key> only the first of which has a
comdat key. Should these all match the LTO IR key? */
key = name;
}
already_linked_list = bfd_section_already_linked_table_lookup (key);
for (l = already_linked_list->entry; l != NULL; l = l->next)
{
struct coff_comdat_info *l_comdat;
l_comdat = bfd_coff_get_comdat_section (l->sec->owner, l->sec);
/* The section names must match, and both sections must be
comdat and have the same comdat name, or both sections must
be non-comdat. LTO IR plugin sections are an exception. They
are always named .gnu.linkonce.t.<key> (<key> is some string)
and match any comdat section with comdat name of <key>, and
any linkonce section with the same suffix, ie.
.gnu.linkonce.*.<key>. */
if (((s_comdat != NULL) == (l_comdat != NULL)
&& strcmp (name, l->sec->name) == 0)
|| (l->sec->owner->flags & BFD_PLUGIN) != 0)
{
/* The section has already been linked. See if we should
issue a warning. */
return _bfd_handle_already_linked (sec, l, info);
}
}
/* This is the first section with this name. Record it. */
if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
return FALSE;
}