* srec.c (srec_write_symbols): Use bfd_is_local_label rather than
[deliverable/binutils-gdb.git] / bfd / archive.c
index 50421ca32bfdd975d728b58c028358deacdc3906..10bf43c2b7f4a602d45f3297f44e8c9191961c09 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, 1998
+   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.
@@ -16,7 +17,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
 @setfilename archive-info
@@ -142,12 +143,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
 
@@ -175,15 +173,9 @@ static char *get_extended_arelt_filename PARAMS ((bfd *arch,
                                                  const char *name));
 static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd));
 static boolean do_slurp_coff_armap PARAMS ((bfd *abfd));
-static const char *normalize PARAMS ((const char *file));
-static boolean bfd_construct_extended_name_table PARAMS ((bfd *abfd,
-                                                         char **tabloc,
-                                                         unsigned int *));
+static const char *normalize PARAMS ((bfd *, const char *file));
 static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
                                                             const char *));
-static boolean compute_and_write_armap PARAMS ((bfd *arch,
-                                               unsigned int elength));
-static boolean bsd_update_armap_timestamp PARAMS ((bfd *arch));
 \f
 boolean
 _bfd_generic_mkarchive (abfd)
@@ -193,10 +185,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;
@@ -242,7 +231,9 @@ bfd_get_next_mapent (abfd, prev, entry)
 
   if (prev == BFD_NO_MORE_SYMBOLS)
     prev = 0;
-  else if (++prev >= bfd_ardata (abfd)->symdef_count)
+  else
+    ++prev;
+  if (prev >= bfd_ardata (abfd)->symdef_count)
     return BFD_NO_MORE_SYMBOLS;
 
   *entry = (bfd_ardata (abfd)->symdefs + prev);
@@ -255,15 +246,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);
 }
 
 /*
@@ -314,10 +297,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,14 +349,21 @@ get_extended_arelt_filename (arch, name)
    could have been moved arbitrarily.
 */
 
-struct areltdata *
-_bfd_snarf_ar_hdr (abfd)
+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,10 +376,13 @@ _bfd_snarf_ar_hdr (abfd)
   if (bfd_read ((PTR) hdrp, 1, sizeof (struct ar_hdr), abfd)
       != sizeof (struct ar_hdr))
     {
-      bfd_set_error (bfd_error_no_more_archived_files);
+      if (bfd_get_error () != bfd_error_system_call)
+       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;
@@ -423,8 +413,10 @@ _bfd_snarf_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]);
@@ -433,16 +425,14 @@ _bfd_snarf_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));
       if (bfd_read (filename, 1, namelen, abfd) != namelen)
        {
-         bfd_set_error (bfd_error_no_more_archived_files);
+         if (bfd_get_error () != bfd_error_system_call)
+           bfd_set_error (bfd_error_no_more_archived_files);
          return NULL;
        }
       filename[namelen] = '\0';
@@ -453,21 +443,21 @@ _bfd_snarf_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)
+       {
+         bfd_set_error (bfd_error_malformed_archive);
+         return NULL;
        }
 
+      namelen = e - hdr.ar_name;
       allocsize += namelen + 1;
     }
 
@@ -475,10 +465,7 @@ _bfd_snarf_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;
@@ -498,7 +485,7 @@ _bfd_snarf_ar_hdr (abfd)
       ared->filename[namelen] = '\0';
     }
 
-  return ared;
+  return (PTR) ared;
 }
 \f
 /* This is an internal function; it's mainly used when indexing
@@ -520,7 +507,7 @@ _bfd_get_elt_at_filepos (archive, filepos)
   if (0 > bfd_seek (archive, filepos, SEEK_SET))
     return NULL;
 
-  if ((new_areldata = _bfd_snarf_ar_hdr (archive)) == NULL)
+  if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL)
     return NULL;
 
   n_nfd = _bfd_create_empty_archive_element_shell (archive);
@@ -543,23 +530,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;
 
@@ -625,15 +602,19 @@ bfd_generic_openr_next_archived_file (archive, last_file)
 }
 
 
-bfd_target *
+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)
     {
-      bfd_set_error (bfd_error_wrong_format);
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
@@ -652,10 +633,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;
@@ -667,17 +645,58 @@ 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;
     }
 
+  if (bfd_has_map (abfd))
+    {
+      bfd *first;
+
+      /* This archive has a map, so we may presume that the contents
+        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.
+        We do accept an empty archive.  */
+
+      first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
+      if (first != NULL)
+       {
+         boolean fail;
+
+         first->target_defaulted = false;
+         fail = false;
+         if (bfd_check_format (first, bfd_object)
+             && first->xvec != abfd->xvec)
+           {
+             (void) bfd_close (first);
+             bfd_release (abfd, bfd_ardata (abfd));
+             abfd->tdata.aout_ar_data = tdata_hold;
+             bfd_set_error (bfd_error_wrong_format);
+             return NULL;
+           }
+
+         /* We ought to close first here, but we can't, because we
+             have no way to remove it from the archive cache.  FIXME.  */
+       }
+    }
+
   return abfd->xvec;
 }
 
@@ -712,7 +731,7 @@ do_slurp_bsd_armap (abfd)
   unsigned int parsed_size;
   carsym *set;
 
-  mapdata = _bfd_snarf_ar_hdr (abfd);
+  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
   if (mapdata == NULL)
     return false;
   parsed_size = mapdata->parsed_size;
@@ -720,14 +739,12 @@ 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)
     {
-      bfd_set_error (bfd_error_malformed_archive);
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_malformed_archive);
     byebye:
       bfd_release (abfd, (PTR) raw_armap);
       return false;
@@ -752,10 +769,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;
@@ -770,7 +784,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;
 }
@@ -792,7 +806,7 @@ do_slurp_coff_armap (abfd)
   char int_buf[sizeof (long)];
   unsigned int carsym_size, ptrsize, i;
 
-  mapdata = _bfd_snarf_ar_hdr (abfd);
+  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
   if (mapdata == NULL)
     return false;
   parsed_size = mapdata->parsed_size;
@@ -800,7 +814,8 @@ do_slurp_coff_armap (abfd)
 
   if (bfd_read ((PTR) int_buf, 1, 4, abfd) != 4)
     {
-      bfd_set_error (bfd_error_malformed_archive);
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_malformed_archive);
       return false;
     }
   /* It seems that all numeric information in a coff archive is always
@@ -815,7 +830,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);
@@ -832,24 +849,19 @@ 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)
     {
-      bfd_set_error (bfd_error_malformed_archive);
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_malformed_archive);
       goto release_raw_armap;
     }
 
@@ -869,8 +881,29 @@ do_slurp_coff_armap (abfd)
   /* Pad to an even boundary if you have to */
   ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
 
+
   bfd_has_map (abfd) = true;
   bfd_release (abfd, (PTR) raw_armap);
+
+
+  /* Check for a second archive header (as used by PE) */
+  {
+    struct areltdata *tmp;
+
+    bfd_seek (abfd,   ardata->first_file_filepos, SEEK_SET);
+    tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+    if (tmp != NULL) 
+      {
+       if (tmp->arch_header[0] == '/'
+           && tmp->arch_header[1] == ' ') 
+         {
+           ardata->first_file_filepos +=
+             (tmp->parsed_size + sizeof(struct ar_hdr) + 1) & ~1;
+         }
+       bfd_release (abfd, tmp);
+      }
+  }
+
   return true;
 
 release_raw_armap:
@@ -895,12 +928,20 @@ bfd_slurp_armap (abfd)
   if (i != 16)
     return false;
 
-  bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR);
+  if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+    return false;
 
-  if (!strncmp (nextname, "__.SYMDEF       ", 16))
+  if (!strncmp (nextname, "__.SYMDEF       ", 16)
+      || !strncmp (nextname, "__.SYMDEF/      ", 16)) /* old Linux archives */
     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;
@@ -933,9 +974,11 @@ bfd_slurp_bsd_armap_f2 (abfd)
     return false;
 
   /* The archive has at least 16 bytes in it */
-  bfd_seek (abfd, -16L, SEEK_CUR);
+  if (bfd_seek (abfd, -16L, SEEK_CUR) != 0)
+    return false;
 
-  if (!strncmp (nextname, "__.SYMDEF       ", 16))
+  if (!strncmp (nextname, "__.SYMDEF       ", 16)
+      || !strncmp (nextname, "__.SYMDEF/      ", 16)) /* old Linux archives */
     return do_slurp_bsd_armap (abfd);
 
   if (strncmp (nextname, "/               ", 16))
@@ -944,14 +987,13 @@ bfd_slurp_bsd_armap_f2 (abfd)
       return true;
     }
 
-  mapdata = _bfd_snarf_ar_hdr (abfd);
+  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
   if (mapdata == NULL)
     return false;
 
   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;
@@ -960,7 +1002,8 @@ bfd_slurp_bsd_armap_f2 (abfd)
   if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) !=
       mapdata->parsed_size)
     {
-      bfd_set_error (bfd_error_malformed_archive);
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_malformed_archive);
     byebyebye:
       bfd_release (abfd, (PTR) raw_armap);
       goto byebye;
@@ -988,10 +1031,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;
@@ -1006,7 +1046,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;
 }
@@ -1031,10 +1071,11 @@ _bfd_slurp_extended_name_table (abfd)
 
   /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
      we probably don't want to return true.  */
+  bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET);
   if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16)
     {
-
-      bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR);
+      if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+       return false;
 
       if (strncmp (nextname, "ARFILENAMES/    ", 16) != 0 &&
          strncmp (nextname, "//              ", 16) != 0)
@@ -1043,7 +1084,7 @@ _bfd_slurp_extended_name_table (abfd)
          return true;
        }
 
-      namedata = _bfd_snarf_ar_hdr (abfd);
+      namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
       if (namedata == NULL)
        return false;
 
@@ -1051,7 +1092,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;
@@ -1060,7 +1100,8 @@ _bfd_slurp_extended_name_table (abfd)
       if (bfd_read ((PTR) bfd_ardata (abfd)->extended_names, 1,
                    namedata->parsed_size, abfd) != namedata->parsed_size)
        {
-         bfd_set_error (bfd_error_malformed_archive);
+         if (bfd_get_error () != bfd_error_system_call)
+           bfd_set_error (bfd_error_malformed_archive);
          bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names));
          bfd_ardata (abfd)->extended_names = NULL;
          goto byebye;
@@ -1069,13 +1110,17 @@ _bfd_slurp_extended_name_table (abfd)
       /* Since the archive is supposed to be printable if it contains
         text, the entries in the list are newline-padded, not null
         padded. In SVR4-style archives, the names also have a
-        trailing '/'.  We'll fix both problems here..  */
+        trailing '/'.  DOS/NT created archive often have \ in them
+        We'll fix all problems here..  */
       {
        char *temp = bfd_ardata (abfd)->extended_names;
        char *limit = temp + namedata->parsed_size;
-       for (; temp < limit; ++temp)
+       for (; temp < limit; ++temp) {
          if (*temp == '\012')
            temp[temp[-1] == '/' ? -1 : 0] = '\0';
+         if (*temp == '\\')
+           *temp = '/';
+       }
       }
 
       /* Pad to an even boundary if you have to */
@@ -1084,7 +1129,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;
@@ -1095,7 +1140,8 @@ _bfd_slurp_extended_name_table (abfd)
 /* Return a copy of the stuff in the filename between any :]> and a
    semicolon */
 static const char *
-normalize (file)
+normalize (abfd, file)
+     bfd *abfd;
      const char *file;
 {
   CONST char *first;
@@ -1117,10 +1163,9 @@ normalize (file)
       first--;
     }
 
-
-  copy = malloc (last - first + 1);
-  if (!copy)
-    return copy;
+  copy = (char *) bfd_alloc (abfd, last - first + 1);
+  if (copy == NULL)
+    return NULL;
 
   memcpy (copy, first, last - first);
   copy[last - first] = 0;
@@ -1130,10 +1175,11 @@ normalize (file)
 
 #else
 static const char *
-normalize (file)
+normalize (abfd, file)
+     bfd *abfd;
      const char *file;
 {
-  CONST char *filename = strrchr (file, '/');
+  const char *filename = strrchr (file, '/');
 
   if (filename != (char *) NULL)
     filename++;
@@ -1143,6 +1189,32 @@ normalize (file)
 }
 #endif
 
+/* Build a BFD style extended name table.  */
+
+boolean
+_bfd_archive_bsd_construct_extended_name_table (abfd, tabloc, tablen, name)
+     bfd *abfd;
+     char **tabloc;
+     bfd_size_type *tablen;
+     const char **name;
+{
+  *name = "ARFILENAMES/";
+  return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);
+}
+
+/* Build an SVR4 style extended name table.  */
+
+boolean
+_bfd_archive_coff_construct_extended_name_table (abfd, tabloc, tablen, name)
+     bfd *abfd;
+     char **tabloc;
+     bfd_size_type *tablen;
+     const char **name;
+{
+  *name = "//";
+  return _bfd_construct_extended_name_table (abfd, true, tabloc, tablen);
+}
+
 /* Follows archive_head and produces an extended name table if
    necessary.  Returns (in tabloc) a pointer to an extended name
    table, and in tablen the length of the table.  If it makes an entry
@@ -1151,11 +1223,12 @@ normalize (file)
    something went wrong.  A successful return may still involve a
    zero-length tablen!  */
 
-static boolean
-bfd_construct_extended_name_table (abfd, tabloc, tablen)
+boolean
+_bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen)
      bfd *abfd;
+     boolean trailing_slash;
      char **tabloc;
-     unsigned int *tablen;
+     bfd_size_type *tablen;
 {
   unsigned int maxname = abfd->xvec->ar_max_namelen;
   unsigned int total_namelen = 0;
@@ -1167,17 +1240,44 @@ bfd_construct_extended_name_table (abfd, tabloc, tablen)
   /* Figure out how long the table should be */
   for (current = abfd->archive_head; current != NULL; current = current->next)
     {
-      CONST char *normal = normalize (current->filename);
+      const char *normal;
       unsigned int thislen;
 
-      if (!normal)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+      normal = normalize (current, current->filename);
+      if (normal == NULL)
+       return false;
+
       thislen = strlen (normal);
+
+      if (thislen > maxname
+         && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
+       thislen = maxname;
+
       if (thislen > maxname)
-       total_namelen += thislen + 1;   /* leave room for \n */
+       {
+         /* Add one to leave room for \n.  */
+         total_namelen += thislen + 1;
+         if (trailing_slash)
+           {
+             /* Leave room for trailing slash.  */
+             ++total_namelen;
+           }
+       }
+      else
+       {
+         struct ar_hdr *hdr = arch_hdr (current);
+         if (strncmp (normal, hdr->ar_name, thislen) != 0
+             || (thislen < sizeof hdr->ar_name
+                 && hdr->ar_name[thislen] != ar_padchar (current)))
+           {
+             /* Must have been using extended format even though it
+                didn't need to.  Fix it to use normal format.  */
+             memcpy (hdr->ar_name, normal, thislen);
+             if (thislen < maxname
+                 || (thislen == maxname && thislen < sizeof hdr->ar_name))
+               hdr->ar_name[thislen] = ar_padchar (current);
+           }
+       }
     }
 
   if (total_namelen == 0)
@@ -1185,10 +1285,7 @@ bfd_construct_extended_name_table (abfd, 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;
@@ -1196,14 +1293,13 @@ bfd_construct_extended_name_table (abfd, tabloc, tablen)
   for (current = abfd->archive_head; current != NULL; current =
        current->next)
     {
-      CONST char *normal = normalize (current->filename);
+      const char *normal;
       unsigned int thislen;
 
-      if (!normal)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+      normal = normalize (current, current->filename);
+      if (normal == NULL)
+       return false;
+
       thislen = strlen (normal);
       if (thislen > maxname)
        {
@@ -1212,7 +1308,13 @@ bfd_construct_extended_name_table (abfd, tabloc, tablen)
             generalise this hack. */
          struct ar_hdr *hdr = arch_hdr (current);
          strcpy (strptr, normal);
-         strptr[thislen] = '\012';
+         if (! trailing_slash)
+           strptr[thislen] = '\012';
+         else
+           {
+             strptr[thislen] = '/';
+             strptr[thislen + 1] = '\012';
+           }
          hdr->ar_name[0] = ar_padchar (current);
          /* We know there will always be enough room (one of the few
             cases where you may safely use sprintf). */
@@ -1226,6 +1328,8 @@ bfd_construct_extended_name_table (abfd, tabloc, tablen)
                *temp = ' ';
          }
          strptr += thislen + 1;
+         if (trailing_slash)
+           ++strptr;
        }
     }
 
@@ -1257,10 +1361,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! */
@@ -1296,10 +1397,12 @@ 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);
   if (ar_elt == NULL)
@@ -1351,16 +1454,31 @@ bfd_dont_truncate_arname (abfd, pathname, arhdr)
      intel's release is out the door. */
 
   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
-  int length;
-  CONST char *filename = normalize (pathname);
-  int maxlen = ar_maxnamelen (abfd);
+  size_t length;
+  const char *filename;
+  size_t maxlen = ar_maxnamelen (abfd);
+
+  if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
+    {
+      bfd_bsd_truncate_arname (abfd, pathname, arhdr);
+      return;
+    }
+
+  filename = normalize (abfd, pathname);
+  if (filename == NULL)
+    {
+      /* FIXME */
+      abort ();
+    }
 
   length = strlen (filename);
 
   if (length <= maxlen)
     memcpy (hdr->ar_name, filename, length);
 
-  if (length < maxlen)
+  /* Add the padding character if there is room for it.  */
+  if (length < maxlen
+      || (length == maxlen && length < sizeof hdr->ar_name))
     (hdr->ar_name)[length] = ar_padchar (abfd);
 }
 
@@ -1447,9 +1565,11 @@ _bfd_write_archive_contents (arch)
 {
   bfd *current;
   char *etable = NULL;
-  unsigned int elength = 0;
+  bfd_size_type elength = 0;
+  const char *ename = NULL;
   boolean makemap = bfd_has_map (arch);
   boolean hasobjects = false;  /* if no .o's, don't bother to make a map */
+  bfd_size_type wrote;
   unsigned int i;
   int tries;
 
@@ -1476,7 +1596,7 @@ _bfd_write_archive_contents (arch)
                                              (char *) arch_hdr (current)));
        }
 
-      if (makemap)
+      if (makemap && ! hasobjects)
        {                       /* don't bother if we won't make a map! */
          if ((bfd_check_format (current, bfd_object))
 #if 0                          /* FIXME -- these are not set correctly */
@@ -1487,19 +1607,23 @@ _bfd_write_archive_contents (arch)
        }
     }
 
-  if (!bfd_construct_extended_name_table (arch, &etable, &elength))
+  if (!BFD_SEND (arch, _bfd_construct_extended_name_table,
+                (arch, &etable, &elength, &ename)))
     return false;
 
-  bfd_seek (arch, (file_ptr) 0, SEEK_SET);
+  if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0)
+    return false;
 #ifdef GNU960
-  bfd_write (BFD_GNU960_ARMAG (arch), 1, SARMAG, arch);
+  wrote = bfd_write (BFD_GNU960_ARMAG (arch), 1, SARMAG, arch);
 #else
-  bfd_write (ARMAG, 1, SARMAG, arch);
+  wrote = bfd_write (ARMAG, 1, SARMAG, arch);
 #endif
+  if (wrote != SARMAG)
+    return false;
 
   if (makemap && hasobjects)
     {
-      if (compute_and_write_armap (arch, elength) != true)
+      if (_bfd_compute_and_write_armap (arch, elength) != true)
        return false;
     }
 
@@ -1508,20 +1632,23 @@ _bfd_write_archive_contents (arch)
       struct ar_hdr hdr;
 
       memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
-      if (ar_padchar (arch) == '/')
-       sprintf (&(hdr.ar_name[0]), "//");
-      else
-       sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
-      sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
-      hdr.ar_fmag[0] = '`';
-      hdr.ar_fmag[1] = '\012';
+      strcpy (hdr.ar_name, ename);
+      /* Round size up to even number in archive header.  */
+      sprintf (&(hdr.ar_size[0]), "%-10d",
+              (int) ((elength + 1) & ~1));
+      strncpy (hdr.ar_fmag, ARFMAG, 2);
       for (i = 0; i < sizeof (struct ar_hdr); i++)
        if (((char *) (&hdr))[i] == '\0')
          (((char *) (&hdr))[i]) = ' ';
-      bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch);
-      bfd_write (etable, 1, elength, arch);
+      if ((bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch)
+          != sizeof (struct ar_hdr))
+         || bfd_write (etable, 1, elength, arch) != elength)
+       return false;
       if ((elength % 2) == 1)
-       bfd_write ("\012", 1, 1, arch);
+       {
+         if (bfd_write ("\012", 1, 1, arch) != 1)
+           return false;
+       }
     }
 
   for (current = arch->archive_head; current; current = current->next)
@@ -1552,59 +1679,50 @@ _bfd_write_archive_contents (arch)
          remaining -= amt;
        }
       if ((arelt_size (current) % 2) == 1)
-       bfd_write ("\012", 1, 1, arch);
+       {
+         if (bfd_write ("\012", 1, 1, arch) != 1)
+           return false;
+       }
     }
 
-  /* Verify the timestamp in the archive file.  If it would not be
-     accepted by the linker, rewrite it until it would be.  If
-     anything odd happens, break out and just return.  (The Berkeley
-     linker checks the timestamp and refuses to read the
-     table-of-contents if it is >60 seconds less than the file's
-     modified-time.  That painful hack requires this painful hack.  */
-
-  tries = 1;
-  do
+  if (makemap && hasobjects)
     {
-      /* FIXME!  This kludge is to avoid adding a member to the xvec,
-        while generating a small patch for Adobe.  FIXME!  The
-        update_armap_timestamp function call should be in the xvec,
-        thus:
-
-               if (bfd_update_armap_timestamp (arch) == true) break;
-                     ^
-
-         Instead, we check whether in a BSD archive, and call
-         directly. */
-
-      if (arch->xvec->write_armap != bsd_write_armap)
-       break;
-      if (bsd_update_armap_timestamp (arch) == true) /* FIXME!!!  Vector it */
-       break;
-      if (tries > 0)
-       fprintf (stderr,
-                "Warning: writing archive was slow: rewriting timestamp\n");
+      /* Verify the timestamp in the archive file.  If it would not be
+        accepted by the linker, rewrite it until it would be.  If
+        anything odd happens, break out and just return.  (The
+        Berkeley linker checks the timestamp and refuses to read the
+        table-of-contents if it is >60 seconds less than the file's
+        modified-time.  That painful hack requires this painful hack.  */
+      tries = 1;
+      do
+       {
+         if (bfd_update_armap_timestamp (arch))
+           break;
+         (*_bfd_error_handler)
+           (_("Warning: writing archive was slow: rewriting timestamp\n"));
+       }
+      while (++tries < 6);
     }
-  while (++tries < 6);
 
   return true;
 }
 \f
 /* Note that the namidx for the first symbol is 0 */
 
-static boolean
-compute_and_write_armap (arch, elength)
+boolean
+_bfd_compute_and_write_armap (arch, elength)
      bfd *arch;
      unsigned int elength;
 {
-  char *first_name;
+  char *first_name = NULL;
   bfd *current;
   file_ptr elt_no = 0;
-  struct orl *map;
+  struct orl *map = NULL;
   int orl_max = 1024;          /* fine initial default */
   int orl_count = 0;
   int stridx = 0;              /* string index */
   asymbol **syms = NULL;
-  unsigned int syms_max = 0;
+  long syms_max = 0;
   boolean ret;
 
   /* Dunno if this is the best place for this info... */
@@ -1612,22 +1730,15 @@ 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)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    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)
-    {
-      free (map);
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    goto error_return;
 
   /* Drop all the files called __.SYMDEF, we're going to make our
      own */
@@ -1643,11 +1754,14 @@ compute_and_write_armap (arch, elength)
       if ((bfd_check_format (current, bfd_object) == true)
          && ((bfd_get_file_flags (current) & HAS_SYMS)))
        {
-         unsigned int storage;
-         unsigned int symcount;
-         unsigned int src_count;
+         long storage;
+         long symcount;
+         long src_count;
+
+         storage = bfd_get_symtab_upper_bound (current);
+         if (storage < 0)
+           goto error_return;
 
-         storage = get_symtab_upper_bound (current);
          if (storage != 0)
            {
              if (storage > syms_max)
@@ -1655,16 +1769,13 @@ compute_and_write_armap (arch, elength)
                  if (syms_max > 0)
                    free (syms);
                  syms_max = storage;
-                 syms = (asymbol **) malloc (syms_max);
+                 syms = (asymbol **) bfd_malloc ((size_t) syms_max);
                  if (syms == NULL)
-                   {
-                     free (map);
-                     bfd_release (arch, first_name);
-                     bfd_set_error (bfd_error_no_memory);
-                     return false;
-                   }
+                   goto error_return;
                }
              symcount = bfd_canonicalize_symtab (current, syms);
+             if (symcount < 0)
+               goto error_return;
 
              /* Now map over all the symbols, picking out the ones we want */
              for (src_count = 0; src_count < symcount; src_count++)
@@ -1676,7 +1787,7 @@ compute_and_write_armap (arch, elength)
                       flags & BSF_WEAK ||
                       flags & BSF_INDIRECT ||
                       bfd_is_com_section (sec))
-                     && (sec != &bfd_und_section))
+                     && ! bfd_is_und_section (sec))
                    {
                      size_t namelen;
                      struct orl *new_map;
@@ -1685,18 +1796,11 @@ 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)
-                           {
-                           free_and_quit:
-                             free (syms);
-                             free (map);
-                             bfd_release (arch, first_name);
-                             bfd_set_error (bfd_error_no_memory);
-                             return false;
-                           }
+                           goto error_return;
 
                          map = new_map;
                        }
@@ -1706,10 +1810,10 @@ compute_and_write_armap (arch, elength)
                                             bfd_alloc (arch,
                                                        sizeof (char *)));
                      if (map[orl_count].name == NULL)
-                       goto free_and_quit;
+                       goto error_return;
                      *(map[orl_count].name) = bfd_alloc (arch, namelen + 1);
                      if (*(map[orl_count].name) == NULL)
-                       goto free_and_quit;
+                       goto error_return;
                      strcpy (*(map[orl_count].name), syms[src_count]->name);
                      (map[orl_count]).pos = (file_ptr) current;
                      (map[orl_count]).namidx = stridx;
@@ -1719,6 +1823,11 @@ compute_and_write_armap (arch, elength)
                    }
                }
            }
+
+         /* Now ask the BFD to free up any cached information, so we
+            don't fill all of memory with symbol tables.  */
+         if (! bfd_free_cached_info (current))
+           goto error_return;
        }
     }
 
@@ -1728,10 +1837,22 @@ compute_and_write_armap (arch, elength)
 
   if (syms_max > 0)
     free (syms);
-  free (map);
-  bfd_release (arch, first_name);
+  if (map != NULL)
+    free (map);
+  if (first_name != NULL)
+    bfd_release (arch, first_name);
 
   return ret;
+
+ error_return:
+  if (syms_max > 0)
+    free (syms);
+  if (map != NULL)
+    free (map);
+  if (first_name != NULL)
+    bfd_release (arch, first_name);
+
+  return false;
 }
 
 boolean
@@ -1743,15 +1864,15 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
      int stridx;
 {
   int padit = stridx & 1;
-  unsigned int ranlibsize = orl_count * sizeof (struct ranlib);
+  unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE;
   unsigned int stringsize = stridx + padit;
   /* Include 8 bytes to store ranlibsize and stringsize in output. */
   unsigned int mapsize = ranlibsize + stringsize + 8;
   file_ptr firstreal;
   bfd *current = arch->archive_head;
   bfd *last_elt = current;     /* last element arch seen */
-  int temp;
-  int count;
+  bfd_byte temp[4];
+  unsigned int count;
   struct ar_hdr hdr;
   struct stat statbuf;
   unsigned int i;
@@ -1766,22 +1887,28 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
   bfd_ardata (arch)->armap_datepos = (SARMAG
                                      + offsetof (struct ar_hdr, ar_date[0]));
   sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
-  sprintf (hdr.ar_uid, "%d", getuid ());
-  sprintf (hdr.ar_gid, "%d", getgid ());
+#ifndef _WIN32
+  sprintf (hdr.ar_uid, "%ld", (long) getuid ());
+  sprintf (hdr.ar_gid, "%ld", (long) getgid ());
+#else
+  sprintf (hdr.ar_uid, "%ld", (long) 666);
+  sprintf (hdr.ar_gid, "%ld", (long) 42);
+#endif
   sprintf (hdr.ar_size, "%-10d", (int) mapsize);
-  hdr.ar_fmag[0] = '`';
-  hdr.ar_fmag[1] = '\012';
+  strncpy (hdr.ar_fmag, ARFMAG, 2);
   for (i = 0; i < sizeof (struct ar_hdr); i++)
     if (((char *) (&hdr))[i] == '\0')
       (((char *) (&hdr))[i]) = ' ';
-  bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch);
-  bfd_h_put_32 (arch, (bfd_vma) ranlibsize, (PTR) &temp);
-  bfd_write (&temp, 1, sizeof (temp), arch);
+  if (bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch)
+      != sizeof (struct ar_hdr))
+    return false;
+  bfd_h_put_32 (arch, (bfd_vma) ranlibsize, temp);
+  if (bfd_write (temp, 1, sizeof (temp), arch) != sizeof (temp))
+    return false;
 
   for (count = 0; count < orl_count; count++)
     {
-      struct symdef outs;
-      struct symdef *outp = &outs;
+      bfd_byte buf[BSD_SYMDEF_SIZE];
 
       if (((bfd *) (map[count]).pos) != last_elt)
        {
@@ -1795,22 +1922,31 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
        }                       /* if new archive element */
 
       last_elt = current;
-      bfd_h_put_32 (arch, ((map[count]).namidx), (PTR) &outs.s.string_offset);
-      bfd_h_put_32 (arch, firstreal, (PTR) &outs.file_offset);
-      bfd_write ((char *) outp, 1, sizeof (outs), arch);
+      bfd_h_put_32 (arch, map[count].namidx, buf);
+      bfd_h_put_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
+      if (bfd_write (buf, BSD_SYMDEF_SIZE, 1, arch) != BSD_SYMDEF_SIZE)
+       return false;
     }
 
   /* now write the strings themselves */
-  bfd_h_put_32 (arch, stringsize, (PTR) &temp);
-  bfd_write ((PTR) &temp, 1, sizeof (temp), arch);
+  bfd_h_put_32 (arch, stringsize, temp);
+  if (bfd_write (temp, 1, sizeof (temp), arch) != sizeof (temp))
+    return false;
   for (count = 0; count < orl_count; count++)
-    bfd_write (*((map[count]).name), 1,
-              strlen (*((map[count]).name)) + 1, arch);
+    {
+      size_t len = strlen (*map[count].name) + 1;
+
+      if (bfd_write (*map[count].name, 1, len, arch) != len)
+       return false;
+    }
 
   /* The spec sez this should be a newline.  But in order to be
      bug-compatible for sun's ar we use a null. */
   if (padit)
-    bfd_write ("", 1, 1, arch);
+    {
+      if (bfd_write ("", 1, 1, arch) != 1)
+       return false;
+    }
 
   return true;
 }
@@ -1821,20 +1957,20 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
    Return true if the timestamp was OK, or an unusual problem happened.
    Return false if we updated the timestamp.  */
 
-static boolean
-bsd_update_armap_timestamp (arch)
+boolean
+_bfd_archive_bsd_update_armap_timestamp (arch)
      bfd *arch;
 {
   struct stat archstat;
   struct ar_hdr hdr;
-  int i;
+  unsigned int i;
 
   /* Flush writes, get last-write timestamp from file, and compare it
      to the timestamp IN the file.  */
   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)
@@ -1851,11 +1987,14 @@ bsd_update_armap_timestamp (arch)
       (hdr.ar_date)[i] = ' ';
 
   /* Write it into the file.  */
-  bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET);
-  if (bfd_write (hdr.ar_date, sizeof (hdr.ar_date), 1, arch)
-      != sizeof (hdr.ar_date))
+  bfd_ardata (arch)->armap_datepos = (SARMAG
+                                     + offsetof (struct ar_hdr, ar_date[0]));
+  if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0
+      || (bfd_write (hdr.ar_date, sizeof (hdr.ar_date), 1, arch)
+         != sizeof (hdr.ar_date)))
     {
-      perror ("Writing updated armap timestamp");
+      /* FIXME: bfd can't call perror.  */
+      perror (_("Writing updated armap timestamp"));
       return true;             /* Some error while writing */
     }
 
@@ -1891,7 +2030,7 @@ coff_write_armap (arch, elength, map, symbol_count, stridx)
   unsigned int mapsize = stringsize + ranlibsize;
   file_ptr archive_member_file_ptr;
   bfd *current = arch->archive_head;
-  int count;
+  unsigned int count;
   struct ar_hdr hdr;
   unsigned int i;
   int padit = mapsize & 1;
@@ -1913,8 +2052,7 @@ coff_write_armap (arch, elength, map, symbol_count, stridx)
   sprintf ((hdr.ar_uid), "%d", 0);
   sprintf ((hdr.ar_gid), "%d", 0);
   sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
-  hdr.ar_fmag[0] = '`';
-  hdr.ar_fmag[1] = '\012';
+  strncpy (hdr.ar_fmag, ARFMAG, 2);
 
   for (i = 0; i < sizeof (struct ar_hdr); i++)
     if (((char *) (&hdr))[i] == '\0')
@@ -1922,7 +2060,9 @@ coff_write_armap (arch, elength, map, symbol_count, stridx)
 
   /* Write the ar header for this item and the number of symbols */
 
-  bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch);
+  if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
+      != sizeof (struct ar_hdr))
+    return false;
 
   bfd_write_bigendian_4byte_int (arch, symbol_count);
 
@@ -1954,14 +2094,20 @@ coff_write_armap (arch, elength, map, symbol_count, stridx)
 
   /* now write the strings themselves */
   for (count = 0; count < symbol_count; count++)
-    bfd_write ((PTR) * ((map[count]).name),
-              1,
-              strlen (*((map[count]).name)) + 1, arch);
+    {
+      size_t len = strlen (*map[count].name) + 1;
+
+      if (bfd_write (*map[count].name, 1, len, arch) != len)
+       return false;
+    }
 
   /* The spec sez this should be a newline.  But in order to be
      bug-compatible for arc960 we use a null. */
   if (padit)
-    bfd_write ("", 1, 1, arch);
+    {
+      if (bfd_write ("", 1, 1, arch) != 1)
+       return false;
+    }
 
   return true;
 }
This page took 0.041557 seconds and 4 git commands to generate.