Hello, this patch improves COFF linker for undefined weak symbols and avoids writing symbols for discarded sections - if linker tells so -, and for IR generated sections.
ChangeLog 2011-10-09 Kai Tietz <kti...@redhat.com> * cofflink.c (coff_link_check_ar_symbols): Allow adding of archive-file if symbol was undefined weak. (_bfd_coff_write_global_sym): Skip write for symbol in discared section, or if section is coming from IR, or if input section has explicit SEC_EXCLUDED set. (_bfd_coff_generic_relocate_section): For undefined weak symbol and replacing it by another undefined weak, mark section as absolute. Regression tested for i686-w64-mingw32, x86_64-w64-mingw32, and i686-pc-cygwin. Ok for apply? Regards, Kai Index: src/bfd/cofflink.c =================================================================== --- src.orig/bfd/cofflink.c +++ src/bfd/cofflink.c @@ -242,7 +242,8 @@ coff_link_check_ar_symbols (bfd *abfd, COFF linkers do not bring in an object file which defines it. */ if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_undefined) + && (h->type == bfd_link_hash_undefined + || h->type == bfd_link_hash_undefweak)) { if (!(*info->callbacks ->add_archive_element) (info, abfd, name, subsbfd)) @@ -2527,6 +2528,7 @@ _bfd_coff_write_global_sym (struct bfd_h bfd_size_type symesz; unsigned int i; file_ptr pos; + asection *input_sec; output_bfd = finfo->output_bfd; @@ -2547,6 +2549,21 @@ _bfd_coff_write_global_sym (struct bfd_h h->root.root.string, FALSE, FALSE) == NULL)))) return TRUE; + else if (h->indx != -2 + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && ((finfo->info->strip_discarded + && !bfd_is_abs_section (h->root.u.def.section) + && bfd_is_abs_section (h->root.u.def.section->output_section)) + || (h->root.u.def.section->owner != NULL + && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0))) + return TRUE; + else if (h->indx != -2 + && (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak) + && h->root.u.undef.abfd != NULL + && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0) + return TRUE; switch (h->root.type) { @@ -2560,26 +2577,37 @@ _bfd_coff_write_global_sym (struct bfd_h case bfd_link_hash_undefweak: isym.n_scnum = N_UNDEF; isym.n_value = 0; + input_sec = bfd_und_section_ptr; break; case bfd_link_hash_defined: case bfd_link_hash_defweak: - { - asection *sec; + input_sec = h->root.u.def.section; + if (input_sec->output_section != NULL) + { + asection *sec; - sec = h->root.u.def.section->output_section; - if (bfd_is_abs_section (sec)) - isym.n_scnum = N_ABS; - else - isym.n_scnum = sec->target_index; - isym.n_value = (h->root.u.def.value - + h->root.u.def.section->output_offset); - if (! obj_pe (finfo->output_bfd)) - isym.n_value += sec->vma; - } + sec = h->root.u.def.section->output_section; + if (bfd_is_abs_section (sec)) + isym.n_scnum = N_ABS; + else + isym.n_scnum = sec->target_index; + isym.n_value = (h->root.u.def.value + + h->root.u.def.section->output_offset); + if (! obj_pe (finfo->output_bfd)) + isym.n_value += sec->vma; + } + else + { + BFD_ASSERT (input_sec->owner == NULL); + isym.n_scnum = N_UNDEF; + isym.n_value = 0; + input_sec = bfd_und_section_ptr; + } break; case bfd_link_hash_common: + input_sec = h->root.u.c.p->section; isym.n_scnum = N_UNDEF; isym.n_value = h->root.u.c.size; break; @@ -2589,6 +2617,9 @@ _bfd_coff_write_global_sym (struct bfd_h return TRUE; } + if ((input_sec->flags & SEC_EXCLUDE) != 0) + return TRUE; + if (strlen (h->root.root.string) <= SYMNMLEN) strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN); else @@ -3013,7 +3044,8 @@ _bfd_coff_generic_relocate_section (bfd h->auxbfd->tdata.coff_obj_data->sym_hashes[ h->aux->x_sym.x_tagndx.l]; - if (!h2 || h2->root.type == bfd_link_hash_undefined) + if (!h2 || h2->root.type == bfd_link_hash_undefined + || h2->root.type == bfd_link_hash_undefweak) { sec = bfd_abs_section_ptr; val = 0;