gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / binutils / elfcomm.c
index a50b1ece382621b4ad786fb7f7440a975ccc4391..558afa7d056c29304a2bf2c4061ffad5341a9841 100644 (file)
@@ -1,6 +1,5 @@
 /* elfcomm.c -- common code for ELF format file.
-   Copyright 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2010-2020 Free Software Foundation, Inc.
 
    Originally developed by Eric Youngdale <eric@andante.jic.com>
    Modifications by Nick Clifton <nickc@redhat.com>
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
+/* Do not include bfd.h in this file.  Functions in this file are used
+   by readelf.c and elfedit.c which define BFD64, and by objdump.c
+   which doesn't.  */
+
 #include "sysdep.h"
 #include "libiberty.h"
 #include "filenames.h"
-#include "bfd.h"
 #include "aout/ar.h"
-#include "bucomm.h"
 #include "elfcomm.h"
 #include <assert.h>
 
+extern char *program_name;
+
 void
 error (const char *message, ...)
 {
   va_list args;
 
+  /* Try to keep error messages in sync with the program's normal output.  */
+  fflush (stdout);
+
   va_start (args, message);
   fprintf (stderr, _("%s: Error: "), program_name);
   vfprintf (stderr, message, args);
@@ -47,6 +53,9 @@ warn (const char *message, ...)
 {
   va_list args;
 
+  /* Try to keep warning messages in sync with the program's normal output.  */
+  fflush (stdout);
+
   va_start (args, message);
   fprintf (stderr, _("%s: Warning: "), program_name);
   vfprintf (stderr, message, args);
@@ -120,10 +129,10 @@ byte_put_big_endian (unsigned char * field, elf_vma value, int size)
     }
 }
 
-elf_vma (*byte_get) (unsigned char *, int);
+elf_vma (*byte_get) (const unsigned char *, int);
 
 elf_vma
-byte_get_little_endian (unsigned char *field, int size)
+byte_get_little_endian (const unsigned char *field, int size)
 {
   switch (size)
     {
@@ -145,6 +154,60 @@ byte_get_little_endian (unsigned char *field, int size)
        |    (((unsigned long) (field[2])) << 16)
        |    (((unsigned long) (field[3])) << 24);
 
+    case 5:
+      if (sizeof (elf_vma) == 8)
+       return  ((elf_vma) (field[0]))
+         |    (((elf_vma) (field[1])) << 8)
+         |    (((elf_vma) (field[2])) << 16)
+         |    (((elf_vma) (field[3])) << 24)
+         |    (((elf_vma) (field[4])) << 32);
+      else if (sizeof (elf_vma) == 4)
+       /* We want to extract data from an 8 byte wide field and
+          place it into a 4 byte wide field.  Since this is a little
+          endian source we can just use the 4 byte extraction code.  */
+       return  ((unsigned long) (field[0]))
+         |    (((unsigned long) (field[1])) << 8)
+         |    (((unsigned long) (field[2])) << 16)
+         |    (((unsigned long) (field[3])) << 24);
+      /* Fall through.  */
+
+    case 6:
+      if (sizeof (elf_vma) == 8)
+       return  ((elf_vma) (field[0]))
+         |    (((elf_vma) (field[1])) << 8)
+         |    (((elf_vma) (field[2])) << 16)
+         |    (((elf_vma) (field[3])) << 24)
+         |    (((elf_vma) (field[4])) << 32)
+         |    (((elf_vma) (field[5])) << 40);
+      else if (sizeof (elf_vma) == 4)
+       /* We want to extract data from an 8 byte wide field and
+          place it into a 4 byte wide field.  Since this is a little
+          endian source we can just use the 4 byte extraction code.  */
+       return  ((unsigned long) (field[0]))
+         |    (((unsigned long) (field[1])) << 8)
+         |    (((unsigned long) (field[2])) << 16)
+         |    (((unsigned long) (field[3])) << 24);
+      /* Fall through.  */
+
+    case 7:
+      if (sizeof (elf_vma) == 8)
+       return  ((elf_vma) (field[0]))
+         |    (((elf_vma) (field[1])) << 8)
+         |    (((elf_vma) (field[2])) << 16)
+         |    (((elf_vma) (field[3])) << 24)
+         |    (((elf_vma) (field[4])) << 32)
+         |    (((elf_vma) (field[5])) << 40)
+         |    (((elf_vma) (field[6])) << 48);
+      else if (sizeof (elf_vma) == 4)
+       /* We want to extract data from an 8 byte wide field and
+          place it into a 4 byte wide field.  Since this is a little
+          endian source we can just use the 4 byte extraction code.  */
+       return  ((unsigned long) (field[0]))
+         |    (((unsigned long) (field[1])) << 8)
+         |    (((unsigned long) (field[2])) << 16)
+         |    (((unsigned long) (field[3])) << 24);
+      /* Fall through.  */
+
     case 8:
       if (sizeof (elf_vma) == 8)
        return  ((elf_vma) (field[0]))
@@ -163,6 +226,7 @@ byte_get_little_endian (unsigned char *field, int size)
          |    (((unsigned long) (field[1])) << 8)
          |    (((unsigned long) (field[2])) << 16)
          |    (((unsigned long) (field[3])) << 24);
+      /* Fall through.  */
 
     default:
       error (_("Unhandled data length: %d\n"), size);
@@ -171,7 +235,7 @@ byte_get_little_endian (unsigned char *field, int size)
 }
 
 elf_vma
-byte_get_big_endian (unsigned char *field, int size)
+byte_get_big_endian (const unsigned char *field, int size)
 {
   switch (size)
     {
@@ -192,6 +256,66 @@ byte_get_big_endian (unsigned char *field, int size)
        |   (((unsigned long) (field[1])) << 16)
        |   (((unsigned long) (field[0])) << 24);
 
+    case 5:
+      if (sizeof (elf_vma) == 8)
+       return ((elf_vma) (field[4]))
+         |   (((elf_vma) (field[3])) << 8)
+         |   (((elf_vma) (field[2])) << 16)
+         |   (((elf_vma) (field[1])) << 24)
+         |   (((elf_vma) (field[0])) << 32);
+      else if (sizeof (elf_vma) == 4)
+       {
+         /* Although we are extracting data from an 8 byte wide field,
+            we are returning only 4 bytes of data.  */
+         field += 1;
+         return ((unsigned long) (field[3]))
+           |   (((unsigned long) (field[2])) << 8)
+           |   (((unsigned long) (field[1])) << 16)
+           |   (((unsigned long) (field[0])) << 24);
+       }
+      /* Fall through.  */
+
+    case 6:
+      if (sizeof (elf_vma) == 8)
+       return ((elf_vma) (field[5]))
+         |   (((elf_vma) (field[4])) << 8)
+         |   (((elf_vma) (field[3])) << 16)
+         |   (((elf_vma) (field[2])) << 24)
+         |   (((elf_vma) (field[1])) << 32)
+         |   (((elf_vma) (field[0])) << 40);
+      else if (sizeof (elf_vma) == 4)
+       {
+         /* Although we are extracting data from an 8 byte wide field,
+            we are returning only 4 bytes of data.  */
+         field += 2;
+         return ((unsigned long) (field[3]))
+           |   (((unsigned long) (field[2])) << 8)
+           |   (((unsigned long) (field[1])) << 16)
+           |   (((unsigned long) (field[0])) << 24);
+       }
+      /* Fall through.  */
+
+    case 7:
+      if (sizeof (elf_vma) == 8)
+       return ((elf_vma) (field[6]))
+         |   (((elf_vma) (field[5])) << 8)
+         |   (((elf_vma) (field[4])) << 16)
+         |   (((elf_vma) (field[3])) << 24)
+         |   (((elf_vma) (field[2])) << 32)
+         |   (((elf_vma) (field[1])) << 40)
+         |   (((elf_vma) (field[0])) << 48);
+      else if (sizeof (elf_vma) == 4)
+       {
+         /* Although we are extracting data from an 8 byte wide field,
+            we are returning only 4 bytes of data.  */
+         field += 3;
+         return ((unsigned long) (field[3]))
+           |   (((unsigned long) (field[2])) << 8)
+           |   (((unsigned long) (field[1])) << 16)
+           |   (((unsigned long) (field[0])) << 24);
+       }
+      /* Fall through.  */
+
     case 8:
       if (sizeof (elf_vma) == 8)
        return ((elf_vma) (field[7]))
@@ -204,7 +328,7 @@ byte_get_big_endian (unsigned char *field, int size)
          |   (((elf_vma) (field[0])) << 56);
       else if (sizeof (elf_vma) == 4)
        {
-         /* Although we are extracing data from an 8 byte wide field,
+         /* Although we are extracting data from an 8 byte wide field,
             we are returning only 4 bytes of data.  */
          field += 4;
          return ((unsigned long) (field[3]))
@@ -212,6 +336,7 @@ byte_get_big_endian (unsigned char *field, int size)
            |   (((unsigned long) (field[1])) << 16)
            |   (((unsigned long) (field[0])) << 24);
        }
+      /* Fall through.  */
 
     default:
       error (_("Unhandled data length: %d\n"), size);
@@ -220,7 +345,7 @@ byte_get_big_endian (unsigned char *field, int size)
 }
 
 elf_vma
-byte_get_signed (unsigned char *field, int size)
+byte_get_signed (const unsigned char *field, int size)
 {
   elf_vma x = byte_get (field, size);
 
@@ -230,9 +355,18 @@ byte_get_signed (unsigned char *field, int size)
       return (x ^ 0x80) - 0x80;
     case 2:
       return (x ^ 0x8000) - 0x8000;
+    case 3:
+      return (x ^ 0x800000) - 0x800000;
     case 4:
       return (x ^ 0x80000000) - 0x80000000;
+    case 5:
+    case 6:
+    case 7:
     case 8:
+      /* Reads of 5-, 6-, and 7-byte numbers are the result of
+         trying to read past the end of a buffer, and will therefore
+         not have meaningful values, so we don't try to deal with
+         the sign in these cases.  */
       return x;
     default:
       abort ();
@@ -243,7 +377,7 @@ byte_get_signed (unsigned char *field, int size)
    of an 8-byte value separately.  */
 
 void
-byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
+byte_get_64 (const unsigned char *field, elf_vma *high, elf_vma *low)
 {
   if (byte_get == byte_get_big_endian)
     {
@@ -264,10 +398,11 @@ byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
 
 char *
 adjust_relative_path (const char *file_name, const char *name,
-                     int name_len)
+                     unsigned long name_len)
 {
   char * member_file_name;
   const char * base_name = lbasename (file_name);
+  size_t amt;
 
   /* This is a proxy entry for a thin archive member.
      If the extended name table contains an absolute path
@@ -277,7 +412,10 @@ adjust_relative_path (const char *file_name, const char *name,
      archive is located.  */
   if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
     {
-      member_file_name = (char *) malloc (name_len + 1);
+      amt = name_len + 1;
+      if (amt == 0)
+       return NULL;
+      member_file_name = (char *) malloc (amt);
       if (member_file_name == NULL)
         {
           error (_("Out of memory\n"));
@@ -291,7 +429,18 @@ adjust_relative_path (const char *file_name, const char *name,
       /* Concatenate the path components of the archive file name
          to the relative path name from the extended name table.  */
       size_t prefix_len = base_name - file_name;
-      member_file_name = (char *) malloc (prefix_len + name_len + 1);
+
+      amt = prefix_len + name_len + 1;
+      /* PR 17531: file: 2896dc8b
+        Catch wraparound.  */
+      if (amt < prefix_len || amt < name_len)
+       {
+         error (_("Abnormal length of thin archive member name: %lx\n"),
+                name_len);
+         return NULL;
+       }
+
+      member_file_name = (char *) malloc (amt);
       if (member_file_name == NULL)
         {
           error (_("Out of memory\n"));
@@ -311,18 +460,30 @@ adjust_relative_path (const char *file_name, const char *name,
     ARCH->sym_size and ARCH->sym_table.
    It is the caller's responsibility to free ARCH->index_array and
     ARCH->sym_table.
-   Returns TRUE upon success, FALSE otherwise.
+   Returns 1 upon success, 0 otherwise.
    If failure occurs an error message is printed.  */
 
-static bfd_boolean
-process_archive_index_and_symbols (struct archive_info *  arch,
-                                  unsigned int           sizeof_ar_index,
-                                  bfd_boolean            read_symbols)
+static int
+process_archive_index_and_symbols (struct archive_info *arch,
+                                  unsigned int sizeof_ar_index,
+                                  int read_symbols)
 {
   size_t got;
   unsigned long size;
+  char fmag_save;
 
+  fmag_save = arch->arhdr.ar_fmag[0];
+  arch->arhdr.ar_fmag[0] = 0;
   size = strtoul (arch->arhdr.ar_size, NULL, 10);
+  arch->arhdr.ar_fmag[0] = fmag_save;
+  /* PR 17531: file: 912bd7de.  */
+  if ((signed long) size < 0)
+    {
+      error (_("%s: invalid archive header size: %ld\n"),
+            arch->file_name, size);
+      return 0;
+    }
+
   size = size + (size & 1);
 
   arch->next_arhdr_offset += sizeof arch->arhdr + size;
@@ -333,7 +494,7 @@ process_archive_index_and_symbols (struct archive_info *  arch,
        {
          error (_("%s: failed to skip archive symbol table\n"),
                 arch->file_name);
-         return FALSE;
+         return 0;
        }
     }
   else
@@ -346,12 +507,12 @@ process_archive_index_and_symbols (struct archive_info *  arch,
       unsigned char * index_buffer;
 
       assert (sizeof_ar_index <= sizeof integer_buffer);
-  
+
       /* Check the size of the archive index.  */
       if (size < sizeof_ar_index)
        {
          error (_("%s: the archive index is empty\n"), arch->file_name);
-         return FALSE;
+         return 0;
        }
 
       /* Read the number of entries in the archive index.  */
@@ -359,17 +520,19 @@ process_archive_index_and_symbols (struct archive_info *  arch,
       if (got != sizeof_ar_index)
        {
          error (_("%s: failed to read archive index\n"), arch->file_name);
-         return FALSE;
+         return 0;
        }
 
       arch->index_num = byte_get_big_endian (integer_buffer, sizeof_ar_index);
       size -= sizeof_ar_index;
 
-      if (size < arch->index_num * sizeof_ar_index)
+      if (size < arch->index_num * sizeof_ar_index
+         /* PR 17531: file: 585515d1.  */
+         || size < arch->index_num)
        {
-         error (_("%s: the archive index is supposed to have %ld entries of %d bytes, but the size is only %ld\n"),
+         error (_("%s: the archive index is supposed to have 0x%lx entries of %d bytes, but the size is only 0x%lx\n"),
                 arch->file_name, (long) arch->index_num, sizeof_ar_index, size);
-         return FALSE;
+         return 0;
        }
 
       /* Read in the archive index.  */
@@ -378,7 +541,7 @@ process_archive_index_and_symbols (struct archive_info *  arch,
       if (index_buffer == NULL)
        {
          error (_("Out of memory whilst trying to read archive symbol index\n"));
-         return FALSE;
+         return 0;
        }
 
       got = fread (index_buffer, sizeof_ar_index, arch->index_num, arch->file);
@@ -386,7 +549,7 @@ process_archive_index_and_symbols (struct archive_info *  arch,
        {
          free (index_buffer);
          error (_("%s: failed to read archive index\n"), arch->file_name);
-         return FALSE;
+         return 0;
        }
 
       size -= arch->index_num * sizeof_ar_index;
@@ -398,7 +561,7 @@ process_archive_index_and_symbols (struct archive_info *  arch,
        {
          free (index_buffer);
          error (_("Out of memory whilst trying to convert the archive symbol index\n"));
-         return FALSE;
+         return 0;
        }
 
       for (i = 0; i < arch->index_num; i++)
@@ -412,14 +575,14 @@ process_archive_index_and_symbols (struct archive_info *  arch,
        {
          error (_("%s: the archive has an index but no symbols\n"),
                 arch->file_name);
-         return FALSE;
+         return 0;
        }
 
       arch->sym_table = (char *) malloc (size);
       if (arch->sym_table == NULL)
        {
          error (_("Out of memory whilst trying to read archive index symbol table\n"));
-         return FALSE;
+         return 0;
        }
 
       arch->sym_size = size;
@@ -428,7 +591,7 @@ process_archive_index_and_symbols (struct archive_info *  arch,
        {
          error (_("%s: failed to read archive index symbol table\n"),
                 arch->file_name);
-         return FALSE;
+         return 0;
        }
     }
 
@@ -438,18 +601,18 @@ process_archive_index_and_symbols (struct archive_info *  arch,
     {
       error (_("%s: failed to read archive header following archive index\n"),
             arch->file_name);
-      return FALSE;
+      return 0;
     }
 
-  return TRUE;
+  return 1;
 }
 
 /* Read the symbol table and long-name table from an archive.  */
 
 int
 setup_archive (struct archive_info *arch, const char *file_name,
-              FILE *file, bfd_boolean is_thin_archive,
-              bfd_boolean read_symbols)
+              FILE *file, off_t file_size,
+              int is_thin_archive, int read_symbols)
 {
   size_t got;
 
@@ -463,7 +626,7 @@ setup_archive (struct archive_info *arch, const char *file_name,
   arch->longnames_size = 0;
   arch->nested_member_origin = 0;
   arch->is_thin_archive = is_thin_archive;
-  arch->uses_64bit_indicies = FALSE;
+  arch->uses_64bit_indices = 0;
   arch->next_arhdr_offset = SARMAG;
 
   /* Read the first archive member header.  */
@@ -490,7 +653,7 @@ setup_archive (struct archive_info *arch, const char *file_name,
     }
   else if (const_strneq (arch->arhdr.ar_name, "/SYM64/         "))
     {
-      arch->uses_64bit_indicies = TRUE;
+      arch->uses_64bit_indices = 1;
       if (! process_archive_index_and_symbols (arch, 8, read_symbols))
        return 1;
     }
@@ -500,10 +663,30 @@ setup_archive (struct archive_info *arch, const char *file_name,
   if (const_strneq (arch->arhdr.ar_name, "//              "))
     {
       /* This is the archive string table holding long member names.  */
+      char fmag_save = arch->arhdr.ar_fmag[0];
+      arch->arhdr.ar_fmag[0] = 0;
       arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
+      arch->arhdr.ar_fmag[0] = fmag_save;
+      /* PR 17531: file: 01068045.  */
+      if (arch->longnames_size < 8)
+       {
+         error (_("%s: long name table is too small, (size = %ld)\n"),
+                file_name, arch->longnames_size);
+         return 1;
+       }
+      /* PR 17531: file: 639d6a26.  */
+      if ((off_t) arch->longnames_size > file_size
+         || (signed long) arch->longnames_size < 0)
+       {
+         error (_("%s: long name table is too big, (size = 0x%lx)\n"),
+                file_name, arch->longnames_size);
+         return 1;
+       }
+
       arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
 
-      arch->longnames = (char *) malloc (arch->longnames_size);
+      /* Plus one to allow for a string terminator.  */
+      arch->longnames = (char *) malloc (arch->longnames_size + 1);
       if (arch->longnames == NULL)
        {
          error (_("Out of memory reading long symbol names in archive\n"));
@@ -521,6 +704,8 @@ setup_archive (struct archive_info *arch, const char *file_name,
 
       if ((arch->longnames_size & 1) != 0)
        getc (file);
+
+      arch->longnames[arch->longnames_size] = 0;
     }
 
   return 0;
@@ -533,6 +718,7 @@ setup_nested_archive (struct archive_info *nested_arch,
                      const char *member_file_name)
 {
   FILE * member_file;
+  struct stat statbuf;
 
   /* Have we already setup this archive?  */
   if (nested_arch->file_name != NULL
@@ -547,8 +733,10 @@ setup_nested_archive (struct archive_info *nested_arch,
   member_file = fopen (member_file_name, "rb");
   if (member_file == NULL)
     return 1;
+  if (fstat (fileno (member_file), &statbuf) < 0)
+    return 1;
   return setup_archive (nested_arch, member_file_name, member_file,
-                       FALSE, FALSE);
+                       statbuf.st_size, 0, 0);
 }
 
 /* Release the memory used for the archive information.  */
@@ -556,14 +744,10 @@ setup_nested_archive (struct archive_info *nested_arch,
 void
 release_archive (struct archive_info * arch)
 {
-  if (arch->file_name != NULL)
-    free (arch->file_name);
-  if (arch->index_array != NULL)
-    free (arch->index_array);
-  if (arch->sym_table != NULL)
-    free (arch->sym_table);
-  if (arch->longnames != NULL)
-    free (arch->longnames);
+  free (arch->file_name);
+  free (arch->index_array);
+  free (arch->sym_table);
+  free (arch->longnames);
 }
 
 /* Get the name of an archive member from the current archive header.
@@ -585,22 +769,46 @@ get_archive_member_name (struct archive_info *arch,
       char *endp;
       char *member_file_name;
       char *member_name;
+      char fmag_save;
+
+      if (arch->longnames == NULL || arch->longnames_size == 0)
+       {
+         error (_("Archive member uses long names, but no longname table found\n"));
+         return NULL;
+       }
 
       arch->nested_member_origin = 0;
+      fmag_save = arch->arhdr.ar_fmag[0];
+      arch->arhdr.ar_fmag[0] = 0;
       k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
       if (arch->is_thin_archive && endp != NULL && * endp == ':')
         arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
+      arch->arhdr.ar_fmag[0] = fmag_save;
 
+      if (j > arch->longnames_size)
+       {
+         error (_("Found long name index (%ld) beyond end of long name table\n"),j);
+         return NULL;
+       }
       while ((j < arch->longnames_size)
              && (arch->longnames[j] != '\n')
              && (arch->longnames[j] != '\0'))
         j++;
-      if (arch->longnames[j-1] == '/')
+      if (j > 0 && arch->longnames[j-1] == '/')
         j--;
+      if (j > arch->longnames_size)
+       j = arch->longnames_size;
       arch->longnames[j] = '\0';
 
       if (!arch->is_thin_archive || arch->nested_member_origin == 0)
-        return arch->longnames + k;
+       return xstrdup (arch->longnames + k);
+
+      /* PR 17531: file: 2896dc8b.  */
+      if (k >= j)
+       {
+         error (_("Invalid Thin archive member name\n"));
+         return NULL;
+       }
 
       /* This is a proxy for a member of a nested archive.
          Find the name of the member in that archive.  */
@@ -609,7 +817,7 @@ get_archive_member_name (struct archive_info *arch,
       if (member_file_name != NULL
           && setup_nested_archive (nested_arch, member_file_name) == 0)
        {
-          member_name = get_archive_member_name_at (nested_arch,
+         member_name = get_archive_member_name_at (nested_arch,
                                                    arch->nested_member_origin,
                                                    NULL);
          if (member_name != NULL)
@@ -621,7 +829,7 @@ get_archive_member_name (struct archive_info *arch,
       free (member_file_name);
 
       /* Last resort: just return the name of the nested archive.  */
-      return arch->longnames + k;
+      return xstrdup (arch->longnames + k);
     }
 
   /* We have a normal (short) name.  */
@@ -629,7 +837,7 @@ get_archive_member_name (struct archive_info *arch,
     if (arch->arhdr.ar_name[j] == '/')
       {
        arch->arhdr.ar_name[j] = '\0';
-       return arch->arhdr.ar_name;
+       return xstrdup (arch->arhdr.ar_name);
       }
 
   /* The full ar_name field is used.  Don't rely on ar_date starting
@@ -684,12 +892,20 @@ make_qualified_name (struct archive_info * arch,
                     struct archive_info * nested_arch,
                     const char *member_name)
 {
+  const char * error_name = _("<corrupt>");
   size_t len;
   char * name;
 
   len = strlen (arch->file_name) + strlen (member_name) + 3;
-  if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    len += strlen (nested_arch->file_name) + 2;
+  if (arch->is_thin_archive
+      && arch->nested_member_origin != 0)
+    {
+      /* PR 15140: Allow for corrupt thin archives.  */
+      if (nested_arch->file_name)
+       len += strlen (nested_arch->file_name) + 2;
+      else
+       len += strlen (error_name) + 2;
+    }
 
   name = (char *) malloc (len);
   if (name == NULL)
@@ -698,9 +914,16 @@ make_qualified_name (struct archive_info * arch,
       return NULL;
     }
 
-  if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    snprintf (name, len, "%s[%s(%s)]", arch->file_name,
-             nested_arch->file_name, member_name);
+  if (arch->is_thin_archive
+      && arch->nested_member_origin != 0)
+    {
+      if (nested_arch->file_name)
+       snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+                 nested_arch->file_name, member_name);
+      else
+       snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+                 error_name, member_name);
+    }
   else if (arch->is_thin_archive)
     snprintf (name, len, "%s[%s]", arch->file_name, member_name);
   else
This page took 0.033 seconds and 4 git commands to generate.