]> Git Repo - binutils.git/blobdiff - bfd/archive.c
Add i386aout.c
[binutils.git] / bfd / archive.c
index 0e137b9e9cc68ee4ea18b9a0c3f233e147bb5e48..fdac8df13b22dd0f6c6536621a3e5af035f00c6a 100644 (file)
@@ -1,24 +1,37 @@
-/*** archive.c -- an attempt at combining the machine-independent parts of
-  archives */
+/* BFD back-end for archive files (libraries).
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Written by Cygnus Support.  Mostly Gumby Henkel-Wallace's fault.
 
-/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+This file is part of BFD, the Binary File Descriptor library.
 
-This file is part of BFD, the Binary File Diddler.
-
-BFD is free software; you can redistribute it and/or modify
+This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-BFD is distributed in the hope that it will be useful,
+This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with BFD; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*doc*
+@setfilename archive-info
+@section Archives
+
+Gumby, you promised to write this bit...
+
+Archives are supported in BFD in @code{archive.c}.
 
+An archive is represented internally just like another BFD, with a
+pointer to a chain of contained BFDs. Archives can be created by
+opening BFDs, linking them together and attatching them as children to
+another BFD and then closing the parent BFD. 
+
+*-*/
 
 /* Assumes:
    o - all archive elements start on an even boundary, newline padded;
@@ -26,46 +39,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    o - all arch headers are the same size (across architectures).
 */
 
-/* $Id$ 
- * $Log$
- * Revision 1.3  1991/04/04 14:56:42  gumby
- * Minor format fixes.
- *
- * Revision 1.2  1991/04/03  22:09:43  steve
- * Various noise
- *
- * Revision 1.1.1.1  1991/03/21  21:10:42  gumby
- * Back from Intel with Steve
- *
- * Revision 1.1  1991/03/21  21:10:42  gumby
- * Initial revision
- *
- * Revision 1.3  1991/03/16  05:55:25  rich
- * pop
- *
- * Revision 1.2  1991/03/15  18:15:50  rich
- * *** empty log message ***
- *
- * Revision 1.7  1991/03/08  04:18:02  rich
- * *** empty log message ***
- *
- * Revision 1.6  1991/03/07  21:55:31  sac
- * Added primitive file caching, a file open only for input and
- * less than BFD_INCORE_FILE_SIZE will be malloced and read in
- * only once.
- *
- * Revision 1.5  1991/03/05  16:31:12  sac
- * lint
- *
- */
-
-
-#include "sysdep.h"
+/* $Id$ */
+
+#include <sysdep.h>
 #include "bfd.h"
 #include "libbfd.h"
 #include "ar.h"
 #include "ranlib.h"
 
+#ifdef GNU960
+#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
+#endif
+
 /* We keep a cache of archive filepointers to archive elements to
    speed up searching the archive by filepos.  We only add an entry to
    the cache when we actually read one.  We also don't sort the cache;
@@ -84,27 +69,29 @@ struct ar_cache {
 
 #define arch_hdr(bfd) ((struct ar_hdr *)   \
                       (((struct areltdata *)((bfd)->arelt_data))->arch_header))
-
 \f
-
 boolean
 _bfd_generic_mkarchive (abfd)
      bfd *abfd;
 {
-  abfd->tdata =(void *) zalloc (sizeof (struct artdata));
+  set_tdata (abfd, bfd_zalloc(abfd, sizeof (struct artdata)));
 
-  if (abfd->tdata == NULL) {
+  if (bfd_ardata (abfd) == NULL) {
     bfd_error = no_memory;
     return false;
   }
-bfd_ardata(abfd)->cache = 0;
+  bfd_ardata(abfd)->cache = 0;
   return true;
 }
 
+/*proto* bfd_get_next_mapent
+What this does
+*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
+*/
 symindex
 bfd_get_next_mapent (abfd, prev, entry)
      bfd *abfd;
-   symindex prev;
+     symindex prev;
      carsym **entry;
 {
   if (!bfd_has_map (abfd)) {
@@ -113,7 +100,7 @@ bfd_get_next_mapent (abfd, prev, entry)
   }
   
   if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
-  else if (++prev >= (symindex)(bfd_ardata (abfd)->symdef_count))
+  else if (++prev >= bfd_ardata (abfd)->symdef_count)
     return BFD_NO_MORE_SYMBOLS;
 
   *entry = (bfd_ardata (abfd)->symdefs + prev);
@@ -136,11 +123,18 @@ _bfd_create_empty_archive_element_shell (obfd)
   return nbfd;
 }
 
+/*proto* bfd_set_archive_head
+Used whilst processing archives. Sets the head of the chain of BFDs
+contained in an archive to @var{new_head}. (see chapter on archives)
+*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
+*/
+
 boolean
-bfd_set_archive_head (output_archive, new_head)
-     bfd *output_archive, *new_head;
+DEFUN(bfd_set_archive_head,(output_archive, new_head),
+     bfd *output_archive AND 
+     bfd *new_head)
 {
+
   output_archive->archive_head = new_head;
   return true;
 }
@@ -165,8 +159,8 @@ add_bfd_to_cache (arch_bfd, filepos, new_elt)
      bfd *arch_bfd, *new_elt;
      file_ptr filepos;
 {
-  struct ar_cache *new_cache = ((struct ar_cache *)
-                               zalloc (sizeof (struct ar_cache)));
+  struct ar_cache *new_cache = (struct ar_cache *)
+                               bfd_zalloc(arch_bfd, sizeof (struct ar_cache));
 
   if (new_cache == NULL) {
     bfd_error = no_memory;
@@ -198,7 +192,9 @@ get_extended_arelt_filename (arch, name)
      bfd *arch;
      char *name;
 {
-    extern int errno;
+#ifndef errno
+  extern int errno;
+#endif
     unsigned long index = 0;
 
     /* Should extract string so that I can guarantee not to overflow into
@@ -226,7 +222,10 @@ struct areltdata *
 snarf_ar_hdr (abfd)
      bfd *abfd;
 {
-    extern int errno;
+#ifndef errno
+  extern int errno;
+#endif
+
     struct ar_hdr hdr;
     char *hdrp = (char *) &hdr;
     unsigned int parsed_size;
@@ -236,7 +235,7 @@ snarf_ar_hdr (abfd)
     unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
     char *allocptr;
 
-    if (bfd_read ((void *)hdrp, 1, sizeof (struct ar_hdr), abfd)
+    if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
        != sizeof (struct ar_hdr)) {
        bfd_error = no_more_archived_files;
        return NULL;
@@ -253,8 +252,10 @@ snarf_ar_hdr (abfd)
        return NULL;
     }
 
-    /* extract the filename from the archive */
-    if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
+    /* extract the filename from the archive - there are two ways to
+       specify an extendend 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] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
        filename = get_extended_arelt_filename (abfd, hdr.ar_name);
        if (filename == NULL) {
            bfd_error = malformed_archive;
@@ -278,7 +279,7 @@ snarf_ar_hdr (abfd)
            allocsize += namelen + 1;
        }
 
-    allocptr = zalloc (allocsize);
+    allocptr = bfd_zalloc(abfd, allocsize);
     if (allocptr == NULL) {
        bfd_error = no_memory;
        return NULL;
@@ -287,7 +288,7 @@ snarf_ar_hdr (abfd)
     ared = (struct areltdata *) allocptr;
 
     ared->arch_header = allocptr + sizeof (struct areltdata);
-    memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
+    memcpy ((char *) ared->arch_header, (char *) &hdr, sizeof (struct ar_hdr));
     ared->parsed_size = parsed_size;
 
     if (filename != NULL) ared->filename = filename;
@@ -322,22 +323,27 @@ get_elt_at_filepos (archive, filepos)
   
   n_nfd = _bfd_create_empty_archive_element_shell (archive);
   if (n_nfd == NULL) {
-    free (new_areldata);
+    bfd_release (archive, (PTR)new_areldata);
     return NULL;
   }
   n_nfd->origin = bfd_tell (archive);
-  n_nfd->arelt_data = (void *) new_areldata;
+  n_nfd->arelt_data = (PTR) new_areldata;
   n_nfd->filename = new_areldata->filename;
 
   if (add_bfd_to_cache (archive, filepos, n_nfd))
     return n_nfd;
 
   /* huh? */
-  free (new_areldata);
-  free (n_nfd);
+  bfd_release (archive, (PTR)n_nfd);
+  bfd_release (archive, (PTR)new_areldata);
   return NULL;
 }
 
+/*proto* bfd_get_elt_at_index
+
+*; PROTO(bfd *, bfd_get_elt_at_index, (bfd *, int));
+
+*/
 bfd *
 bfd_get_elt_at_index (abfd, index)
      bfd *abfd;
@@ -349,10 +355,22 @@ bfd_get_elt_at_index (abfd, index)
   return result;
 }
 
-/* If you've got an archive, call this to read each subfile. */
+/*proto* bfd_openr_next_archived_file
+Initially provided a BFD containing an archive and NULL, opens a BFD
+on the first contained element and returns that. Subsequent calls to
+bfd_openr_next_archived_file should pass the archive and the previous
+return value to return a created BFD to the next contained element.
+NULL is returned when there are no more.
+
+*; PROTO(bfd*, bfd_openr_next_archived_file,
+               (bfd *archive, bfd *previous));
+
+*/
+
 bfd *
-bfd_openr_next_archived_file (archive, last_file)
-     bfd *archive, *last_file;
+DEFUN(bfd_openr_next_archived_file,(archive, last_file),
+     bfd *archive AND  
+      bfd*last_file)
 {
 
   if ((bfd_get_format (archive) != bfd_archive) ||
@@ -378,11 +396,10 @@ bfd *bfd_generic_openr_next_archived_file(archive, last_file)
   if (!last_file)
     filestart = bfd_ardata (archive)->first_file_filepos;
   else {
-  unsigned int size = arelt_size(last_file);
-    filestart = last_file->origin +size + size %2;
-}
-
-
+    unsigned int size = arelt_size(last_file);
+    /* Pad to an even boundary... */
+    filestart = last_file->origin + size + size%2;
+  }
 
   return get_elt_at_filepos (archive, filestart);
 }
@@ -394,14 +411,20 @@ bfd_generic_archive_p (abfd)
 {
   char armag[SARMAG+1];
 
-  if (bfd_read ((void *)armag, 1, SARMAG, abfd) != SARMAG) {
+  if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
     bfd_error = wrong_format;
     return 0;
   }
 
+#ifdef GNU960
+  if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
+#else
   if (strncmp (armag, ARMAG, SARMAG)) return 0;
+#endif
 
-  bfd_set_ardata(abfd, (struct artdata *) zalloc (sizeof (struct artdata)));
+  /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
+     involves a cast, we can't do it as the left operand of assignment. */
+  set_tdata (abfd, bfd_zalloc(abfd,sizeof (struct artdata)));
 
   if (bfd_ardata (abfd)  == NULL) {
     bfd_error = no_memory;
@@ -411,14 +434,13 @@ bfd_generic_archive_p (abfd)
   bfd_ardata (abfd)->first_file_filepos = SARMAG;
   
   if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
-    free (bfd_ardata (abfd));
+    bfd_release(abfd, bfd_ardata (abfd));
     abfd->tdata = NULL;
     return 0;
   }
 
-  /* armap could be left ungc'd! FIXME -- potential storage leak */
   if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
-    free (bfd_ardata (abfd));
+    bfd_release(abfd, bfd_ardata (abfd));
     abfd->tdata = NULL;
     return 0;
   }
@@ -431,6 +453,7 @@ boolean
 bfd_slurp_bsd_armap (abfd)
      bfd *abfd;
 {
+
   struct areltdata *mapdata;
   char nextname[17];
   unsigned int counter = 0;
@@ -438,10 +461,15 @@ bfd_slurp_bsd_armap (abfd)
   struct artdata *ardata = bfd_ardata (abfd);
   char *stringbase;
 
-  if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
+  /* FIXME, if the read fails, this routine quietly returns "true"!!
+     It should probably do that if the read gives 0 bytes (empty archive),
+     but fail for any other size... */
+  if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
       /* The archive has at least 16 bytes in it */
       bfd_seek (abfd, -16L, SEEK_CUR);
 
+      /* This should be using RANLIBMAG, but at least it can be grepped for
+        in this comment.  */
       if (strncmp (nextname, "__.SYMDEF       ", 16)) {
          bfd_has_map (abfd) = false;
          return true;
@@ -450,36 +478,39 @@ bfd_slurp_bsd_armap (abfd)
       mapdata = snarf_ar_hdr (abfd);
       if (mapdata == NULL) return false;
 
-      raw_armap = (int *) zalloc (mapdata->parsed_size);
+      raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
       if (raw_armap == NULL) {
          bfd_error = no_memory;
   byebye:
-         free (mapdata);
+         bfd_release (abfd, (PTR)mapdata);
          return false;
       }
 
-      if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
+      if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
          mapdata->parsed_size) {
          bfd_error = malformed_archive;
-         free (raw_armap);
+         bfd_release (abfd, (PTR)raw_armap);
          goto byebye;
       }
 
-      ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
+      ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
       ardata->cache = 0;
       rbase = raw_armap+1;
       ardata->symdefs = (carsym *) rbase;
       stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
 
-      for (;counter < (unsigned)( ardata->symdef_count); counter++) {
+      for (;counter < ardata->symdef_count; counter++) {
          struct symdef *sym = ((struct symdef *) rbase) + counter;
-         sym->s.name = sym->s.string_offset + stringbase;
+         sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
+         sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
       }
   
       ardata->first_file_filepos = bfd_tell (abfd);
       /* Pad to an even boundary if you have to */
       ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
-      free (mapdata);
+      /* 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... */
       bfd_has_map (abfd) = true;
   }
   return true;
@@ -497,35 +528,36 @@ bfd_slurp_coff_armap (abfd)
   char *stringbase;
   unsigned int stringsize;
   carsym *carsyms;
+  int result;
 
-  if (bfd_read ((void *)&nextname, 1, 1, abfd) != 1) {
-    bfd_has_map(abfd) = false;
-    return true;
-  }
+  result = bfd_read ((PTR)&nextname, 1, 1, abfd);
+  bfd_seek (abfd, -1L, SEEK_CUR);
 
-  if (nextname != '/') {
+  if (result != 1 || nextname != '/') {
     /* Actually I think this is an error for a COFF archive */
     bfd_has_map (abfd) = false;
     return true;
   }
 
-  bfd_seek (abfd, -1L, SEEK_CUR);
   mapdata = snarf_ar_hdr (abfd);
   if (mapdata == NULL) return false;
 
-  raw_armap = (int *) zalloc (mapdata->parsed_size);
-  if (raw_armap == NULL) {
+  raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
+
+  if (raw_armap == NULL) 
+      {
     bfd_error = no_memory;
   byebye:
-    free (mapdata);
+    bfd_release (abfd, (PTR)mapdata);
     return false;
   }
 
-  if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
+  /* read in the raw map */
+  if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
       mapdata->parsed_size) {
     bfd_error = malformed_archive;
   oops:
-    free (raw_armap);
+    bfd_release (abfd, (PTR)raw_armap);
     goto byebye;
   }
 
@@ -539,7 +571,7 @@ bfd_slurp_coff_armap (abfd)
     unsigned int carsym_size = (nsymz * sizeof (carsym));
     unsigned int ptrsize = (4 * nsymz);
     unsigned int i;
-    ardata->symdefs = (carsym *) zalloc (carsym_size + stringsize + 1);
+    ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
     if (ardata->symdefs == NULL) {
       bfd_error = no_memory;
       goto oops;
@@ -565,20 +597,25 @@ bfd_slurp_coff_armap (abfd)
   ardata->first_file_filepos = bfd_tell (abfd);
   /* Pad to an even boundary if you have to */
   ardata->first_file_filepos += (ardata->first_file_filepos) %2;
-  free (raw_armap);
-  free (mapdata);
+
+  /* We'd like to release these allocations, but we have allocated stuff
+     since then (using the same obstack, if bfd_release is obstack based).
+     So they will stick around until the BFD is closed.  */
+  /*  bfd_release (abfd, (PTR)raw_armap);
+      bfd_release (abfd, (PTR)mapdata);  */
   bfd_has_map (abfd) = true;
   return true;
 }
-
 \f
 /** Extended name table.
 
-  Normally archives support only 14-character filenames.  Intel has extended
-  the format: longer names are stored in a special element (the first in the
-  archive, or second if there is an armap); the name in the ar_hdr is replaced
-  by <space><index into filename element>.  Index is the P.R. of an int (radix:
-  8). */
+  Normally archives support only 14-character filenames.
+
+  Intel has extended the format: longer names are stored in a special
+  element (the first in the archive, or second if there is an armap);
+  the name in the ar_hdr is replaced by <space><index into filename
+  element>.  Index is the P.R. of an int (radix: 8).  Data General have
+  extended the format by using the prefix // for the special element */
 
 /* Returns false on error, true otherwise */
 boolean
@@ -588,42 +625,56 @@ _bfd_slurp_extended_name_table (abfd)
   char nextname[17];
   struct areltdata *namedata;
 
-  if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
+  /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
+     we probably don't want to return true.  */
+  if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
 
-  bfd_seek (abfd, -16L, SEEK_CUR);
+    bfd_seek (abfd, -16L, SEEK_CUR);
 
-  if (strncmp (nextname, "ARFILENAMES/    ", 16)) {
-    bfd_ardata (abfd)->extended_names = NULL;
-    return true;
-  }
+    if (strncmp (nextname, "ARFILENAMES/    ", 16) != 0 &&
+       strncmp (nextname, "//              ", 16) != 0) 
+       {
+      bfd_ardata (abfd)->extended_names = NULL;
+      return true;
+    }
 
-  namedata = snarf_ar_hdr (abfd);
-  if (namedata == NULL) return false;
-  
+    namedata = snarf_ar_hdr (abfd);
+    if (namedata == NULL) return false;
   
-  bfd_ardata (abfd)->extended_names = zalloc (namedata->parsed_size);
-  if (bfd_ardata (abfd)->extended_names == NULL) {
-    bfd_error = no_memory;
-  byebye:
-    free (namedata);
-    return false;
-  }
-
-  if (bfd_read ((void*)bfd_ardata (abfd)->extended_names, 1,
-               namedata->parsed_size, abfd) != namedata->parsed_size) {
-    bfd_error = malformed_archive;
-    free (bfd_ardata (abfd)->extended_names);
-    bfd_ardata (abfd)->extended_names = NULL;
-    goto byebye;
-  }
+    bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
+    if (bfd_ardata (abfd)->extended_names == NULL) {
+      bfd_error = no_memory;
+    byebye:
+      bfd_release (abfd, (PTR)namedata);
+      return false;
+    }
 
-  /* Pad to an even boundary if you have to */
-  bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
-  bfd_ardata (abfd)->first_file_filepos +=
-    (bfd_ardata (abfd)->first_file_filepos) %2;
+    if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
+                 namedata->parsed_size, abfd) != namedata->parsed_size) {
+      bfd_error = malformed_archive;
+      bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
+      bfd_ardata (abfd)->extended_names = NULL;
+      goto byebye;
+    }
 
-  free (namedata);
-}
+    /* Since the archive is supposed to be printable if it contains
+       text, the entries in the list are newline-padded, not null
+       padded. We'll fix that there..  */
+      {
+       char *temp = bfd_ardata (abfd)->extended_names;
+       for (; *temp != '\0'; ++temp)
+         if (*temp == '\n') *temp = '\0';
+      }
+  
+    /* Pad to an even boundary if you have to */
+    bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
+    bfd_ardata (abfd)->first_file_filepos +=
+      (bfd_ardata (abfd)->first_file_filepos) %2;
+
+    /* FIXME, we can't release namedata here because it was allocated
+       below extended_names on the obstack... */
+    /* bfd_release (abfd, namedata); */
+  }
   return true;
 }
 
@@ -654,46 +705,56 @@ bfd_construct_extended_name_table (abfd, tabloc, tablen)
      char **tabloc;
      unsigned int *tablen;
 {
-    unsigned int maxname = abfd->xvec->ar_max_namelen;
-    unsigned int total_namelen = 0;
-    bfd *current;
-    char *strptr;
+  unsigned int maxname = abfd->xvec->ar_max_namelen;
+  unsigned int total_namelen = 0;
+  bfd *current;
+  char *strptr;
 
-    *tablen = 0;
+  *tablen = 0;
   
-    /* Figure out how long the table should be */
-    for (current = abfd->archive_head; current != NULL; current = current->next){
-       unsigned int thislen = strlen (normalize(current->filename));
-       if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \0 */
-    }
+  /* Figure out how long the table should be */
+  for (current = abfd->archive_head; current != NULL; current = current->next){
+    unsigned int thislen = strlen (normalize(current->filename));
+    if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
+  }
 
-    if (total_namelen == 0) return true;
+  if (total_namelen == 0) return true;
 
-    *tabloc = zalloc (total_namelen);
-    if (*tabloc == NULL) {
-       bfd_error = no_memory;
-       return false;
-    }
+  *tabloc = bfd_zalloc (abfd,total_namelen);
+  if (*tabloc == NULL) {
+    bfd_error = no_memory;
+    return false;
+  }
 
-    *tablen = total_namelen;
-    strptr = *tabloc;
-
-    for (current = abfd->archive_head; current != NULL; current =
-        current->next) {
-       char *normal =normalize( current->filename);
-       unsigned int thislen = strlen (normal);
-       if (thislen > maxname) {
-           strcpy (strptr, normal);
-           current->filename[0] = ' ';
-           /* We know there will always be enough room (one of the few cases
-              where you may safely use sprintf). */
-           sprintf ((current->filename) + 1, "-%o", (unsigned) (strptr - *tabloc));
-
-           strptr += thislen + 1;
+  *tablen = total_namelen;
+  strptr = *tabloc;
+
+  for (current = abfd->archive_head; current != NULL; current =
+       current->next) {
+    char *normal =normalize( current->filename);
+    unsigned int thislen = strlen (normal);
+    if (thislen > maxname) {
+      /* Works for now; may need to be re-engineered if we encounter an oddball
+        archive format and want to generalise this hack. */
+      struct ar_hdr *hdr = arch_hdr(current);
+      strcpy (strptr, normal);
+      strptr[thislen] = '\n';
+      hdr->ar_name[0] = ' ';
+      /* We know there will always be enough room (one of the few cases
+        where you may safely use sprintf). */
+      sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
+      /* Kinda Kludgy.   We should just use the returned value of sprintf
+        but not all implementations get this right */
+       {
+         char *temp = hdr->ar_name +2; 
+         for (; temp < hdr->ar_name + maxname; temp++)
+           if (*temp == '\0') *temp = ' ';
        }
+      strptr += thislen + 1;
     }
+  }
 
-    return true;
+  return true;
 }
 \f
 /** A couple of functions for creating ar_hdrs */
@@ -704,8 +765,9 @@ bfd_construct_extended_name_table (abfd, tabloc, tablen)
 */
 
 struct areltdata *
-bfd_ar_hdr_from_filesystem (filename)
-     char *filename;
+DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
+      bfd* abfd AND
+      CONST char *filename)
 {
   struct stat status;
   struct areltdata *ared;
@@ -718,7 +780,7 @@ bfd_ar_hdr_from_filesystem (filename)
     return NULL;
   }
 
-  ared = (struct areltdata *) zalloc (sizeof (struct ar_hdr) +
+  ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
                                      sizeof (struct areltdata));
   if (ared == NULL) {
     bfd_error = no_memory;
@@ -754,11 +816,12 @@ bfd_ar_hdr_from_filesystem (filename)
 }
 
 struct ar_hdr *
-bfd_special_undocumented_glue (filename)
-     char *filename;
+DEFUN(bfd_special_undocumented_glue, (abfd, filename),
+      bfd *abfd AND
+      char *filename)
 {
 
-  return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (filename) -> arch_header;
+  return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
 }
 
 
@@ -791,32 +854,46 @@ bfd_generic_stat_arch_elt (abfd, buf)
   return 0;
 }
 
-/* Don't do anything -- it'll be taken care of later */
 void
-bfd_dont_truncate_arname (ignore_abfd, ignore_filename, ignore_arhdr)
-     bfd *ignore_abfd;
-     char *ignore_filename;
-     char *ignore_arhdr;
+bfd_dont_truncate_arname (abfd, pathname, arhdr)
+     bfd *abfd;
+     CONST char *pathname;
+     char *arhdr;
 {
-  /* FIXME -- Actually this is incorrect.  If the name is short we
-    should insert into the header; only if it is long should we do
-    nothing.
+  /* FIXME: This interacts unpleasantly with ar's quick-append option.
+     Fortunately ic960 users will never use that option.  Fixing this
+     is very hard; fortunately I know how to do it and will do so once
+     intel's release is out the door. */
+   
+  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
+  int length;
+  CONST char *filename = strrchr (pathname, '/');
+  int maxlen = ar_maxnamelen (abfd);
 
-    Anyway, this interacts unpleasantly with ar's quick-append option,
-    for now just be compatible with the old system */
+  if (filename == NULL)
+    filename = pathname;
+  else
+    ++filename;
 
+  length = strlen (filename);
+
+  if (length <= maxlen)
+    memcpy (hdr->ar_name, filename, length);
+
+  if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
   return;
+
 }
 
 void
 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
      bfd *abfd;
-     char *pathname;
+     CONST char *pathname;
      char *arhdr;
 {
   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
   int length;
-  char *filename = strrchr (pathname, '/');
+  CONST char *filename = strrchr (pathname, '/');
   int maxlen = ar_maxnamelen (abfd);
 
 
@@ -835,7 +912,7 @@ bfd_bsd_truncate_arname (abfd, pathname, arhdr)
     length = maxlen;
   }
 
-  if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
+  if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
 }
 
 /* Store name into ar header.  Truncates the name to fit.
@@ -849,12 +926,12 @@ bfd_bsd_truncate_arname (abfd, pathname, arhdr)
 void
 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
      bfd *abfd;
-     char *pathname;
+     CONST char *pathname;
      char *arhdr;
 {
   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
   int length;
-  char *filename = strrchr (pathname, '/');
+  CONST char *filename = strrchr (pathname, '/');
   int maxlen = ar_maxnamelen (abfd);
        
   if (filename == NULL)
@@ -881,7 +958,7 @@ bfd_gnu_truncate_arname (abfd, pathname, arhdr)
 
 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
 
-/* The bfd is open for write and has its format set to bfd_archive */
+/* The BFD is open for write and has its format set to bfd_archive */
 boolean
 _bfd_write_archive_contents (arch)
      bfd *arch;
@@ -893,7 +970,6 @@ _bfd_write_archive_contents (arch)
   boolean hasobjects = false;  /* if no .o's, don't bother to make a map */
   unsigned int i;
 
-
   /* Verify the viability of all entries; if any of them live in the
      filesystem (as opposed to living in an archive open for input)
      then construct a fresh ar_hdr for them.
@@ -905,7 +981,7 @@ _bfd_write_archive_contents (arch)
     }
     if (!current->arelt_data) {
       current->arelt_data =
-         (void *) bfd_ar_hdr_from_filesystem (current->filename);
+         (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
       if (!current->arelt_data) return false;
 
       /* Put in the file name */
@@ -931,12 +1007,15 @@ _bfd_write_archive_contents (arch)
     return false;
 
   bfd_seek (arch, 0, SEEK_SET);
+#ifdef GNU960
+  bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
+#else
   bfd_write (ARMAG, 1, SARMAG, arch);
+#endif
 
   if (makemap && hasobjects) {
 
     if (compute_and_write_armap (arch, elength) != true) {
-      if (etable) free (etable);
       return false;
     }
   }
@@ -950,10 +1029,10 @@ _bfd_write_archive_contents (arch)
     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
     for (i = 0; i < sizeof (struct ar_hdr); i++)
       if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
-    bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
+    bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
     bfd_write (etable, 1, elength, arch);
     if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
-    if (etable) free (etable);
+
   }
 
   for (current = arch->archive_head; current; current = current->next) {
@@ -962,7 +1041,7 @@ _bfd_write_archive_contents (arch)
     struct ar_hdr *hdr = arch_hdr(current);
     /* write ar header */
 
-    if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
+    if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
     syserr:
        bfd_error = system_call_error;
        return false;
@@ -985,8 +1064,6 @@ return true;
 \f
 /* Note that the namidx for the first symbol is 0 */
 
-  
-
 boolean
 compute_and_write_armap (arch, elength)
      bfd *arch;
@@ -1003,7 +1080,7 @@ compute_and_write_armap (arch, elength)
   if (elength != 0) elength += sizeof (struct ar_hdr);
   elength += elength %2 ;
 
-  map = (struct orl *) zalloc (orl_max * sizeof (struct orl));
+  map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
   if (map == NULL) {
     bfd_error = no_memory;
     return false;
@@ -1024,7 +1101,7 @@ compute_and_write_armap (arch, elength)
          storage = get_symtab_upper_bound (current);
          if (storage != 0) {
 
-           syms = (asymbol **) zalloc (storage);
+           syms = (asymbol **) bfd_zalloc (arch,storage);
            if (syms == NULL) {
              bfd_error = no_memory; /* FIXME -- memory leak */
              return false;
@@ -1042,12 +1119,12 @@ compute_and_write_armap (arch, elength)
                if (orl_count == orl_max) 
                    {
                      orl_max *= 2;
-                     map = (struct orl *) realloc ((char *) map,
+                     map = (struct orl *) bfd_realloc (arch, (char *) map,
                                                    orl_max * sizeof (struct orl));
                    }
 
-               (map[orl_count]).name = &((syms[src_count])->name);
-               (map[orl_count]).pos = elt_no;
+               (map[orl_count]).name = (char **) &((syms[src_count])->name);
+               (map[orl_count]).pos = (file_ptr) current;
                (map[orl_count]).namidx = stridx;
 
                stridx += strlen ((syms[src_count])->name) + 1;
@@ -1060,17 +1137,14 @@ compute_and_write_armap (arch, elength)
   /* OK, now we have collected all the data, let's write them out */
   if (!BFD_SEND (arch, write_armap,
                 (arch, elength, map, orl_count, stridx))) {
-    free (map);
+
     return false;
   }
 
-  free (map);
+
   return true;
 }
 
-\f
- /* FIXME -- have to byte-swap this */
-
 boolean
 bsd_write_armap (arch, elength, map, orl_count, stridx)
      bfd *arch;
@@ -1084,7 +1158,7 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
   unsigned int mapsize = stringsize + ranlibsize;
   file_ptr firstreal;
   bfd *current = arch->archive_head;
-  int last_eltno = 0;          /* last element arch seen */
+  bfd *last_elt = current;             /* last element arch seen */
   int temp;
   int count;
   struct ar_hdr hdr;
@@ -1096,38 +1170,41 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
 
   firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
 
-  fstat (arch->iostream, &statbuf); /* FIXME -- descriptor must be open! */
+  stat (arch->filename, &statbuf);
   memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
-  sprintf (hdr.ar_name, "__.SYMDEF");
-  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+  sprintf (hdr.ar_name, RANLIBMAG);
   sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);  
+  sprintf (hdr.ar_uid, "%d", getuid());
+  sprintf (hdr.ar_gid, "%d", getgid());
+  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
   hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
   for (i = 0; i < sizeof (struct ar_hdr); i++)
     if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
-  bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
-
-  temp = orl_count /* + 4 */;
+  bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
+  bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
   bfd_write (&temp, 1, sizeof (temp), arch);
   
   for (count = 0; count < orl_count; count++) {
     struct symdef outs;
     struct symdef *outp = &outs;
     
-    if ((map[count]).pos != last_eltno) {
-      firstreal += arelt_size (current) + sizeof (struct ar_hdr);
-      firstreal += firstreal % 2;
-    last_eltno = (map[count]).pos;
-      current = current->next;
-    }
-
-    outs.s.string_offset = ((map[count]).namidx) +4;
-    outs.file_offset = firstreal;
+    if (((bfd *)(map[count]).pos) != last_elt) {
+           do {
+                   firstreal += arelt_size (current) + sizeof (struct ar_hdr);
+                   firstreal += firstreal % 2;
+                   current = current->next;
+           } while (current != (bfd *)(map[count]).pos);
+    } /* 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);
   }
 
   /* now write the strings themselves */
-  temp = stridx + 4;
-  bfd_write (&temp, 1, sizeof (temp), arch);
+  bfd_h_put_32(arch, stridx, (PTR)&temp);
+  bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
   for (count = 0; count < orl_count; count++)
     bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
 
@@ -1182,11 +1259,11 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
     memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
     hdr.ar_name[0] = '/';
     sprintf (hdr.ar_size, "%-10d", (int) mapsize);
-    sprintf (hdr.ar_date, "%ld", time (NULL));
+    sprintf (hdr.ar_date, "%ld", (long)time (NULL));
     /* This, at least, is what Intel coff sets the values to.: */
     sprintf ((hdr.ar_uid), "%d", 0);
     sprintf ((hdr.ar_gid), "%d", 0);
-    sprintf ((hdr.ar_mode), "%-7o", 0);
+    sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
 
     for (i = 0; i < sizeof (struct ar_hdr); i++)
@@ -1194,8 +1271,9 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
 
     /* Write the ar header for this item and the number of symbols */
 
-    bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
-    bfd_write (&orl_count, 1, sizeof (orl_count), arch);
+    bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
+    /* FIXME, this needs to be byte-swapped */
+    bfd_write ((PTR)&orl_count, 1, sizeof (orl_count), arch);
 
     /* Two passes, first write the file offsets for each symbol -
        remembering that each offset is on a two byte boundary
@@ -1211,7 +1289,8 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
            current = current->next;
            last_eltno++;
        }
-       bfd_write (&archive_member_file_ptr,
+       /* FIXME, this needs to be byte-swapped */
+       bfd_write ((PTR)&archive_member_file_ptr,
                   1,
                   sizeof (archive_member_file_ptr),
                   arch);
@@ -1219,7 +1298,7 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
 
     /* now write the strings themselves */
     for (count = 0; count < orl_count; count++) {
-       bfd_write (*((map[count]).name),
+       bfd_write ((PTR)*((map[count]).name),
                   1,
                   strlen (*((map[count]).name))+1, arch);
 
This page took 0.05762 seconds and 4 git commands to generate.