X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoff64-rs6000.c;h=0588567f0782ee1a1cab95262d8c773603f87614;hb=ade4fd9ba4827769326207fc0d8d835205c08ae3;hp=7b5bb2460f729307aecfd0f73a30b78039a8f7db;hpb=4f3b23b390640efdc36c575dbda2175e61154bc9;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 7b5bb2460f..0588567f07 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -1,5 +1,5 @@ /* BFD back-end for IBM RS/6000 "XCOFF64" files. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2020 Free Software Foundation, Inc. Written Clinton Popetz. Contributed by Cygnus Support. @@ -278,7 +278,6 @@ extern int rs6000coff_core_file_failing_signal #define bfd_pe_print_pdata NULL #endif -#include #include "coffcode.h" /* For XCOFF64, the effective width of symndx changes depending on @@ -345,7 +344,7 @@ _bfd_xcoff64_swap_sym_out (bfd *abfd, void *inp, void *extp) static void _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class, - int indx, int numaux, void *in1) + int indx, int numaux, void *in1) { union external_auxent *ext = (union external_auxent *) ext1; union internal_auxent *in = (union internal_auxent *) in1; @@ -357,7 +356,7 @@ _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class, { in->x_file.x_n.x_zeroes = 0; in->x_file.x_n.x_offset = - H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset); + H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset); } else { @@ -432,9 +431,9 @@ _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class, static unsigned int _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, - int indx ATTRIBUTE_UNUSED, - int numaux ATTRIBUTE_UNUSED, - void *extp) + int indx ATTRIBUTE_UNUSED, + int numaux ATTRIBUTE_UNUSED, + void *extp) { union internal_auxent *in = (union internal_auxent *) inp; union external_auxent *ext = (union external_auxent *) extp; @@ -447,7 +446,7 @@ _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, { H_PUT_32 (abfd, 0, ext->x_file.x_n.x_n.x_zeroes); H_PUT_32 (abfd, in->x_file.x_n.x_offset, - ext->x_file.x_n.x_n.x_offset); + ext->x_file.x_n.x_n.x_offset); } else { @@ -521,8 +520,8 @@ _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, static bfd_boolean _bfd_xcoff64_put_symbol_name (struct bfd_link_info *info, struct bfd_strtab_hash *strtab, - struct internal_syment *sym, - const char *name) + struct internal_syment *sym, + const char *name) { bfd_boolean hash; bfd_size_type indx; @@ -541,9 +540,9 @@ _bfd_xcoff64_put_symbol_name (struct bfd_link_info *info, static bfd_boolean _bfd_xcoff64_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED, - struct xcoff_loader_info *ldinfo, - struct internal_ldsym *ldsym, - const char *name) + struct xcoff_loader_info *ldinfo, + struct internal_ldsym *ldsym, + const char *name) { size_t len; len = strlen (name); @@ -588,8 +587,8 @@ _bfd_xcoff64_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED, static void xcoff64_swap_ldhdr_in (bfd *abfd, - const void *s, - struct internal_ldhdr *dst) + const void *s, + struct internal_ldhdr *dst) { const struct external_ldhdr *src = (const struct external_ldhdr *) s; @@ -960,7 +959,7 @@ xcoff64_write_object_contents (bfd *abfd) if (text_sec != NULL) { internal_a.o_sntext = text_sec->target_index; - internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec); + internal_a.o_algntext = bfd_section_alignment (text_sec); } else { @@ -971,7 +970,7 @@ xcoff64_write_object_contents (bfd *abfd) if (data_sec != NULL) { internal_a.o_sndata = data_sec->target_index; - internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec); + internal_a.o_algndata = bfd_section_alignment (data_sec); } else { @@ -1062,15 +1061,15 @@ xcoff64_write_object_contents (bfd *abfd) static bfd_boolean xcoff64_reloc_type_br (bfd *input_bfd, - asection *input_section, - bfd *output_bfd ATTRIBUTE_UNUSED, - struct internal_reloc *rel, - struct internal_syment *sym ATTRIBUTE_UNUSED, - struct reloc_howto_struct *howto, - bfd_vma val, - bfd_vma addend, - bfd_vma *relocation, - bfd_byte *contents) + asection *input_section, + bfd *output_bfd ATTRIBUTE_UNUSED, + struct internal_reloc *rel, + struct internal_syment *sym ATTRIBUTE_UNUSED, + struct reloc_howto_struct *howto, + bfd_vma val, + bfd_vma addend, + bfd_vma *relocation, + bfd_byte *contents) { struct xcoff_link_hash_entry *h; bfd_vma section_offset; @@ -1169,13 +1168,13 @@ xcoff64_reloc_type_br (bfd *input_bfd, bfd_boolean xcoff64_ppc_relocate_section (bfd *output_bfd, - struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - struct internal_reloc *relocs, - struct internal_syment *syms, - asection **sections) + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + struct internal_syment *syms, + asection **sections) { struct internal_reloc *rel; struct internal_reloc *relend; @@ -1250,15 +1249,11 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, { if (info->unresolved_syms_in_objects != RM_IGNORE && (h->flags & XCOFF_WAS_UNDEFINED) != 0) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, - input_bfd, input_section, - rel->r_vaddr - input_section->vma, - (info->unresolved_syms_in_objects - == RM_GENERATE_ERROR)))) - return FALSE; - } + (*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, input_section, + rel->r_vaddr - input_section->vma, + info->unresolved_syms_in_objects == RM_GENERATE_ERROR); + if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { @@ -1310,10 +1305,6 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, operation, which would be tedious, or we must do the computations in a type larger than bfd_vma, which would be inefficient. */ - if ((unsigned int) howto.complain_on_overflow - >= XCOFF_MAX_COMPLAIN_OVERFLOW) - abort (); - if (((*xcoff_complain_overflow[howto.complain_on_overflow]) (input_bfd, value_to_relocate, relocation, &howto))) { @@ -1337,11 +1328,10 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, } sprintf (reloc_type_name, "0x%02x", rel->r_type); - if (! ((*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), name, reloc_type_name, - (bfd_vma) 0, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return FALSE; + (*info->callbacks->reloc_overflow) + (info, (h ? &h->root : NULL), name, reloc_type_name, + (bfd_vma) 0, input_bfd, input_section, + rel->r_vaddr - input_section->vma); } /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */ @@ -1812,7 +1802,7 @@ xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) reloc_howto_type * xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, - bfd_reloc_code_real_type code) + bfd_reloc_code_real_type code) { switch (code) { @@ -1857,6 +1847,46 @@ xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, return NULL; } +/* PR 21786: The PE/COFF standard does not require NUL termination for any of + the ASCII fields in the archive headers. So in order to be able to extract + numerical values we provide our own versions of strtol and strtoll which + take a maximum length as an additional parameter. Also - just to save space, + we omit the endptr return parameter, since we know that it is never used. */ + +static long +_bfd_strntol (const char * nptr, int base, unsigned int maxlen) +{ + char buf[24]; /* Should be enough. */ + + BFD_ASSERT (maxlen < (sizeof (buf) - 1)); + + memcpy (buf, nptr, maxlen); + buf[maxlen] = 0; + return strtol (buf, NULL, base); +} + +static long long +_bfd_strntoll (const char * nptr, int base, unsigned int maxlen) +{ + char buf[32]; /* Should be enough. */ + + BFD_ASSERT (maxlen < (sizeof (buf) - 1)); + + memcpy (buf, nptr, maxlen); + buf[maxlen] = 0; + return strtoll (buf, NULL, base); +} + +/* Macro to read an ASCII value stored in an archive header field. */ +#define GET_VALUE_IN_FIELD(VAR, FIELD, BASE) \ + do \ + { \ + (VAR) = (sizeof (VAR) > sizeof (long) \ + ? _bfd_strntoll (FIELD, BASE, sizeof FIELD) \ + : _bfd_strntol (FIELD, BASE, sizeof FIELD)); \ + } \ + while (0) + /* Read in the armap of an XCOFF archive. */ static bfd_boolean @@ -1876,7 +1906,7 @@ xcoff64_slurp_armap (bfd *abfd) if (xcoff_ardata (abfd) == NULL) { - bfd_has_map (abfd) = FALSE; + abfd->has_armap = FALSE; return TRUE; } @@ -1884,7 +1914,7 @@ xcoff64_slurp_armap (bfd *abfd) (const char **) NULL, 10); if (off == 0) { - bfd_has_map (abfd) = FALSE; + abfd->has_armap = FALSE; return TRUE; } @@ -1897,24 +1927,33 @@ xcoff64_slurp_armap (bfd *abfd) return FALSE; /* Skip the name (normally empty). */ - namlen = strtol (hdr.namlen, (char **) NULL, 10); + GET_VALUE_IN_FIELD (namlen, hdr.namlen, 10); pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG; if (bfd_seek (abfd, pos, SEEK_CUR) != 0) return FALSE; sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10); + if (sz == (bfd_size_type) -1) + { + bfd_set_error (bfd_error_no_memory); + return FALSE; + } /* Read in the entire symbol table. */ - contents = (bfd_byte *) bfd_alloc (abfd, sz); + contents = (bfd_byte *) bfd_alloc (abfd, sz + 1); if (contents == NULL) return FALSE; if (bfd_bread (contents, sz, abfd) != sz) return FALSE; + /* Ensure strings are NULL terminated so we don't wander off the end + of the buffer. */ + contents[sz] = 0; + /* The symbol table starts with an eight byte count. */ c = H_GET_64 (abfd, contents); - if (c * 8 >= sz) + if (c >= sz / 8) { bfd_set_error (bfd_error_bad_value); return FALSE; @@ -1946,7 +1985,7 @@ xcoff64_slurp_armap (bfd *abfd) } bfd_ardata (abfd)->symdef_count = c; - bfd_has_map (abfd) = TRUE; + abfd->has_armap = TRUE; return TRUE; } @@ -2086,7 +2125,7 @@ xcoff64_sizeof_headers (bfd *abfd, static asection * xcoff64_create_csect_from_smclas (bfd *abfd, union internal_auxent *aux, - const char *symbol_name) + const char *symbol_name) { asection *return_value = NULL; @@ -2110,8 +2149,9 @@ xcoff64_create_csect_from_smclas (bfd *abfd, union internal_auxent *aux, } else { - (*_bfd_error_handler) - (_("%B: symbol `%s' has unrecognized smclas %d"), + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: symbol `%s' has unrecognized smclas %d"), abfd, symbol_name, aux->x_csect.x_smclas); bfd_set_error (bfd_error_bad_value); } @@ -2121,28 +2161,28 @@ xcoff64_create_csect_from_smclas (bfd *abfd, union internal_auxent *aux, static bfd_boolean xcoff64_is_lineno_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, - bfd_vma value ATTRIBUTE_UNUSED) + bfd_vma value ATTRIBUTE_UNUSED) { return FALSE; } static bfd_boolean xcoff64_is_reloc_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, - bfd_vma value ATTRIBUTE_UNUSED) + bfd_vma value ATTRIBUTE_UNUSED) { return FALSE; } static bfd_vma xcoff64_loader_symbol_offset (bfd *abfd ATTRIBUTE_UNUSED, - struct internal_ldhdr *ldhdr) + struct internal_ldhdr *ldhdr) { return (ldhdr->l_symoff); } static bfd_vma xcoff64_loader_reloc_offset (bfd *abfd ATTRIBUTE_UNUSED, - struct internal_ldhdr *ldhdr) + struct internal_ldhdr *ldhdr) { return (ldhdr->l_rldoff); } @@ -2164,7 +2204,7 @@ xcoff64_bad_format_hook (bfd * abfd, void *filehdr) static bfd_boolean xcoff64_generate_rtinit (bfd *abfd, const char *init, const char *fini, - bfd_boolean rtld) + bfd_boolean rtld) { bfd_byte filehdr_ext[FILHSZ]; bfd_byte scnhdr_ext[SCNHSZ * 3]; @@ -2658,22 +2698,22 @@ const bfd_target rs6000_xcoff64_vec = }, { /* bfd_set_format */ - bfd_false, + _bfd_bool_bfd_false_error, coff_mkobject, _bfd_generic_mkarchive, - bfd_false + _bfd_bool_bfd_false_error }, {/* bfd_write_contents */ - bfd_false, + _bfd_bool_bfd_false_error, xcoff64_write_object_contents, _bfd_xcoff_write_archive_contents, - bfd_false + _bfd_bool_bfd_false_error }, /* Generic */ _bfd_archive_close_and_cleanup, - bfd_true, + _bfd_bool_bfd_true, coff_new_section_hook, _bfd_generic_get_section_contents, _bfd_generic_get_section_contents_in_window, @@ -2702,7 +2742,7 @@ const bfd_target rs6000_xcoff64_vec = xcoff64_openr_next_archived_file, _bfd_generic_get_elt_at_index, _bfd_xcoff_stat_arch_elt, - bfd_true, + _bfd_bool_bfd_true, /* Symbols */ coff_get_symtab_upper_bound, @@ -2724,6 +2764,7 @@ const bfd_target rs6000_xcoff64_vec = /* Reloc */ coff_get_reloc_upper_bound, coff_canonicalize_reloc, + _bfd_generic_set_reloc, xcoff64_reloc_type_lookup, xcoff64_reloc_name_lookup, @@ -2746,9 +2787,12 @@ const bfd_target rs6000_xcoff64_vec = bfd_generic_lookup_section_flags, bfd_generic_merge_sections, bfd_generic_is_group_section, + bfd_generic_group_name, bfd_generic_discard_group, _bfd_generic_section_already_linked, _bfd_xcoff_define_common_symbol, + _bfd_generic_link_hide_symbol, + bfd_generic_define_start_stop, /* Dynamic */ _bfd_xcoff_get_dynamic_symtab_upper_bound, @@ -2917,22 +2961,22 @@ const bfd_target rs6000_xcoff64_aix_vec = }, { /* bfd_set_format */ - bfd_false, + _bfd_bool_bfd_false_error, coff_mkobject, _bfd_generic_mkarchive, - bfd_false + _bfd_bool_bfd_false_error }, {/* bfd_write_contents */ - bfd_false, + _bfd_bool_bfd_false_error, xcoff64_write_object_contents, _bfd_xcoff_write_archive_contents, - bfd_false + _bfd_bool_bfd_false_error }, /* Generic */ _bfd_archive_close_and_cleanup, - bfd_true, + _bfd_bool_bfd_true, coff_new_section_hook, _bfd_generic_get_section_contents, _bfd_generic_get_section_contents_in_window, @@ -2961,7 +3005,7 @@ const bfd_target rs6000_xcoff64_aix_vec = xcoff64_openr_next_archived_file, _bfd_generic_get_elt_at_index, _bfd_xcoff_stat_arch_elt, - bfd_true, + _bfd_bool_bfd_true, /* Symbols */ coff_get_symtab_upper_bound, @@ -2983,6 +3027,7 @@ const bfd_target rs6000_xcoff64_aix_vec = /* Reloc */ coff_get_reloc_upper_bound, coff_canonicalize_reloc, + _bfd_generic_set_reloc, xcoff64_reloc_type_lookup, xcoff64_reloc_name_lookup, @@ -3005,9 +3050,12 @@ const bfd_target rs6000_xcoff64_aix_vec = bfd_generic_lookup_section_flags, bfd_generic_merge_sections, bfd_generic_is_group_section, + bfd_generic_group_name, bfd_generic_discard_group, _bfd_generic_section_already_linked, _bfd_xcoff_define_common_symbol, + _bfd_generic_link_hide_symbol, + bfd_generic_define_start_stop, /* Dynamic */ _bfd_xcoff_get_dynamic_symtab_upper_bound,