[BACK]Return to elfcomm.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils / dist / binutils

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/external/gpl3/binutils/dist/binutils/elfcomm.c between version 1.1.1.6 and 1.1.1.7

version 1.1.1.6, 2020/04/03 23:39:56 version 1.1.1.7, 2022/12/23 19:01:06
Line 1 
Line 1 
 /* elfcomm.c -- common code for ELF format file.  /* elfcomm.c -- common code for ELF format file.
    Copyright (C) 2010-2020 Free Software Foundation, Inc.     Copyright (C) 2010-2022 Free Software Foundation, Inc.
   
    Originally developed by Eric Youngdale <eric@andante.jic.com>     Originally developed by Eric Youngdale <eric@andante.jic.com>
    Modifications by Nick Clifton <nickc@redhat.com>     Modifications by Nick Clifton <nickc@redhat.com>
Line 21 
Line 21 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */     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 "sysdep.h"
 #include "libiberty.h"  #include "libiberty.h"
 #include "filenames.h"  
 #include "bfd.h"  #include "bfd.h"
   #include "filenames.h"
 #include "aout/ar.h"  #include "aout/ar.h"
 #include "bucomm.h"  
 #include "elfcomm.h"  #include "elfcomm.h"
 #include <assert.h>  #include <assert.h>
   
   extern char *program_name;
   
 void  void
 error (const char *message, ...)  error (const char *message, ...)
 {  {
Line 58  warn (const char *message, ...)
Line 63  warn (const char *message, ...)
   va_end (args);    va_end (args);
 }  }
   
 void (*byte_put) (unsigned char *, elf_vma, int);  void (*byte_put) (unsigned char *, elf_vma, unsigned int);
   
 void  void
 byte_put_little_endian (unsigned char * field, elf_vma value, int size)  byte_put_little_endian (unsigned char * field, elf_vma value, unsigned int size)
 {  {
   switch (size)    if (size > sizeof (elf_vma))
     {      {
     case 8:  
       field[7] = (((value >> 24) >> 24) >> 8) & 0xff;  
       field[6] = ((value >> 24) >> 24) & 0xff;  
       field[5] = ((value >> 24) >> 16) & 0xff;  
       field[4] = ((value >> 24) >> 8) & 0xff;  
       /* Fall through.  */  
     case 4:  
       field[3] = (value >> 24) & 0xff;  
       /* Fall through.  */  
     case 3:  
       field[2] = (value >> 16) & 0xff;  
       /* Fall through.  */  
     case 2:  
       field[1] = (value >> 8) & 0xff;  
       /* Fall through.  */  
     case 1:  
       field[0] = value & 0xff;  
       break;  
   
     default:  
       error (_("Unhandled data length: %d\n"), size);        error (_("Unhandled data length: %d\n"), size);
       abort ();        abort ();
     }      }
     while (size--)
       {
         *field++ = value & 0xff;
         value >>= 8;
       }
 }  }
   
 void  void
 byte_put_big_endian (unsigned char * field, elf_vma value, int size)  byte_put_big_endian (unsigned char * field, elf_vma value, unsigned int size)
 {  {
   switch (size)    if (size > sizeof (elf_vma))
     {      {
     case 8:  
       field[7] = value & 0xff;  
       field[6] = (value >> 8) & 0xff;  
       field[5] = (value >> 16) & 0xff;  
       field[4] = (value >> 24) & 0xff;  
       value >>= 16;  
       value >>= 16;  
       /* Fall through.  */  
     case 4:  
       field[3] = value & 0xff;  
       value >>= 8;  
       /* Fall through.  */  
     case 3:  
       field[2] = value & 0xff;  
       value >>= 8;  
       /* Fall through.  */  
     case 2:  
       field[1] = value & 0xff;  
       value >>= 8;  
       /* Fall through.  */  
     case 1:  
       field[0] = value & 0xff;  
       break;  
   
     default:  
       error (_("Unhandled data length: %d\n"), size);        error (_("Unhandled data length: %d\n"), size);
       abort ();        abort ();
     }      }
     while (size--)
       {
         field[size] = value & 0xff;
         value >>= 8;
       }
 }  }
   
 elf_vma (*byte_get) (const unsigned char *, int);  elf_vma (*byte_get) (const unsigned char *, unsigned int);
   
 elf_vma  elf_vma
 byte_get_little_endian (const unsigned char *field, int size)  byte_get_little_endian (const unsigned char *field, unsigned int size)
 {  {
   switch (size)    switch (size)
     {      {
Line 151  byte_get_little_endian (const unsigned c
Line 121  byte_get_little_endian (const unsigned c
         |    (((unsigned long) (field[3])) << 24);          |    (((unsigned long) (field[3])) << 24);
   
     case 5:      case 5:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return  ((elf_vma) (field[0]))          return  ((elf_vma) (field[0]))
           |    (((elf_vma) (field[1])) << 8)            |    (((elf_vma) (field[1])) << 8)
           |    (((elf_vma) (field[2])) << 16)            |    (((elf_vma) (field[2])) << 16)
           |    (((elf_vma) (field[3])) << 24)            |    (((elf_vma) (field[3])) << 24)
           |    (((elf_vma) (field[4])) << 32);            |    (((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.  */        /* Fall through.  */
   
     case 6:      case 6:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return  ((elf_vma) (field[0]))          return  ((elf_vma) (field[0]))
           |    (((elf_vma) (field[1])) << 8)            |    (((elf_vma) (field[1])) << 8)
           |    (((elf_vma) (field[2])) << 16)            |    (((elf_vma) (field[2])) << 16)
           |    (((elf_vma) (field[3])) << 24)            |    (((elf_vma) (field[3])) << 24)
           |    (((elf_vma) (field[4])) << 32)            |    (((elf_vma) (field[4])) << 32)
           |    (((elf_vma) (field[5])) << 40);            |    (((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.  */        /* Fall through.  */
   
     case 7:      case 7:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return  ((elf_vma) (field[0]))          return  ((elf_vma) (field[0]))
           |    (((elf_vma) (field[1])) << 8)            |    (((elf_vma) (field[1])) << 8)
           |    (((elf_vma) (field[2])) << 16)            |    (((elf_vma) (field[2])) << 16)
Line 194  byte_get_little_endian (const unsigned c
Line 148  byte_get_little_endian (const unsigned c
           |    (((elf_vma) (field[4])) << 32)            |    (((elf_vma) (field[4])) << 32)
           |    (((elf_vma) (field[5])) << 40)            |    (((elf_vma) (field[5])) << 40)
           |    (((elf_vma) (field[6])) << 48);            |    (((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.  */        /* Fall through.  */
   
     case 8:      case 8:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return  ((elf_vma) (field[0]))          return  ((elf_vma) (field[0]))
           |    (((elf_vma) (field[1])) << 8)            |    (((elf_vma) (field[1])) << 8)
           |    (((elf_vma) (field[2])) << 16)            |    (((elf_vma) (field[2])) << 16)
Line 214  byte_get_little_endian (const unsigned c
Line 160  byte_get_little_endian (const unsigned c
           |    (((elf_vma) (field[5])) << 40)            |    (((elf_vma) (field[5])) << 40)
           |    (((elf_vma) (field[6])) << 48)            |    (((elf_vma) (field[6])) << 48)
           |    (((elf_vma) (field[7])) << 56);            |    (((elf_vma) (field[7])) << 56);
       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.  */        /* Fall through.  */
   
     default:      default:
Line 231  byte_get_little_endian (const unsigned c
Line 169  byte_get_little_endian (const unsigned c
 }  }
   
 elf_vma  elf_vma
 byte_get_big_endian (const unsigned char *field, int size)  byte_get_big_endian (const unsigned char *field, unsigned int size)
 {  {
   switch (size)    switch (size)
     {      {
Line 253  byte_get_big_endian (const unsigned char
Line 191  byte_get_big_endian (const unsigned char
         |   (((unsigned long) (field[0])) << 24);          |   (((unsigned long) (field[0])) << 24);
   
     case 5:      case 5:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return ((elf_vma) (field[4]))          return ((elf_vma) (field[4]))
           |   (((elf_vma) (field[3])) << 8)            |   (((elf_vma) (field[3])) << 8)
           |   (((elf_vma) (field[2])) << 16)            |   (((elf_vma) (field[2])) << 16)
           |   (((elf_vma) (field[1])) << 24)            |   (((elf_vma) (field[1])) << 24)
           |   (((elf_vma) (field[0])) << 32);            |   (((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.  */        /* Fall through.  */
   
     case 6:      case 6:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return ((elf_vma) (field[5]))          return ((elf_vma) (field[5]))
           |   (((elf_vma) (field[4])) << 8)            |   (((elf_vma) (field[4])) << 8)
           |   (((elf_vma) (field[3])) << 16)            |   (((elf_vma) (field[3])) << 16)
           |   (((elf_vma) (field[2])) << 24)            |   (((elf_vma) (field[2])) << 24)
           |   (((elf_vma) (field[1])) << 32)            |   (((elf_vma) (field[1])) << 32)
           |   (((elf_vma) (field[0])) << 40);            |   (((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.  */        /* Fall through.  */
   
     case 7:      case 7:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return ((elf_vma) (field[6]))          return ((elf_vma) (field[6]))
           |   (((elf_vma) (field[5])) << 8)            |   (((elf_vma) (field[5])) << 8)
           |   (((elf_vma) (field[4])) << 16)            |   (((elf_vma) (field[4])) << 16)
Line 300  byte_get_big_endian (const unsigned char
Line 218  byte_get_big_endian (const unsigned char
           |   (((elf_vma) (field[2])) << 32)            |   (((elf_vma) (field[2])) << 32)
           |   (((elf_vma) (field[1])) << 40)            |   (((elf_vma) (field[1])) << 40)
           |   (((elf_vma) (field[0])) << 48);            |   (((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.  */        /* Fall through.  */
   
     case 8:      case 8:
       if (sizeof (elf_vma) == 8)        if (sizeof (elf_vma) >= 8)
         return ((elf_vma) (field[7]))          return ((elf_vma) (field[7]))
           |   (((elf_vma) (field[6])) << 8)            |   (((elf_vma) (field[6])) << 8)
           |   (((elf_vma) (field[5])) << 16)            |   (((elf_vma) (field[5])) << 16)
Line 322  byte_get_big_endian (const unsigned char
Line 230  byte_get_big_endian (const unsigned char
           |   (((elf_vma) (field[2])) << 40)            |   (((elf_vma) (field[2])) << 40)
           |   (((elf_vma) (field[1])) << 48)            |   (((elf_vma) (field[1])) << 48)
           |   (((elf_vma) (field[0])) << 56);            |   (((elf_vma) (field[0])) << 56);
       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 += 4;  
           return ((unsigned long) (field[3]))  
             |   (((unsigned long) (field[2])) << 8)  
             |   (((unsigned long) (field[1])) << 16)  
             |   (((unsigned long) (field[0])) << 24);  
         }  
       /* Fall through.  */        /* Fall through.  */
   
     default:      default:
Line 341  byte_get_big_endian (const unsigned char
Line 239  byte_get_big_endian (const unsigned char
 }  }
   
 elf_vma  elf_vma
 byte_get_signed (const unsigned char *field, int size)  byte_get_signed (const unsigned char *field, unsigned int size)
 {  {
   elf_vma x = byte_get (field, size);    elf_vma x = byte_get (field, size);
   
Line 369  byte_get_signed (const unsigned char *fi
Line 267  byte_get_signed (const unsigned char *fi
     }      }
 }  }
   
 /* Return the high-order 32-bits and the low-order 32-bits  
    of an 8-byte value separately.  */  
   
 void  
 byte_get_64 (const unsigned char *field, elf_vma *high, elf_vma *low)  
 {  
   if (byte_get == byte_get_big_endian)  
     {  
       *high = byte_get_big_endian (field, 4);  
       *low = byte_get_big_endian (field + 4, 4);  
     }  
   else  
     {  
       *high = byte_get_little_endian (field + 4, 4);  
       *low = byte_get_little_endian (field, 4);  
     }  
   return;  
 }  
   
 /* Return the path name for a proxy entry in a thin archive, adjusted  /* Return the path name for a proxy entry in a thin archive, adjusted
    relative to the path name of the thin archive itself if necessary.     relative to the path name of the thin archive itself if necessary.
    Always returns a pointer to malloc'ed memory.  */     Always returns a pointer to malloc'ed memory.  */
Line 456  adjust_relative_path (const char *file_n
Line 335  adjust_relative_path (const char *file_n
     ARCH->sym_size and ARCH->sym_table.      ARCH->sym_size and ARCH->sym_table.
    It is the caller's responsibility to free ARCH->index_array and     It is the caller's responsibility to free ARCH->index_array and
     ARCH->sym_table.      ARCH->sym_table.
    Returns TRUE upon success, FALSE otherwise.     Returns 1 upon success, 0 otherwise.
    If failure occurs an error message is printed.  */     If failure occurs an error message is printed.  */
   
 static bfd_boolean  static int
 process_archive_index_and_symbols (struct archive_info *  arch,  process_archive_index_and_symbols (struct archive_info *arch,
                                    unsigned int           sizeof_ar_index,                                     unsigned int sizeof_ar_index,
                                    bfd_boolean            read_symbols)                                     int read_symbols)
 {  {
   size_t got;    size_t got;
   unsigned long size;    unsigned long size;
Line 477  process_archive_index_and_symbols (struc
Line 356  process_archive_index_and_symbols (struc
     {      {
       error (_("%s: invalid archive header size: %ld\n"),        error (_("%s: invalid archive header size: %ld\n"),
              arch->file_name, size);               arch->file_name, size);
       return FALSE;        return 0;
     }      }
   
   size = size + (size & 1);    size = size + (size & 1);
Line 490  process_archive_index_and_symbols (struc
Line 369  process_archive_index_and_symbols (struc
         {          {
           error (_("%s: failed to skip archive symbol table\n"),            error (_("%s: failed to skip archive symbol table\n"),
                  arch->file_name);                   arch->file_name);
           return FALSE;            return 0;
         }          }
     }      }
   else    else
Line 508  process_archive_index_and_symbols (struc
Line 387  process_archive_index_and_symbols (struc
       if (size < sizeof_ar_index)        if (size < sizeof_ar_index)
         {          {
           error (_("%s: the archive index is empty\n"), arch->file_name);            error (_("%s: the archive index is empty\n"), arch->file_name);
           return FALSE;            return 0;
         }          }
   
       /* Read the number of entries in the archive index.  */        /* Read the number of entries in the archive index.  */
Line 516  process_archive_index_and_symbols (struc
Line 395  process_archive_index_and_symbols (struc
       if (got != sizeof_ar_index)        if (got != sizeof_ar_index)
         {          {
           error (_("%s: failed to read archive index\n"), arch->file_name);            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);        arch->index_num = byte_get_big_endian (integer_buffer, sizeof_ar_index);
Line 528  process_archive_index_and_symbols (struc
Line 407  process_archive_index_and_symbols (struc
         {          {
           error (_("%s: the archive index is supposed to have 0x%lx entries of %d bytes, but the size is only 0x%lx\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);                   arch->file_name, (long) arch->index_num, sizeof_ar_index, size);
           return FALSE;            return 0;
         }          }
   
       /* Read in the archive index.  */        /* Read in the archive index.  */
Line 537  process_archive_index_and_symbols (struc
Line 416  process_archive_index_and_symbols (struc
       if (index_buffer == NULL)        if (index_buffer == NULL)
         {          {
           error (_("Out of memory whilst trying to read archive symbol index\n"));            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);        got = fread (index_buffer, sizeof_ar_index, arch->index_num, arch->file);
Line 545  process_archive_index_and_symbols (struc
Line 424  process_archive_index_and_symbols (struc
         {          {
           free (index_buffer);            free (index_buffer);
           error (_("%s: failed to read archive index\n"), arch->file_name);            error (_("%s: failed to read archive index\n"), arch->file_name);
           return FALSE;            return 0;
         }          }
   
       size -= arch->index_num * sizeof_ar_index;        size -= arch->index_num * sizeof_ar_index;
Line 557  process_archive_index_and_symbols (struc
Line 436  process_archive_index_and_symbols (struc
         {          {
           free (index_buffer);            free (index_buffer);
           error (_("Out of memory whilst trying to convert the archive symbol index\n"));            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++)        for (i = 0; i < arch->index_num; i++)
Line 571  process_archive_index_and_symbols (struc
Line 450  process_archive_index_and_symbols (struc
         {          {
           error (_("%s: the archive has an index but no symbols\n"),            error (_("%s: the archive has an index but no symbols\n"),
                  arch->file_name);                   arch->file_name);
           return FALSE;            return 0;
         }          }
   
       arch->sym_table = (char *) malloc (size);        arch->sym_table = (char *) malloc (size);
       if (arch->sym_table == NULL)        if (arch->sym_table == NULL)
         {          {
           error (_("Out of memory whilst trying to read archive index symbol table\n"));            error (_("Out of memory whilst trying to read archive index symbol table\n"));
           return FALSE;            return 0;
         }          }
   
       arch->sym_size = size;        arch->sym_size = size;
Line 587  process_archive_index_and_symbols (struc
Line 466  process_archive_index_and_symbols (struc
         {          {
           error (_("%s: failed to read archive index symbol table\n"),            error (_("%s: failed to read archive index symbol table\n"),
                  arch->file_name);                   arch->file_name);
           return FALSE;            return 0;
         }          }
     }      }
   
Line 597  process_archive_index_and_symbols (struc
Line 476  process_archive_index_and_symbols (struc
     {      {
       error (_("%s: failed to read archive header following archive index\n"),        error (_("%s: failed to read archive header following archive index\n"),
              arch->file_name);               arch->file_name);
       return FALSE;        return 0;
     }      }
   
   return TRUE;    return 1;
 }  }
   
 /* Read the symbol table and long-name table from an archive.  */  /* Read the symbol table and long-name table from an archive.  */
   
 int  int
 setup_archive (struct archive_info *arch, const char *file_name,  setup_archive (struct archive_info *arch, const char *file_name,
                FILE *file, bfd_boolean is_thin_archive,                 FILE *file, off_t file_size,
                bfd_boolean read_symbols)                 int is_thin_archive, int read_symbols)
 {  {
   size_t got;    size_t got;
   
Line 622  setup_archive (struct archive_info *arch
Line 501  setup_archive (struct archive_info *arch
   arch->longnames_size = 0;    arch->longnames_size = 0;
   arch->nested_member_origin = 0;    arch->nested_member_origin = 0;
   arch->is_thin_archive = is_thin_archive;    arch->is_thin_archive = is_thin_archive;
   arch->uses_64bit_indices = FALSE;    arch->uses_64bit_indices = 0;
   arch->next_arhdr_offset = SARMAG;    arch->next_arhdr_offset = SARMAG;
   
   /* Read the first archive member header.  */    /* Read the first archive member header.  */
Line 642  setup_archive (struct archive_info *arch
Line 521  setup_archive (struct archive_info *arch
     }      }
   
   /* See if this is the archive symbol table.  */    /* See if this is the archive symbol table.  */
   if (const_strneq (arch->arhdr.ar_name, "/               "))    if (startswith (arch->arhdr.ar_name, "/               "))
     {      {
       if (! process_archive_index_and_symbols (arch, 4, read_symbols))        if (! process_archive_index_and_symbols (arch, 4, read_symbols))
         return 1;          return 1;
     }      }
   else if (const_strneq (arch->arhdr.ar_name, "/SYM64/         "))    else if (startswith (arch->arhdr.ar_name, "/SYM64/         "))
     {      {
       arch->uses_64bit_indices = TRUE;        arch->uses_64bit_indices = 1;
       if (! process_archive_index_and_symbols (arch, 8, read_symbols))        if (! process_archive_index_and_symbols (arch, 8, read_symbols))
         return 1;          return 1;
     }      }
   else if (read_symbols)    else if (read_symbols)
     printf (_("%s has no archive index\n"), file_name);      printf (_("%s has no archive index\n"), file_name);
   
   if (const_strneq (arch->arhdr.ar_name, "//              "))    if (startswith (arch->arhdr.ar_name, "//              "))
     {      {
       /* This is the archive string table holding long member names.  */        /* This is the archive string table holding long member names.  */
       char fmag_save = arch->arhdr.ar_fmag[0];        char fmag_save = arch->arhdr.ar_fmag[0];
Line 671  setup_archive (struct archive_info *arch
Line 550  setup_archive (struct archive_info *arch
           return 1;            return 1;
         }          }
       /* PR 17531: file: 639d6a26.  */        /* PR 17531: file: 639d6a26.  */
       if ((signed long) arch->longnames_size < 0)        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"),            error (_("%s: long name table is too big, (size = 0x%lx)\n"),
                  file_name, arch->longnames_size);                   file_name, arch->longnames_size);
Line 713  setup_nested_archive (struct archive_inf
Line 593  setup_nested_archive (struct archive_inf
                       const char *member_file_name)                        const char *member_file_name)
 {  {
   FILE * member_file;    FILE * member_file;
     struct stat statbuf;
   
   /* Have we already setup this archive?  */    /* Have we already setup this archive?  */
   if (nested_arch->file_name != NULL    if (nested_arch->file_name != NULL
Line 721  setup_nested_archive (struct archive_inf
Line 602  setup_nested_archive (struct archive_inf
   
   /* Close previous file and discard cached information.  */    /* Close previous file and discard cached information.  */
   if (nested_arch->file != NULL)    if (nested_arch->file != NULL)
     fclose (nested_arch->file);      {
         fclose (nested_arch->file);
         nested_arch->file = NULL;
       }
   release_archive (nested_arch);    release_archive (nested_arch);
   
   member_file = fopen (member_file_name, "rb");    member_file = fopen (member_file_name, "rb");
   if (member_file == NULL)    if (member_file == NULL)
     return 1;      return 1;
     if (fstat (fileno (member_file), &statbuf) < 0)
       return 1;
   return setup_archive (nested_arch, member_file_name, member_file,    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.  */  /* Release the memory used for the archive information.  */
Line 736  setup_nested_archive (struct archive_inf
Line 622  setup_nested_archive (struct archive_inf
 void  void
 release_archive (struct archive_info * arch)  release_archive (struct archive_info * arch)
 {  {
   if (arch->file_name != NULL)    free (arch->file_name);
     free (arch->file_name);    free (arch->index_array);
   if (arch->index_array != NULL)    free (arch->sym_table);
     free (arch->index_array);    free (arch->longnames);
   if (arch->sym_table != NULL)    arch->file_name = NULL;
     free (arch->sym_table);    arch->index_array = NULL;
   if (arch->longnames != NULL)    arch->sym_table = NULL;
     free (arch->longnames);    arch->longnames = NULL;
 }  }
   
 /* Get the name of an archive member from the current archive header.  /* Get the name of an archive member from the current archive header.
Line 797  get_archive_member_name (struct archive_
Line 683  get_archive_member_name (struct archive_
       arch->longnames[j] = '\0';        arch->longnames[j] = '\0';
   
       if (!arch->is_thin_archive || arch->nested_member_origin == 0)        if (!arch->is_thin_archive || arch->nested_member_origin == 0)
         return arch->longnames + k;          return xstrdup (arch->longnames + k);
   
       /* PR 17531: file: 2896dc8b.  */        /* PR 17531: file: 2896dc8b.  */
       if (k >= j)        if (k >= j)
Line 813  get_archive_member_name (struct archive_
Line 699  get_archive_member_name (struct archive_
       if (member_file_name != NULL        if (member_file_name != NULL
           && setup_nested_archive (nested_arch, member_file_name) == 0)            && 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,                                                      arch->nested_member_origin,
                                                     NULL);                                                      NULL);
           if (member_name != NULL)            if (member_name != NULL)
Line 825  get_archive_member_name (struct archive_
Line 711  get_archive_member_name (struct archive_
       free (member_file_name);        free (member_file_name);
   
       /* Last resort: just return the name of the nested archive.  */        /* 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.  */    /* We have a normal (short) name.  */
Line 833  get_archive_member_name (struct archive_
Line 719  get_archive_member_name (struct archive_
     if (arch->arhdr.ar_name[j] == '/')      if (arch->arhdr.ar_name[j] == '/')
       {        {
         arch->arhdr.ar_name[j] = '\0';          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    /* The full ar_name field is used.  Don't rely on ar_date starting

Legend:
Removed from v.1.1.1.6  
changed lines
  Added in v.1.1.1.7

CVSweb <webmaster@jp.NetBSD.org>