2004-07-21  H.J. Lu  <hongjiu.lu@intel.com>

	* aout-adobe.c (aout_32_section_already_linked): Defined.
	* aout-target.h (MY_section_already_linked): Likewise.
	* aout-tic30.c (MY_section_already_linked): Likewise.
	* binary.c (binary_section_already_linked): Likewise.
	* bout.c (b_out_section_already_linked): Likewise.
	* coff-alpha.c (_bfd_ecoff_section_already_linked): Likewise.
	* coff-mips.c (_bfd_ecoff_section_already_linked): Likewise.
	* coffcode.h (coff_section_already_linked): Likewise.
	* i386msdos.c (msdos_section_already_linked): Likewise.
	* i386os9k.c (os9k_section_already_linked): Likewise.
	* ieee.c (ieee_section_already_linked): Likewise.
	* ihex.c (ihex_section_already_linked): Likewise.
	* mach-o.c (bfd_mach_o_section_already_linked): Likewise.
	* mmo.c (mmo_section_already_linked): Likewise.
	* nlm-target.h (nlm_section_already_linked): Likewise.
	* oasys.c (oasys_section_already_linked): Likewise.
	* pef.c (bfd_pef_section_already_linked): Likewise.
	* ppcboot.c (ppcboot_section_already_linked): Likewise.
	* som.c (som_bfd_discard_group): Likewise.
	* srec.c (srec_section_already_linked): Likewise.
	* tekhex.c (tekhex_section_already_linked): Likewise.
	* versados.c (versados_section_already_linked): Likewise.
	* vms.c (vms_section_already_linked): Likewise.
	* coff-target.h (_bfd_xcoff_section_already_linked): Likewise.
	* xsym.c (bfd_sym_section_already_linked): Likewise.

	* bfd-in.h (bfd_section_already_linked_table_init): New.
	(bfd_section_already_linked_table_free): Likewise.

	* coff-rs6000.c (rs6000coff_vec): Add
	_bfd_generic_section_already_linked.
	(pmac_xcoff_vec): Likewise.
	* coff64-rs6000.c (rs6000coff64_vec): Likewise.
	(aix5coff64_vec): Likewise.

	* elf-bfd.h (_bfd_elf_section_already_linked): New prototype.
	* elflink.c (_bfd_elf_section_already_linked): New function.

	* elfxx-target.h (bfd_elfNN_section_already_linked): Defined.

	* libbfd-in.h (_bfd_nolink_section_already_linked): Defined.
	(_bfd_generic_section_already_linked): New.
	(bfd_section_already_linked_hash_entry): Likewise.
	(bfd_section_already_linked): Likewise.
	(bfd_section_already_linked_table_lookup): Likewise.
	(bfd_section_already_linked_table_insert): Likewise.

	* linker.c (bfd_section_already_linked): New.
	(_bfd_section_already_linked_table): Likewise.
	(bfd_section_already_linked_table_lookup): Likewise.
	(bfd_section_already_linked_table_insert): Likewise.
	(already_linked_newfunc): Likewise.
	(bfd_section_already_linked_table_init): Likewise.
	(bfd_section_already_linked_table_free): Likewise.
	(_bfd_generic_section_already_linked): Likewise.

	* section.c (bfd_section): Remove comdat.
	(bfd_comdat_info): Moved to ...
	* bfd-in.h (coff_comdat_info): Here.
	(bfd_coff_get_comdat_section): New.
	* coffgen.c (bfd_coff_get_comdat_section): Likewise.
	* libcoff-in.h (coff_section_tdata): Add comdat.
	* coffcode.h (handle_COMDAT): Updated.
	* cofflink.c (coff_link_add_symbols): Likewise.
	* ecoff.c (bfd_debug_section): Likewise.

	* targets.c (bfd_target): Add _section_already_linked.
	(BFD_JUMP_TABLE_LINK): Updated.

	* bfd-in2.h: Regenerated.
	* libbfd.h: Likewise.
	* libcoff.h: Likewise.

binutils/

2004-07-21  H.J. Lu  <hongjiu.lu@intel.com>

	* objcopy.c (filter_symbols): Use bfd_coff_get_comdat_section
	to access comdat.
	* objdump.c (dump_section_header): Likewise.

ld/

2004-07-21  H.J. Lu  <hongjiu.lu@intel.com>

	* ldlang.c (already_linked_hash_entry): Removed.
	(already_linked): Likewise.
	(already_linked_table): Likewise.
	(section_already_linked): Call bfd_section_already_linked.
	(lang_process): Replace already_linked_table_init with
	bfd_section_already_linked_table_init and check return. Replace
	already_linked_table_free with bfd_section_already_linked_table_free.
This commit is contained in:
H.J. Lu
2004-07-21 15:42:58 +00:00
parent 76d7af2d04
commit 082b729701
48 changed files with 591 additions and 218 deletions

View File

@@ -2827,3 +2827,197 @@ _bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED,
{
return FALSE;
}
/*
FUNCTION
bfd_section_already_linked
SYNOPSIS
void bfd_section_already_linked (bfd *abfd, asection *sec);
DESCRIPTION
Check if @var{sec} has been already linked during a reloceatable
or final link.
.#define bfd_section_already_linked(abfd, sec) \
. BFD_SEND (abfd, _section_already_linked, (abfd, sec))
.
*/
/* Sections marked with the SEC_LINK_ONCE flag should only be linked
once into the output. This routine checks each section, and
arrange to discard it if a section of the same name has already
been linked. This code assumes that all relevant sections have the
SEC_LINK_ONCE flag set; that is, it does not depend solely upon the
section name. bfd_section_already_linked is called via
bfd_map_over_sections. */
/* The hash table. */
static struct bfd_hash_table _bfd_section_already_linked_table;
/* Support routines for the hash table used by section_already_linked,
initialize the table, lookup, fill in an entry and remove the
table. */
struct bfd_section_already_linked_hash_entry *
bfd_section_already_linked_table_lookup (const char *name)
{
return ((struct bfd_section_already_linked_hash_entry *)
bfd_hash_lookup (&_bfd_section_already_linked_table, name,
TRUE, FALSE));
}
void
bfd_section_already_linked_table_insert
(struct bfd_section_already_linked_hash_entry *already_linked_list,
asection *sec)
{
struct bfd_section_already_linked *l;
/* Allocate the memory from the same obstack as the hash table is
kept in. */
l = bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
l->sec = sec;
l->next = already_linked_list->entry;
already_linked_list->entry = l;
}
static struct bfd_hash_entry *
already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
struct bfd_hash_table *table,
const char *string ATTRIBUTE_UNUSED)
{
struct bfd_section_already_linked_hash_entry *ret =
bfd_hash_allocate (table, sizeof *ret);
ret->entry = NULL;
return &ret->root;
}
bfd_boolean
bfd_section_already_linked_table_init (void)
{
return bfd_hash_table_init_n (&_bfd_section_already_linked_table,
already_linked_newfunc, 42);
}
void
bfd_section_already_linked_table_free (void)
{
bfd_hash_table_free (&_bfd_section_already_linked_table);
}
/* This is used on non-ELF inputs. */
void
_bfd_generic_section_already_linked (bfd *abfd, asection *sec)
{
flagword flags;
const char *name;
struct bfd_section_already_linked *l;
struct bfd_section_already_linked_hash_entry *already_linked_list;
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.
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);
/* We may have 3 different sections on the list: group section,
comdat section and linkonce section. SEC may be a linkonce or
comdat section. We always ignore group section. For non-COFF
inputs, we also ignore comdat section.
FIXME: Is that safe to match a linkonce section with a comdat
section for COFF inputs? */
if ((l->sec->flags & SEC_GROUP) != 0)
skip = TRUE;
else if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
{
if (s_comdat != NULL
&& l_comdat != NULL
&& strcmp (s_comdat->name, l_comdat->name) != 0)
skip = TRUE;
}
else if (l_comdat != NULL)
skip = TRUE;
if (!skip)
{
/* The section has already been linked. See if we should
issue a warning. */
switch (flags & SEC_LINK_DUPLICATES)
{
default:
abort ();
case SEC_LINK_DUPLICATES_DISCARD:
break;
case SEC_LINK_DUPLICATES_ONE_ONLY:
if (s_comdat == NULL)
(*_bfd_error_handler)
(_("%s: %s: warning: ignoring duplicate section `%s'\n"),
bfd_archive_filename (abfd), name);
else
(*_bfd_error_handler)
(_("%s: %s: warning: ignoring duplicate `%s' section symbol `%s'\n"),
bfd_archive_filename (abfd), name, s_comdat->name);
break;
case SEC_LINK_DUPLICATES_SAME_CONTENTS:
/* FIXME: We should really dig out the contents of both
sections and memcmp them. The COFF/PE spec says that
the Microsoft linker does not implement this
correctly, so I'm not going to bother doing it
either. */
/* Fall through. */
case SEC_LINK_DUPLICATES_SAME_SIZE:
if (sec->size != l->sec->size)
(*_bfd_error_handler)
(_("%s: %s: warning: duplicate section `%s' has different size\n"),
bfd_archive_filename (abfd), name);
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;
return;
}
}
/* This is the first section with this name. Record it. */
bfd_section_already_linked_table_insert (already_linked_list, sec);
}