Imported Upstream version 7.9
[platform/upstream/gdb.git] / bfd / archive.c
index 157a3f7..cc4c52f 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for archive files (libraries).
-   Copyright (C) 1990-2014 Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
    Written by Cygnus Support.  Mostly Gumby Henkel-Wallace's fault.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -140,6 +140,7 @@ SUBSECTION
 #include "safe-ctype.h"
 #include "hashtab.h"
 #include "filenames.h"
+#include "bfdlink.h"
 
 #ifndef errno
 extern int errno;
@@ -901,6 +902,10 @@ do_slurp_bsd_armap (bfd *abfd)
     return FALSE;
   parsed_size = mapdata->parsed_size;
   free (mapdata);
+  /* PR 17512: file: 883ff754.  */
+  /* PR 17512: file: 0458885f.  */
+  if (parsed_size < 4)
+    return FALSE;
 
   raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
   if (raw_armap == NULL)
@@ -916,7 +921,6 @@ do_slurp_bsd_armap (bfd *abfd)
     }
 
   ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE;
-
   if (ardata->symdef_count * BSD_SYMDEF_SIZE >
       parsed_size - BSD_SYMDEF_COUNT_SIZE)
     {
@@ -1037,12 +1041,19 @@ do_slurp_coff_armap (bfd *abfd)
     }
 
   /* OK, build the carsyms.  */
-  for (i = 0; i < nsymz; i++)
+  for (i = 0; i < nsymz && stringsize > 0; i++)
     {
+      bfd_size_type len;
+
       rawptr = raw_armap + i;
       carsyms->file_offset = swap ((bfd_byte *) rawptr);
       carsyms->name = stringbase;
-      stringbase += strlen (stringbase) + 1;
+      /* PR 17512: file: 4a1d50c1.  */
+      len = strnlen (stringbase, stringsize);
+      if (len < stringsize)
+       len ++;
+      stringbase += len;
+      stringsize -= len;
       carsyms++;
     }
   *stringbase = 0;
@@ -1130,6 +1141,7 @@ bfd_slurp_armap (bfd *abfd)
        return FALSE;
       if (bfd_seek (abfd, -(file_ptr) (sizeof (hdr) + 20), SEEK_CUR) != 0)
        return FALSE;
+      extname[20] = 0;
       if (CONST_STRNEQ (extname, "__.SYMDEF SORTED")
          || CONST_STRNEQ (extname, "__.SYMDEF"))
        return do_slurp_bsd_armap (abfd);
@@ -1299,6 +1311,8 @@ _bfd_slurp_extended_name_table (bfd *abfd)
        {
        byebye:
          free (namedata);
+         bfd_ardata (abfd)->extended_names = NULL;
+         bfd_ardata (abfd)->extended_names_size = 0;
          return FALSE;
        }
 
@@ -1315,11 +1329,12 @@ _bfd_slurp_extended_name_table (bfd *abfd)
         text, the entries in the list are newline-padded, not null
         padded. In SVR4-style archives, the names also have a
         trailing '/'.  DOS/NT created archive often have \ in them
-        We'll fix all problems here..  */
+        We'll fix all problems here.  */
       {
        char *ext_names = bfd_ardata (abfd)->extended_names;
        char *temp = ext_names;
        char *limit = temp + namedata->parsed_size;
+
        for (; temp < limit; ++temp)
          {
            if (*temp == ARFMAG[1])
@@ -1960,7 +1975,9 @@ bfd_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
     }
 
   hdr = arch_hdr (abfd);
-
+  /* PR 17512: file: 3d9e9fe9.  */
+  if (hdr == NULL)
+    return -1;
 #define foo(arelt, stelt, size)                                \
   buf->stelt = strtol (hdr->arelt, &aloser, size);     \
   if (aloser == hdr->arelt)                            \
@@ -2356,6 +2373,10 @@ _bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
                          map = new_map;
                        }
 
+                     if (strcmp (syms[src_count]->name, "__gnu_lto_slim") == 0)
+                       (*_bfd_error_handler)
+                         (_("%s: plugin needed to handle lto object"),
+                          bfd_get_filename (current));
                      namelen = strlen (syms[src_count]->name);
                      amt = sizeof (char *);
                      map[orl_count].name = (char **) bfd_alloc (arch, amt);
@@ -2751,5 +2772,8 @@ _bfd_archive_close_and_cleanup (bfd *abfd)
            }
        }
     }
+  if (abfd->is_linker_output)
+    (*abfd->link.hash->hash_table_free) (abfd);
+
   return TRUE;
 }