PR ld/12942

bfd/
	* elflink.c (elf_link_add_object_symbols): Use elf_discarded_section
	rather than kept_section to determine whether a symbol is from
	a discarded section.
	* cofflink.c (coff_link_add_symbols): Make symbols from discarded
	sections appear undefined.

	* elf-bfd.h (_bfd_elf_section_already_linked): Replace
	"asection *" with "struct already_linked *".
	* libbfd-in.h (_bfd_nolink_section_already_linked): Likewise.
	(_bfd_generic_section_already_linked): Likewise.
	(bfd_section_already_linked_table_insert): Likewise.
	(struct already_linked): New.
	(struct bfd_section_already_linked): Use it.
	* elflink.c (_bfd_elf_section_already_linked): Replace.
	"asection *" with "struct already_linked *".  Replace the plugin
	dummy with the LTO output.
	* linker.c (_bfd_generic_section_already_linked): Likewise.
	* targets.c (struct already_linked): Add forward declaration.
	(bfd_target): Replace "struct bfd_section *" with
	"struct already_linked *" in _section_already_linked.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.

include/
	* bfdlink.h (bfd_link_info): Add loading_lto_outputs.

ld/
	* ldlang.c (section_already_linked): Pass "struct already_linked *"
	to bfd_section_already_linked.
	(lang_process): Set link_info.loading_lto_outputs before
	loading LTO outputs.
	* plugin.c: Include "libbfd.h".
	(add_symbols): Call bfd_section_already_linked with comdat_key.
This commit is contained in:
Alan Modra
2011-07-09 06:20:52 +00:00
parent beabb2c68f
commit 0c51100021
14 changed files with 406 additions and 174 deletions

View File

@ -2888,15 +2888,16 @@ FUNCTION
bfd_section_already_linked
SYNOPSIS
void bfd_section_already_linked (bfd *abfd, asection *sec,
void bfd_section_already_linked (bfd *abfd,
struct already_linked *data,
struct bfd_link_info *info);
DESCRIPTION
Check if @var{sec} has been already linked during a reloceatable
Check if @var{data} has been already linked during a reloceatable
or final link.
.#define bfd_section_already_linked(abfd, sec, info) \
. BFD_SEND (abfd, _section_already_linked, (abfd, sec, info))
.#define bfd_section_already_linked(abfd, data, info) \
. BFD_SEND (abfd, _section_already_linked, (abfd, data, info))
.
*/
@ -2939,7 +2940,7 @@ bfd_section_already_linked_table_lookup (const char *name)
bfd_boolean
bfd_section_already_linked_table_insert
(struct bfd_section_already_linked_hash_entry *already_linked_list,
asection *sec)
struct already_linked *data)
{
struct bfd_section_already_linked *l;
@ -2949,7 +2950,7 @@ bfd_section_already_linked_table_insert
bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
if (l == NULL)
return FALSE;
l->sec = sec;
l->linked = *data;
l->next = already_linked_list->entry;
already_linked_list->entry = l;
return TRUE;
@ -2990,42 +2991,74 @@ bfd_section_already_linked_table_free (void)
/* This is used on non-ELF inputs. */
void
_bfd_generic_section_already_linked (bfd *abfd, asection *sec,
_bfd_generic_section_already_linked (bfd *abfd,
struct already_linked *linked,
struct bfd_link_info *info)
{
flagword flags;
const char *name;
struct bfd_section_already_linked *l;
struct bfd_section_already_linked_hash_entry *already_linked_list;
struct coff_comdat_info *s_comdat;
asection *sec;
flags = sec->flags;
if ((flags & SEC_LINK_ONCE) == 0)
return;
name = linked->comdat_key;
if (name)
{
sec = NULL;
flags = SEC_GROUP | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
s_comdat = NULL;
}
else
{
sec = linked->u.sec;
flags = sec->flags;
if ((flags & SEC_LINK_ONCE) == 0)
return;
/* FIXME: When doing a relocatable link, we may have trouble
copying relocations in other sections that refer to local symbols
in the section being discarded. Those relocations will have to
be converted somehow; as of this writing I'm not sure that any of
the backends handle that correctly.
s_comdat = bfd_coff_get_comdat_section (abfd, sec);
It is tempting to instead not discard link once sections when
doing a relocatable link (technically, they should be discarded
whenever we are building constructors). However, that fails,
because the linker winds up combining all the link once sections
into a single large link once section, which defeats the purpose
of having link once sections in the first place. */
/* FIXME: When doing a relocatable link, we may have trouble
copying relocations in other sections that refer to local symbols
in the section being discarded. Those relocations will have to
be converted somehow; as of this writing I'm not sure that any of
the backends handle that correctly.
name = bfd_get_section_name (abfd, sec);
It is tempting to instead not discard link once sections when
doing a relocatable link (technically, they should be discarded
whenever we are building constructors). However, that fails,
because the linker winds up combining all the link once sections
into a single large link once section, which defeats the purpose
of having link once sections in the first place. */
name = bfd_get_section_name (abfd, sec);
}
already_linked_list = bfd_section_already_linked_table_lookup (name);
for (l = already_linked_list->entry; l != NULL; l = l->next)
{
bfd_boolean skip = FALSE;
struct coff_comdat_info *s_comdat
= bfd_coff_get_comdat_section (abfd, sec);
struct coff_comdat_info *l_comdat
= bfd_coff_get_comdat_section (l->sec->owner, l->sec);
bfd *l_owner;
flagword l_flags;
struct coff_comdat_info *l_comdat;
asection *l_sec;
if (l->linked.comdat_key)
{
l_sec = NULL;
l_owner = l->linked.u.abfd;
l_comdat = NULL;
l_flags = (SEC_GROUP
| SEC_LINK_ONCE
| SEC_LINK_DUPLICATES_DISCARD);
}
else
{
l_sec = l->linked.u.sec;
l_owner = l_sec->owner;
l_comdat = bfd_coff_get_comdat_section (l_sec->owner, l_sec);
}
/* We may have 3 different sections on the list: group section,
comdat section and linkonce section. SEC may be a linkonce or
@ -3034,7 +3067,7 @@ _bfd_generic_section_already_linked (bfd *abfd, asection *sec,
FIXME: Is that safe to match a linkonce section with a comdat
section for COFF inputs? */
if ((l->sec->flags & SEC_GROUP) != 0)
if ((l_flags & SEC_GROUP) != 0)
skip = TRUE;
else if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
{
@ -3056,6 +3089,18 @@ _bfd_generic_section_already_linked (bfd *abfd, asection *sec,
abort ();
case SEC_LINK_DUPLICATES_DISCARD:
/* If we found an LTO IR match for this comdat group on
the first pass, replace it with the LTO output on the
second pass. We can't simply choose real object
files over IR because the first pass may contain a
mix of LTO and normal objects and we must keep the
first match, be it IR or real. */
if (info->loading_lto_outputs
&& (l_owner->flags & BFD_PLUGIN) != 0)
{
l->linked = *linked;
return;
}
break;
case SEC_LINK_DUPLICATES_ONE_ONLY:
@ -3072,27 +3117,31 @@ _bfd_generic_section_already_linked (bfd *abfd, asection *sec,
either. */
/* Fall through. */
case SEC_LINK_DUPLICATES_SAME_SIZE:
if (sec->size != l->sec->size)
if (sec->size != l_sec->size)
(*_bfd_error_handler)
(_("%B: warning: duplicate section `%A' has different size\n"),
abfd, sec);
break;
}
/* Set the output_section field so that lang_add_section
does not create a lang_input_section structure for this
section. Since there might be a symbol in the section
being discarded, we must retain a pointer to the section
which we are really going to use. */
sec->output_section = bfd_abs_section_ptr;
sec->kept_section = l->sec;
if (sec)
{
/* Set the output_section field so that lang_add_section
does not create a lang_input_section structure for this
section. Since there might be a symbol in the section
being discarded, we must retain a pointer to the section
which we are really going to use. */
sec->output_section = bfd_abs_section_ptr;
sec->kept_section = l_sec;
}
return;
}
}
/* This is the first section with this name. Record it. */
if (! bfd_section_already_linked_table_insert (already_linked_list, sec))
if (! bfd_section_already_linked_table_insert (already_linked_list,
linked))
info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
}