forked from Imagelibrary/binutils-gdb
bfd/
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:
194
bfd/linker.c
194
bfd/linker.c
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user