bfd/
2004-07-21 H.J. Lu <hongjiu.lu@intel.com> * aout-adobe.c (aout_32_section_already_linked): Defined. * aout-target.h (MY_section_already_linked): Likewise. * aout-tic30.c (MY_section_already_linked): Likewise. * binary.c (binary_section_already_linked): Likewise. * bout.c (b_out_section_already_linked): Likewise. * coff-alpha.c (_bfd_ecoff_section_already_linked): Likewise. * coff-mips.c (_bfd_ecoff_section_already_linked): Likewise. * coffcode.h (coff_section_already_linked): Likewise. * i386msdos.c (msdos_section_already_linked): Likewise. * i386os9k.c (os9k_section_already_linked): Likewise. * ieee.c (ieee_section_already_linked): Likewise. * ihex.c (ihex_section_already_linked): Likewise. * mach-o.c (bfd_mach_o_section_already_linked): Likewise. * mmo.c (mmo_section_already_linked): Likewise. * nlm-target.h (nlm_section_already_linked): Likewise. * oasys.c (oasys_section_already_linked): Likewise. * pef.c (bfd_pef_section_already_linked): Likewise. * ppcboot.c (ppcboot_section_already_linked): Likewise. * som.c (som_bfd_discard_group): Likewise. * srec.c (srec_section_already_linked): Likewise. * tekhex.c (tekhex_section_already_linked): Likewise. * versados.c (versados_section_already_linked): Likewise. * vms.c (vms_section_already_linked): Likewise. * coff-target.h (_bfd_xcoff_section_already_linked): Likewise. * xsym.c (bfd_sym_section_already_linked): Likewise. * bfd-in.h (bfd_section_already_linked_table_init): New. (bfd_section_already_linked_table_free): Likewise. * coff-rs6000.c (rs6000coff_vec): Add _bfd_generic_section_already_linked. (pmac_xcoff_vec): Likewise. * coff64-rs6000.c (rs6000coff64_vec): Likewise. (aix5coff64_vec): Likewise. * elf-bfd.h (_bfd_elf_section_already_linked): New prototype. * elflink.c (_bfd_elf_section_already_linked): New function. * elfxx-target.h (bfd_elfNN_section_already_linked): Defined. * libbfd-in.h (_bfd_nolink_section_already_linked): Defined. (_bfd_generic_section_already_linked): New. (bfd_section_already_linked_hash_entry): Likewise. (bfd_section_already_linked): Likewise. (bfd_section_already_linked_table_lookup): Likewise. (bfd_section_already_linked_table_insert): Likewise. * linker.c (bfd_section_already_linked): New. (_bfd_section_already_linked_table): Likewise. (bfd_section_already_linked_table_lookup): Likewise. (bfd_section_already_linked_table_insert): Likewise. (already_linked_newfunc): Likewise. (bfd_section_already_linked_table_init): Likewise. (bfd_section_already_linked_table_free): Likewise. (_bfd_generic_section_already_linked): Likewise. * section.c (bfd_section): Remove comdat. (bfd_comdat_info): Moved to ... * bfd-in.h (coff_comdat_info): Here. (bfd_coff_get_comdat_section): New. * coffgen.c (bfd_coff_get_comdat_section): Likewise. * libcoff-in.h (coff_section_tdata): Add comdat. * coffcode.h (handle_COMDAT): Updated. * cofflink.c (coff_link_add_symbols): Likewise. * ecoff.c (bfd_debug_section): Likewise. * targets.c (bfd_target): Add _section_already_linked. (BFD_JUMP_TABLE_LINK): Updated. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. * libcoff.h: Likewise. binutils/ 2004-07-21 H.J. Lu <hongjiu.lu@intel.com> * objcopy.c (filter_symbols): Use bfd_coff_get_comdat_section to access comdat. * objdump.c (dump_section_header): Likewise. ld/ 2004-07-21 H.J. Lu <hongjiu.lu@intel.com> * ldlang.c (already_linked_hash_entry): Removed. (already_linked): Likewise. (already_linked_table): Likewise. (section_already_linked): Call bfd_section_already_linked. (lang_process): Replace already_linked_table_init with bfd_section_already_linked_table_init and check return. Replace already_linked_table_free with bfd_section_already_linked_table_free.
This commit is contained in:
parent
76d7af2d04
commit
082b729701
48 changed files with 591 additions and 218 deletions
|
@ -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,
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
23
bfd/bfd-in.h
23
bfd/bfd-in.h
|
@ -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);
|
||||
|
||||
/* 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 *);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* 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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = \
|
||||
{ \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
26
bfd/libbfd.h
26
bfd/libbfd.h
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
194
bfd/linker.c
194
bfd/linker.c
|
@ -2827,3 +2827,197 @@ _bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED,
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_section_already_linked
|
||||
|
||||
SYNOPSIS
|
||||
void bfd_section_already_linked (bfd *abfd, asection *sec);
|
||||
|
||||
DESCRIPTION
|
||||
Check if @var{sec} has been already linked during a reloceatable
|
||||
or final link.
|
||||
|
||||
.#define bfd_section_already_linked(abfd, sec) \
|
||||
. BFD_SEND (abfd, _section_already_linked, (abfd, sec))
|
||||
.
|
||||
|
||||
*/
|
||||
|
||||
/* Sections marked with the SEC_LINK_ONCE flag should only be linked
|
||||
once into the output. This routine checks each section, and
|
||||
arrange to discard it if a section of the same name has already
|
||||
been linked. This code assumes that all relevant sections have the
|
||||
SEC_LINK_ONCE flag set; that is, it does not depend solely upon the
|
||||
section name. bfd_section_already_linked is called via
|
||||
bfd_map_over_sections. */
|
||||
|
||||
/* The hash table. */
|
||||
|
||||
static struct bfd_hash_table _bfd_section_already_linked_table;
|
||||
|
||||
/* Support routines for the hash table used by section_already_linked,
|
||||
initialize the table, lookup, fill in an entry and remove the
|
||||
table. */
|
||||
|
||||
struct bfd_section_already_linked_hash_entry *
|
||||
bfd_section_already_linked_table_lookup (const char *name)
|
||||
{
|
||||
return ((struct bfd_section_already_linked_hash_entry *)
|
||||
bfd_hash_lookup (&_bfd_section_already_linked_table, name,
|
||||
TRUE, FALSE));
|
||||
}
|
||||
|
||||
void
|
||||
bfd_section_already_linked_table_insert
|
||||
(struct bfd_section_already_linked_hash_entry *already_linked_list,
|
||||
asection *sec)
|
||||
{
|
||||
struct bfd_section_already_linked *l;
|
||||
|
||||
/* Allocate the memory from the same obstack as the hash table is
|
||||
kept in. */
|
||||
l = bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
|
||||
l->sec = sec;
|
||||
l->next = already_linked_list->entry;
|
||||
already_linked_list->entry = l;
|
||||
}
|
||||
|
||||
static struct bfd_hash_entry *
|
||||
already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
|
||||
struct bfd_hash_table *table,
|
||||
const char *string ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct bfd_section_already_linked_hash_entry *ret =
|
||||
bfd_hash_allocate (table, sizeof *ret);
|
||||
|
||||
ret->entry = NULL;
|
||||
|
||||
return &ret->root;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
bfd_section_already_linked_table_init (void)
|
||||
{
|
||||
return bfd_hash_table_init_n (&_bfd_section_already_linked_table,
|
||||
already_linked_newfunc, 42);
|
||||
}
|
||||
|
||||
void
|
||||
bfd_section_already_linked_table_free (void)
|
||||
{
|
||||
bfd_hash_table_free (&_bfd_section_already_linked_table);
|
||||
}
|
||||
|
||||
/* This is used on non-ELF inputs. */
|
||||
|
||||
void
|
||||
_bfd_generic_section_already_linked (bfd *abfd, asection *sec)
|
||||
{
|
||||
flagword flags;
|
||||
const char *name;
|
||||
struct bfd_section_already_linked *l;
|
||||
struct bfd_section_already_linked_hash_entry *already_linked_list;
|
||||
|
||||
flags = sec->flags;
|
||||
if ((flags & SEC_LINK_ONCE) == 0)
|
||||
return;
|
||||
|
||||
/* FIXME: When doing a relocatable link, we may have trouble
|
||||
copying relocations in other sections that refer to local symbols
|
||||
in the section being discarded. Those relocations will have to
|
||||
be converted somehow; as of this writing I'm not sure that any of
|
||||
the backends handle that correctly.
|
||||
|
||||
It is tempting to instead not discard link once sections when
|
||||
doing a relocatable link (technically, they should be discarded
|
||||
whenever we are building constructors). However, that fails,
|
||||
because the linker winds up combining all the link once sections
|
||||
into a single large link once section, which defeats the purpose
|
||||
of having link once sections in the first place. */
|
||||
|
||||
name = bfd_get_section_name (abfd, sec);
|
||||
|
||||
already_linked_list = bfd_section_already_linked_table_lookup (name);
|
||||
|
||||
for (l = already_linked_list->entry; l != NULL; l = l->next)
|
||||
{
|
||||
bfd_boolean skip = FALSE;
|
||||
struct coff_comdat_info *s_comdat
|
||||
= bfd_coff_get_comdat_section (abfd, sec);
|
||||
struct coff_comdat_info *l_comdat
|
||||
= bfd_coff_get_comdat_section (l->sec->owner, l->sec);
|
||||
|
||||
/* We may have 3 different sections on the list: group section,
|
||||
comdat section and linkonce section. SEC may be a linkonce or
|
||||
comdat section. We always ignore group section. For non-COFF
|
||||
inputs, we also ignore comdat section.
|
||||
|
||||
FIXME: Is that safe to match a linkonce section with a comdat
|
||||
section for COFF inputs? */
|
||||
if ((l->sec->flags & SEC_GROUP) != 0)
|
||||
skip = TRUE;
|
||||
else if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
|
||||
{
|
||||
if (s_comdat != NULL
|
||||
&& l_comdat != NULL
|
||||
&& strcmp (s_comdat->name, l_comdat->name) != 0)
|
||||
skip = TRUE;
|
||||
}
|
||||
else if (l_comdat != NULL)
|
||||
skip = TRUE;
|
||||
|
||||
if (!skip)
|
||||
{
|
||||
/* The section has already been linked. See if we should
|
||||
issue a warning. */
|
||||
switch (flags & SEC_LINK_DUPLICATES)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
|
||||
case SEC_LINK_DUPLICATES_DISCARD:
|
||||
break;
|
||||
|
||||
case SEC_LINK_DUPLICATES_ONE_ONLY:
|
||||
if (s_comdat == NULL)
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: %s: warning: ignoring duplicate section `%s'\n"),
|
||||
bfd_archive_filename (abfd), name);
|
||||
else
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: %s: warning: ignoring duplicate `%s' section symbol `%s'\n"),
|
||||
bfd_archive_filename (abfd), name, s_comdat->name);
|
||||
break;
|
||||
|
||||
case SEC_LINK_DUPLICATES_SAME_CONTENTS:
|
||||
/* FIXME: We should really dig out the contents of both
|
||||
sections and memcmp them. The COFF/PE spec says that
|
||||
the Microsoft linker does not implement this
|
||||
correctly, so I'm not going to bother doing it
|
||||
either. */
|
||||
/* Fall through. */
|
||||
case SEC_LINK_DUPLICATES_SAME_SIZE:
|
||||
if (sec->size != l->sec->size)
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: %s: warning: duplicate section `%s' has different size\n"),
|
||||
bfd_archive_filename (abfd), name);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the output_section field so that lang_add_section
|
||||
does not create a lang_input_section structure for this
|
||||
section. Since there might be a symbol in the section
|
||||
being discarded, we must retain a pointer to the section
|
||||
which we are really going to use. */
|
||||
sec->output_section = bfd_abs_section_ptr;
|
||||
sec->kept_section = l->sec;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is the first section with this name. Record it. */
|
||||
bfd_section_already_linked_table_insert (already_linked_list, sec);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = ", ";
|
||||
}
|
||||
|
|
10
ld/ChangeLog
10
ld/ChangeLog
|
@ -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
|
||||
|
|
162
ld/ldlang.c
162
ld/ldlang.c
|
@ -886,44 +886,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. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
|
Loading…
Add table
Reference in a new issue