Fix formatting.
[deliverable/binutils-gdb.git] / bfd / archive.c
index f847384a2e939080f842bc4de0600b29236d388f..6fe5997b7abb5dd2feaba7a706a01a31b476fb91 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD back-end for archive files (libraries).
-   Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+   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.
@@ -130,8 +131,6 @@ DESCRIPTION
 #include "libbfd.h"
 #include "aout/ar.h"
 #include "aout/ranlib.h"
-#include <errno.h>
-#include <string.h>            /* For memchr, strrchr and friends */
 #include <ctype.h>
 
 #ifndef errno
@@ -142,12 +141,9 @@ extern int errno;
 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
 #endif
 
-/* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file
-   is included, then obstack.h, which thinks if offsetof is defined, it
-   doesn't need to include stddef.h.  */
 /* Define offsetof for those systems which lack it */
 
-#if !defined (offsetof)
+#ifndef offsetof
 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
 #endif
 
@@ -177,7 +173,8 @@ static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd));
 static boolean do_slurp_coff_armap PARAMS ((bfd *abfd));
 static const char *normalize PARAMS ((bfd *, const char *file));
 static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
-                                                            const char *));
+                                                            const char *,
+                                                            bfd *member));
 \f
 boolean
 _bfd_generic_mkarchive (abfd)
@@ -187,10 +184,7 @@ _bfd_generic_mkarchive (abfd)
                              bfd_zalloc (abfd, sizeof (struct artdata)));
 
   if (bfd_ardata (abfd) == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   bfd_ardata (abfd)->cache = NULL;
   bfd_ardata (abfd)->archive_head = NULL;
@@ -251,15 +245,7 @@ bfd *
 _bfd_create_empty_archive_element_shell (obfd)
      bfd *obfd;
 {
-  bfd *nbfd;
-
-  nbfd = _bfd_new_bfd_contained_in (obfd);
-  if (nbfd == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
-  return nbfd;
+  return _bfd_new_bfd_contained_in (obfd);
 }
 
 /*
@@ -310,10 +296,7 @@ _bfd_add_bfd_to_archive_cache (arch_bfd, filepos, new_elt)
                                            sizeof (struct ar_cache)));
 
   if (new_cache == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   new_cache->ptr = filepos;
   new_cache->arelt = new_elt;
@@ -369,10 +352,17 @@ PTR
 _bfd_generic_read_ar_hdr (abfd)
      bfd *abfd;
 {
-#ifndef errno
-  extern int errno;
-#endif
+  return _bfd_generic_read_ar_hdr_mag (abfd, (const char *) NULL);
+}
 
+/* Alpha ECOFF uses an optional different ARFMAG value, so we have a
+   variant of _bfd_generic_read_ar_hdr which accepts a magic string.  */
+
+PTR
+_bfd_generic_read_ar_hdr_mag (abfd, mag)
+     bfd *abfd;
+     const char *mag;
+{
   struct ar_hdr hdr;
   char *hdrp = (char *) &hdr;
   unsigned int parsed_size;
@@ -389,7 +379,9 @@ _bfd_generic_read_ar_hdr (abfd)
        bfd_set_error (bfd_error_no_more_archived_files);
       return NULL;
     }
-  if (strncmp (hdr.ar_fmag, ARFMAG, 2))
+  if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
+      && (mag == NULL
+         || strncmp (hdr.ar_fmag, mag, 2) != 0))
     {
       bfd_set_error (bfd_error_malformed_archive);
       return NULL;
@@ -404,7 +396,7 @@ _bfd_generic_read_ar_hdr (abfd)
     }
 
   /* Extract the filename from the archive - there are two ways to
-     specify an extendend name table, either the first char of the
+     specify an extended name table, either the first char of the
      name is a space, or it's a slash.  */
   if ((hdr.ar_name[0] == '/'
        || (hdr.ar_name[0] == ' '
@@ -420,8 +412,10 @@ _bfd_generic_read_ar_hdr (abfd)
     }
   /* BSD4.4-style long filename.
      Only implemented for reading, so far! */
-  else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1'
-          && hdr.ar_name[2] == '/' && isdigit (hdr.ar_name[3]))
+  else if (hdr.ar_name[0] == '#'
+          && hdr.ar_name[1] == '1'
+          && hdr.ar_name[2] == '/'
+          && isdigit ((unsigned char) hdr.ar_name[3]))
     {
       /* BSD-4.4 extended name */
       namelen = atoi (&hdr.ar_name[3]);
@@ -430,10 +424,7 @@ _bfd_generic_read_ar_hdr (abfd)
 
       allocptr = bfd_zalloc (abfd, allocsize);
       if (allocptr == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return NULL;
-       }
+       return NULL;
       filename = (allocptr
                  + sizeof (struct areltdata)
                  + sizeof (struct ar_hdr));
@@ -451,19 +442,22 @@ _bfd_generic_read_ar_hdr (abfd)
         Note:  The SYSV format (terminated by '/') allows embedded
         spaces, so only look for ' ' if we don't find '/'. */
 
-      namelen = 0;
-      while (hdr.ar_name[namelen] != '\0' &&
-            hdr.ar_name[namelen] != '/')
+      char *e;
+      e = memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
+      if (e == NULL)
        {
-         namelen++;
-         if (namelen == (unsigned) ar_maxnamelen (abfd))
-           {
-             namelen = 0;
-             while (hdr.ar_name[namelen] != ' '
-                    && namelen < (unsigned) ar_maxnamelen (abfd))
-               namelen++;
-             break;
-           }
+          e = memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
+         if (e == NULL)
+            e = memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
+       }
+
+      if (e != NULL)
+       namelen = e - hdr.ar_name;
+      else
+       {
+         /* If we didn't find a termination character, then the name
+            must be the entire field.  */
+         namelen = ar_maxnamelen (abfd);
        }
 
       allocsize += namelen + 1;
@@ -473,10 +467,7 @@ _bfd_generic_read_ar_hdr (abfd)
     {
       allocptr = bfd_zalloc (abfd, allocsize);
       if (allocptr == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return NULL;
-       }
+       return NULL;
     }
 
   ared = (struct areltdata *) allocptr;
@@ -541,23 +532,13 @@ _bfd_get_elt_at_filepos (archive, filepos)
   return NULL;
 }
 
-/*
-FUNCTION
-       bfd_get_elt_at_index
-
-SYNOPSIS
-       bfd *bfd_get_elt_at_index(bfd *archive, int index);
-
-DESCRIPTION
-       Return the BFD which is referenced by the symbol in @var{archive}
-       indexed by @var{index}.  @var{index} should have been returned by
-       <<bfd_get_next_mapent>> (q.v.).
+/* Return the BFD which is referenced by the symbol in ABFD indexed by
+   INDEX.  INDEX should have been returned by bfd_get_next_mapent.  */
 
-*/
 bfd *
-bfd_get_elt_at_index (abfd, index)
+_bfd_generic_get_elt_at_index (abfd, index)
      bfd *abfd;
-     int index;
+     symindex index;
 {
   carsym *entry;
 
@@ -627,8 +608,11 @@ const bfd_target *
 bfd_generic_archive_p (abfd)
      bfd *abfd;
 {
+  struct artdata *tdata_hold;
   char armag[SARMAG + 1];
 
+  tdata_hold = abfd->tdata.aout_ar_data;
+
   if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG)
     {
       if (bfd_get_error () != bfd_error_system_call)
@@ -651,10 +635,7 @@ bfd_generic_archive_p (abfd)
                              bfd_zalloc (abfd, sizeof (struct artdata)));
 
   if (bfd_ardata (abfd) == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   bfd_ardata (abfd)->first_file_filepos = SARMAG;
   bfd_ardata (abfd)->cache = NULL;
@@ -666,14 +647,18 @@ bfd_generic_archive_p (abfd)
   if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd)))
     {
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = NULL;
+      abfd->tdata.aout_ar_data = tdata_hold;
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
   if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
     {
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = NULL;
+      abfd->tdata.aout_ar_data = tdata_hold;
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
@@ -682,9 +667,11 @@ bfd_generic_archive_p (abfd)
       bfd *first;
 
       /* This archive has a map, so we may presume that the contents
-        are object files.  Make sure that the first file in the
-        archive can be recognized as an object file for this target.
-        If not, assume that this is the wrong format.
+        are object files.  Make sure that if the first file in the
+        archive can be recognized as an object file, it is for this
+        target.  If not, assume that this is the wrong format.  If
+        the first file is not an object file, somebody is doing
+        something weird, and we permit it so that ar -t will work.
 
         This is done because any normal format will recognize any
         normal archive, regardless of the format of the object files.
@@ -697,22 +684,13 @@ bfd_generic_archive_p (abfd)
 
          first->target_defaulted = false;
          fail = false;
-         if (! bfd_check_format (first, bfd_object))
-           fail = true;
-         else if (first->xvec != abfd->xvec)
-           {
-             bfd_set_error (bfd_error_wrong_format);
-             fail = true;
-           }
-         if (fail)
+         if (bfd_check_format (first, bfd_object)
+             && first->xvec != abfd->xvec)
            {
-             bfd_error_type err;
-
-             err = bfd_get_error ();
              (void) bfd_close (first);
              bfd_release (abfd, bfd_ardata (abfd));
-             abfd->tdata.aout_ar_data = NULL;
-             bfd_set_error (err);
+             abfd->tdata.aout_ar_data = tdata_hold;
+             bfd_set_error (bfd_error_wrong_format);
              return NULL;
            }
 
@@ -763,10 +741,7 @@ do_slurp_bsd_armap (abfd)
 
   raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
   if (raw_armap == (bfd_byte *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size)
     {
@@ -796,10 +771,7 @@ do_slurp_bsd_armap (abfd)
                                          (ardata->symdef_count
                                           * sizeof (carsym)));
   if (!ardata->symdefs)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   for (counter = 0, set = ardata->symdefs;
        counter < ardata->symdef_count;
@@ -814,7 +786,7 @@ do_slurp_bsd_armap (abfd)
   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
   /* FIXME, we should provide some way to free raw_ardata when
      we are done using the strings from it.  For now, it seems
-     to be allocated on an obstack anyway... */
+     to be allocated on an objalloc anyway... */
   bfd_has_map (abfd) = true;
   return true;
 }
@@ -860,7 +832,9 @@ do_slurp_coff_armap (abfd)
      little, because our tools changed.  Here's a horrible hack to clean
      up the crap.  */
 
-  if (stringsize > 0xfffff)
+  if (stringsize > 0xfffff
+      && bfd_get_arch (abfd) == bfd_arch_i960
+      && bfd_get_flavour (abfd) == bfd_target_coff_flavour)
     {
       /* This looks dangerous, let's do it the other way around */
       nsymz = bfd_getl32 ((PTR) int_buf);
@@ -877,20 +851,14 @@ do_slurp_coff_armap (abfd)
 
   ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
   if (ardata->symdefs == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   carsyms = ardata->symdefs;
   stringbase = ((char *) ardata->symdefs) + carsym_size;
 
   /* Allocate and read in the raw offsets. */
   raw_armap = (int *) bfd_alloc (abfd, ptrsize);
   if (raw_armap == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto release_symdefs;
-    }
+    goto release_symdefs;
   if (bfd_read ((PTR) raw_armap, 1, ptrsize, abfd) != ptrsize
       || bfd_read ((PTR) stringbase, 1, stringsize, abfd) != stringsize)
     {
@@ -926,10 +894,10 @@ do_slurp_coff_armap (abfd)
 
     bfd_seek (abfd,   ardata->first_file_filepos, SEEK_SET);
     tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd);
-    if (tmp != NULL) 
+    if (tmp != NULL)
       {
        if (tmp->arch_header[0] == '/'
-           && tmp->arch_header[1] == ' ') 
+           && tmp->arch_header[1] == ' ')
          {
            ardata->first_file_filepos +=
              (tmp->parsed_size + sizeof(struct ar_hdr) + 1) & ~1;
@@ -970,6 +938,12 @@ bfd_slurp_armap (abfd)
     return do_slurp_bsd_armap (abfd);
   else if (!strncmp (nextname, "/               ", 16))
     return do_slurp_coff_armap (abfd);
+  else if (!strncmp (nextname, "/SYM64/         ", 16))
+    {
+      /* Irix 6 archive--must be recognized by code in elf64-mips.c.  */
+      bfd_set_error (bfd_error_wrong_format);
+      return false;
+    }
 
   bfd_has_map (abfd) = false;
   return true;
@@ -1022,7 +996,6 @@ bfd_slurp_bsd_armap_f2 (abfd)
   raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size);
   if (raw_armap == NULL)
     {
-      bfd_set_error (bfd_error_no_memory);
     byebye:
       bfd_release (abfd, (PTR) mapdata);
       return false;
@@ -1060,10 +1033,7 @@ bfd_slurp_bsd_armap_f2 (abfd)
                                          (ardata->symdef_count
                                           * BSD_SYMDEF_SIZE));
   if (!ardata->symdefs)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   for (counter = 0, set = ardata->symdefs;
        counter < ardata->symdef_count;
@@ -1078,7 +1048,7 @@ bfd_slurp_bsd_armap_f2 (abfd)
   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
   /* FIXME, we should provide some way to free raw_ardata when
      we are done using the strings from it.  For now, it seems
-     to be allocated on an obstack anyway... */
+     to be allocated on an objalloc anyway... */
   bfd_has_map (abfd) = true;
   return true;
 }
@@ -1124,7 +1094,6 @@ _bfd_slurp_extended_name_table (abfd)
        bfd_zalloc (abfd, namedata->parsed_size);
       if (bfd_ardata (abfd)->extended_names == NULL)
        {
-         bfd_set_error (bfd_error_no_memory);
        byebye:
          bfd_release (abfd, (PTR) namedata);
          return false;
@@ -1162,7 +1131,7 @@ _bfd_slurp_extended_name_table (abfd)
        (bfd_ardata (abfd)->first_file_filepos) % 2;
 
       /* FIXME, we can't release namedata here because it was allocated
-        below extended_names on the obstack... */
+        below extended_names on the objalloc... */
       /* bfd_release (abfd, namedata); */
     }
   return true;
@@ -1198,10 +1167,7 @@ normalize (abfd, file)
 
   copy = (char *) bfd_alloc (abfd, last - first + 1);
   if (copy == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   memcpy (copy, first, last - first);
   copy[last - first] = 0;
@@ -1212,11 +1178,22 @@ normalize (abfd, file)
 #else
 static const char *
 normalize (abfd, file)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      const char *file;
 {
   const char *filename = strrchr (file, '/');
 
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
+    char *bslash = strrchr (file, '\\');
+    if (filename == NULL || (bslash != NULL && bslash > filename))
+      filename = bslash;
+    if (filename == NULL && file[0] != '\0' && file[1] == ':')
+      filename = file + 1;
+  }
+#endif
   if (filename != (char *) NULL)
     filename++;
   else
@@ -1321,10 +1298,7 @@ _bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen)
 
   *tabloc = bfd_zalloc (abfd, total_namelen);
   if (*tabloc == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   *tablen = total_namelen;
   strptr = *tabloc;
@@ -1377,21 +1351,58 @@ _bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen)
 \f
 /** A couple of functions for creating ar_hdrs */
 
+#ifdef HPUX_LARGE_AR_IDS
+/* Function to encode large UID/GID values according to HP.  */
+static void
+hpux_uid_gid_encode (str, id)
+     char str[6];
+     long int id;
+{
+  int cnt;
+
+  str[5] = '@' + (id & 3);
+  id >>= 2;
+
+  for (cnt = 4; cnt >= 0; ++cnt, id >>= 6)
+    str[cnt] = ' ' + (id & 0x3f);
+}
+#endif /* HPUX_LARGE_AR_IDS */
+
+#ifndef HAVE_GETUID
+#define getuid() 0
+#endif
+
+#ifndef HAVE_GETGID
+#define getgid() 0
+#endif
+
 /* Takes a filename, returns an arelt_data for it, or NULL if it can't
    make one.  The filename must refer to a filename in the filesystem.
-   The filename field of the ar_hdr will NOT be initialized */
+   The filename field of the ar_hdr will NOT be initialized.  If member
+   is set, and it's an in-memory bfd, we fake it. */
 
 static struct areltdata *
-bfd_ar_hdr_from_filesystem (abfd, filename)
+bfd_ar_hdr_from_filesystem (abfd, filename, member)
      bfd *abfd;
      const char *filename;
+     bfd *member;
 {
   struct stat status;
   struct areltdata *ared;
   struct ar_hdr *hdr;
   char *temp, *temp1;
 
-  if (stat (filename, &status) != 0)
+  if (member && (member->flags & BFD_IN_MEMORY) != 0)
+    {
+      /* Assume we just "made" the member, and fake it */
+      struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream;
+      time(&status.st_mtime);
+      status.st_uid = getuid();
+      status.st_gid = getgid();
+      status.st_mode = 0644;
+      status.st_size = bim->size;
+    }
+  else if (stat (filename, &status) != 0)
     {
       bfd_set_error (bfd_error_system_call);
       return NULL;
@@ -1400,10 +1411,7 @@ bfd_ar_hdr_from_filesystem (abfd, filename)
   ared = (struct areltdata *) bfd_zalloc (abfd, sizeof (struct ar_hdr) +
                                          sizeof (struct areltdata));
   if (ared == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
   hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
 
   /* ar headers are space padded, not null padded! */
@@ -1413,7 +1421,21 @@ bfd_ar_hdr_from_filesystem (abfd, filename)
 
   /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
   sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime);
-  sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid);
+#ifdef HPUX_LARGE_AR_IDS
+  /* HP has a very "special" way to handle UID/GID's with numeric values
+     > 99999.  */
+  if (status.st_uid > 99999)
+    hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_uid);
+  else
+#endif
+    sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid);
+#ifdef HPUX_LARGE_AR_IDS
+  /* HP has a very "special" way to handle UID/GID's with numeric values
+     > 99999.  */
+  if (status.st_gid > 99999)
+    hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_gid);
+  else
+#endif
   sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid);
   sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode);
   sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size);
@@ -1439,12 +1461,14 @@ bfd_ar_hdr_from_filesystem (abfd, filename)
     a strong stomach to write this, and it does, but it takes even a
     stronger stomach to try to code around such a thing!  */
 
+struct ar_hdr *bfd_special_undocumented_glue PARAMS ((bfd *, const char *));
+
 struct ar_hdr *
 bfd_special_undocumented_glue (abfd, filename)
      bfd *abfd;
-     char *filename;
+     const char *filename;
 {
-  struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename);
+  struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename, 0);
   if (ar_elt == NULL)
     return NULL;
   return (struct ar_hdr *) ar_elt->arch_header;
@@ -1471,10 +1495,30 @@ bfd_generic_stat_arch_elt (abfd, buf)
 #define foo(arelt, stelt, size)  \
   buf->stelt = strtol (hdr->arelt, &aloser, size); \
   if (aloser == hdr->arelt) return -1;
+  /* Some platforms support special notations for large IDs.  */
+#ifdef HPUX_LARGE_AR_IDS
+# define foo2(arelt, stelt, size) \
+  if (hdr->arelt[5] == ' ') { foo (arelt, stelt, size); } \
+  else { \
+    int cnt; \
+    for (buf->stelt = cnt = 0; cnt < 5; ++cnt) \
+      { \
+       if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f) \
+         return -1; \
+       buf->stelt <<= 6; \
+       buf->stelt += hdr->arelt[cnt] - ' '; \
+      } \
+    if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3) return -1; \
+    buf->stelt <<= 2; \
+    buf->stelt += hdr->arelt[5] - '@'; \
+  }
+#else
+# define foo2(arelt, stelt, size) foo (arelt, stelt, size)
+#endif
 
   foo (ar_date, st_mtime, 10);
-  foo (ar_uid, st_uid, 10);
-  foo (ar_gid, st_gid, 10);
+  foo2 (ar_uid, st_uid, 10);
+  foo2 (ar_gid, st_gid, 10);
   foo (ar_mode, st_mode, 8);
 
   buf->st_size = arch_eltdata (abfd)->parsed_size;
@@ -1533,6 +1577,17 @@ bfd_bsd_truncate_arname (abfd, pathname, arhdr)
   CONST char *filename = strrchr (pathname, '/');
   int maxlen = ar_maxnamelen (abfd);
 
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
+    char *bslash = strrchr (pathname, '\\');
+    if (filename == NULL || (bslash != NULL && bslash > filename))
+      filename = bslash;
+    if (filename == NULL && pathname[0] != '\0' && pathname[1] == ':')
+      filename = pathname + 1;
+  }
+#endif
+
   if (filename == NULL)
     filename = pathname;
   else
@@ -1573,6 +1628,17 @@ bfd_gnu_truncate_arname (abfd, pathname, arhdr)
   CONST char *filename = strrchr (pathname, '/');
   int maxlen = ar_maxnamelen (abfd);
 
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
+    char *bslash = strrchr (pathname, '\\');
+    if (filename == NULL || (bslash != NULL && bslash > filename))
+      filename = bslash;
+    if (filename == NULL && pathname[0] != '\0' && pathname[1] == ':')
+      filename = pathname + 1;
+  }
+#endif
+
   if (filename == NULL)
     filename = pathname;
   else
@@ -1626,7 +1692,7 @@ _bfd_write_archive_contents (arch)
       if (!current->arelt_data)
        {
          current->arelt_data =
-           (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
+           (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename, current);
          if (!current->arelt_data)
            return false;
 
@@ -1739,7 +1805,7 @@ _bfd_write_archive_contents (arch)
          if (bfd_update_armap_timestamp (arch))
            break;
          (*_bfd_error_handler)
-           ("Warning: writing archive was slow: rewriting timestamp\n");
+           (_("Warning: writing archive was slow: rewriting timestamp\n"));
        }
       while (++tries < 6);
     }
@@ -1770,15 +1836,15 @@ _bfd_compute_and_write_armap (arch, elength)
     elength += sizeof (struct ar_hdr);
   elength += elength % 2;
 
-  map = (struct orl *) malloc (orl_max * sizeof (struct orl));
+  map = (struct orl *) bfd_malloc (orl_max * sizeof (struct orl));
   if (map == NULL)
-    goto no_memory_return;
+    goto error_return;
 
-  /* We put the symbol names on the arch obstack, and then discard
+  /* We put the symbol names on the arch objalloc, and then discard
      them when done.  */
   first_name = bfd_alloc (arch, 1);
   if (first_name == NULL)
-    goto no_memory_return;
+    goto error_return;
 
   /* Drop all the files called __.SYMDEF, we're going to make our
      own */
@@ -1809,9 +1875,9 @@ _bfd_compute_and_write_armap (arch, elength)
                  if (syms_max > 0)
                    free (syms);
                  syms_max = storage;
-                 syms = (asymbol **) malloc ((size_t) syms_max);
+                 syms = (asymbol **) bfd_malloc ((size_t) syms_max);
                  if (syms == NULL)
-                   goto no_memory_return;
+                   goto error_return;
                }
              symcount = bfd_canonicalize_symtab (current, syms);
              if (symcount < 0)
@@ -1836,11 +1902,11 @@ _bfd_compute_and_write_armap (arch, elength)
                      if (orl_count == orl_max)
                        {
                          orl_max *= 2;
-                         new_map = ((struct orl *)
-                                    realloc ((PTR) map,
-                                             orl_max * sizeof (struct orl)));
+                         new_map =
+                           ((struct orl *)
+                            bfd_realloc (map, orl_max * sizeof (struct orl)));
                          if (new_map == (struct orl *) NULL)
-                           goto no_memory_return;
+                           goto error_return;
 
                          map = new_map;
                        }
@@ -1850,10 +1916,10 @@ _bfd_compute_and_write_armap (arch, elength)
                                             bfd_alloc (arch,
                                                        sizeof (char *)));
                      if (map[orl_count].name == NULL)
-                       goto no_memory_return;
+                       goto error_return;
                      *(map[orl_count].name) = bfd_alloc (arch, namelen + 1);
                      if (*(map[orl_count].name) == NULL)
-                       goto no_memory_return;
+                       goto error_return;
                      strcpy (*(map[orl_count].name), syms[src_count]->name);
                      (map[orl_count]).pos = (file_ptr) current;
                      (map[orl_count]).namidx = stridx;
@@ -1884,9 +1950,6 @@ _bfd_compute_and_write_armap (arch, elength)
 
   return ret;
 
- no_memory_return:
-  bfd_set_error (bfd_error_no_memory);
-
  error_return:
   if (syms_max > 0)
     free (syms);
@@ -2008,7 +2071,7 @@ _bfd_archive_bsd_update_armap_timestamp (arch)
   bfd_flush (arch);
   if (bfd_stat (arch, &archstat) == -1)
     {
-      perror ("Reading archive file mod timestamp");
+      perror (_("Reading archive file mod timestamp"));
       return true;             /* Can't read mod time for some reason */
     }
   if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp)
@@ -2032,7 +2095,7 @@ _bfd_archive_bsd_update_armap_timestamp (arch)
          != sizeof (hdr.ar_date)))
     {
       /* FIXME: bfd can't call perror.  */
-      perror ("Writing updated armap timestamp");
+      perror (_("Writing updated armap timestamp"));
       return true;             /* Some error while writing */
     }
 
This page took 0.033067 seconds and 4 git commands to generate.