gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / som.c
index ce69eac563e8e027ba929f4ecdec3e65ad3bb587..887d9b187ef88b2b9d255f4243d3bf1cb4995325 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -1,5 +1,5 @@
 /* bfd back-end for HP PA-RISC SOM objects.
-   Copyright (C) 1990-2019 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
    University of Utah.
@@ -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])
@@ -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,
@@ -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
@@ -2079,23 +2079,20 @@ setup_sections (bfd *abfd,
   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;
-  if (amt == (bfd_size_type) -1)
+  if (amt == (size_t) -1)
     {
       bfd_set_error (bfd_error_no_memory);
       goto error_return;
     }
-  space_strings = bfd_malloc (amt + 1);
-  if (space_strings == NULL && amt != 0)
-    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;
@@ -2200,6 +2197,9 @@ setup_sections (bfd *abfd,
          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;
@@ -2344,7 +2344,12 @@ setup_sections (bfd *abfd,
     }
   /* Now that we've read in all the subspace records, we need to assign
      a target index to each subspace.  */
-  subspace_sections = bfd_malloc2 (total_subspaces, 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;
 
@@ -2364,27 +2369,20 @@ setup_sections (bfd *abfd,
   for (i = 0; i < total_subspaces; i++)
     subspace_sections[i]->target_index = i;
 
-  if (space_strings != NULL)
-    free (space_strings);
-
-  if (subspace_sections != NULL)
-    free (subspace_sections);
-
+  free (space_strings);
+  free (subspace_sections);
   return TRUE;
 
  error_return:
-  if (space_strings != NULL)
-    free (space_strings);
-
-  if (subspace_sections != NULL)
-    free (subspace_sections);
+  free (space_strings);
+  free (subspace_sections);
   return FALSE;
 }
 
 
 /* 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;
@@ -2393,7 +2391,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)
 
@@ -2548,7 +2546,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);
@@ -2798,12 +2796,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;
+  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
@@ -2875,7 +2874,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.  */
-  sorted_syms = bfd_zalloc2 (abfd, num_syms, 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;
@@ -2891,6 +2897,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
@@ -2907,7 +2914,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;
@@ -3313,7 +3320,7 @@ som_write_space_strings (bfd *abfd,
   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)
@@ -3425,7 +3432,7 @@ som_write_symbol_strings (bfd *abfd,
   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)
@@ -3955,7 +3962,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
@@ -4009,9 +4016,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.  */
@@ -4456,12 +4464,18 @@ 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.  */
-  som_symtab
-    = bfd_zmalloc2 (num_syms,
-                   sizeof (struct som_external_symbol_dictionary_record));
+  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;
 
@@ -4500,19 +4514,18 @@ som_build_and_write_symbol_table (bfd *abfd)
   /* 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;
 
-  if (som_symtab != NULL)
-    free (som_symtab);
+  free (som_symtab);
   return TRUE;
+
  error_return:
-  if (som_symtab != NULL)
-    free (som_symtab);
+  free (som_symtab);
   return FALSE;
 }
 
@@ -4557,15 +4570,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.  */
@@ -4634,12 +4643,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)
@@ -4654,19 +4663,26 @@ som_slurp_symbol_table (bfd *abfd)
 
   stringtab = obj_som_stringtab (abfd);
 
-  symbase = bfd_zmalloc2 (symbol_count, sizeof (som_symbol_type));
-  if (symbase == NULL)
-    goto error_return;
-
   /* Read in the external SOM representation.  */
-  buf = bfd_malloc2 (symbol_count, symsize);
-  if (buf == NULL)
-    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;
-  amt = symbol_count;
-  amt *= symsize;
-  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.  */
@@ -4803,13 +4819,12 @@ som_slurp_symbol_table (bfd *abfd)
   /* Save our results and return success.  */
   obj_som_symtab (abfd) = symbase;
  successful_return:
-  if (buf != NULL)
-    free (buf);
+  free (buf);
   return (TRUE);
 
  error_return:
-  if (buf != NULL)
-    free (buf);
+  free (symbase);
+  free (buf);
   return FALSE;
 }
 
@@ -4841,7 +4856,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)
@@ -5204,8 +5219,7 @@ som_set_reloc_info (unsigned char *fixup,
                      if (!bfd_malloc_and_get_section (section->owner, section,
                                                       &contents))
                        {
-                         if (contents != NULL)
-                           free (contents);
+                         free (contents);
                          return (unsigned) -1;
                        }
                      section->contents = contents;
@@ -5255,7 +5269,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.  */
@@ -5266,17 +5280,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.
@@ -5299,7 +5309,12 @@ som_slurp_reloc_table (bfd *abfd,
   if (section->relocation != NULL)
     return TRUE;
 
-  internal_relocs = bfd_zalloc2 (abfd, num_relocs, sizeof (arelent));
+  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;
 
@@ -5371,7 +5386,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)
@@ -5417,7 +5432,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
@@ -5525,7 +5540,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)
@@ -5555,7 +5570,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)
@@ -5589,7 +5604,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)
     {
@@ -5880,24 +5895,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);
 
-  hash_table = bfd_malloc2 (lst_header->hash_size, 4);
+  /* 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.  */
-  amt = (bfd_size_type) lst_header->hash_size * 4;
-  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++)
@@ -5928,6 +5944,15 @@ som_bfd_count_ar_symbols (bfd *abfd,
          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)
            goto error_return;
@@ -5940,13 +5965,11 @@ som_bfd_count_ar_symbols (bfd *abfd,
          (*count)++;
        }
     }
-  if (hash_table != NULL)
-    free (hash_table);
+  free (hash_table);
   return TRUE;
 
  error_return:
-  if (hash_table != NULL)
-    free (hash_table);
+  free (hash_table);
   return FALSE;
 }
 
@@ -5962,19 +5985,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);
-  hash_table = bfd_malloc2 (lst_header->hash_size, 4);
-  if (hash_table == NULL && lst_header->hash_size != 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.  */
-  amt = (bfd_size_type) lst_header->hash_size * 4;
-  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
@@ -5982,16 +6007,17 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
   if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) != 0)
     goto error_return;
 
-  som_dict = bfd_malloc2 (lst_header->module_count,
-                         sizeof (struct som_external_som_entry));
+  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;
 
-  amt = lst_header->module_count;
-  amt *= sizeof (struct som_external_som_entry);
-  if (bfd_bread ((void *) som_dict, amt, abfd) != amt)
-    goto error_return;
-
   string_loc = lst_header->string_loc;
 
   /* Walk each chain filling in the carsyms as we go along.  */
@@ -6002,6 +6028,7 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
       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);
@@ -6037,20 +6064,22 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
          bfd_set_error (bfd_error_no_memory);
          goto error_return;
        }
-      name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
+      name = (char *) _bfd_alloc_and_read (abfd, len + 1, len);
       if (!name)
        goto error_return;
-      if (bfd_bread (name, (bfd_size_type) len, abfd) != len)
-       goto error_return;
-
       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++;
@@ -6086,20 +6115,22 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
              bfd_set_error (bfd_error_no_memory);
              goto error_return;
            }
-         name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
+         name = (char *) _bfd_alloc_and_read (abfd, len + 1, len);
          if (!name)
            goto error_return;
-
-         if (bfd_bread (name, (bfd_size_type) len, abfd) != len)
-           goto error_return;
          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++;
@@ -6107,17 +6138,13 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
     }
   /* If we haven't died by now, then we successfully read the entire
      archive symbol table.  */
-  if (hash_table != NULL)
-    free (hash_table);
-  if (som_dict != NULL)
-    free (som_dict);
+  free (hash_table);
+  free (som_dict);
   return TRUE;
 
  error_return:
-  if (hash_table != NULL)
-    free (hash_table);
-  if (som_dict != NULL)
-    free (som_dict);
+  free (hash_table);
+  free (som_dict);
   return FALSE;
 }
 
@@ -6132,7 +6159,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.  */
@@ -6201,7 +6228,12 @@ som_slurp_armap (bfd *abfd)
 
   /* Initialize the cache and allocate space for the library symbols.  */
   ardata->cache = 0;
-  ardata->symdefs = bfd_alloc2 (abfd, ardata->symdef_count, 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;
 
@@ -6328,22 +6360,39 @@ 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);
-  hash_table = bfd_zmalloc2 (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);
-  som_dict = bfd_zmalloc2 (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;
 
-  last_hash_entry
-    = bfd_zmalloc2 (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;
 
@@ -6371,10 +6420,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...  */
-  lst_syms = bfd_malloc2 (nsyms, 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;
 
@@ -6519,17 +6574,17 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd,
     }
 
   /* Now scribble out the hash table.  */
-  amt = (bfd_size_type) 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 = (bfd_size_type) 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 = (bfd_size_type) 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;
 
@@ -6538,29 +6593,19 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd,
   if (bfd_bwrite ((void *) strings, amt, abfd) != amt)
     goto error_return;
 
-  if (hash_table != NULL)
-    free (hash_table);
-  if (som_dict != NULL)
-    free (som_dict);
-  if (last_hash_entry != NULL)
-    free (last_hash_entry);
-  if (lst_syms != NULL)
-    free (lst_syms);
-  if (strings != NULL)
-    free (strings);
+  free (hash_table);
+  free (som_dict);
+  free (last_hash_entry);
+  free (lst_syms);
+  free (strings);
   return TRUE;
 
  error_return:
-  if (hash_table != NULL)
-    free (hash_table);
-  if (som_dict != NULL)
-    free (som_dict);
-  if (last_hash_entry != NULL)
-    free (last_hash_entry);
-  if (lst_syms != NULL)
-    free (lst_syms);
-  if (strings != NULL)
-    free (strings);
+  free (hash_table);
+  free (som_dict);
+  free (last_hash_entry);
+  free (lst_syms);
+  free (strings);
 
   return FALSE;
 }
@@ -6582,12 +6627,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;
@@ -6712,7 +6757,7 @@ som_bfd_free_cached_info (bfd *abfd)
     {
       asection *o;
 
-#define FREE(x) if (x != NULL) { free (x); x = NULL; }
+#define FREE(x) do { free (x); x = NULL; } while (0)
       /* Free the native string and symbol tables.  */
       FREE (obj_som_symtab (abfd));
       FREE (obj_som_stringtab (abfd));
This page took 0.033449 seconds and 4 git commands to generate.