PATCH: Support mixing COMDAT and linkonce
H. J. Lu
hjl@lucon.org
Mon May 17 21:24:00 GMT 2004
More information about the Binutils mailing list
Mon May 17 21:24:00 GMT 2004
- Previous message (by thread): PATCH: Support mixing COMDAT and linkonce
- Next message (by thread): PATCH: Support mixing COMDAT and linkonce
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Sat, May 15, 2004 at 11:09:47AM +0930, Alan Modra wrote: > On Fri, May 14, 2004 at 02:07:37PM -0700, H. J. Lu wrote: > > When there are mixed COMDAT and linkonce inputs, linker doesn't handle > > them gracefully: > > Ewww. Should we even try? I understand that such a patch might be > useful while gcc is emitting both comdat and linkonce, but once you've > completed the change to comdat it shouldn't be necessary. Also, I'm not > really happy with where you have added this code. At least, it is the > wrong place to be discarding duplicate sections. That ought to happen > in ldlang.c:section_already_linked. > This patch implements it. H.J. -------------- next part -------------- bfd/ 2004-05-17 H.J. Lu <hongjiu.lu@intel.com> * aout-adobe.c (aout_32_bfd_match_symbols_in_sections): Defined. * aout-target.h (MY_bfd_match_symbols_in_sections): Likewise. * aout-tic30.c (MY_bfd_match_symbols_in_sections): Likewise. * binary.c (binary_bfd_match_symbols_in_sections): Likewise. * bout.c (b_out_bfd_match_symbols_in_sections): Likewise. * coff-alpha.c (_bfd_ecoff_bfd_match_symbols_in_sections): Likewise. * coff-mips.c (_bfd_ecoff_bfd_match_symbols_in_sections): Likewise. * coffcode.h (coff_bfd_match_symbols_in_sections): Likewise. * i386msdos.c (msdos_bfd_match_symbols_in_sections): Likewise. * i386os9k.c (os9k_bfd_match_symbols_in_sections): Likewise. * ieee.c (ieee_bfd_match_symbols_in_sections): Likewise. * ihex.c (ihex_bfd_match_symbols_in_sections): Likewise. * mach-o.c (bfd_mach_o_bfd_match_symbols_in_sections): Likewise. * mmo.c (mmo_bfd_discard_group): Likewise. * nlm-target.h (nlm_bfd_match_symbols_in_sections): Likewise. * oasys.c (oasys_bfd_match_symbols_in_sections): Likewise. * pef.c (bfd_pef_bfd_match_symbols_in_sections): Likewise. * ppcboot.c (ppcboot_bfd_match_symbols_in_sections): Likewise. * som.c (som_bfd_discard_group): Likewise. * srec.c (srec_bfd_match_symbols_in_sections): Likewise. * tekhex.c (tekhex_bfd_match_symbols_in_sections): Likewise. * versados.c (versados_bfd_match_symbols_in_sections): Likewise. * vms.c (vms_bfd_match_symbols_in_sections): Likewise. * coff-target.h (_bfd_xcoff_bfd_match_symbols_in_sections): Likewise. * xsym.c (bfd_sym_bfd_match_symbols_in_sections): Likewise. * bfd.c (bfd_match_symbols_in_sections): New. * coff-rs6000.c (rs6000coff_vec): Add _bfd_nolink_bfd_match_symbols_in_sections, (pmac_xcoff_vec): Likewise. * coff64-rs6000.c (rs6000coff64_vec): Likewise. (aix5coff64_vec): Likewise. * elf-bfd.h (bfd_elf_match_symbols_in_sections): New prototype. (_bfd_elf_setup_group_pointers): Likewise. * elf.c (_bfd_elf_setup_group_pointers): New function. (elf_sort_elf_symbol): Likewise. (elf_sym_name_compare): Likewise. (bfd_elf_match_symbols_in_sections): Likewise. * elfcode.h (elf_object_p): Call _bfd_elf_setup_group_pointers. * elfxx-target.h (bfd_elfNN_bfd_match_symbols_in_sections): Defined. * libbfd-in.h (_bfd_nolink_bfd_match_symbols_in_sections): Defined/ * section.c (bfd_section): Add group, a pointer to section group. * section (STD_SECTION): Initialize group to NULL. * ecoff.c (bfd_debug_section): Likewise. * targets.c (bfd_target): Add _bfd_match_symbols_in_sections. (BFD_JUMP_TABLE_LINK): Updated. * bfd-in2.h: Regenerated. * libbfd.h: Regenerated. ld/ 2004-05-17 H.J. Lu <hongjiu.lu@intel.com> * ldlang.c (already_linked_section): New structure. (try_match_symbols_in_sections): New function. (section_already_linked): Check if a member of a COMDAT group matches a .gnu.linkonce section. --- binutils/bfd/aout-adobe.c.linkonce 2004-04-30 08:25:52.000000000 -0700 +++ binutils/bfd/aout-adobe.c 2004-05-17 13:27:55.000000000 -0700 @@ -519,6 +519,8 @@ aout_adobe_sizeof_headers (ignore_abfd, #define aout_32_bfd_merge_sections bfd_generic_merge_sections #define aout_32_bfd_is_group_section bfd_generic_is_group_section #define aout_32_bfd_discard_group bfd_generic_discard_group +#define aout_32_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define aout_32_bfd_link_hash_table_create \ _bfd_generic_link_hash_table_create #define aout_32_bfd_link_hash_table_free \ --- binutils/bfd/aout-target.h.linkonce 2004-04-30 08:25:53.000000000 -0700 +++ binutils/bfd/aout-target.h 2004-05-17 09:41:08.000000000 -0700 @@ -519,6 +519,10 @@ MY_bfd_final_link (abfd, info) #ifndef MY_bfd_discard_group #define MY_bfd_discard_group bfd_generic_discard_group #endif +#ifndef MY_bfd_match_symbols_in_sections +#define MY_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections +#endif #ifndef MY_bfd_reloc_type_lookup #define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup) #endif --- binutils/bfd/aout-tic30.c.linkonce 2004-04-30 08:25:54.000000000 -0700 +++ binutils/bfd/aout-tic30.c 2004-05-17 09:41:32.000000000 -0700 @@ -976,6 +976,10 @@ tic30_aout_set_arch_mach (abfd, arch, ma #ifndef MY_bfd_discard_group #define MY_bfd_discard_group bfd_generic_discard_group #endif +#ifndef MY_bfd_match_symbols_in_sections +#define MY_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections +#endif #ifndef MY_bfd_reloc_type_lookup #define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup #endif --- binutils/bfd/bfd.c.linkonce 2004-05-14 09:00:52.000000000 -0700 +++ binutils/bfd/bfd.c 2004-05-17 09:40:43.000000000 -0700 @@ -1089,6 +1089,9 @@ DESCRIPTION .#define bfd_discard_group(abfd, sec) \ . BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) . +.#define bfd_match_symbols_in_sections(abfd, sec1, sec2) \ +. BFD_SEND (abfd, _bfd_match_symbols_in_sections, (sec1, sec2)) +. .#define bfd_link_hash_table_create(abfd) \ . BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) . --- binutils/bfd/binary.c.linkonce 2004-04-30 08:26:01.000000000 -0700 +++ binutils/bfd/binary.c 2004-05-17 09:41:47.000000000 -0700 @@ -341,6 +341,8 @@ binary_sizeof_headers (abfd, exec) #define binary_bfd_merge_sections bfd_generic_merge_sections #define binary_bfd_is_group_section bfd_generic_is_group_section #define binary_bfd_discard_group bfd_generic_discard_group +#define binary_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define binary_bfd_link_just_syms _bfd_generic_link_just_syms --- binutils/bfd/bout.c.linkonce 2004-04-30 08:26:02.000000000 -0700 +++ binutils/bfd/bout.c 2004-05-17 13:28:43.000000000 -0700 @@ -1489,6 +1489,8 @@ b_out_bfd_get_relocated_section_contents #define b_out_bfd_merge_sections bfd_generic_merge_sections #define b_out_bfd_is_group_section bfd_generic_is_group_section #define b_out_bfd_discard_group bfd_generic_discard_group +#define b_out_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define aout_32_get_section_contents_in_window \ _bfd_generic_get_section_contents_in_window --- binutils/bfd/coff-alpha.c.linkonce 2004-04-30 08:26:04.000000000 -0700 +++ binutils/bfd/coff-alpha.c 2004-05-17 09:41:52.000000000 -0700 @@ -2361,6 +2361,8 @@ static const struct ecoff_backend_data a #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group +#define _bfd_ecoff_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections const bfd_target ecoffalpha_little_vec = { --- binutils/bfd/coff-mips.c.linkonce 2004-04-30 08:26:06.000000000 -0700 +++ binutils/bfd/coff-mips.c 2004-05-17 09:42:02.000000000 -0700 @@ -1395,6 +1395,8 @@ static const struct ecoff_backend_data m #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group +#define _bfd_ecoff_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections extern const bfd_target ecoff_big_vec; --- binutils/bfd/coff-rs6000.c.linkonce 2004-04-30 08:26:10.000000000 -0700 +++ binutils/bfd/coff-rs6000.c 2004-05-17 09:42:06.000000000 -0700 @@ -4198,6 +4198,7 @@ const bfd_target rs6000coff_vec = bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, + _bfd_nolink_bfd_match_symbols_in_sections, /* Dynamic */ _bfd_xcoff_get_dynamic_symtab_upper_bound, @@ -4442,6 +4443,7 @@ const bfd_target pmac_xcoff_vec = bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, + _bfd_nolink_bfd_match_symbols_in_sections, /* Dynamic */ _bfd_xcoff_get_dynamic_symtab_upper_bound, --- binutils/bfd/coff64-rs6000.c.linkonce 2004-04-30 08:26:13.000000000 -0700 +++ binutils/bfd/coff64-rs6000.c 2004-05-17 09:42:18.000000000 -0700 @@ -2739,6 +2739,7 @@ const bfd_target rs6000coff64_vec = bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, + _bfd_nolink_bfd_match_symbols_in_sections, /* Dynamic */ _bfd_xcoff_get_dynamic_symtab_upper_bound, @@ -2984,6 +2985,7 @@ const bfd_target aix5coff64_vec = bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, + _bfd_nolink_bfd_match_symbols_in_sections, /* Dynamic */ _bfd_xcoff_get_dynamic_symtab_upper_bound, --- binutils/bfd/coffcode.h.linkonce 2004-05-07 13:21:00.000000000 -0700 +++ binutils/bfd/coffcode.h 2004-05-17 09:42:24.000000000 -0700 @@ -5574,6 +5574,11 @@ static const bfd_coff_backend_data ticof #define coff_bfd_discard_group bfd_generic_discard_group #endif +#ifndef coff_bfd_match_symbols_in_sections +#define coff_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections +#endif + #define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \ const bfd_target VAR = \ { \ --- binutils/bfd/ecoff.c.linkonce 2004-04-26 21:11:29.000000000 -0700 +++ binutils/bfd/ecoff.c 2004-05-17 13:30:52.000000000 -0700 @@ -95,8 +95,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, comdat, group, kept_section, moving_line_filepos, */ + 0, NULL, NULL, NULL, 0, /* target_index, used_by_bfd, constructor_chain, owner, */ 0, NULL, NULL, NULL, /* symbol, */ --- binutils/bfd/elf-bfd.h.linkonce 2004-05-11 13:33:49.000000000 -0700 +++ binutils/bfd/elf-bfd.h 2004-05-17 12:32:04.000000000 -0700 @@ -1375,6 +1375,8 @@ extern bfd_boolean bfd_elf_is_group_sect (bfd *, const struct bfd_section *); extern bfd_boolean bfd_elf_discard_group (bfd *, struct bfd_section *); +extern bfd_boolean bfd_elf_match_symbols_in_sections + (struct bfd_section *, struct bfd_section *); extern void bfd_elf_set_group_contents (bfd *, asection *, void *); extern void _bfd_elf_link_just_syms @@ -1554,6 +1556,9 @@ extern bfd_boolean _bfd_elf_dynamic_symb extern bfd_boolean _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean); +extern void _bfd_elf_setup_group_pointers + (bfd *); + extern const bfd_target *bfd_elf32_object_p (bfd *); extern const bfd_target *bfd_elf32_core_file_p --- binutils/bfd/elf.c.linkonce 2004-05-11 13:33:56.000000000 -0700 +++ binutils/bfd/elf.c 2004-05-17 14:14:58.000000000 -0700 @@ -612,6 +612,26 @@ setup_group (bfd *abfd, Elf_Internal_Shd return TRUE; } +void +_bfd_elf_setup_group_pointers (bfd *abfd) +{ + unsigned int i; + unsigned int num_group = elf_tdata (abfd)->num_group; + + if (num_group == (unsigned) -1) + return; + + for (i = 0; i < num_group; i++) + { + Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; + Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents; + unsigned int n_elt = shdr->sh_size / 4; + + while (--n_elt != 0) + (++idx)->shdr->bfd_section->group = shdr->bfd_section; + } +} + bfd_boolean bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec) { @@ -7678,3 +7698,240 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd return n; } + +/* Sort symbol by binding and section. We want to put global + symbols sorted by section at the beginning. */ + +static int +elf_sort_elf_symbol (const void *arg1, const void *arg2) +{ + const Elf_Internal_Sym *s1; + const Elf_Internal_Sym *s2; + + /* Make sure local or undefined symbols are at the end. */ + s1 = (const Elf_Internal_Sym *) arg1; + if (s1->st_shndx == SHN_UNDEF + || ELF_ST_BIND (s1->st_info) == STB_LOCAL) + return 1; + s2 = (const Elf_Internal_Sym *) arg2; + if (s2->st_shndx == SHN_UNDEF + || ELF_ST_BIND (s2->st_info) == STB_LOCAL) + return -1; + + /* Grouped by section index. */ + return s1->st_shndx - s2->st_shndx; +} + +struct elf_symbol +{ + Elf_Internal_Sym *sym; + const char *name; +}; + +static int +elf_sym_name_compare (const void *arg1, const void *arg2) +{ + const struct elf_symbol *s1 = (const struct elf_symbol *) arg1; + const struct elf_symbol *s2 = (const struct elf_symbol *) arg2; + return strcmp (s1->name, s2->name); +} + +/* Check if 2 sections export the same set of symbols. */ + +bfd_boolean +bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2) +{ + bfd *bfd1, *bfd2; + const struct elf_backend_data *bed1, *bed2; + Elf_Internal_Shdr *hdr1, *hdr2; + bfd_size_type symcount1, symcount2; + bfd_size_type extsymcount1, extsymcount2; + bfd_size_type extsymoff1, extsymoff2; + Elf_Internal_Sym *isymbuf1, *isymbuf2; + Elf_Internal_Sym *isymstart1 = NULL, *isymstart2 = NULL, *isym; + Elf_Internal_Sym *isymend; + struct elf_symbol *symp, *symtable1 = NULL, *symtable2 = NULL; + bfd_size_type count1, count2, i; + int shndx1, shndx2; + bfd_boolean result; + + bfd1 = sec1->owner; + bfd2 = sec2->owner; + + /* Both sections have to be in ELF. */ + if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour + || bfd_get_flavour (bfd2) != bfd_target_elf_flavour) + return FALSE; + + /* One section has to be in a COMDAT group with only one section and + the other one has to be a .gnu.linkonce section. */ + if (!(elf_section_type (sec1) == elf_section_type (sec2) + && ((elf_section_flags (sec1) & ~SHF_GROUP) + == (elf_section_flags (sec2) & ~SHF_GROUP)) + && ((sec1->group != NULL + && ((sec1->group->flags & (SEC_LINK_ONCE + | SEC_LINK_DUPLICATES_DISCARD)) + == (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD)) + && elf_next_in_group (sec1) == sec1 + && sec2->group == NULL + && ((sec2->flags & (SEC_LINK_ONCE + | SEC_LINK_DUPLICATES_DISCARD)) + == (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD))) + || (sec1->group == NULL + && sec2->group != NULL + && ((sec2->group->flags & (SEC_LINK_ONCE + | SEC_LINK_DUPLICATES_DISCARD)) + == (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD)) + && elf_next_in_group (sec2) == sec2 + && ((sec1->flags & (SEC_LINK_ONCE + | SEC_LINK_DUPLICATES_DISCARD)) + == (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD)))))) + return FALSE; + + shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1); + shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2); + if (shndx1 == -1 || shndx2 == -1) + return FALSE; + + bed1 = get_elf_backend_data (bfd1); + bed2 = get_elf_backend_data (bfd2); + hdr1 = &elf_tdata (bfd1)->symtab_hdr; + symcount1 = hdr1->sh_size / bed1->s->sizeof_sym; + hdr2 = &elf_tdata (bfd2)->symtab_hdr; + symcount2 = hdr2->sh_size / bed2->s->sizeof_sym; + + if (elf_bad_symtab (bfd1)) + { + extsymcount1 = symcount1; + extsymoff1 = 0; + } + else + { + extsymcount1 = symcount1 - hdr1->sh_info; + extsymoff1 = hdr1->sh_info; + } + + if (elf_bad_symtab (bfd2)) + { + extsymcount2 = symcount2; + extsymoff2 = 0; + } + else + { + extsymcount2 = symcount2 - hdr2->sh_info; + extsymoff2 = hdr2->sh_info; + } + + if (extsymcount1 == 0 || extsymcount2 == 0) + return FALSE; + + isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, extsymcount1, + extsymoff1, NULL, NULL, NULL); + isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, extsymcount2, + extsymoff2, NULL, NULL, NULL); + if (isymbuf1 == NULL || isymbuf2 == NULL) + return FALSE; + + /* Sort symbols by binding and section. Global definitions are at + the beginning. */ + qsort (isymbuf1, extsymcount1, sizeof (Elf_Internal_Sym), + elf_sort_elf_symbol); + qsort (isymbuf2, extsymcount2, sizeof (Elf_Internal_Sym), + elf_sort_elf_symbol); + + /* Count global symbols defined in the section. */ + count1 = 0; + for (isym = isymbuf1, isymend = isym + extsymcount1; + isym < isymend; isym++) + { + if (isym->st_shndx == (unsigned int) shndx1) + { + if (count1 == 0) + isymstart1 = isym; + count1++; + } + + if (count1 && isym->st_shndx != (unsigned int) shndx1) + break; + } + + count2 = 0; + for (isym = isymbuf2, isymend = isym + extsymcount2; + isym < isymend; isym++) + { + if (isym->st_shndx == (unsigned int) shndx2) + { + if (count2 == 0) + isymstart2 = isym; + count2++; + } + + if (count2 && isym->st_shndx != (unsigned int) shndx2) + break; + } + + if (count1 == 0 && count2 == 0) + { + result = TRUE; + goto done; + } + + result = FALSE; + if (count1 != count2) + goto done; + + symtable1 = bfd_malloc (count1 * sizeof (struct elf_symbol)); + symtable2 = bfd_malloc (count1 * sizeof (struct elf_symbol)); + + if (symtable1 == NULL || symtable2 == NULL) + goto done; + + symp = symtable1; + for (isym = isymstart1, isymend = isym + count1; + isym < isymend; isym++) + { + symp->sym = isym; + symp->name = bfd_elf_string_from_elf_section (bfd1, + hdr1->sh_link, + isym->st_name); + symp++; + } + + symp = symtable2; + for (isym = isymstart2, isymend = isym + count1; + isym < isymend; isym++) + { + symp->sym = isym; + symp->name = bfd_elf_string_from_elf_section (bfd2, + hdr2->sh_link, + isym->st_name); + symp++; + } + + /* Sort symbol by name. */ + qsort (symtable1, count1, sizeof (struct elf_symbol), + elf_sym_name_compare); + qsort (symtable2, count1, sizeof (struct elf_symbol), + elf_sym_name_compare); + + for (i = 0; i < count1; i++) + /* Two symbols must have the same binding, type and name. */ + if (symtable1 [i].sym->st_info != symtable2 [i].sym->st_info + || symtable1 [i].sym->st_other != symtable2 [i].sym->st_other + || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) + goto done; + + result = TRUE; + +done: + if (symtable1) + free (symtable1); + if (symtable2) + free (symtable2); + if (isymbuf1) + free (isymbuf1); + if (isymbuf2) + free (isymbuf2); + + return result; +} --- binutils/bfd/elfcode.h.linkonce 2004-04-22 08:20:00.000000000 -0700 +++ binutils/bfd/elfcode.h 2004-05-17 12:30:41.000000000 -0700 @@ -742,6 +742,9 @@ elf_object_p (bfd *abfd) if (shindex == SHN_LORESERVE - 1) shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE; } + + /* Set up group pointers. */ + _bfd_elf_setup_group_pointers (abfd); } /* Let the backend double check the format and override global --- binutils/bfd/elfxx-target.h.linkonce 2004-04-30 08:26:46.000000000 -0700 +++ binutils/bfd/elfxx-target.h 2004-05-17 09:42:45.000000000 -0700 @@ -144,6 +144,11 @@ #define bfd_elfNN_bfd_discard_group bfd_elf_discard_group #endif +#ifndef bfd_elfNN_bfd_match_symbols_in_sections +#define bfd_elfNN_bfd_match_symbols_in_sections \ + bfd_elf_match_symbols_in_sections +#endif + #ifndef bfd_elfNN_bfd_make_debug_symbol #define bfd_elfNN_bfd_make_debug_symbol \ ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr) --- binutils/bfd/i386msdos.c.linkonce 2004-04-30 08:26:47.000000000 -0700 +++ binutils/bfd/i386msdos.c 2004-05-17 09:42:50.000000000 -0700 @@ -178,6 +178,8 @@ msdos_set_section_contents (abfd, sectio #define msdos_bfd_merge_sections bfd_generic_merge_sections #define msdos_bfd_is_group_section bfd_generic_is_group_section #define msdos_bfd_discard_group bfd_generic_discard_group +#define msdos_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define msdos_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/i386os9k.c.linkonce 2004-04-30 08:26:47.000000000 -0700 +++ binutils/bfd/i386os9k.c 2004-05-17 13:33:11.000000000 -0700 @@ -335,6 +335,8 @@ os9k_sizeof_headers (ignore_abfd, ignore #define os9k_bfd_merge_sections bfd_generic_merge_sections #define os9k_bfd_is_group_section bfd_generic_is_group_section #define os9k_bfd_discard_group bfd_generic_discard_group +#define os9k_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define os9k_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define os9k_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/ieee.c.linkonce 2004-04-30 08:26:50.000000000 -0700 +++ binutils/bfd/ieee.c 2004-05-17 09:42:58.000000000 -0700 @@ -4039,6 +4039,8 @@ ieee_bfd_debug_info_accumulate (abfd, se #define ieee_bfd_merge_sections bfd_generic_merge_sections #define ieee_bfd_is_group_section bfd_generic_is_group_section #define ieee_bfd_discard_group bfd_generic_discard_group +#define ieee_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/ihex.c.linkonce 2004-04-30 08:26:51.000000000 -0700 +++ binutils/bfd/ihex.c 2004-05-17 09:43:03.000000000 -0700 @@ -990,6 +990,8 @@ ihex_sizeof_headers (abfd, exec) #define ihex_bfd_merge_sections bfd_generic_merge_sections #define ihex_bfd_is_group_section bfd_generic_is_group_section #define ihex_bfd_discard_group bfd_generic_discard_group +#define ihex_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define ihex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define ihex_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/libbfd-in.h.linkonce 2004-04-30 08:26:52.000000000 -0700 +++ binutils/bfd/libbfd-in.h 2004-05-17 09:43:08.000000000 -0700 @@ -361,6 +361,9 @@ extern bfd_boolean _bfd_generic_set_sect #define _bfd_nolink_bfd_discard_group \ ((bfd_boolean (*) (bfd *, struct bfd_section *)) \ bfd_false) +#define _bfd_nolink_bfd_match_symbols_in_sections \ + ((bfd_boolean (*) (struct bfd_section *, struct bfd_section *)) \ + bfd_false) #define _bfd_nolink_bfd_link_hash_table_create \ ((struct bfd_link_hash_table *(*) (bfd *)) bfd_nullvoidptr) #define _bfd_nolink_bfd_link_hash_table_free \ --- binutils/bfd/mach-o.c.linkonce 2004-04-30 08:26:56.000000000 -0700 +++ binutils/bfd/mach-o.c 2004-05-17 09:43:35.000000000 -0700 @@ -70,6 +70,8 @@ #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group +#define bfd_mach_o_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *, bfd *, asymbol *)); --- binutils/bfd/mmo.c.linkonce 2004-04-30 08:26:59.000000000 -0700 +++ binutils/bfd/mmo.c 2004-05-17 09:43:40.000000000 -0700 @@ -3288,6 +3288,8 @@ mmo_canonicalize_reloc (abfd, section, r #define mmo_bfd_merge_sections bfd_generic_merge_sections #define mmo_bfd_is_group_section bfd_generic_is_group_section #define mmo_bfd_discard_group bfd_generic_discard_group +#define mmo_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections /* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by using BFD_JUMP_TABLE_RELOCS (_bfd_norelocs) rather than 0. FIXME: Most --- binutils/bfd/nlm-target.h.linkonce 2004-04-30 08:26:59.000000000 -0700 +++ binutils/bfd/nlm-target.h 2004-05-17 09:43:45.000000000 -0700 @@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suit #define nlm_bfd_merge_sections bfd_generic_merge_sections #define nlm_bfd_is_group_section bfd_generic_is_group_section #define nlm_bfd_discard_group bfd_generic_discard_group +#define nlm_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define nlm_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define nlm_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define nlm_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/oasys.c.linkonce 2004-04-30 08:27:01.000000000 -0700 +++ binutils/bfd/oasys.c 2004-05-17 09:43:49.000000000 -0700 @@ -1508,6 +1508,8 @@ oasys_sizeof_headers (abfd, exec) #define oasys_bfd_merge_sections bfd_generic_merge_sections #define oasys_bfd_is_group_section bfd_generic_is_group_section #define oasys_bfd_discard_group bfd_generic_discard_group +#define oasys_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/pef.c.linkonce 2004-04-30 08:27:01.000000000 -0700 +++ binutils/bfd/pef.c 2004-05-17 13:33:50.000000000 -0700 @@ -54,6 +54,7 @@ #define bfd_pef_bfd_merge_sections bfd_generic_merge_sections #define bfd_pef_bfd_is_group_section bfd_generic_is_group_section #define bfd_pef_bfd_discard_group bfd_generic_discard_group +#define bfd_pef_bfd_match_symbols_in_sections _bfd_nolink_bfd_match_symbols_in_sections #define bfd_pef_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define bfd_pef_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define bfd_pef_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/ppcboot.c.linkonce 2004-04-30 08:27:02.000000000 -0700 +++ binutils/bfd/ppcboot.c 2004-05-17 09:44:21.000000000 -0700 @@ -471,6 +471,8 @@ ppcboot_bfd_print_private_bfd_data (abfd #define ppcboot_bfd_merge_sections bfd_generic_merge_sections #define ppcboot_bfd_is_group_section bfd_generic_is_group_section #define ppcboot_bfd_discard_group bfd_generic_discard_group +#define ppcboot_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define ppcboot_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define ppcboot_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/section.c.linkonce 2004-05-17 07:37:17.000000000 -0700 +++ binutils/bfd/section.c 2004-05-17 07:38:59.000000000 -0700 @@ -493,6 +493,10 @@ CODE_FRAGMENT . {* Optional information about a COMDAT entry; NULL if not COMDAT. *} . struct bfd_comdat_info *comdat; . +. {* Optional information about section group; NULL if it doesn't +. belongs to any section group. *} +. struct bfd_section *group; +. . {* Points to the kept section if this section is a link-once section, . and is discarded. *} . struct bfd_section *kept_section; @@ -643,8 +647,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, comdat, group, kept_section, moving_line_filepos, */ \ + 0, NULL, NULL, NULL, 0, \ \ /* target_index, used_by_bfd, constructor_chain, owner, */ \ 0, NULL, NULL, NULL, \ --- binutils/bfd/som.c.linkonce 2004-05-03 09:00:44.000000000 -0700 +++ binutils/bfd/som.c 2004-05-17 09:44:25.000000000 -0700 @@ -6412,6 +6412,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_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections const bfd_target som_vec = { "som", /* name */ --- binutils/bfd/srec.c.linkonce 2004-04-30 08:27:15.000000000 -0700 +++ binutils/bfd/srec.c 2004-05-17 09:44:33.000000000 -0700 @@ -1286,6 +1286,8 @@ srec_print_symbol (abfd, afile, symbol, #define srec_bfd_merge_sections bfd_generic_merge_sections #define srec_bfd_is_group_section bfd_generic_is_group_section #define srec_bfd_discard_group bfd_generic_discard_group +#define srec_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define srec_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/targets.c.linkonce 2004-05-14 09:00:50.000000000 -0700 +++ binutils/bfd/targets.c 2004-05-17 09:44:55.000000000 -0700 @@ -407,7 +407,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##_bfd_match_symbols_in_sections \ . . int (*_bfd_sizeof_headers) (bfd *, bfd_boolean); . bfd_byte * (*_bfd_get_relocated_section_contents) @@ -450,6 +451,11 @@ BFD_JUMP_TABLE macros. . {* Discard members of a group. *} . bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); . +. {* Return TRUE if need to try if 2 sections export the same set of +. symbols. *} +. bfd_boolean (*_bfd_match_symbols_in_sections) +. (struct bfd_section *, struct bfd_section *); +. . {* Routines to handle dynamic symbols and relocs. *} .#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ . NAME##_get_dynamic_symtab_upper_bound, \ --- binutils/bfd/tekhex.c.linkonce 2004-04-30 08:27:18.000000000 -0700 +++ binutils/bfd/tekhex.c 2004-05-17 09:45:02.000000000 -0700 @@ -1003,6 +1003,8 @@ tekhex_print_symbol (abfd, filep, symbol #define tekhex_bfd_merge_sections bfd_generic_merge_sections #define tekhex_bfd_is_group_section bfd_generic_is_group_section #define tekhex_bfd_discard_group bfd_generic_discard_group +#define tekhex_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/versados.c.linkonce 2004-04-30 08:27:18.000000000 -0700 +++ binutils/bfd/versados.c 2004-05-17 09:45:10.000000000 -0700 @@ -874,6 +874,8 @@ versados_canonicalize_reloc (abfd, secti #define versados_bfd_merge_sections bfd_generic_merge_sections #define versados_bfd_is_group_section bfd_generic_is_group_section #define versados_bfd_discard_group bfd_generic_discard_group +#define versados_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/bfd/vms.c.linkonce 2004-04-30 08:27:20.000000000 -0700 +++ binutils/bfd/vms.c 2004-05-17 13:35:00.000000000 -0700 @@ -168,6 +168,8 @@ static bfd_boolean vms_bfd_set_private_f #define vms_bfd_link_just_syms _bfd_generic_link_just_syms #define vms_bfd_is_group_section bfd_generic_is_group_section #define vms_bfd_discard_group bfd_generic_discard_group +#define vms_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections /*===========================================================================*/ --- binutils/bfd/xcoff-target.h.linkonce 2002-12-04 09:03:10.000000000 -0800 +++ binutils/bfd/xcoff-target.h 2004-05-17 09:45:17.000000000 -0700 @@ -99,6 +99,8 @@ extern int lynx_core_file_failing_signal #define _bfd_xcoff_bfd_gc_sections coff_bfd_gc_sections #define _bfd_xcoff_bfd_merge_sections coff_bfd_merge_sections #define _bfd_xcoff_bfd_discard_group bfd_generic_discard_group +#define _bfd_xcoff_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section /* XCOFF archives do not have anything which corresponds to an --- binutils/bfd/xsym.c.linkonce 2004-04-30 08:27:22.000000000 -0700 +++ binutils/bfd/xsym.c 2004-05-17 09:45:22.000000000 -0700 @@ -44,6 +44,8 @@ #define bfd_sym_bfd_merge_sections bfd_generic_merge_sections #define bfd_sym_bfd_is_group_section bfd_generic_is_group_section #define bfd_sym_bfd_discard_group bfd_generic_discard_group +#define bfd_sym_bfd_match_symbols_in_sections \ + _bfd_nolink_bfd_match_symbols_in_sections #define bfd_sym_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define bfd_sym_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define bfd_sym_bfd_link_add_symbols _bfd_generic_link_add_symbols --- binutils/ld/ldlang.c.linkonce 2004-05-14 09:00:52.000000000 -0700 +++ binutils/ld/ldlang.c 2004-05-17 13:57:34.000000000 -0700 @@ -853,6 +853,36 @@ struct already_linked asection *sec; }; +struct already_linked_section +{ + asection *sec; + asection *linked; +}; + +static bfd_boolean +try_match_symbols_in_sections (struct already_linked_hash_entry *h, + void *info) +{ + struct already_linked *l; + struct already_linked_section *s + = (struct already_linked_section *) info; + + /* No need to check group section. */ + if ((s->sec->flags & SEC_GROUP) != 0) + return TRUE; + + for (l = h->entry; l != NULL; l = l->next) + if ((l->sec->flags & SEC_GROUP) == 0 + && bfd_match_symbols_in_sections (l->sec->owner, + l->sec, s->sec)) + { + s->linked = l->sec; + return FALSE; + } + + return TRUE; +} + /* The hash table. */ static struct bfd_hash_table already_linked_table; @@ -865,6 +895,8 @@ section_already_linked (bfd *abfd, asect const char *name; struct already_linked *l; struct already_linked_hash_entry *already_linked_list; + struct already_linked_section result; + asection *group; /* If we are only reading symbols from this object, then we want to discard all sections. */ @@ -876,7 +908,13 @@ section_already_linked (bfd *abfd, asect flags = bfd_get_section_flags (abfd, sec); - if ((flags & SEC_LINK_ONCE) == 0) + /* Check if it belongs to a section group. */ + group = sec->group; + + if ((flags & SEC_LINK_ONCE) == 0 + && (group == NULL + || (group->flags + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD)) == 0)) return; /* FIXME: When doing a relocatable link, we may have trouble @@ -957,6 +995,25 @@ section_already_linked (bfd *abfd, asect } } + /* When we get here, we must be either a group member or a + .gnu.linkonce section. Check if a member of a COMDAT group + matches a .gnu.linkonce section and vice versa. */ + result.sec = sec; + result.linked = NULL; + bfd_hash_traverse (&already_linked_table, + (bfd_boolean (*) (struct bfd_hash_entry *, void *)) + try_match_symbols_in_sections, + &result); + if (result.linked) + { + sec->output_section = bfd_abs_section_ptr; + sec->kept_section = result.linked; + + /* Also discard the group section. */ + if (group != NULL) + group->output_section = bfd_abs_section_ptr; + } + /* This is the first section with this name. Record it. Allocate the memory from the same obstack as the hash table is kept in. */
- Previous message (by thread): PATCH: Support mixing COMDAT and linkonce
- Next message (by thread): PATCH: Support mixing COMDAT and linkonce
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list