X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fsom.c;h=d36d163bb6b11910325c0581d9f1ad28fbab6045;hb=7b958a48e1322880f23cdb0a1c35643dd27d3ddb;hp=513e4fa6049874e866e4b9e2212de802fbe557b1;hpb=fb167eb272279154dc2502614eb5331b01dc6ea4;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/som.c b/bfd/som.c index 513e4fa604..d36d163bb6 100644 --- a/bfd/som.c +++ b/bfd/som.c @@ -1,5 +1,5 @@ /* bfd back-end for HP PA-RISC SOM objects. - Copyright (C) 1990-2014 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Contributed by the Center for Software Science at the University of Utah. @@ -24,7 +24,7 @@ #include "sysdep.h" #include "alloca-conf.h" #include "bfd.h" - +#include "libiberty.h" #include "libbfd.h" #include "som.h" #include "safe-ctype.h" @@ -1425,7 +1425,7 @@ hppa_som_gen_reloc_type (bfd *abfd, /* The difference of two symbols needs *very* special handling. */ if (sym_diff) { - bfd_size_type amt = sizeof (int); + size_t amt = sizeof (int); final_types[0] = bfd_alloc (abfd, amt); final_types[1] = bfd_alloc (abfd, amt); @@ -1509,7 +1509,7 @@ hppa_som_gen_reloc_type (bfd *abfd, /* The difference of two symbols needs *very* special handling. */ if (sym_diff) { - bfd_size_type amt = sizeof (int); + size_t amt = sizeof (int); final_types[0] = bfd_alloc (abfd, amt); final_types[1] = bfd_alloc (abfd, amt); @@ -1548,7 +1548,7 @@ hppa_som_gen_reloc_type (bfd *abfd, /* If we have short and long pcrel modes, then generate the proper mode selector, then the pcrel relocation. Redundant selectors will be eliminated as the relocs are sized and emitted. */ - bfd_size_type amt = sizeof (int); + size_t amt = sizeof (int); final_types[0] = bfd_alloc (abfd, amt); if (!final_types[0]) @@ -1601,7 +1601,7 @@ som_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, static void som_swap_clock_in (struct som_external_clock *src, - struct som_clock *dst) + struct som_clock *dst) { dst->secs = bfd_getb32 (src->secs); dst->nanosecs = bfd_getb32 (src->nanosecs); @@ -1609,7 +1609,7 @@ som_swap_clock_in (struct som_external_clock *src, static void som_swap_clock_out (struct som_clock *src, - struct som_external_clock *dst) + struct som_external_clock *dst) { bfd_putb32 (src->secs, dst->secs); bfd_putb32 (src->nanosecs, dst->nanosecs); @@ -1617,7 +1617,7 @@ som_swap_clock_out (struct som_clock *src, static void som_swap_header_in (struct som_external_header *src, - struct som_header *dst) + struct som_header *dst) { dst->system_id = bfd_getb16 (src->system_id); dst->a_magic = bfd_getb16 (src->a_magic); @@ -1655,7 +1655,7 @@ som_swap_header_in (struct som_external_header *src, static void som_swap_header_out (struct som_header *src, - struct som_external_header *dst) + struct som_external_header *dst) { bfd_putb16 (src->system_id, dst->system_id); bfd_putb16 (src->a_magic, dst->a_magic); @@ -1693,7 +1693,7 @@ som_swap_header_out (struct som_header *src, static void som_swap_space_dictionary_in (struct som_external_space_dictionary_record *src, - struct som_space_dictionary_record *dst) + struct som_space_dictionary_record *dst) { unsigned int flags; @@ -1718,7 +1718,7 @@ som_swap_space_dictionary_in (struct som_external_space_dictionary_record *src, static void som_swap_space_dictionary_out (struct som_space_dictionary_record *src, - struct som_external_space_dictionary_record *dst) + struct som_external_space_dictionary_record *dst) { unsigned int flags; @@ -1831,7 +1831,7 @@ som_swap_subspace_dictionary_record_out static void som_swap_aux_id_in (struct som_external_aux_id *src, - struct som_aux_id *dst) + struct som_aux_id *dst) { unsigned int flags = bfd_getb32 (src->flags); @@ -1845,7 +1845,7 @@ som_swap_aux_id_in (struct som_external_aux_id *src, static void som_swap_aux_id_out (struct som_aux_id *src, - struct som_external_aux_id *dst) + struct som_external_aux_id *dst) { unsigned int flags = 0; @@ -1864,7 +1864,7 @@ som_swap_aux_id_out (struct som_aux_id *src, static void som_swap_string_auxhdr_out (struct som_string_auxhdr *src, - struct som_external_string_auxhdr *dst) + struct som_external_string_auxhdr *dst) { som_swap_aux_id_out (&src->header_id, &dst->header_id); bfd_putb32 (src->string_length, dst->string_length); @@ -1872,7 +1872,7 @@ som_swap_string_auxhdr_out (struct som_string_auxhdr *src, static void som_swap_compilation_unit_out (struct som_compilation_unit *src, - struct som_external_compilation_unit *dst) + struct som_external_compilation_unit *dst) { bfd_putb32 (src->name.strx, dst->name); bfd_putb32 (src->language_name.strx, dst->language_name); @@ -1885,7 +1885,7 @@ som_swap_compilation_unit_out (struct som_compilation_unit *src, static void som_swap_exec_auxhdr_in (struct som_external_exec_auxhdr *src, - struct som_exec_auxhdr *dst) + struct som_exec_auxhdr *dst) { som_swap_aux_id_in (&src->som_auxhdr, &dst->som_auxhdr); dst->exec_tsize = bfd_getb32 (src->exec_tsize); @@ -1902,7 +1902,7 @@ som_swap_exec_auxhdr_in (struct som_external_exec_auxhdr *src, static void som_swap_exec_auxhdr_out (struct som_exec_auxhdr *src, - struct som_external_exec_auxhdr *dst) + struct som_external_exec_auxhdr *dst) { som_swap_aux_id_out (&src->som_auxhdr, &dst->som_auxhdr); bfd_putb32 (src->exec_tsize, dst->exec_tsize); @@ -1919,7 +1919,7 @@ som_swap_exec_auxhdr_out (struct som_exec_auxhdr *src, static void som_swap_lst_header_in (struct som_external_lst_header *src, - struct som_lst_header *dst) + struct som_lst_header *dst) { dst->system_id = bfd_getb16 (src->system_id); dst->a_magic = bfd_getb16 (src->a_magic); @@ -1945,7 +1945,7 @@ som_swap_lst_header_in (struct som_external_lst_header *src, /* Perform some initialization for an object. Save results of this initialization in the BFD. */ -static const bfd_target * +static bfd_cleanup som_object_setup (bfd *abfd, struct som_header *file_hdrp, struct som_exec_auxhdr *aux_hdrp, @@ -2031,12 +2031,12 @@ som_object_setup (bfd *abfd, || (aux_hdrp->exec_entry & 0x3) != 0 || ! found) { - bfd_get_start_address (abfd) = aux_hdrp->exec_flags; + abfd->start_address = aux_hdrp->exec_flags; obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry; } else { - bfd_get_start_address (abfd) = aux_hdrp->exec_entry + current_offset; + abfd->start_address = aux_hdrp->exec_entry + current_offset; obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags; } } @@ -2044,7 +2044,7 @@ som_object_setup (bfd *abfd, obj_som_exec_data (abfd)->version_id = file_hdrp->version_id; bfd_default_set_arch_mach (abfd, bfd_arch_hppa, pa10); - bfd_get_symcount (abfd) = file_hdrp->symbol_total; + abfd->symcount = file_hdrp->symbol_total; /* Initialize the saved symbol table and string table to NULL. Save important offsets and sizes from the SOM header into @@ -2060,7 +2060,7 @@ som_object_setup (bfd *abfd, + current_offset); obj_som_exec_data (abfd)->system_id = file_hdrp->system_id; - return abfd->xvec; + return _bfd_no_cleanup; } /* Convert all of the space and subspace info into BFD sections. Each space @@ -2074,24 +2074,28 @@ setup_sections (bfd *abfd, struct som_header *file_hdr, unsigned long current_offset) { - char *space_strings; + char *space_strings = NULL; unsigned int space_index, i; unsigned int total_subspaces = 0; asection **subspace_sections = NULL; asection *section; - bfd_size_type amt; + size_t amt; /* First, read in space names. */ amt = file_hdr->space_strings_size; - space_strings = bfd_malloc (amt); - if (!space_strings && amt != 0) - goto error_return; - + if (amt == (size_t) -1) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location, SEEK_SET) != 0) goto error_return; - if (bfd_bread (space_strings, amt, abfd) != amt) + space_strings = (char *) _bfd_malloc_and_read (abfd, amt + 1, amt); + if (space_strings == NULL) goto error_return; + /* Make sure that the string table is NUL terminated. */ + space_strings[amt] = 0; /* Loop over all of the space dictionaries, building up sections. */ for (space_index = 0; space_index < file_hdr->space_total; space_index++) @@ -2119,6 +2123,9 @@ setup_sections (bfd *abfd, som_swap_space_dictionary_in (&ext_space, &space); /* Setup the space name string. */ + if (space.name >= file_hdr->space_strings_size) + goto error_return; + space_name = space.name + space_strings; /* Make a section out of it. */ @@ -2180,16 +2187,19 @@ setup_sections (bfd *abfd, subspace_index++) { asection *subspace_asect; - char *subspace_name; + char *subspace_name; /* Read in the next subspace. */ amt = sizeof ext_subspace; if (bfd_bread (&ext_subspace, amt, abfd) != amt) goto error_return; - som_swap_subspace_dictionary_in (&ext_subspace, &subspace); + som_swap_subspace_dictionary_in (&ext_subspace, &subspace); /* Setup the subspace name string. */ + if (subspace.name >= file_hdr->space_strings_size) + goto error_return; + subspace_name = subspace.name + space_strings; amt = strlen (subspace_name) + 1; @@ -2324,7 +2334,7 @@ setup_sections (bfd *abfd, else { /* The subspace_start field is not initialised in relocatable - only objects, so it cannot be used for length calculations. + only objects, so it cannot be used for length calculations. Instead we use the space_size value which we have been accumulating. This isn't an accurate estimate since it ignores alignment and ordering issues. */ @@ -2334,8 +2344,11 @@ setup_sections (bfd *abfd, } /* Now that we've read in all the subspace records, we need to assign a target index to each subspace. */ - amt = total_subspaces; - amt *= sizeof (asection *); + if (_bfd_mul_overflow (total_subspaces, sizeof (asection *), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + goto error_return; + } subspace_sections = bfd_malloc (amt); if (subspace_sections == NULL) goto error_return; @@ -2376,7 +2389,7 @@ setup_sections (bfd *abfd, /* Read in a SOM object and make it into a BFD. */ -static const bfd_target * +static bfd_cleanup som_object_p (bfd *abfd) { struct som_external_header ext_file_hdr; @@ -2385,7 +2398,7 @@ som_object_p (bfd *abfd) unsigned long current_offset = 0; struct som_external_lst_header ext_lst_header; struct som_external_som_entry ext_som_entry; - bfd_size_type amt; + size_t amt; unsigned int loc; #define ENTRY_SIZE sizeof (struct som_external_som_entry) @@ -2540,7 +2553,7 @@ som_prep_headers (bfd *abfd) { struct som_header *file_hdr; asection *section; - bfd_size_type amt = sizeof (struct som_header); + size_t amt = sizeof (struct som_header); /* Make and attach a file header to the BFD. */ file_hdr = bfd_zalloc (abfd, amt); @@ -2790,13 +2803,13 @@ compare_subspaces (const void *arg1, const void *arg2) /* Perform various work in preparation for emitting the fixup stream. */ -static void +static bfd_boolean som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms) { unsigned long i; asection *section; asymbol **sorted_syms; - bfd_size_type amt; + size_t amt; /* Most SOM relocations involving a symbol have a length which is dependent on the index of the symbol. So symbols which are @@ -2868,9 +2881,14 @@ som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms) /* Sort a copy of the symbol table, rather than the canonical output symbol table. */ - amt = num_syms; - amt *= sizeof (asymbol *); + if (_bfd_mul_overflow (num_syms, sizeof (asymbol *), &amt)) + { + bfd_set_error (bfd_error_no_memory); + return FALSE; + } sorted_syms = bfd_zalloc (abfd, amt); + if (sorted_syms == NULL) + return FALSE; memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *)); qsort (sorted_syms, num_syms, sizeof (asymbol *), compare_syms); obj_som_sorted_syms (abfd) = sorted_syms; @@ -2886,6 +2904,7 @@ som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms) else som_symbol_data (sorted_syms[i])->index = i; } + return TRUE; } static bfd_boolean @@ -2902,7 +2921,7 @@ som_write_fixups (bfd *abfd, unsigned int subspace_reloc_size = 0; unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total; asection *section = abfd->sections; - bfd_size_type amt; + size_t amt; memset (tmp_space, 0, SOM_TMP_BUFSIZE); p = tmp_space; @@ -3304,11 +3323,15 @@ som_write_space_strings (bfd *abfd, /* Chunk of memory that we can use as buffer space, then throw away. */ size_t tmp_space_size = SOM_TMP_BUFSIZE; - char *tmp_space = alloca (tmp_space_size); + char *tmp_space = bfd_malloc (tmp_space_size); char *p = tmp_space; unsigned int strings_size = 0; asection *section; - bfd_size_type amt; + size_t amt; + bfd_size_type res; + + if (tmp_space == NULL) + return FALSE; /* Seek to the start of the space strings in preparation for writing them out. */ @@ -3351,11 +3374,11 @@ som_write_space_strings (bfd *abfd, returning from this function.) The same technique is used a few more times below when a buffer is reallocated. */ - if (2 * tmp_space_size < length + 5) - tmp_space_size = length + 5; - else - tmp_space_size = 2 * tmp_space_size; - tmp_space = alloca (tmp_space_size); + if (2 * tmp_space_size < length + 5) + tmp_space_size = length + 5; + else + tmp_space_size = 2 * tmp_space_size; + tmp_space = xrealloc (tmp_space, tmp_space_size); } /* Reset to beginning of the (possibly new) buffer space. */ @@ -3391,7 +3414,9 @@ som_write_space_strings (bfd *abfd, /* Done with the space/subspace strings. Write out any information contained in a partial block. */ amt = p - tmp_space; - if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt) + res = bfd_bwrite ((void *) &tmp_space[0], amt, abfd); + free (tmp_space); + if (res != amt) return FALSE; *string_sizep = strings_size; return TRUE; @@ -3408,15 +3433,17 @@ som_write_symbol_strings (bfd *abfd, struct som_compilation_unit *compilation_unit) { unsigned int i; - /* Chunk of memory that we can use as buffer space, then throw away. */ size_t tmp_space_size = SOM_TMP_BUFSIZE; - char *tmp_space = alloca (tmp_space_size); + char *tmp_space = bfd_malloc (tmp_space_size); char *p = tmp_space; - unsigned int strings_size = 0; - bfd_size_type amt; + size_t amt; + bfd_size_type res; + + if (tmp_space == NULL) + return FALSE; /* This gets a bit gruesome because of the compilation unit. The strings within the compilation unit are part of the symbol @@ -3434,8 +3461,8 @@ som_write_symbol_strings (bfd *abfd, { for (i = 0; i < 4; i++) { - struct som_name_pt *name; - size_t length; + struct som_name_pt *name; + size_t length; switch (i) { @@ -3451,8 +3478,8 @@ som_write_symbol_strings (bfd *abfd, case 3: name = &compilation_unit->version_id; break; - default: - abort (); + default: + abort (); } length = strlen (name->name); @@ -3471,11 +3498,11 @@ som_write_symbol_strings (bfd *abfd, if (5 + length > tmp_space_size) { /* See alloca above for discussion of new size. */ - if (2 * tmp_space_size < 5 + length) - tmp_space_size = 5 + length; - else - tmp_space_size = 2 * tmp_space_size; - tmp_space = alloca (tmp_space_size); + if (2 * tmp_space_size < 5 + length) + tmp_space_size = 5 + length; + else + tmp_space_size = 2 * tmp_space_size; + tmp_space = xrealloc (tmp_space, tmp_space_size); } /* Reset to beginning of the (possibly new) buffer @@ -3494,7 +3521,7 @@ som_write_symbol_strings (bfd *abfd, /* Next comes the string itself + a null terminator. */ strcpy (p, name->name); - name->strx = strings_size; + name->strx = strings_size; p += length + 1; strings_size += length + 1; @@ -3526,11 +3553,11 @@ som_write_symbol_strings (bfd *abfd, if (5 + length > tmp_space_size) { /* See alloca above for discussion of new size. */ - if (2 * tmp_space_size < 5 + length) - tmp_space_size = 5 + length; - else - tmp_space_size = 2 * tmp_space_size; - tmp_space = alloca (tmp_space_size); + if (2 * tmp_space_size < 5 + length) + tmp_space_size = 5 + length; + else + tmp_space_size = 2 * tmp_space_size; + tmp_space = xrealloc (tmp_space, tmp_space_size); } /* Reset to beginning of the (possibly new) buffer space. */ @@ -3563,7 +3590,9 @@ som_write_symbol_strings (bfd *abfd, /* Scribble out any partial block. */ amt = p - tmp_space; - if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt) + res = bfd_bwrite ((void *) &tmp_space[0], amt, abfd); + free (tmp_space); + if (res != amt) return FALSE; *string_sizep = strings_size; @@ -3627,7 +3656,7 @@ som_begin_writing (bfd *abfd) obj_som_file_hdr (abfd)->aux_header_size += len; current_offset += len; som_swap_string_auxhdr_out - (obj_som_version_hdr (abfd), &ext_string_auxhdr); + (obj_som_version_hdr (abfd), &ext_string_auxhdr); if (bfd_bwrite (&ext_string_auxhdr, len, abfd) != len) return FALSE; @@ -3653,7 +3682,7 @@ som_begin_writing (bfd *abfd) obj_som_file_hdr (abfd)->aux_header_size += len; current_offset += len; som_swap_string_auxhdr_out - (obj_som_copyright_hdr (abfd), &ext_string_auxhdr); + (obj_som_copyright_hdr (abfd), &ext_string_auxhdr); if (bfd_bwrite (&ext_string_auxhdr, len, abfd) != len) return FALSE; @@ -3940,7 +3969,7 @@ som_finish_writing (bfd *abfd) asection *section; unsigned long current_offset; unsigned int strings_size, total_reloc_size; - bfd_size_type amt; + size_t amt; struct som_external_header ext_header; /* We must set up the version identifier here as objcopy/strip copy @@ -3994,9 +4023,10 @@ som_finish_writing (bfd *abfd) current_offset += strings_size; /* Do prep work before handling fixups. */ - som_prep_for_fixups (abfd, - bfd_get_outsymbols (abfd), - bfd_get_symcount (abfd)); + if (!som_prep_for_fixups (abfd, + bfd_get_outsymbols (abfd), + bfd_get_symcount (abfd))) + return FALSE; /* At the end of the file is the fixup stream which starts on a word boundary. */ @@ -4043,7 +4073,7 @@ som_finish_writing (bfd *abfd) subsection != NULL; subsection = subsection->next) { - struct som_external_subspace_dictionary_record ext_subspace_dict; + struct som_external_subspace_dictionary_record ext_subspace_dict; /* Skip any section which does not correspond to a space or subspace. Or does not have SEC_ALLOC set (and therefore @@ -4074,8 +4104,8 @@ som_finish_writing (bfd *abfd) som_section_data (subsection)->subspace_dict->space_index = i; /* Dump the current subspace header. */ - som_swap_subspace_dictionary_record_out - (som_section_data (subsection)->subspace_dict, &ext_subspace_dict); + som_swap_subspace_dictionary_record_out + (som_section_data (subsection)->subspace_dict, &ext_subspace_dict); amt = sizeof (struct som_subspace_dictionary_record); if (bfd_bwrite (&ext_subspace_dict, amt, abfd) != amt) return FALSE; @@ -4100,7 +4130,7 @@ som_finish_writing (bfd *abfd) subsection != NULL; subsection = subsection->next) { - struct som_external_subspace_dictionary_record ext_subspace_dict; + struct som_external_subspace_dictionary_record ext_subspace_dict; /* Skip any section which does not correspond to a space or subspace, or which SEC_ALLOC set (and therefore handled @@ -4132,8 +4162,8 @@ som_finish_writing (bfd *abfd) som_section_data (subsection)->subspace_dict->space_index = i; /* Dump this subspace header. */ - som_swap_subspace_dictionary_record_out - (som_section_data (subsection)->subspace_dict, &ext_subspace_dict); + som_swap_subspace_dictionary_record_out + (som_section_data (subsection)->subspace_dict, &ext_subspace_dict); amt = sizeof (struct som_subspace_dictionary_record); if (bfd_bwrite (&ext_subspace_dict, amt, abfd) != amt) return FALSE; @@ -4162,7 +4192,7 @@ som_finish_writing (bfd *abfd) /* Dump its header. */ som_swap_space_dictionary_out (som_section_data (section)->space_dict, - &ext_space_dict); + &ext_space_dict); amt = sizeof (struct som_external_space_dictionary_record); if (bfd_bwrite (&ext_space_dict, amt, abfd) != amt) return FALSE; @@ -4181,7 +4211,7 @@ som_finish_writing (bfd *abfd) return FALSE; som_swap_compilation_unit_out - (obj_som_compilation_unit (abfd), &ext_comp_unit); + (obj_som_compilation_unit (abfd), &ext_comp_unit); amt = sizeof (struct som_external_compilation_unit); if (bfd_bwrite (&ext_comp_unit, amt, abfd) != amt) @@ -4441,13 +4471,19 @@ som_build_and_write_symbol_table (bfd *abfd) struct som_external_symbol_dictionary_record *som_symtab = NULL; unsigned int i; bfd_size_type symtab_size; + size_t amt; /* Compute total symbol table size and allocate a chunk of memory to hold the symbol table as we build it. */ - symtab_size = num_syms; - symtab_size *= sizeof (struct som_external_symbol_dictionary_record); - som_symtab = bfd_zmalloc (symtab_size); - if (som_symtab == NULL && symtab_size != 0) + if (_bfd_mul_overflow (num_syms, + sizeof (struct som_external_symbol_dictionary_record), + &amt)) + { + bfd_set_error (bfd_error_no_memory); + return FALSE; + } + som_symtab = bfd_zmalloc (amt); + if (som_symtab == NULL && num_syms != 0) goto error_return; /* Walk over each symbol. */ @@ -4460,33 +4496,35 @@ som_build_and_write_symbol_table (bfd *abfd) By the time we get here, the index has already been computed and stored into the name field in the BFD symbol. */ bfd_putb32 (som_symbol_data (bfd_syms[i])->stringtab_offset, - som_symtab[i].name); + som_symtab[i].name); /* Derive SOM information from the BFD symbol. */ som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info); /* Now use it. */ flags = (info.symbol_type << SOM_SYMBOL_TYPE_SH) - | (info.symbol_scope << SOM_SYMBOL_SCOPE_SH) - | (info.arg_reloc << SOM_SYMBOL_ARG_RELOC_SH) - | (3 << SOM_SYMBOL_XLEAST_SH) - | (info.secondary_def ? SOM_SYMBOL_SECONDARY_DEF : 0) - | (info.is_common ? SOM_SYMBOL_IS_COMMON : 0) - | (info.dup_common ? SOM_SYMBOL_DUP_COMMON : 0); + | (info.symbol_scope << SOM_SYMBOL_SCOPE_SH) + | (info.arg_reloc << SOM_SYMBOL_ARG_RELOC_SH) + | (3 << SOM_SYMBOL_XLEAST_SH) + | (info.secondary_def ? SOM_SYMBOL_SECONDARY_DEF : 0) + | (info.is_common ? SOM_SYMBOL_IS_COMMON : 0) + | (info.dup_common ? SOM_SYMBOL_DUP_COMMON : 0); bfd_putb32 (flags, som_symtab[i].flags); flags = (info.symbol_info << SOM_SYMBOL_SYMBOL_INFO_SH) - | (info.is_comdat ? SOM_SYMBOL_IS_COMDAT : 0); + | (info.is_comdat ? SOM_SYMBOL_IS_COMDAT : 0); bfd_putb32 (flags, som_symtab[i].info); bfd_putb32 (info.symbol_value | info.priv_level, - som_symtab[i].symbol_value); + som_symtab[i].symbol_value); } /* Everything is ready, seek to the right location and scribble out the symbol table. */ if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0) - return FALSE; + goto error_return; + symtab_size = num_syms; + symtab_size *= sizeof (struct som_external_symbol_dictionary_record); if (bfd_bwrite ((void *) som_symtab, symtab_size, abfd) != symtab_size) goto error_return; @@ -4540,15 +4578,11 @@ som_slurp_string_table (bfd *abfd) } /* Allocate and read in the string table. */ - amt = obj_som_stringtab_size (abfd); - stringtab = bfd_zmalloc (amt); - if (stringtab == NULL) - return FALSE; - if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) != 0) return FALSE; - - if (bfd_bread (stringtab, amt, abfd) != amt) + amt = obj_som_stringtab_size (abfd); + stringtab = (char *) _bfd_malloc_and_read (abfd, amt, amt); + if (stringtab == NULL) return FALSE; /* Save our results and return success. */ @@ -4588,7 +4622,7 @@ bfd_section_from_som_symbol && symbol_type != ST_MILLICODE)) { int idx = (bfd_getb32 (symbol->info) >> SOM_SYMBOL_SYMBOL_INFO_SH) - & SOM_SYMBOL_SYMBOL_INFO_MASK; + & SOM_SYMBOL_SYMBOL_INFO_MASK; for (section = abfd->sections; section != NULL; section = section->next) if (section->target_index == idx && som_is_subspace (section)) @@ -4617,12 +4651,12 @@ bfd_section_from_som_symbol static unsigned int som_slurp_symbol_table (bfd *abfd) { - int symbol_count = bfd_get_symcount (abfd); - int symsize = sizeof (struct som_external_symbol_dictionary_record); + unsigned int symbol_count = bfd_get_symcount (abfd); + size_t symsize = sizeof (struct som_external_symbol_dictionary_record); char *stringtab; struct som_external_symbol_dictionary_record *buf = NULL, *bufp, *endbufp; - som_symbol_type *sym, *symbase; - bfd_size_type amt; + som_symbol_type *sym, *symbase = NULL; + size_t amt; /* Return saved value if it exists. */ if (obj_som_symtab (abfd) != NULL) @@ -4637,21 +4671,26 @@ som_slurp_symbol_table (bfd *abfd) stringtab = obj_som_stringtab (abfd); - amt = symbol_count; - amt *= sizeof (som_symbol_type); - symbase = bfd_zmalloc (amt); - if (symbase == NULL) - goto error_return; - /* Read in the external SOM representation. */ - amt = symbol_count; - amt *= symsize; - buf = bfd_malloc (amt); - if (buf == NULL && amt != 0) - goto error_return; + if (_bfd_mul_overflow (symbol_count, symsize, &amt)) + { + bfd_set_error (bfd_error_file_too_big); + goto error_return; + } if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) != 0) goto error_return; - if (bfd_bread (buf, amt, abfd) != amt) + buf = (struct som_external_symbol_dictionary_record *) + _bfd_malloc_and_read (abfd, amt, amt); + if (buf == NULL) + goto error_return; + + if (_bfd_mul_overflow (symbol_count, sizeof (som_symbol_type), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + goto error_return; + } + symbase = bfd_zmalloc (amt); + if (symbase == NULL) goto error_return; /* Iterate over all the symbols and internalize them. */ @@ -4660,9 +4699,9 @@ som_slurp_symbol_table (bfd *abfd) { unsigned int flags = bfd_getb32 (bufp->flags); unsigned int symbol_type = - (flags >> SOM_SYMBOL_TYPE_SH) & SOM_SYMBOL_TYPE_MASK; + (flags >> SOM_SYMBOL_TYPE_SH) & SOM_SYMBOL_TYPE_MASK; unsigned int symbol_scope = - (flags >> SOM_SYMBOL_SCOPE_SH) & SOM_SYMBOL_SCOPE_MASK; + (flags >> SOM_SYMBOL_SCOPE_SH) & SOM_SYMBOL_SCOPE_MASK; /* I don't think we care about these. */ if (symbol_type == ST_SYM_EXT || symbol_type == ST_ARG_EXT) @@ -4690,7 +4729,7 @@ som_slurp_symbol_table (bfd *abfd) else som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN; som_symbol_data (sym)->tc_data.ap.hppa_arg_reloc = - (flags >> SOM_SYMBOL_ARG_RELOC_SH) & SOM_SYMBOL_ARG_RELOC_MASK; + (flags >> SOM_SYMBOL_ARG_RELOC_SH) & SOM_SYMBOL_ARG_RELOC_MASK; /* Some reasonable defaults. */ sym->symbol.the_bfd = abfd; @@ -4783,7 +4822,7 @@ som_slurp_symbol_table (bfd *abfd) /* We modify the symbol count to record the number of BFD symbols we created. */ - bfd_get_symcount (abfd) = sym - symbase; + abfd->symcount = sym - symbase; /* Save our results and return success. */ obj_som_symtab (abfd) = symbase; @@ -4793,6 +4832,8 @@ som_slurp_symbol_table (bfd *abfd) return (TRUE); error_return: + if (symbase != NULL) + free (symbase); if (buf != NULL) free (buf); return FALSE; @@ -4826,7 +4867,7 @@ som_canonicalize_symtab (bfd *abfd, asymbol **location) static asymbol * som_make_empty_symbol (bfd *abfd) { - bfd_size_type amt = sizeof (som_symbol_type); + size_t amt = sizeof (som_symbol_type); som_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt); if (new_symbol_type == NULL) @@ -5003,7 +5044,7 @@ som_set_reloc_info (unsigned char *fixup, push (v); } else - /* An operator. Pop two two values from the stack and + /* An operator. Pop two values from the stack and use them as operands to the given operation. Push the result of the operation back on the stack. */ switch (c) @@ -5240,7 +5281,7 @@ som_slurp_reloc_table (bfd *abfd, unsigned int fixup_stream_size; arelent *internal_relocs; unsigned int num_relocs; - bfd_size_type amt; + size_t amt; fixup_stream_size = som_section_data (section)->reloc_size; /* If there were no relocations, then there is nothing to do. */ @@ -5251,17 +5292,13 @@ som_slurp_reloc_table (bfd *abfd, parsed. We must do so now to know how many relocations exist. */ if (section->reloc_count == (unsigned) -1) { - amt = fixup_stream_size; - external_relocs = bfd_malloc (amt); - if (external_relocs == NULL) - return FALSE; /* Read in the external forms. */ - if (bfd_seek (abfd, - obj_som_reloc_filepos (abfd) + section->rel_filepos, - SEEK_SET) - != 0) + if (bfd_seek (abfd, obj_som_reloc_filepos (abfd) + section->rel_filepos, + SEEK_SET) != 0) return FALSE; - if (bfd_bread (external_relocs, amt, abfd) != amt) + amt = fixup_stream_size; + external_relocs = _bfd_malloc_and_read (abfd, amt, amt); + if (external_relocs == NULL) return FALSE; /* Let callers know how many relocations found. @@ -5284,9 +5321,12 @@ som_slurp_reloc_table (bfd *abfd, if (section->relocation != NULL) return TRUE; - amt = num_relocs; - amt *= sizeof (arelent); - internal_relocs = bfd_zalloc (abfd, (amt)); + if (_bfd_mul_overflow (num_relocs, sizeof (arelent), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } + internal_relocs = bfd_zalloc (abfd, amt); if (internal_relocs == NULL) return FALSE; @@ -5358,7 +5398,7 @@ som_new_section_hook (bfd *abfd, asection *newsect) { if (!newsect->used_by_bfd) { - bfd_size_type amt = sizeof (struct som_section_data_struct); + size_t amt = sizeof (struct som_section_data_struct); newsect->used_by_bfd = bfd_zalloc (abfd, amt); if (!newsect->used_by_bfd) @@ -5404,7 +5444,7 @@ som_bfd_copy_private_section_data (bfd *ibfd, bfd *obfd, asection *osection) { - bfd_size_type amt; + size_t amt; /* One day we may try to grok other private data. */ if (ibfd->xvec->flavour != bfd_target_som_flavour @@ -5482,7 +5522,7 @@ som_bfd_print_private_bfd_data (bfd *abfd, void *farg) fprintf (f, " length %#x\n", auxhdr->length); /* Note that, depending on the HP-UX version, the following fields can be - either ints, or longs. */ + either ints, or longs. */ fprintf (f, " text size %#lx\n", (long) exec_header->exec_tsize); fprintf (f, " text memory offset %#lx\n", (long) exec_header->exec_tmem); @@ -5512,7 +5552,7 @@ bfd_som_set_section_attributes (asection *section, /* Allocate memory to hold the magic information. */ if (som_section_data (section)->copy_data == NULL) { - bfd_size_type amt = sizeof (struct som_copyable_section_data_struct); + size_t amt = sizeof (struct som_copyable_section_data_struct); som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt); if (som_section_data (section)->copy_data == NULL) @@ -5542,7 +5582,7 @@ bfd_som_set_subsection_attributes (asection *section, /* Allocate memory to hold the magic information. */ if (som_section_data (section)->copy_data == NULL) { - bfd_size_type amt = sizeof (struct som_copyable_section_data_struct); + size_t amt = sizeof (struct som_copyable_section_data_struct); som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt); if (som_section_data (section)->copy_data == NULL) @@ -5576,7 +5616,7 @@ bfd_som_set_symbol_type (asymbol *symbol, unsigned int type) bfd_boolean bfd_som_attach_aux_hdr (bfd *abfd, int type, char *string) { - bfd_size_type amt; + size_t amt; if (type == VERSION_AUX_ID) { @@ -5597,7 +5637,7 @@ bfd_som_attach_aux_hdr (bfd *abfd, int type, char *string) } else if (type == COPYRIGHT_AUX_ID) { - int len = strlen (string); + size_t len = strlen (string); int pad = 0; if (len % 4) @@ -5732,9 +5772,9 @@ som_find_nearest_line (bfd *abfd, *discriminator_ptr = 0; if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, - & found, filename_ptr, - functionname_ptr, line_ptr, - & somdata (abfd).line_info)) + & found, filename_ptr, + functionname_ptr, line_ptr, + & somdata (abfd).line_info)) return FALSE; if (found) @@ -5775,7 +5815,7 @@ static int som_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED) { - (*_bfd_error_handler) (_("som_sizeof_headers unimplemented")); + _bfd_error_handler (_("som_sizeof_headers unimplemented")); abort (); return 0; } @@ -5867,24 +5907,25 @@ som_bfd_count_ar_symbols (bfd *abfd, { unsigned int i; unsigned char *hash_table; - bfd_size_type amt; + size_t amt; file_ptr lst_filepos; lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header); - amt = lst_header->hash_size * 4; - hash_table = bfd_malloc (amt); - if (hash_table == NULL && amt != 0) + /* Read in the hash table. The hash table is an array of 32-bit + file offsets which point to the hash chains. */ + if (_bfd_mul_overflow (lst_header->hash_size, 4, &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } + hash_table = _bfd_malloc_and_read (abfd, amt, amt); + if (hash_table == NULL && lst_header->hash_size != 0) goto error_return; /* Don't forget to initialize the counter! */ *count = 0; - /* Read in the hash table. The has table is an array of 32bit file offsets - which point to the hash chains. */ - if (bfd_bread ((void *) hash_table, amt, abfd) != amt) - goto error_return; - /* Walk each chain counting the number of symbols found on that particular chain. */ for (i = 0; i < lst_header->hash_size; i++) @@ -5910,10 +5951,19 @@ som_bfd_count_ar_symbols (bfd *abfd, /* Now iterate through the rest of the symbols on this chain. */ while (1) { - unsigned int next_entry = bfd_getb32 (ext_lst_symbol.next_entry); + unsigned int next_entry = bfd_getb32 (ext_lst_symbol.next_entry); + + if (next_entry == 0) + break; - if (next_entry == 0) - break; + /* Assume symbols on a chain are in increasing file offset + order. Otherwise we can loop here with fuzzed input. */ + if (next_entry < hash_val + sizeof (ext_lst_symbol)) + { + bfd_set_error (bfd_error_bad_value); + goto error_return; + } + hash_val = next_entry; /* Seek to the next symbol. */ if (bfd_seek (abfd, lst_filepos + next_entry, SEEK_SET) != 0) @@ -5949,19 +5999,21 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, carsym *set = syms[0]; unsigned char *hash_table; struct som_external_som_entry *som_dict = NULL; - bfd_size_type amt; + size_t amt; file_ptr lst_filepos; unsigned int string_loc; lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header); - amt = lst_header->hash_size * 4; - hash_table = bfd_malloc (amt); - if (hash_table == NULL && amt != 0) - goto error_return; /* Read in the hash table. The has table is an array of 32bit file offsets which point to the hash chains. */ - if (bfd_bread ((void *) hash_table, amt, abfd) != amt) + if (_bfd_mul_overflow (lst_header->hash_size, 4, &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } + hash_table = _bfd_malloc_and_read (abfd, amt, amt); + if (hash_table == NULL && lst_header->hash_size != 0) goto error_return; /* Seek to and read in the SOM dictionary. We will need this to fill @@ -5969,12 +6021,15 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) != 0) goto error_return; - amt = lst_header->module_count * sizeof (struct som_external_som_entry); - som_dict = bfd_malloc (amt); - if (som_dict == NULL && amt != 0) - goto error_return; - - if (bfd_bread ((void *) som_dict, amt, abfd) != amt) + if (_bfd_mul_overflow (lst_header->module_count, + sizeof (struct som_external_som_entry), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + goto error_return; + } + som_dict = (struct som_external_som_entry *) + _bfd_malloc_and_read (abfd, amt, amt); + if (som_dict == NULL && lst_header->module_count != 0) goto error_return; string_loc = lst_header->string_loc; @@ -5984,8 +6039,10 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, { struct som_external_lst_symbol_record lst_symbol; unsigned int hash_val; - unsigned int len; + size_t len; unsigned char ext_len[4]; + char *name; + unsigned int ndx; /* An empty chain has zero as it's file offset. */ hash_val = bfd_getb32 (hash_table + 4 * i); @@ -6008,7 +6065,7 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, index can point *anywhere* in the archive to save space, so just using the string table would not be safe. */ if (bfd_seek (abfd, (lst_filepos + string_loc - + bfd_getb32 (lst_symbol.name) - 4), SEEK_SET) != 0) + + bfd_getb32 (lst_symbol.name) - 4), SEEK_SET) != 0) goto error_return; if (bfd_bread (&ext_len, (bfd_size_type) 4, abfd) != 4) @@ -6016,19 +6073,27 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, len = bfd_getb32 (ext_len); /* Allocate space for the name and null terminate it too. */ - set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1); - if (!set->name) - goto error_return; - if (bfd_bread (set->name, (bfd_size_type) len, abfd) != len) + if (len == (size_t) -1) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } + name = (char *) _bfd_alloc_and_read (abfd, len + 1, len); + if (!name) goto error_return; - - set->name[len] = 0; + name[len] = 0; + set->name = name; /* Fill in the file offset. Note that the "location" field points to the SOM itself, not the ar_hdr in front of it. */ - set->file_offset = - bfd_getb32 (som_dict[bfd_getb32 (lst_symbol.som_index)].location) - - sizeof (struct ar_hdr); + ndx = bfd_getb32 (lst_symbol.som_index); + if (ndx >= lst_header->module_count) + { + bfd_set_error (bfd_error_bad_value); + goto error_return; + } + set->file_offset + = bfd_getb32 (som_dict[ndx].location) - sizeof (struct ar_hdr); /* Go to the next symbol. */ set++; @@ -6036,10 +6101,10 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, /* Iterate through the rest of the chain. */ while (1) { - unsigned int next_entry = bfd_getb32 (lst_symbol.next_entry); + unsigned int next_entry = bfd_getb32 (lst_symbol.next_entry); - if (next_entry == 0) - break; + if (next_entry == 0) + break; /* Seek to the next symbol and read it in. */ if (bfd_seek (abfd, lst_filepos + next_entry, SEEK_SET) != 0) @@ -6051,27 +6116,35 @@ som_bfd_fill_in_ar_symbols (bfd *abfd, /* Seek to the name length & string and read them in. */ if (bfd_seek (abfd, lst_filepos + string_loc - + bfd_getb32 (lst_symbol.name) - 4, SEEK_SET) != 0) + + bfd_getb32 (lst_symbol.name) - 4, SEEK_SET) != 0) goto error_return; if (bfd_bread (&ext_len, (bfd_size_type) 4, abfd) != 4) goto error_return; - len = bfd_getb32 (ext_len); + len = bfd_getb32 (ext_len); /* Allocate space for the name and null terminate it too. */ - set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1); - if (!set->name) - goto error_return; - - if (bfd_bread (set->name, (bfd_size_type) len, abfd) != len) + if (len == (size_t) -1) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } + name = (char *) _bfd_alloc_and_read (abfd, len + 1, len); + if (!name) goto error_return; - set->name[len] = 0; + name[len] = 0; + set->name = name; /* Fill in the file offset. Note that the "location" field points to the SOM itself, not the ar_hdr in front of it. */ - set->file_offset = - bfd_getb32 (som_dict[bfd_getb32 (lst_symbol.som_index)].location) - - sizeof (struct ar_hdr); + ndx = bfd_getb32 (lst_symbol.som_index); + if (ndx >= lst_header->module_count) + { + bfd_set_error (bfd_error_bad_value); + goto error_return; + } + set->file_offset + = bfd_getb32 (som_dict[ndx].location) - sizeof (struct ar_hdr); /* Go on to the next symbol. */ set++; @@ -6104,7 +6177,7 @@ som_slurp_armap (bfd *abfd) unsigned int parsed_size; struct artdata *ardata = bfd_ardata (abfd); char nextname[17]; - bfd_size_type amt = 16; + size_t amt = 16; int i = bfd_bread ((void *) nextname, amt, abfd); /* Special cases. */ @@ -6119,7 +6192,7 @@ som_slurp_armap (bfd *abfd) /* For archives without .o files there is no symbol table. */ if (! CONST_STRNEQ (nextname, "/ ")) { - bfd_has_map (abfd) = FALSE; + abfd->has_armap = FALSE; return TRUE; } @@ -6168,13 +6241,16 @@ som_slurp_armap (bfd *abfd) /* Get back to the start of the library symbol table. */ if (bfd_seek (abfd, (ardata->first_file_filepos - parsed_size + sizeof (struct som_external_lst_header)), - SEEK_SET) != 0) + SEEK_SET) != 0) return FALSE; /* Initialize the cache and allocate space for the library symbols. */ ardata->cache = 0; - amt = ardata->symdef_count; - amt *= sizeof (carsym); + if (_bfd_mul_overflow (ardata->symdef_count, sizeof (carsym), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } ardata->symdefs = bfd_alloc (abfd, amt); if (!ardata->symdefs) return FALSE; @@ -6189,7 +6265,7 @@ som_slurp_armap (bfd *abfd) return FALSE; /* Notify the generic archive code that we have a symbol map. */ - bfd_has_map (abfd) = TRUE; + abfd->has_armap = TRUE; return TRUE; } @@ -6302,23 +6378,38 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd, struct som_external_som_entry *som_dict = NULL; struct som_external_lst_symbol_record **last_hash_entry = NULL; unsigned int curr_som_offset, som_index = 0; - bfd_size_type amt; + size_t amt; unsigned int module_count; unsigned int hash_size; hash_size = bfd_getb32 (lst.hash_size); - amt = hash_size * 4; + if (_bfd_mul_overflow (hash_size, 4, &amt)) + { + bfd_set_error (bfd_error_no_memory); + return FALSE; + } hash_table = bfd_zmalloc (amt); if (hash_table == NULL && hash_size != 0) goto error_return; module_count = bfd_getb32 (lst.module_count); - amt = module_count * sizeof (struct som_external_som_entry); + if (_bfd_mul_overflow (module_count, + sizeof (struct som_external_som_entry), &amt)) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } som_dict = bfd_zmalloc (amt); if (som_dict == NULL && module_count != 0) goto error_return; - amt = hash_size * sizeof (struct som_external_lst_symbol_record *); + if (_bfd_mul_overflow (hash_size, + sizeof (struct som_external_lst_symbol_record *), + &amt)) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } last_hash_entry = bfd_zmalloc (amt); if (last_hash_entry == NULL && hash_size != 0) goto error_return; @@ -6347,12 +6438,16 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd, curr_som_offset = (curr_som_offset + 0x1) & ~0x1; /* FIXME should be done with buffers just like everything else... */ - amt = nsyms; - amt *= sizeof (struct som_external_lst_symbol_record); + if (_bfd_mul_overflow (nsyms, + sizeof (struct som_external_lst_symbol_record), &amt)) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } lst_syms = bfd_malloc (amt); if (lst_syms == NULL && nsyms != 0) goto error_return; - strings = bfd_malloc ((bfd_size_type) string_size); + strings = bfd_malloc (string_size); if (strings == NULL && string_size != 0) goto error_return; @@ -6385,11 +6480,11 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd, for (i = 0; i < curr_count; i++, sym++) { struct som_misc_symbol_info info; - struct som_external_lst_symbol_record *last; - unsigned int symbol_pos; - unsigned int slen; - unsigned int symbol_key; - unsigned int flags; + struct som_external_lst_symbol_record *last; + unsigned int symbol_pos; + unsigned int slen; + unsigned int symbol_key; + unsigned int flags; /* Derive SOM information from the BFD symbol. */ som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info); @@ -6417,40 +6512,40 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd, bfd_putb32 (arelt_size (curr_bfd), som_dict[som_index].length); } - symbol_key = som_bfd_ar_symbol_hash (&sym->symbol); + symbol_key = som_bfd_ar_symbol_hash (&sym->symbol); /* Fill in the lst symbol record. */ - flags = 0; - if (info.secondary_def) - flags |= LST_SYMBOL_SECONDARY_DEF; - flags |= info.symbol_type << LST_SYMBOL_SYMBOL_TYPE_SH; - flags |= info.symbol_scope << LST_SYMBOL_SYMBOL_SCOPE_SH; - if (bfd_is_com_section (sym->symbol.section)) - flags |= LST_SYMBOL_IS_COMMON; - if (info.dup_common) - flags |= LST_SYMBOL_DUP_COMMON; - flags |= 3 << LST_SYMBOL_XLEAST_SH; - flags |= info.arg_reloc << LST_SYMBOL_ARG_RELOC_SH; - bfd_putb32 (flags, curr_lst_sym->flags); - bfd_putb32 (p - strings + 4, curr_lst_sym->name); - bfd_putb32 (0, curr_lst_sym->qualifier_name); - bfd_putb32 (info.symbol_info, curr_lst_sym->symbol_info); - bfd_putb32 (info.symbol_value | info.priv_level, - curr_lst_sym->symbol_value); - bfd_putb32 (0, curr_lst_sym->symbol_descriptor); - curr_lst_sym->reserved = 0; - bfd_putb32 (som_index, curr_lst_sym->som_index); - bfd_putb32 (symbol_key, curr_lst_sym->symbol_key); - bfd_putb32 (0, curr_lst_sym->next_entry); + flags = 0; + if (info.secondary_def) + flags |= LST_SYMBOL_SECONDARY_DEF; + flags |= info.symbol_type << LST_SYMBOL_SYMBOL_TYPE_SH; + flags |= info.symbol_scope << LST_SYMBOL_SYMBOL_SCOPE_SH; + if (bfd_is_com_section (sym->symbol.section)) + flags |= LST_SYMBOL_IS_COMMON; + if (info.dup_common) + flags |= LST_SYMBOL_DUP_COMMON; + flags |= 3 << LST_SYMBOL_XLEAST_SH; + flags |= info.arg_reloc << LST_SYMBOL_ARG_RELOC_SH; + bfd_putb32 (flags, curr_lst_sym->flags); + bfd_putb32 (p - strings + 4, curr_lst_sym->name); + bfd_putb32 (0, curr_lst_sym->qualifier_name); + bfd_putb32 (info.symbol_info, curr_lst_sym->symbol_info); + bfd_putb32 (info.symbol_value | info.priv_level, + curr_lst_sym->symbol_value); + bfd_putb32 (0, curr_lst_sym->symbol_descriptor); + curr_lst_sym->reserved = 0; + bfd_putb32 (som_index, curr_lst_sym->som_index); + bfd_putb32 (symbol_key, curr_lst_sym->symbol_key); + bfd_putb32 (0, curr_lst_sym->next_entry); /* Insert into the hash table. */ - symbol_pos = - (curr_lst_sym - lst_syms) - * sizeof (struct som_external_lst_symbol_record) - + hash_size * 4 - + module_count * sizeof (struct som_external_som_entry) - + sizeof (struct som_external_lst_header); - last = last_hash_entry[symbol_key % hash_size]; + symbol_pos = + (curr_lst_sym - lst_syms) + * sizeof (struct som_external_lst_symbol_record) + + hash_size * 4 + + module_count * sizeof (struct som_external_som_entry) + + sizeof (struct som_external_lst_header); + last = last_hash_entry[symbol_key % hash_size]; if (last != NULL) { /* There is already something at the head of this hash chain, @@ -6459,26 +6554,26 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd, } else /* First entry in this hash chain. */ - bfd_putb32 (symbol_pos, hash_table + 4 * (symbol_key % hash_size)); + bfd_putb32 (symbol_pos, hash_table + 4 * (symbol_key % hash_size)); /* Keep track of the last symbol we added to this chain so we can easily update its next_entry pointer. */ - last_hash_entry[symbol_key % hash_size] = curr_lst_sym; + last_hash_entry[symbol_key % hash_size] = curr_lst_sym; /* Update the string table. */ - slen = strlen (sym->symbol.name); + slen = strlen (sym->symbol.name); bfd_put_32 (abfd, slen, p); p += 4; - slen++; /* Nul terminator. */ + slen++; /* Nul terminator. */ memcpy (p, sym->symbol.name, slen); p += slen; while (slen % 4) { bfd_put_8 (abfd, 0, p); p++; - slen++; + slen++; } - BFD_ASSERT (p <= strings + string_size); + BFD_ASSERT (p <= strings + string_size); /* Head to the next symbol. */ curr_lst_sym++; @@ -6497,17 +6592,17 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd, } /* Now scribble out the hash table. */ - amt = hash_size * 4; + amt = (size_t) hash_size * 4; if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt) goto error_return; /* Then the SOM dictionary. */ - amt = module_count * sizeof (struct som_external_som_entry); + amt = (size_t) module_count * sizeof (struct som_external_som_entry); if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt) goto error_return; /* The library symbols. */ - amt = nsyms * sizeof (struct som_external_lst_symbol_record); + amt = (size_t) nsyms * sizeof (struct som_external_lst_symbol_record); if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt) goto error_return; @@ -6560,12 +6655,12 @@ som_write_armap (bfd *abfd, struct ar_hdr hdr; struct som_external_lst_header lst; unsigned char *p; - bfd_size_type amt; + size_t amt; unsigned int csum; unsigned int module_count; /* We'll use this for the archive's date and mode later. */ - if (stat (abfd->filename, &statbuf) != 0) + if (stat (bfd_get_filename (abfd), &statbuf) != 0) { bfd_set_error (bfd_error_system_call); return FALSE; @@ -6645,15 +6740,15 @@ som_write_armap (bfd *abfd, sprintf (hdr.ar_name, "/ "); _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%-12ld", - bfd_ardata (abfd)->armap_timestamp); + bfd_ardata (abfd)->armap_timestamp); _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", - statbuf.st_uid); + statbuf.st_uid); _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", - statbuf.st_gid); + statbuf.st_gid); _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-8o", - (unsigned int)statbuf.st_mode); + (unsigned int)statbuf.st_mode); _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10d", - (int) lst_size); + (int) lst_size); hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\012'; @@ -6686,25 +6781,25 @@ som_write_armap (bfd *abfd, static bfd_boolean som_bfd_free_cached_info (bfd *abfd) { - asection *o; - - if (bfd_get_format (abfd) != bfd_object) - return TRUE; + if (bfd_get_format (abfd) == bfd_object) + { + asection *o; #define FREE(x) if (x != NULL) { free (x); x = NULL; } - /* Free the native string and symbol tables. */ - FREE (obj_som_symtab (abfd)); - FREE (obj_som_stringtab (abfd)); - for (o = abfd->sections; o != NULL; o = o->next) - { - /* Free the native relocations. */ - o->reloc_count = (unsigned) -1; - FREE (som_section_data (o)->reloc_stream); - /* Do not free the generic relocations as they are objalloc'ed. */ - } + /* Free the native string and symbol tables. */ + FREE (obj_som_symtab (abfd)); + FREE (obj_som_stringtab (abfd)); + for (o = abfd->sections; o != NULL; o = o->next) + { + /* Free the native relocations. */ + o->reloc_count = (unsigned) -1; + FREE (som_section_data (o)->reloc_stream); + /* Do not free the generic relocations as they are objalloc'ed. */ + } #undef FREE + } - return TRUE; + return _bfd_generic_close_and_cleanup (abfd); } /* End of miscellaneous support functions. */ @@ -6717,42 +6812,48 @@ som_bfd_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) return som_is_subspace (sec) && sec->size > 240000; } -#define som_find_line _bfd_nosymbols_find_line -#define som_close_and_cleanup som_bfd_free_cached_info -#define som_read_ar_hdr _bfd_generic_read_ar_hdr -#define som_write_ar_hdr _bfd_generic_write_ar_hdr -#define som_openr_next_archived_file bfd_generic_openr_next_archived_file -#define som_get_elt_at_index _bfd_generic_get_elt_at_index -#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define som_truncate_arname bfd_bsd_truncate_arname -#define som_slurp_extended_name_table _bfd_slurp_extended_name_table -#define som_construct_extended_name_table _bfd_archive_coff_construct_extended_name_table -#define som_update_armap_timestamp bfd_true -#define som_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#define som_get_lineno _bfd_nosymbols_get_lineno -#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define som_read_minisymbols _bfd_generic_read_minisymbols -#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define som_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define som_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define som_bfd_relax_section bfd_generic_relax_section -#define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define som_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define som_bfd_link_just_syms _bfd_generic_link_just_syms +#define som_find_line _bfd_nosymbols_find_line +#define som_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string +#define som_close_and_cleanup som_bfd_free_cached_info +#define som_read_ar_hdr _bfd_generic_read_ar_hdr +#define som_write_ar_hdr _bfd_generic_write_ar_hdr +#define som_openr_next_archived_file bfd_generic_openr_next_archived_file +#define som_get_elt_at_index _bfd_generic_get_elt_at_index +#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt +#define som_truncate_arname bfd_bsd_truncate_arname +#define som_slurp_extended_name_table _bfd_slurp_extended_name_table +#define som_construct_extended_name_table _bfd_archive_coff_construct_extended_name_table +#define som_update_armap_timestamp _bfd_bool_bfd_true +#define som_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false +#define som_get_lineno _bfd_nosymbols_get_lineno +#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define som_read_minisymbols _bfd_generic_read_minisymbols +#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol +#define som_get_section_contents_in_window _bfd_generic_get_section_contents_in_window +#define som_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents +#define som_bfd_relax_section bfd_generic_relax_section +#define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create +#define som_bfd_link_add_symbols _bfd_generic_link_add_symbols +#define som_bfd_link_just_syms _bfd_generic_link_just_syms #define som_bfd_copy_link_hash_symbol_type \ _bfd_generic_copy_link_hash_symbol_type -#define som_bfd_final_link _bfd_generic_final_link -#define som_bfd_gc_sections bfd_generic_gc_sections -#define som_bfd_lookup_section_flags bfd_generic_lookup_section_flags -#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_section_already_linked _bfd_generic_section_already_linked -#define som_bfd_define_common_symbol bfd_generic_define_common_symbol +#define som_bfd_final_link _bfd_generic_final_link +#define som_bfd_gc_sections bfd_generic_gc_sections +#define som_bfd_lookup_section_flags bfd_generic_lookup_section_flags +#define som_bfd_merge_sections bfd_generic_merge_sections +#define som_bfd_is_group_section bfd_generic_is_group_section +#define som_bfd_group_name bfd_generic_group_name +#define som_bfd_discard_group bfd_generic_discard_group +#define som_section_already_linked _bfd_generic_section_already_linked +#define som_bfd_define_common_symbol bfd_generic_define_common_symbol +#define som_bfd_link_hide_symbol _bfd_generic_link_hide_symbol +#define som_bfd_define_start_stop bfd_generic_define_start_stop #define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data #define som_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data #define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags #define som_find_inliner_info _bfd_nosymbols_find_inliner_info +#define som_bfd_link_check_relocs _bfd_generic_link_check_relocs +#define som_set_reloc _bfd_generic_set_reloc const bfd_target hppa_som_vec = { @@ -6784,16 +6885,16 @@ const bfd_target hppa_som_vec = _bfd_dummy_target }, { - bfd_false, + _bfd_bool_bfd_false_error, som_mkobject, _bfd_generic_mkarchive, - bfd_false + _bfd_bool_bfd_false_error }, { - bfd_false, + _bfd_bool_bfd_false_error, som_write_object_contents, _bfd_write_archive_contents, - bfd_false, + _bfd_bool_bfd_false_error, }, #undef som