OSDN Git Service

bfd/
authorH.J. Lu <hjl@lucon.org>
Wed, 21 Jul 2004 15:42:58 +0000 (15:42 +0000)
committerH.J. Lu <hjl@lucon.org>
Wed, 21 Jul 2004 15:42:58 +0000 (15:42 +0000)
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.

48 files changed:
bfd/ChangeLog
bfd/aout-adobe.c
bfd/aout-target.h
bfd/aout-tic30.c
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/binary.c
bfd/bout.c
bfd/coff-alpha.c
bfd/coff-mips.c
bfd/coff-rs6000.c
bfd/coff64-rs6000.c
bfd/coffcode.h
bfd/coffgen.c
bfd/cofflink.c
bfd/ecoff.c
bfd/elf-bfd.h
bfd/elflink.c
bfd/elfxx-target.h
bfd/i386msdos.c
bfd/i386os9k.c
bfd/ieee.c
bfd/ihex.c
bfd/libbfd-in.h
bfd/libbfd.h
bfd/libcoff-in.h
bfd/libcoff.h
bfd/linker.c
bfd/mach-o.c
bfd/mmo.c
bfd/nlm-target.h
bfd/oasys.c
bfd/pef.c
bfd/ppcboot.c
bfd/section.c
bfd/som.c
bfd/srec.c
bfd/targets.c
bfd/tekhex.c
bfd/versados.c
bfd/vms.c
bfd/xcoff-target.h
bfd/xsym.c
binutils/ChangeLog
binutils/objcopy.c
binutils/objdump.c
ld/ChangeLog
ld/ldlang.c

index b733251..fce9926 100644 (file)
@@ -1,3 +1,78 @@
+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.
+
 2003-07-21  Paul Brook  <paul@codesourcery.com>
 
        * elflink.c (elf_get_linked_section_vma, compare_link_order,
index 2e3a65f..6de2a31 100644 (file)
@@ -518,6 +518,8 @@ aout_adobe_sizeof_headers (ignore_abfd, ignore)
 #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 \
index 5fb58d0..a169704 100644 (file)
@@ -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
index cf574ff..a9c06ff 100644 (file)
@@ -976,6 +976,10 @@ tic30_aout_set_arch_mach (abfd, arch, machine)
 #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
index f48e9d7..062e55e 100644 (file)
@@ -559,6 +559,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);
 \f
 /* Externally visible ECOFF routines.  */
 
@@ -847,3 +850,23 @@ 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 *);
+
index 502a01b..f661889 100644 (file)
@@ -566,6 +566,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);
 \f
 /* Externally visible ECOFF routines.  */
 
@@ -854,6 +857,26 @@ 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 *);
+
 /* Extracted from init.c.  */
 void bfd_init (void);
 
@@ -1019,23 +1042,6 @@ long bfd_get_size (bfd *abfd);
 
 /* Extracted from bfdwin.c.  */
 /* Extracted from section.c.  */
-/* 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
@@ -1359,9 +1365,6 @@ typedef struct bfd_section
   /* 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;
@@ -4430,7 +4433,8 @@ typedef struct bfd_target
   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)
@@ -4473,6 +4477,10 @@ typedef struct bfd_target
   /* 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, \
@@ -4530,6 +4538,11 @@ bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
 #define bfd_link_split_section(abfd, sec) \
        BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
 
+void bfd_section_already_linked (bfd *abfd, asection *sec);
+
+#define bfd_section_already_linked(abfd, sec) \
+       BFD_SEND (abfd, _section_already_linked, (abfd, sec))
+
 /* Extracted from simple.c.  */
 bfd_byte *bfd_simple_get_relocated_section_contents
    (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
index 2669ed3..4335a28 100644 (file)
@@ -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
index 63c3084..fe0c867 100644 (file)
@@ -1487,6 +1487,8 @@ b_out_bfd_get_relocated_section_contents (output_bfd, link_info, link_order,
 #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
index 7f3f831..2acb800 100644 (file)
@@ -2356,6 +2356,8 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
 #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 =
 {
index f351eb1..39f7f22 100644 (file)
@@ -1395,6 +1395,8 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
 
 #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;
 
index 79c5ae1..ed4a242 100644 (file)
@@ -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,
index 098ea42..e8abaa1 100644 (file)
@@ -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,
index d40cc80..c9773a6 100644 (file)
@@ -965,12 +965,13 @@ handle_COMDAT (abfd, sec_flags, hdr, name, section)
                   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, name, section)
                  abort ();
 
                strcpy (newname, symname);
-               section->comdat->name = newname;
+               coff_section_data (abfd, section)->comdat->name
+                 = newname;
              }
 
              goto breakloop;
@@ -5586,6 +5588,11 @@ static const bfd_coff_backend_data ticoff1_swap_table =
 #define coff_bfd_discard_group             bfd_generic_discard_group
 #endif
 
+#ifndef coff_section_already_linked
+#define coff_section_already_linked \
+  _bfd_generic_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 =                                                 \
 {                                                                      \
index 22a85b3..b6fa5ca 100644 (file)
@@ -2496,3 +2496,12 @@ bfd_coff_set_symbol_class (abfd, symbol, class)
 
   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;
+}
index af6dd3d..ddb56f4 100644 (file)
@@ -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;
            }
 
index 40faea7..eba6236 100644 (file)
@@ -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,                                                       */
index ee60894..5e50683 100644 (file)
@@ -1394,6 +1394,8 @@ extern bfd_boolean bfd_elf_is_group_section
   (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
index 1e04be8..f75dbac 100644 (file)
@@ -9154,3 +9154,89 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 
   return ret;
 }
+
+void
+_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * 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 = bfd_section_already_linked_table_lookup (name);
+
+  for (l = already_linked_list->entry; l != NULL; l = l->next)
+    {
+      /* We may have 3 different sections on the list: group section,
+        comdat section and linkonce section. SEC may be a linkonce or
+        group section. We match a group section with a group section,
+        a linkonce section with a linkonce section, and ignore comdat
+        section.  */
+      if ((sec->flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
+         && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
+       {
+         /* 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_elf_discard_group (abfd, sec);
+
+         return;
+       }
+    }
+
+  /* This is the first section with this name.  Record it.  */
+  bfd_section_already_linked_table_insert (already_linked_list, sec);
+}
index a48b9f3..b4aa171 100644 (file)
 #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)
index 65080e3..aedcef0 100644 (file)
@@ -177,6 +177,8 @@ msdos_set_section_contents (abfd, section, location, offset, count)
 #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
index 1a272d2..c4b9d1e 100644 (file)
@@ -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
index ac0dcc3..d7baa88 100644 (file)
@@ -4039,6 +4039,8 @@ ieee_bfd_debug_info_accumulate (abfd, section)
 #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
index e818034..a7636a9 100644 (file)
@@ -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
index 1bfa220..31cc1ba 100644 (file)
@@ -375,6 +375,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
   ((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_link
 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,24 @@ extern bfd_boolean _bfd_sh_align_load_span
    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;
+};
+
+extern struct bfd_section_already_linked_hash_entry *
+  bfd_section_already_linked_table_lookup (const char *);
+extern void bfd_section_already_linked_table_insert
+  (struct bfd_section_already_linked_hash_entry *, asection *);
index 095010c..03005f9 100644 (file)
@@ -380,6 +380,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
   ((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
@@ -479,6 +481,9 @@ extern bfd_boolean _bfd_generic_final_link
 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 *);
@@ -658,6 +663,27 @@ extern bfd_boolean _bfd_sh_align_load_span
    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;
+};
+
+extern struct bfd_section_already_linked_hash_entry *
+  bfd_section_already_linked_table_lookup (const char *);
+extern void bfd_section_already_linked_table_insert
+  (struct bfd_section_already_linked_hash_entry *, asection *);
 /* Extracted from init.c.  */
 /* Extracted from libbfd.c.  */
 bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
index 589f88c..f3a0359 100644 (file)
@@ -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;
index fd3ecd1..efb7b1f 100644 (file)
@@ -198,6 +198,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;
index 10b4467..cd2adb5 100644 (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);
+}
index 194898c..c4c05ab 100644 (file)
@@ -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
index 0324462..1b7eb86 100644 (file)
--- a/bfd/mmo.c
+++ b/bfd/mmo.c
@@ -3286,6 +3286,8 @@ mmo_canonicalize_reloc (abfd, section, relptr, symbols)
 #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
index cf84000..30ae4b1 100644 (file)
@@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #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
index 7df9c87..c99919a 100644 (file)
@@ -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
index 8e63359..b52ae65 100644 (file)
--- a/bfd/pef.c
+++ b/bfd/pef.c
@@ -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
index 5c80561..49f8140 100644 (file)
@@ -471,6 +471,8 @@ ppcboot_bfd_print_private_bfd_data (abfd, farg)
 #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
index e178f58..b9272db 100644 (file)
@@ -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
@@ -489,9 +472,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;
@@ -634,8 +614,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,             \
index 5903c1a..4b40f1b 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -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 */
index d75fa51..3002c0b 100644 (file)
@@ -1286,6 +1286,8 @@ srec_print_symbol (abfd, afile, symbol, how)
 #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
index 0719d4f..a08cd0b 100644 (file)
@@ -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, \
index b5ec803..a7a9254 100644 (file)
@@ -1003,6 +1003,8 @@ tekhex_print_symbol (abfd, filep, symbol, how)
 #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
index e454cf3..50b3487 100644 (file)
@@ -874,6 +874,8 @@ versados_canonicalize_reloc (abfd, section, relptr, symbols)
 #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
index 9d160e9..640d0eb 100644 (file)
--- a/bfd/vms.c
+++ b/bfd/vms.c
@@ -168,6 +168,8 @@ static bfd_boolean vms_bfd_set_private_flags
 #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
 \f
index 7bf3de7..9b80e3c 100644 (file)
@@ -99,6 +99,8 @@ extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd));
 #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
index aa44e97..3c4c84d 100644 (file)
@@ -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
index fe5664e..8ab3d7a 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2004-07-15  Aravinda PR  <aravindapr@rediffmail.com>
 
        * nlmconv.c (main): Pass map_file argument to link_inputs.
index 44e9331..7fd6711 100644 (file)
@@ -891,7 +891,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
        keep = (strip_symbols != STRIP_DEBUG
                && strip_symbols != STRIP_UNNEEDED
                && ! convert_debugging);
-      else if (bfd_get_section (sym)->comdat)
+      else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
        /* COMDAT sections store special information in local
           symbols, so we cannot risk stripping any of them.  */
        keep = 1;
index 6c42d3a..683203f 100644 (file)
@@ -331,6 +331,7 @@ dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
   if ((section->flags & SEC_LINK_ONCE) != 0)
     {
       const char *ls;
+      struct coff_comdat_info *comdat;
 
       switch (section->flags & SEC_LINK_DUPLICATES)
        {
@@ -351,9 +352,9 @@ dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
        }
       printf ("%s%s", comma, ls);
 
-      if (section->comdat != NULL)
-       printf (" (COMDAT %s %ld)", section->comdat->name,
-               section->comdat->symbol);
+      comdat = bfd_coff_get_comdat_section (abfd, section);
+      if (comdat != NULL)
+       printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol);
 
       comma = ", ";
     }
index b34292d..25aa0a0 100644 (file)
@@ -1,3 +1,13 @@
+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.
+
 2004-07-21  Nick Clifton  <nickc@redhat.com>
 
        * ldlang.c (init_os): Make sure that the newly allocated userdata
index 9ea2869..6cc05a6 100644 (file)
@@ -886,44 +886,10 @@ exp_init_os (etree_type *exp)
     }
 }
 \f
-/* 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.  */
@@ -933,128 +899,7 @@ section_already_linked (bfd *abfd, asection *sec, void *data)
       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);
 }
 \f
 /* The wild routines.
@@ -4347,7 +4192,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;
@@ -4359,7 +4205,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