switch inferior/thread before calling target methods
[deliverable/binutils-gdb.git] / bfd / archive64.c
index 6b87ec520283b831175c19602f3c305dbdc1b3dc..59e42c699e78774bc11c5dc976448f8469027b01 100644 (file)
@@ -1,5 +1,5 @@
-/* Support for 64-bit ELF archives.
-   Copyright (C) 1996-2014 Free Software Foundation, Inc.
+/* Support for 64-bit archives.
+   Copyright (C) 1996-2020 Free Software Foundation, Inc.
    Ian Lance Taylor, Cygnus Support
    Linker support added by Mark Mitchell, CodeSourcery, LLC.
    <mark@codesourcery.com>
@@ -21,7 +21,8 @@
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-/* This file supports the 64-bit (MIPS) ELF archives.  */
+/* This file supports the 64-bit archives.  We use the same format as
+   the 64-bit (MIPS) ELF archives.  */
 
 #include "sysdep.h"
 #include "bfd.h"
 /* Irix 6 defines a 64bit archive map format, so that they can
    have archives more than 4 GB in size.  */
 
-bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
-bfd_boolean bfd_elf64_archive_write_armap
-  (bfd *, unsigned int, struct orl *, unsigned int, int);
-
 /* Read an Irix 6 armap.  */
 
 bfd_boolean
-bfd_elf64_archive_slurp_armap (bfd *abfd)
+_bfd_archive_64_bit_slurp_armap (bfd *abfd)
 {
   struct artdata *ardata = bfd_ardata (abfd);
   char nextname[17];
@@ -46,6 +43,7 @@ bfd_elf64_archive_slurp_armap (bfd *abfd)
   struct areltdata *mapdata;
   bfd_byte int_buf[8];
   char *stringbase;
+  char *stringend;
   bfd_byte *raw_armap = NULL;
   carsym *carsyms;
   bfd_size_type amt;
@@ -68,7 +66,7 @@ bfd_elf64_archive_slurp_armap (bfd *abfd)
 
   if (! CONST_STRNEQ (nextname, "/SYM64/         "))
     {
-      bfd_has_map (abfd) = FALSE;
+      abfd->has_armap = FALSE;
       return TRUE;
     }
 
@@ -92,6 +90,18 @@ bfd_elf64_archive_slurp_armap (bfd *abfd)
   ptrsize = 8 * nsymz;
 
   amt = carsym_size + stringsize + 1;
+  if (/* Catch overflow in stringsize (and ptrsize) expression.  */
+      nsymz >= (bfd_size_type) -1 / 8
+      || stringsize > parsed_size
+      /* Catch overflow in carsym_size expression.  */
+      || nsymz > (bfd_size_type) -1 / sizeof (carsym)
+      /* Catch overflow in amt expression.  */
+      || amt <= carsym_size
+      || amt <= stringsize)
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return FALSE;
+    }
   ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt);
   if (ardata->symdefs == NULL)
     return FALSE;
@@ -110,21 +120,24 @@ bfd_elf64_archive_slurp_armap (bfd *abfd)
       goto release_raw_armap;
     }
 
+  stringend = stringbase + stringsize;
+  *stringend = 0;
   for (i = 0; i < nsymz; i++)
     {
       carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
       carsyms->name = stringbase;
-      stringbase += strlen (stringbase) + 1;
+      stringbase += strlen (stringbase);
+      if (stringbase != stringend)
+       ++stringbase;
       ++carsyms;
     }
-  *stringbase = '\0';
 
   ardata->symdef_count = nsymz;
   ardata->first_file_filepos = bfd_tell (abfd);
   /* Pad to an even boundary if you have to.  */
   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
 
-  bfd_has_map (abfd) = TRUE;
+  abfd->has_armap = TRUE;
   bfd_release (abfd, raw_armap);
 
   return TRUE;
@@ -141,11 +154,11 @@ release_symdefs:
    linker crashes.  */
 
 bfd_boolean
-bfd_elf64_archive_write_armap (bfd *arch,
-                              unsigned int elength,
-                              struct orl *map,
-                              unsigned int symbol_count,
-                              int stridx)
+_bfd_archive_64_bit_write_armap (bfd *arch,
+                                unsigned int elength,
+                                struct orl *map,
+                                unsigned int symbol_count,
+                                int stridx)
 {
   unsigned int ranlibsize = (symbol_count * 8) + 8;
   unsigned int stringsize = stridx;
@@ -171,7 +184,7 @@ bfd_elf64_archive_write_armap (bfd *arch,
   if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
     return FALSE;
   _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
-                    time (NULL));
+                   time (NULL));
   /* This, at least, is what Intel coff sets the values to.: */
   _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
   _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
This page took 0.025123 seconds and 4 git commands to generate.