X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcofflink.c;h=bca136445de141eef3bb77cac9b734139810dad7;hb=7686d77de353217f4a1d50e07ccb5aecd2579e67;hp=12a693e0edad2006252900cab3015d6af188a59b;hpb=a50b1753d42fa4c760f96d72890684d3a3a221d0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 12a693e0ed..bca136445d 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -1,6 +1,6 @@ /* COFF specific linker code. Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -197,7 +197,8 @@ coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) static bfd_boolean coff_link_check_ar_symbols (bfd *abfd, struct bfd_link_info *info, - bfd_boolean *pneeded) + bfd_boolean *pneeded, + bfd **subsbfd) { bfd_size_type symesz; bfd_byte *esym; @@ -243,7 +244,8 @@ coff_link_check_ar_symbols (bfd *abfd, if (h != (struct bfd_link_hash_entry *) NULL && h->type == bfd_link_hash_undefined) { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) + if (!(*info->callbacks + ->add_archive_element) (info, abfd, name, subsbfd)) return FALSE; *pneeded = TRUE; return TRUE; @@ -267,20 +269,38 @@ coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded) { - if (! _bfd_coff_get_external_symbols (abfd)) - return FALSE; + bfd *oldbfd; + bfd_boolean needed; - if (! coff_link_check_ar_symbols (abfd, info, pneeded)) + if (!_bfd_coff_get_external_symbols (abfd)) return FALSE; - if (*pneeded - && ! coff_link_add_symbols (abfd, info)) + oldbfd = abfd; + if (!coff_link_check_ar_symbols (abfd, info, pneeded, &abfd)) return FALSE; - if ((! info->keep_memory || ! *pneeded) - && ! _bfd_coff_free_symbols (abfd)) - return FALSE; + needed = *pneeded; + if (needed) + { + /* Potentially, the add_archive_element hook may have set a + substitute BFD for us. */ + if (abfd != oldbfd) + { + if (!info->keep_memory + && !_bfd_coff_free_symbols (oldbfd)) + return FALSE; + if (!_bfd_coff_get_external_symbols (abfd)) + return FALSE; + } + if (!coff_link_add_symbols (abfd, info)) + return FALSE; + } + if (!info->keep_memory || !needed) + { + if (!_bfd_coff_free_symbols (abfd)) + return FALSE; + } return TRUE; } @@ -999,8 +1019,7 @@ _bfd_coff_final_link (bfd *abfd, /* Write out the global symbols. */ finfo.failed = FALSE; - coff_link_hash_traverse (coff_hash_table (info), - _bfd_coff_write_global_sym, &finfo); + bfd_hash_traverse (&info->hash->table, _bfd_coff_write_global_sym, &finfo); if (finfo.failed) goto error_return; @@ -1514,11 +1533,13 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd) /* Skip section symbols for sections which are not going to be emitted. */ if (!skip - && dont_skip_symbol == 0 + && !dont_skip_symbol && isym.n_sclass == C_STAT && isym.n_type == T_NULL - && isym.n_numaux > 0 - && (*secpp)->output_section == bfd_abs_section_ptr) + && isym.n_numaux > 0 + && ((*secpp)->output_section == bfd_abs_section_ptr + || bfd_section_removed_from_list (output_bfd, + (*secpp)->output_section))) skip = TRUE; #endif @@ -2343,6 +2364,35 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd) if (internal_relocs == NULL) return FALSE; + /* Run through the relocs looking for relocs against symbols + coming from discarded sections and complain about them. */ + irel = internal_relocs; + for (; irel < &internal_relocs[o->reloc_count]; irel++) + { + struct coff_link_hash_entry *h; + asection *ps = NULL; + long symndx = irel->r_symndx; + if (symndx < 0) + continue; + h = obj_coff_sym_hashes (input_bfd)[symndx]; + if (h == NULL) + continue; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct coff_link_hash_entry *) h->root.u.i.link; + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + ps = h->root.u.def.section; + if (ps == NULL) + continue; + /* Complain if definition comes from an excluded section. */ + if (ps->flags & SEC_EXCLUDE) + (*finfo->info->callbacks->einfo) + (_("%X`%s' referenced in section `%A' of %B: " + "defined in discarded section `%A' of %B\n"), + h->root.root.string, o, input_bfd, ps, ps->owner); + } + /* Call processor specific code to relocate the section contents. */ if (! bfd_coff_relocate_section (output_bfd, finfo->info, @@ -2465,11 +2515,12 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd) return TRUE; } -/* Write out a global symbol. Called via coff_link_hash_traverse. */ +/* Write out a global symbol. Called via bfd_hash_traverse. */ bfd_boolean -_bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data) +_bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) { + struct coff_link_hash_entry *h = (struct coff_link_hash_entry *) bh; struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; bfd *output_bfd; struct internal_syment isym; @@ -2694,7 +2745,7 @@ _bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data) case bfd_link_hash_defweak: save_global_to_static = finfo->global_to_static; finfo->global_to_static = TRUE; - rtnval = _bfd_coff_write_global_sym (h, data); + rtnval = _bfd_coff_write_global_sym (&h->root.root, data); finfo->global_to_static = save_global_to_static; break; default: @@ -2959,7 +3010,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, See also linker.c: generic_link_check_archive_element. */ asection *sec; struct coff_link_hash_entry *h2 = - input_bfd->tdata.coff_obj_data->sym_hashes[ + h->auxbfd->tdata.coff_obj_data->sym_hashes[ h->aux->x_sym.x_tagndx.l]; if (!h2 || h2->root.type == bfd_link_hash_undefined)