X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fxcofflink.c;h=443ff770228e466320fd6ff2bf3a78182143da3c;hb=ec892a0718dc47c2d009532865c353daa749eaa1;hp=4adfb1746699af54da617d750331ae3d633182cc;hpb=7686d77de353217f4a1d50e07ccb5aecd2579e67;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 4adfb17466..443ff77022 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -1,6 +1,5 @@ /* POWER/PowerPC XCOFF linker support. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1995-2015 Free Software Foundation, Inc. Written by Ian Lance Taylor , Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -148,7 +147,7 @@ struct xcoff_link_hash_table struct xcoff_link_size_list *next; struct xcoff_link_hash_entry *h; bfd_size_type size; - } + } *size_list; /* Information about archives. */ @@ -572,7 +571,22 @@ xcoff_link_hash_newfunc (struct bfd_hash_entry *entry, return (struct bfd_hash_entry *) ret; } -/* Create a XCOFF link hash table. */ +/* Destroy an XCOFF link hash table. */ + +static void +_bfd_xcoff_bfd_link_hash_table_free (bfd *obfd) +{ + struct xcoff_link_hash_table *ret; + + ret = (struct xcoff_link_hash_table *) obfd->link.hash; + if (ret->archive_info) + htab_delete (ret->archive_info); + if (ret->debug_strtab) + _bfd_stringtab_free (ret->debug_strtab); + _bfd_generic_link_hash_table_free (obfd); +} + +/* Create an XCOFF link hash table. */ struct bfd_link_hash_table * _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd) @@ -580,7 +594,7 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd) struct xcoff_link_hash_table *ret; bfd_size_type amt = sizeof (* ret); - ret = bfd_malloc (amt); + ret = bfd_zmalloc (amt); if (ret == NULL) return NULL; if (!_bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc, @@ -591,20 +605,14 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd) } ret->debug_strtab = _bfd_xcoff_stringtab_init (); - ret->debug_section = NULL; - ret->loader_section = NULL; - ret->ldrel_count = 0; - memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr)); - ret->linkage_section = NULL; - ret->toc_section = NULL; - ret->descriptor_section = NULL; - ret->imports = NULL; - ret->file_align = 0; - ret->textro = FALSE; - ret->gc = FALSE; ret->archive_info = htab_create (37, xcoff_archive_info_hash, xcoff_archive_info_eq, NULL); - memset (ret->special_sections, 0, sizeof ret->special_sections); + if (!ret->debug_strtab || !ret->archive_info) + { + _bfd_xcoff_bfd_link_hash_table_free (abfd); + return NULL; + } + ret->root.hash_table_free = _bfd_xcoff_bfd_link_hash_table_free; /* The linker will always generate a full a.out header. We need to record that fact now, before the sizeof_headers routine could be @@ -613,18 +621,6 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd) return &ret->root; } - -/* Free a XCOFF link hash table. */ - -void -_bfd_xcoff_bfd_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - struct xcoff_link_hash_table *ret = (struct xcoff_link_hash_table *) hash; - - _bfd_stringtab_free (ret->debug_strtab); - bfd_hash_table_free (&ret->root.table); - free (ret); -} /* Read internal relocs for an XCOFF csect. This is a wrapper around _bfd_coff_read_internal_relocs which tries to take advantage of any @@ -1054,7 +1050,7 @@ xcoff_link_create_extra_sections (bfd * abfd, struct bfd_link_info *info) won't work if we're producing an XCOFF output file with no XCOFF input files. FIXME. */ - if (!info->relocatable + if (!bfd_link_relocatable (info) && xcoff_hash_table (info)->loader_section == NULL) { asection *lsec; @@ -2388,6 +2384,8 @@ xcoff_link_check_ar_symbols (bfd *abfd, static bfd_boolean xcoff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, + struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, bfd_boolean *pneeded) { bfd_boolean keep_syms_p; @@ -2467,7 +2465,7 @@ _bfd_xcoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info) bfd_boolean needed; if (! xcoff_link_check_archive_element (member, info, - &needed)) + NULL, NULL, &needed)) return FALSE; if (needed) member->archive_pass = -1; @@ -2702,7 +2700,7 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h) /* If we're marking an undefined symbol, try find some way of defining it. */ - if (!info->relocatable + if (!bfd_link_relocatable (info) && (h->flags & XCOFF_IMPORT) == 0 && (h->flags & XCOFF_DEF_REGULAR) == 0 && (h->root.type == bfd_link_hash_undefined @@ -2998,7 +2996,7 @@ xcoff_sweep (struct bfd_link_info *info) { bfd *sub; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { asection *o; @@ -3716,14 +3714,14 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, } /* Garbage collect unused sections. */ - if (info->relocatable || !gc) + if (bfd_link_relocatable (info) || !gc) { gc = FALSE; xcoff_hash_table (info)->gc = FALSE; /* We still need to call xcoff_mark, in order to set ldrel_count correctly. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { asection *o; @@ -3817,7 +3815,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, and figure out the contents of the .debug section. */ debug_strtab = xcoff_hash_table (info)->debug_strtab; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { asection *subdeb; bfd_size_type symcount; @@ -3986,7 +3984,7 @@ bfd_xcoff_link_generate_rtinit (bfd *abfd, bim->size = 0; bim->buffer = 0; - abfd->link_next = 0; + abfd->link.next = 0; abfd->format = bfd_object; abfd->iostream = (void *) bim; abfd->flags = BFD_IN_MEMORY; @@ -4147,7 +4145,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo, if (! flinfo->info->keep_memory) copy = TRUE; hash = TRUE; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) + if (flinfo->info->traditional_format) hash = FALSE; if (! _bfd_coff_get_external_symbols (input_bfd)) @@ -4496,7 +4494,10 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo, if (strings == NULL) return FALSE; } - filename = strings + aux.x_file.x_n.x_offset; + if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd)) + filename = _(""); + else + filename = strings + aux.x_file.x_n.x_offset; indx = _bfd_stringtab_add (flinfo->strtab, filename, hash, copy); if (indx == (bfd_size_type) -1) @@ -5054,7 +5055,7 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo) section_index = -1; for (input_bfd = flinfo->info->input_bfds; input_bfd != NULL; - input_bfd = input_bfd->link_next) + input_bfd = input_bfd->link.next) for (sec = input_bfd->sections; sec != NULL; sec = sec->next) if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec)) { @@ -5086,7 +5087,7 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo) best_address = toc_end; for (input_bfd = flinfo->info->input_bfds; input_bfd != NULL; - input_bfd = input_bfd->link_next) + input_bfd = input_bfd->link.next) for (sec = input_bfd->sections; sec != NULL; sec = sec->next) if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec)) { @@ -5117,7 +5118,8 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo) xcoff_data (output_bfd)->sntoc = section_index; /* Fill out the TC0 symbol. */ - if (!bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, &irsym, "TOC")) + if (!bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, flinfo->strtab, + &irsym, "TOC")) return FALSE; irsym.n_value = best_address; irsym.n_scnum = section_index; @@ -5382,7 +5384,8 @@ xcoff_write_global_symbol (struct bfd_hash_entry *bh, void * inf) the reloc. */ if (flinfo->info->strip != strip_all) { - result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, + result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, + flinfo->strtab, &irsym, h->root.root.string); if (!result) return FALSE; @@ -5556,8 +5559,8 @@ xcoff_write_global_symbol (struct bfd_hash_entry *bh, void * inf) h->indx = obj_raw_syment_count (output_bfd); - result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, &isym, - h->root.root.string); + result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, flinfo->strtab, + &isym, h->root.root.string); if (!result) return FALSE; @@ -5737,7 +5740,7 @@ xcoff_reloc_link_order (bfd *output_bfd, size = bfd_get_reloc_size (howto); buf = bfd_zmalloc (size); - if (buf == NULL) + if (buf == NULL && size != 0) return FALSE; rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); @@ -5829,7 +5832,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) file_ptr pos; bfd_size_type amt; - if (info->shared) + if (bfd_link_pic (info)) abfd->flags |= DYNAMIC; symesz = bfd_coff_symesz (abfd); @@ -6116,7 +6119,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) input BFD's. We want at least 6 symbols, since that is the number which xcoff_write_global_symbol may need. */ max_sym_count = 6; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { bfd_size_type sz; @@ -6273,7 +6276,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) irel = flinfo.section_info[o->target_index].relocs; irelend = irel + o->reloc_count; rel_hash = flinfo.section_info[o->target_index].rel_hashes; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) + for (; irel < irelend; irel++, rel_hash++) { if (*rel_hash != NULL) {