This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: RFC: Move section_already_linked from ld to bfd target vector
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Tue, 29 Jun 2004 00:56:06 -0700
- Subject: Re: RFC: Move section_already_linked from ld to bfd target vector
- References: <20040629012242.GA19269@lucon.org>
On Mon, Jun 28, 2004 at 06:22:42PM -0700, H. J. Lu wrote:
> section_already_linked in ldlang.c has some code to deal with PE's
> comdat, which isn't use by any other targets. Also there is
> bfd_comdat_info in bfd_section for it. I suggest we move
> bfd_comdat_info to PE target and move section_already_linked into
> bfd target vector. We can have a special section_already_linked
> function for PE and a generic one for others. With those changes, we
> can remove PE specifc code from linker as well as bfd_section. Any
> comments?
>
>
>
Here is the proposed patch. It moves bfd_comdat_info from bfd_section
to coff_section_data.
H.J.
---
--- binutils/bfd/aout-adobe.c.comdat 2004-06-28 19:01:58.559534610 -0700
+++ binutils/bfd/aout-adobe.c 2004-06-28 21:29:04.060031807 -0700
@@ -518,6 +518,8 @@ aout_adobe_sizeof_headers (ignore_abfd,
#define aout_32_bfd_merge_sections bfd_generic_merge_sections
#define aout_32_bfd_is_group_section bfd_generic_is_group_section
#define aout_32_bfd_discard_group bfd_generic_discard_group
+#define aout_32_section_already_linked \
+ _bfd_generic_section_already_linked
#define aout_32_bfd_link_hash_table_create \
_bfd_generic_link_hash_table_create
#define aout_32_bfd_link_hash_table_free \
--- binutils/bfd/aout-target.h.comdat 2004-06-28 19:01:58.565533835 -0700
+++ binutils/bfd/aout-target.h 2004-06-28 21:29:04.061031677 -0700
@@ -519,6 +519,10 @@ MY_bfd_final_link (abfd, info)
#ifndef MY_bfd_discard_group
#define MY_bfd_discard_group bfd_generic_discard_group
#endif
+#ifndef MY_section_already_linked
+#define MY_section_already_linked \
+ _bfd_generic_section_already_linked
+#endif
#ifndef MY_bfd_reloc_type_lookup
#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup)
#endif
--- binutils/bfd/aout-tic30.c.comdat 2004-06-28 19:01:58.602529050 -0700
+++ binutils/bfd/aout-tic30.c 2004-06-28 21:29:04.063031418 -0700
@@ -978,6 +978,10 @@ tic30_aout_set_arch_mach (abfd, arch, ma
#ifndef MY_bfd_discard_group
#define MY_bfd_discard_group bfd_generic_discard_group
#endif
+#ifndef MY_section_already_linked
+#define MY_section_already_linked \
+ _bfd_generic_section_already_linked
+#endif
#ifndef MY_bfd_reloc_type_lookup
#define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup
#endif
--- binutils/bfd/bfd-in.h.comdat 2004-06-29 00:37:18.181810072 -0700
+++ binutils/bfd/bfd-in.h 2004-06-29 00:46:31.252197963 -0700
@@ -555,6 +555,9 @@ void bfd_putl16 (bfd_vma, void *);
bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean);
void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean);
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
/* Externally visible ECOFF routines. */
@@ -839,3 +842,21 @@ extern void bfd_elf32_ia64_after_parse
extern void bfd_elf64_ia64_after_parse
(int);
+/* This structure is used for a comdat section, as in PE. A comdat
+ section is associated with a particular symbol. When the linker
+ sees a comdat section, it keeps only one of the sections with a
+ given name and associated with a given symbol. */
+
+struct coff_comdat_info
+{
+ /* The name of the symbol associated with a comdat section. */
+ const char *name;
+
+ /* The local symbol table index of the symbol associated with a
+ comdat section. This is only meaningful to the object file format
+ specific code; it is not an index into the list returned by
+ bfd_canonicalize_symtab. */
+ long symbol;
+};
+extern struct coff_comdat_info *bfd_coff_get_comdat_section
+ (bfd *, struct bfd_section *);
--- binutils/bfd/binary.c.comdat 2004-06-28 19:01:59.103464268 -0700
+++ binutils/bfd/binary.c 2004-06-28 21:29:04.065031160 -0700
@@ -341,6 +341,8 @@ binary_sizeof_headers (abfd, exec)
#define binary_bfd_merge_sections bfd_generic_merge_sections
#define binary_bfd_is_group_section bfd_generic_is_group_section
#define binary_bfd_discard_group bfd_generic_discard_group
+#define binary_section_already_linked \
+ _bfd_generic_section_already_linked
#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define binary_bfd_link_just_syms _bfd_generic_link_just_syms
--- binutils/bfd/bout.c.comdat 2004-06-28 19:01:59.176454829 -0700
+++ binutils/bfd/bout.c 2004-06-28 21:29:04.066031030 -0700
@@ -1487,6 +1487,8 @@ b_out_bfd_get_relocated_section_contents
#define b_out_bfd_merge_sections bfd_generic_merge_sections
#define b_out_bfd_is_group_section bfd_generic_is_group_section
#define b_out_bfd_discard_group bfd_generic_discard_group
+#define b_out_section_already_linked \
+ _bfd_generic_section_already_linked
#define aout_32_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
--- binutils/bfd/coff-alpha.c.comdat 2004-06-28 19:01:59.302438536 -0700
+++ binutils/bfd/coff-alpha.c 2004-06-28 21:29:04.069030642 -0700
@@ -2356,6 +2356,8 @@ static const struct ecoff_backend_data a
#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
+#define _bfd_ecoff_section_already_linked \
+ _bfd_generic_section_already_linked
const bfd_target ecoffalpha_little_vec =
{
--- binutils/bfd/coff-mips.c.comdat 2004-06-28 19:01:59.536408279 -0700
+++ binutils/bfd/coff-mips.c 2004-06-28 21:29:04.071030383 -0700
@@ -1399,6 +1399,8 @@ static const struct ecoff_backend_data m
#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
+#define _bfd_ecoff_section_already_linked \
+ _bfd_generic_section_already_linked
extern const bfd_target ecoff_big_vec;
--- binutils/bfd/coff-rs6000.c.comdat 2004-06-28 19:01:59.778376987 -0700
+++ binutils/bfd/coff-rs6000.c 2004-06-28 21:29:04.075029865 -0700
@@ -4198,6 +4198,7 @@ const bfd_target rs6000coff_vec =
bfd_generic_merge_sections,
bfd_generic_is_group_section,
bfd_generic_discard_group,
+ _bfd_generic_section_already_linked,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
@@ -4443,6 +4444,7 @@ const bfd_target pmac_xcoff_vec =
bfd_generic_merge_sections,
bfd_generic_is_group_section,
bfd_generic_discard_group,
+ _bfd_generic_section_already_linked,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
--- binutils/bfd/coff64-rs6000.c.comdat 2004-06-28 19:02:00.076338454 -0700
+++ binutils/bfd/coff64-rs6000.c 2004-06-28 21:29:04.078029477 -0700
@@ -2739,6 +2739,7 @@ const bfd_target rs6000coff64_vec =
bfd_generic_merge_sections,
bfd_generic_is_group_section,
bfd_generic_discard_group,
+ _bfd_generic_section_already_linked,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
@@ -2985,6 +2986,7 @@ const bfd_target aix5coff64_vec =
bfd_generic_merge_sections,
bfd_generic_is_group_section,
bfd_generic_discard_group,
+ _bfd_generic_section_already_linked,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
--- binutils/bfd/coffcode.h.comdat 2004-06-28 19:02:00.352302766 -0700
+++ binutils/bfd/coffcode.h 2004-06-28 23:56:17.682255473 -0700
@@ -965,12 +965,13 @@ handle_COMDAT (abfd, sec_flags, hdr, nam
Intel puts the two adjacent, but Alpha (at
least) spreads them out. */
- amt = sizeof (struct bfd_comdat_info);
- section->comdat = bfd_alloc (abfd, amt);
- if (section->comdat == NULL)
+ amt = sizeof (struct coff_comdat_info);
+ coff_section_data (abfd, section)->comdat
+ = bfd_alloc (abfd, amt);
+ if (coff_section_data (abfd, section)->comdat == NULL)
abort ();
- section->comdat->symbol =
+ coff_section_data (abfd, section)->comdat->symbol =
(esym - esymstart) / bfd_coff_symesz (abfd);
amt = strlen (symname) + 1;
@@ -979,7 +980,8 @@ handle_COMDAT (abfd, sec_flags, hdr, nam
abort ();
strcpy (newname, symname);
- section->comdat->name = newname;
+ coff_section_data (abfd, section)->comdat->name
+ = newname;
}
goto breakloop;
@@ -5586,6 +5588,10 @@ static const bfd_coff_backend_data ticof
#define coff_bfd_discard_group bfd_generic_discard_group
#endif
+#ifndef coff_section_already_linked
+#define coff_section_already_linked _bfd_coff_section_already_linked
+#endif
+
#define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \
const bfd_target VAR = \
{ \
--- binutils/bfd/coffgen.c.comdat 2004-06-28 19:02:00.451289964 -0700
+++ binutils/bfd/coffgen.c 2004-06-29 00:44:53.067909497 -0700
@@ -2496,3 +2496,13 @@ bfd_coff_set_symbol_class (abfd, symbol,
return TRUE;
}
+
+struct coff_comdat_info *
+bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec)
+{
+ if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
+ return coff_section_data (abfd, sec)->comdat;
+ else
+ return NULL;
+}
+
--- binutils/bfd/cofflink.c.comdat 2004-06-28 19:02:00.607269793 -0700
+++ binutils/bfd/cofflink.c 2004-06-29 00:25:46.558289146 -0700
@@ -435,18 +435,18 @@ coff_link_add_symbols (bfd *abfd,
if (obj_pe (abfd)
&& (classification == COFF_SYMBOL_GLOBAL
|| classification == COFF_SYMBOL_PE_SECTION)
- && section->comdat != NULL
+ && coff_section_data (abfd, section)->comdat != NULL
&& strncmp (name, "??_", 3) == 0
- && strcmp (name, section->comdat->name) == 0)
+ && strcmp (name, coff_section_data (abfd, section)->comdat->name) == 0)
{
if (*sym_hash == NULL)
*sym_hash = coff_link_hash_lookup (coff_hash_table (info),
name, FALSE, copy, FALSE);
if (*sym_hash != NULL
&& (*sym_hash)->root.type == bfd_link_hash_defined
- && (*sym_hash)->root.u.def.section->comdat != NULL
- && strcmp ((*sym_hash)->root.u.def.section->comdat->name,
- section->comdat->name) == 0)
+ && coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat != NULL
+ && strcmp (coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat->name,
+ coff_section_data (abfd, section)->comdat->name) == 0)
addit = FALSE;
}
@@ -3012,3 +3012,113 @@ _bfd_coff_generic_relocate_section (bfd
}
return TRUE;
}
+
+/* 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. */
+
+void
+_bfd_coff_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.
+
+ Also, not merging link once sections in a relocatable link
+ causes trouble for MIPS ELF, which relies on link once semantics
+ to handle the .reginfo section correctly. */
+
+ name = bfd_get_section_name (abfd, sec);
+
+ already_linked_list =
+ ((struct bfd_section_already_linked_hash_entry *)
+ bfd_hash_lookup (&_bfd_section_already_linked_table, name,
+ TRUE, FALSE));
+
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ {
+ if (coff_section_data (abfd, sec)->comdat == NULL
+ || coff_section_data (abfd, l->sec)->comdat == NULL
+ || strcmp (coff_section_data (abfd, sec)->comdat->name,
+ coff_section_data (abfd, l->sec)->comdat->name) == 0)
+ {
+ /* 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 (coff_section_data (abfd, sec)->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,
+ coff_section_data (abfd, sec)->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. 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;
+}
--- binutils/bfd/ecoff.c.comdat 2004-06-28 19:02:01.299180313 -0700
+++ binutils/bfd/ecoff.c 2004-06-28 23:20:52.872038271 -0700
@@ -92,8 +92,8 @@ static asection bfd_debug_section =
NULL, NULL, 0, 0, 0,
/* line_filepos, userdata, contents, lineno, lineno_count, */
0, NULL, NULL, NULL, 0,
- /* entsize, comdat, kept_section, moving_line_filepos, */
- 0, NULL, NULL, 0,
+ /* entsize, kept_section, moving_line_filepos, */
+ 0, NULL, 0,
/* target_index, used_by_bfd, constructor_chain, owner, */
0, NULL, NULL, NULL,
/* symbol, */
--- binutils/bfd/elf-bfd.h.comdat 2004-06-28 19:02:01.401167124 -0700
+++ binutils/bfd/elf-bfd.h 2004-06-29 00:23:03.578359823 -0700
@@ -1380,6 +1380,8 @@ extern bfd_boolean bfd_elf_is_group_sect
(bfd *, const struct bfd_section *);
extern bfd_boolean bfd_elf_discard_group
(bfd *, struct bfd_section *);
+extern void _bfd_elf_section_already_linked
+ (bfd *, struct bfd_section *);
extern void bfd_elf_set_group_contents
(bfd *, asection *, void *);
extern void _bfd_elf_link_just_syms
--- binutils/bfd/elflink.c.comdat 2004-06-28 19:02:08.554242073 -0700
+++ binutils/bfd/elflink.c 2004-06-29 00:28:17.717737947 -0700
@@ -8974,3 +8974,9 @@ bfd_elf_discard_info (bfd *output_bfd, s
return ret;
}
+
+void
+_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
+{
+ return _bfd_generic_section_already_linked (abfd, sec);
+}
--- binutils/bfd/elfxx-target.h.comdat 2004-06-21 14:05:28.000000000 -0700
+++ binutils/bfd/elfxx-target.h 2004-06-29 00:23:41.967398128 -0700
@@ -144,6 +144,11 @@
#define bfd_elfNN_bfd_discard_group bfd_elf_discard_group
#endif
+#ifndef bfd_elfNN_section_already_linked
+#define bfd_elfNN_section_already_linked \
+ _bfd_elf_section_already_linked
+#endif
+
#ifndef bfd_elfNN_bfd_make_debug_symbol
#define bfd_elfNN_bfd_make_debug_symbol \
((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
--- binutils/bfd/i386msdos.c.comdat 2004-06-28 19:02:09.441127379 -0700
+++ binutils/bfd/i386msdos.c 2004-06-28 21:29:04.087028312 -0700
@@ -177,6 +177,8 @@ msdos_set_section_contents (abfd, sectio
#define msdos_bfd_merge_sections bfd_generic_merge_sections
#define msdos_bfd_is_group_section bfd_generic_is_group_section
#define msdos_bfd_discard_group bfd_generic_discard_group
+#define msdos_section_already_linked \
+ _bfd_generic_section_already_linked
#define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define msdos_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/i386os9k.c.comdat 2004-06-28 19:02:09.444126992 -0700
+++ binutils/bfd/i386os9k.c 2004-06-28 21:29:04.087028312 -0700
@@ -335,6 +335,8 @@ os9k_sizeof_headers (ignore_abfd, ignore
#define os9k_bfd_merge_sections bfd_generic_merge_sections
#define os9k_bfd_is_group_section bfd_generic_is_group_section
#define os9k_bfd_discard_group bfd_generic_discard_group
+#define os9k_section_already_linked \
+ _bfd_generic_section_already_linked
#define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define os9k_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define os9k_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/ieee.c.comdat 2004-06-28 19:02:09.620104234 -0700
+++ binutils/bfd/ieee.c 2004-06-28 21:29:04.089028053 -0700
@@ -4039,6 +4039,8 @@ ieee_bfd_debug_info_accumulate (abfd, se
#define ieee_bfd_merge_sections bfd_generic_merge_sections
#define ieee_bfd_is_group_section bfd_generic_is_group_section
#define ieee_bfd_discard_group bfd_generic_discard_group
+#define ieee_section_already_linked \
+ _bfd_generic_section_already_linked
#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/ihex.c.comdat 2004-06-28 19:02:09.712092338 -0700
+++ binutils/bfd/ihex.c 2004-06-28 21:29:04.091027794 -0700
@@ -990,6 +990,8 @@ ihex_sizeof_headers (abfd, exec)
#define ihex_bfd_merge_sections bfd_generic_merge_sections
#define ihex_bfd_is_group_section bfd_generic_is_group_section
#define ihex_bfd_discard_group bfd_generic_discard_group
+#define ihex_section_already_linked \
+ _bfd_generic_section_already_linked
#define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ihex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define ihex_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/libbfd-in.h.comdat 2004-06-28 19:02:09.915066089 -0700
+++ binutils/bfd/libbfd-in.h 2004-06-28 23:59:37.473336135 -0700
@@ -375,6 +375,8 @@ extern bfd_boolean _bfd_generic_set_sect
((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false)
#define _bfd_nolink_bfd_link_split_section \
((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
+#define _bfd_nolink_section_already_linked \
+ ((void (*) (bfd *, struct bfd_section *)) bfd_void)
/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC
@@ -474,6 +476,9 @@ extern bfd_boolean _bfd_generic_final_li
extern bfd_boolean _bfd_generic_link_split_section
(bfd *, struct bfd_section *);
+extern void _bfd_generic_section_already_linked
+ (bfd *, struct bfd_section *);
+
/* Generic reloc_link_order processing routine. */
extern bfd_boolean _bfd_generic_reloc_link_order
(bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
@@ -653,3 +658,23 @@ extern bfd_boolean _bfd_sh_align_load_sp
bfd_boolean (*) (bfd *, asection *, void *, bfd_byte *, bfd_vma),
void *, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *);
#endif
+
+/* This is the shape of the elements inside the already_linked hash
+ table. It maps a name onto a list of already_linked elements with
+ the same name. */
+
+struct bfd_section_already_linked_hash_entry
+{
+ struct bfd_hash_entry root;
+ struct bfd_section_already_linked *entry;
+};
+
+struct bfd_section_already_linked
+{
+ struct bfd_section_already_linked *next;
+ asection *sec;
+};
+
+/* The hash table. */
+
+extern struct bfd_hash_table _bfd_section_already_linked_table;
--- binutils/bfd/libcoff-in.h.comdat 2004-06-28 19:02:10.235024711 -0700
+++ binutils/bfd/libcoff-in.h 2004-06-29 00:45:21.062285126 -0700
@@ -194,6 +194,8 @@ struct coff_section_tdata
bfd_vma offset;
unsigned int i;
const char *function;
+ /* Optional information about a COMDAT entry; NULL if not COMDAT. */
+ struct coff_comdat_info *comdat;
int line_base;
/* A pointer used for .stab linking optimizations. */
PTR stab_info;
@@ -357,6 +359,8 @@ extern bfd_vma bfd_coff_reloc16_get_valu
PARAMS ((arelent *, struct bfd_link_info *, asection *));
extern void bfd_perform_slip
PARAMS ((bfd *, unsigned int, asection *, bfd_vma));
+extern void _bfd_coff_section_already_linked
+ (bfd *, asection *);
/* Functions and types in cofflink.c. */
--- binutils/bfd/linker.c.comdat 2004-06-28 19:02:10.388004927 -0700
+++ binutils/bfd/linker.c 2004-06-29 00:24:46.728026442 -0700
@@ -2825,3 +2825,147 @@ _bfd_generic_link_split_section (bfd *ab
{
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. */
+
+struct bfd_hash_table _bfd_section_already_linked_table;
+
+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.
+
+ Also, not merging link once sections in a relocatable link
+ causes trouble for MIPS ELF, which relies on link once semantics
+ to handle the .reginfo section correctly. */
+
+ name = bfd_get_section_name (abfd, sec);
+
+ already_linked_list =
+ ((struct bfd_section_already_linked_hash_entry *)
+ bfd_hash_lookup (&_bfd_section_already_linked_table, name,
+ TRUE, FALSE));
+
+ l = already_linked_list->entry;
+ if (l)
+ {
+ /* 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:
+ (*_bfd_error_handler)
+ (_("%s: %s: warning: ignoring duplicate section `%s'\n"),
+ bfd_archive_filename (abfd), name);
+ break;
+
+ 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;
+
+ if (flags & SEC_GROUP)
+ bfd_discard_group (abfd, sec);
+
+ return;
+ }
+
+ /* This is the first section with this name. Record it. 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;
+}
+
+/* Support routines for the hash table used by section_already_linked,
+ initialize the table, fill in an entry and remove the table. */
+
+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 (struct bfd_section_already_linked_hash_entry));
+
+ 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);
+}
--- binutils/bfd/mach-o.c.comdat 2004-06-28 19:02:10.488991867 -0700
+++ binutils/bfd/mach-o.c 2004-06-28 21:29:04.093027535 -0700
@@ -70,6 +70,8 @@
#define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
#define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
#define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
+#define bfd_mach_o_section_already_linked \
+ _bfd_generic_section_already_linked
#define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data
--- binutils/bfd/mmo.c.comdat 2004-06-28 19:02:10.811950102 -0700
+++ binutils/bfd/mmo.c 2004-06-28 21:29:04.096027147 -0700
@@ -3286,6 +3286,8 @@ mmo_canonicalize_reloc (abfd, section, r
#define mmo_bfd_merge_sections bfd_generic_merge_sections
#define mmo_bfd_is_group_section bfd_generic_is_group_section
#define mmo_bfd_discard_group bfd_generic_discard_group
+#define mmo_section_already_linked \
+ _bfd_generic_section_already_linked
/* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by
using BFD_JUMP_TABLE_RELOCS (_bfd_norelocs) rather than 0. FIXME: Most
--- binutils/bfd/nlm-target.h.comdat 2004-05-10 07:18:16.000000000 -0700
+++ binutils/bfd/nlm-target.h 2004-06-28 21:29:04.097027017 -0700
@@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suit
#define nlm_bfd_merge_sections bfd_generic_merge_sections
#define nlm_bfd_is_group_section bfd_generic_is_group_section
#define nlm_bfd_discard_group bfd_generic_discard_group
+#define nlm_section_already_linked \
+ _bfd_generic_section_already_linked
#define nlm_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define nlm_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define nlm_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/oasys.c.comdat 2004-06-28 19:02:11.054918681 -0700
+++ binutils/bfd/oasys.c 2004-06-28 21:29:04.098026888 -0700
@@ -1508,6 +1508,8 @@ oasys_sizeof_headers (abfd, exec)
#define oasys_bfd_merge_sections bfd_generic_merge_sections
#define oasys_bfd_is_group_section bfd_generic_is_group_section
#define oasys_bfd_discard_group bfd_generic_discard_group
+#define oasys_section_already_linked \
+ _bfd_generic_section_already_linked
#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/pef.c.comdat 2004-06-28 19:02:11.521858295 -0700
+++ binutils/bfd/pef.c 2004-06-28 21:29:04.099026758 -0700
@@ -54,6 +54,7 @@
#define bfd_pef_bfd_merge_sections bfd_generic_merge_sections
#define bfd_pef_bfd_is_group_section bfd_generic_is_group_section
#define bfd_pef_bfd_discard_group bfd_generic_discard_group
+#define bfd_pef_section_already_linked _bfd_generic_section_already_linked
#define bfd_pef_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define bfd_pef_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define bfd_pef_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/ppcboot.c.comdat 2004-06-28 19:02:11.525857778 -0700
+++ binutils/bfd/ppcboot.c 2004-06-28 21:29:04.100026629 -0700
@@ -471,6 +471,8 @@ ppcboot_bfd_print_private_bfd_data (abfd
#define ppcboot_bfd_merge_sections bfd_generic_merge_sections
#define ppcboot_bfd_is_group_section bfd_generic_is_group_section
#define ppcboot_bfd_discard_group bfd_generic_discard_group
+#define ppcboot_section_already_linked \
+ _bfd_generic_section_already_linked
#define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ppcboot_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define ppcboot_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/section.c.comdat 2004-06-28 19:02:11.856814978 -0700
+++ binutils/bfd/section.c 2004-06-28 23:21:09.369896697 -0700
@@ -149,23 +149,6 @@ SUBSECTION
CODE_FRAGMENT
.
-.{* This structure is used for a comdat section, as in PE. A comdat
-. section is associated with a particular symbol. When the linker
-. sees a comdat section, it keeps only one of the sections with a
-. given name and associated with a given symbol. *}
-.
-.struct bfd_comdat_info
-.{
-. {* The name of the symbol associated with a comdat section. *}
-. const char *name;
-.
-. {* The local symbol table index of the symbol associated with a
-. comdat section. This is only meaningful to the object file format
-. specific code; it is not an index into the list returned by
-. bfd_canonicalize_symtab. *}
-. long symbol;
-.};
-.
.typedef struct bfd_section
.{
. {* The name of the section; the name isn't a copy, the pointer is
@@ -488,9 +471,6 @@ CODE_FRAGMENT
. {* Entity size for merging purposes. *}
. unsigned int entsize;
.
-. {* Optional information about a COMDAT entry; NULL if not COMDAT. *}
-. struct bfd_comdat_info *comdat;
-.
. {* Points to the kept section if this section is a link-once section,
. and is discarded. *}
. struct bfd_section *kept_section;
@@ -633,8 +613,8 @@ static const asymbol global_syms[] =
/* line_filepos, userdata, contents, lineno, lineno_count, */ \
0, NULL, NULL, NULL, 0, \
\
- /* entsize, comdat, kept_section, moving_line_filepos, */ \
- 0, NULL, NULL, 0, \
+ /* entsize, kept_section, moving_line_filepos, */ \
+ 0, NULL, 0, \
\
/* target_index, used_by_bfd, constructor_chain, owner, */ \
0, NULL, NULL, NULL, \
--- binutils/bfd/som.c.comdat 2004-06-28 19:02:12.099783556 -0700
+++ binutils/bfd/som.c 2004-06-28 21:29:04.105025982 -0700
@@ -6404,6 +6404,8 @@ som_bfd_link_split_section (abfd, sec)
#define som_bfd_merge_sections bfd_generic_merge_sections
#define som_bfd_is_group_section bfd_generic_is_group_section
#define som_bfd_discard_group bfd_generic_discard_group
+#define som_section_already_linked \
+ _bfd_generic_section_already_linked
const bfd_target som_vec = {
"som", /* name */
--- binutils/bfd/srec.c.comdat 2004-06-28 19:02:12.184772565 -0700
+++ binutils/bfd/srec.c 2004-06-28 21:29:04.106025852 -0700
@@ -1286,6 +1286,8 @@ srec_print_symbol (abfd, afile, symbol,
#define srec_bfd_merge_sections bfd_generic_merge_sections
#define srec_bfd_is_group_section bfd_generic_is_group_section
#define srec_bfd_discard_group bfd_generic_discard_group
+#define srec_section_already_linked \
+ _bfd_generic_section_already_linked
#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define srec_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/targets.c.comdat 2004-05-25 22:45:54.000000000 -0700
+++ binutils/bfd/targets.c 2004-06-28 21:54:25.227081136 -0700
@@ -412,7 +412,8 @@ BFD_JUMP_TABLE macros.
. NAME##_bfd_gc_sections, \
. NAME##_bfd_merge_sections, \
. NAME##_bfd_is_group_section, \
-. NAME##_bfd_discard_group
+. NAME##_bfd_discard_group, \
+. NAME##_section_already_linked \
.
. int (*_bfd_sizeof_headers) (bfd *, bfd_boolean);
. bfd_byte * (*_bfd_get_relocated_section_contents)
@@ -455,6 +456,10 @@ BFD_JUMP_TABLE macros.
. {* Discard members of a group. *}
. bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
.
+. {* Check if SEC has been already linked during a reloceatable or
+. final link. *}
+. void (*_section_already_linked) (bfd *, struct bfd_section *);
+.
. {* Routines to handle dynamic symbols and relocs. *}
.#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
. NAME##_get_dynamic_symtab_upper_bound, \
--- binutils/bfd/tekhex.c.comdat 2004-06-28 19:02:12.429740886 -0700
+++ binutils/bfd/tekhex.c 2004-06-28 21:29:04.109025464 -0700
@@ -1003,6 +1003,8 @@ tekhex_print_symbol (abfd, filep, symbol
#define tekhex_bfd_merge_sections bfd_generic_merge_sections
#define tekhex_bfd_is_group_section bfd_generic_is_group_section
#define tekhex_bfd_discard_group bfd_generic_discard_group
+#define tekhex_section_already_linked \
+ _bfd_generic_section_already_linked
#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/versados.c.comdat 2004-06-28 19:02:12.474735067 -0700
+++ binutils/bfd/versados.c 2004-06-28 21:29:04.109025464 -0700
@@ -874,6 +874,8 @@ versados_canonicalize_reloc (abfd, secti
#define versados_bfd_merge_sections bfd_generic_merge_sections
#define versados_bfd_is_group_section bfd_generic_is_group_section
#define versados_bfd_discard_group bfd_generic_discard_group
+#define versados_section_already_linked \
+ _bfd_generic_section_already_linked
#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/bfd/vms.c.comdat 2004-06-28 19:02:12.671709594 -0700
+++ binutils/bfd/vms.c 2004-06-28 21:29:04.111025205 -0700
@@ -168,6 +168,8 @@ static bfd_boolean vms_bfd_set_private_f
#define vms_bfd_link_just_syms _bfd_generic_link_just_syms
#define vms_bfd_is_group_section bfd_generic_is_group_section
#define vms_bfd_discard_group bfd_generic_discard_group
+#define vms_section_already_linked \
+ _bfd_generic_section_already_linked
#define vms_bfd_copy_private_header_data \
_bfd_generic_bfd_copy_private_header_data
--- binutils/bfd/xcoff-target.h.comdat 2002-11-30 00:39:40.000000000 -0800
+++ binutils/bfd/xcoff-target.h 2004-06-28 21:29:04.111025205 -0700
@@ -99,6 +99,8 @@ extern int lynx_core_file_failing_signal
#define _bfd_xcoff_bfd_gc_sections coff_bfd_gc_sections
#define _bfd_xcoff_bfd_merge_sections coff_bfd_merge_sections
#define _bfd_xcoff_bfd_discard_group bfd_generic_discard_group
+#define _bfd_xcoff_section_already_linked \
+ _bfd_generic_section_already_linked
#define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section
/* XCOFF archives do not have anything which corresponds to an
--- binutils/bfd/xsym.c.comdat 2004-06-28 19:02:13.059659423 -0700
+++ binutils/bfd/xsym.c 2004-06-28 21:29:04.113024946 -0700
@@ -44,6 +44,8 @@
#define bfd_sym_bfd_merge_sections bfd_generic_merge_sections
#define bfd_sym_bfd_is_group_section bfd_generic_is_group_section
#define bfd_sym_bfd_discard_group bfd_generic_discard_group
+#define bfd_sym_section_already_linked \
+ _bfd_generic_section_already_linked
#define bfd_sym_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define bfd_sym_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define bfd_sym_bfd_link_add_symbols _bfd_generic_link_add_symbols
--- binutils/ld/ldlang.c.comdat 2004-06-28 19:02:15.394357495 -0700
+++ binutils/ld/ldlang.c 2004-06-29 00:52:33.383317486 -0700
@@ -883,44 +883,10 @@ exp_init_os (etree_type *exp)
}
}
-/* 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. If the section has COMDAT information, then it uses
- that to decide whether the section should be included. 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.
- section_already_linked is called via bfd_map_over_sections. */
-
-/* This is the shape of the elements inside the already_linked hash
- table. It maps a name onto a list of already_linked elements with
- the same name. It's possible to get more than one element in a
- list if the COMDAT sections have different names. */
-
-struct already_linked_hash_entry
-{
- struct bfd_hash_entry root;
- struct already_linked *entry;
-};
-
-struct already_linked
-{
- struct already_linked *next;
- asection *sec;
-};
-
-/* The hash table. */
-
-static struct bfd_hash_table already_linked_table;
-
static void
section_already_linked (bfd *abfd, asection *sec, void *data)
{
lang_input_statement_type *entry = data;
- flagword flags;
- const char *name;
- struct already_linked *l;
- struct already_linked_hash_entry *already_linked_list;
/* If we are only reading symbols from this object, then we want to
discard all sections. */
@@ -930,128 +896,7 @@ section_already_linked (bfd *abfd, asect
return;
}
- 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.
-
- Also, not merging link once sections in a relocatable link
- causes trouble for MIPS ELF, which relies on link once semantics
- to handle the .reginfo section correctly. */
-
- name = bfd_get_section_name (abfd, sec);
-
- already_linked_list =
- ((struct already_linked_hash_entry *)
- bfd_hash_lookup (&already_linked_table, name, TRUE, FALSE));
-
- for (l = already_linked_list->entry; l != NULL; l = l->next)
- {
- if (sec->comdat == NULL
- || l->sec->comdat == NULL
- || strcmp (sec->comdat->name, l->sec->comdat->name) == 0)
- {
- /* 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 (sec->comdat == NULL)
- einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"),
- abfd, name);
- else
- einfo (_("%P: %B: warning: ignoring duplicate `%s'"
- " section symbol `%s'\n"),
- abfd, name, sec->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)
- einfo (_("%P: %B: warning: duplicate section `%s'"
- " has different size\n"),
- 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;
-
- if (flags & SEC_GROUP)
- bfd_discard_group (abfd, sec);
-
- return;
- }
- }
-
- /* This is the first section with this name. Record it. Allocate
- the memory from the same obstack as the hash table is kept in. */
-
- l = bfd_hash_allocate (&already_linked_table, sizeof *l);
-
- l->sec = sec;
- l->next = already_linked_list->entry;
- already_linked_list->entry = l;
-}
-
-/* Support routines for the hash table used by section_already_linked,
- initialize the table, fill in an entry and remove the table. */
-
-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 already_linked_hash_entry *ret =
- bfd_hash_allocate (table, sizeof (struct already_linked_hash_entry));
-
- ret->entry = NULL;
-
- return &ret->root;
-}
-
-static void
-already_linked_table_init (void)
-{
- if (! bfd_hash_table_init_n (&already_linked_table,
- already_linked_newfunc,
- 42))
- einfo (_("%P%F: Failed to create hash table\n"));
-}
-
-static void
-already_linked_table_free (void)
-{
- bfd_hash_table_free (&already_linked_table);
+ bfd_section_already_linked (abfd, sec);
}
/* The wild routines.
@@ -4340,7 +4185,8 @@ lang_process (void)
/* Add to the hash table all undefineds on the command line. */
lang_place_undefineds ();
- already_linked_table_init ();
+ if (!bfd_section_already_linked_table_init ())
+ einfo (_("%P%F: Failed to create hash table\n"));
/* Create a bfd for each input file. */
current_target = default_target;
@@ -4352,7 +4198,7 @@ lang_process (void)
ldemul_after_open ();
- already_linked_table_free ();
+ bfd_section_already_linked_table_free ();
/* Make sure that we're not mixing architectures. We call this
after all the input files have been opened, but before we do any