* hosts/h-amix.h (free): Fix prototype.
[deliverable/binutils-gdb.git] / bfd / archive.c
index 13135406f169031dcdb8c5818f5a4cfd6c51d608..fdac8df13b22dd0f6c6536621a3e5af035f00c6a 100644 (file)
@@ -1,25 +1,37 @@
+/* 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.
 
-/*** archive.c -- an attempt at combining the machine-independent parts of
-  archives */
+This file is part of BFD, the Binary File Descriptor library.
 
-/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
-
-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;
@@ -27,11 +39,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    o - all arch headers are the same size (across architectures).
 */
 
-/* $Id$ 
- */
-
+/* $Id$ */
 
-#include "sysdep.h"
+#include <sysdep.h>
 #include "bfd.h"
 #include "libbfd.h"
 #include "ar.h"
@@ -59,16 +69,14 @@ 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 = bfd_zalloc(abfd, 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;
   }
@@ -76,10 +84,14 @@ _bfd_generic_mkarchive (abfd)
   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)) {
@@ -88,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);
@@ -111,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;
 }
@@ -140,7 +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 *)bfd_zalloc(arch_bfd,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;
@@ -172,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
@@ -200,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;
@@ -227,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;
@@ -261,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;
@@ -296,6 +323,7 @@ get_elt_at_filepos (archive, filepos)
   
   n_nfd = _bfd_create_empty_archive_element_shell (archive);
   if (n_nfd == NULL) {
+    bfd_release (archive, (PTR)new_areldata);
     return NULL;
   }
   n_nfd->origin = bfd_tell (archive);
@@ -306,9 +334,16 @@ get_elt_at_filepos (archive, filepos)
     return n_nfd;
 
   /* huh? */
+  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;
@@ -320,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) ||
@@ -349,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);
 }
@@ -376,7 +422,9 @@ bfd_generic_archive_p (abfd)
   if (strncmp (armag, ARMAG, SARMAG)) return 0;
 #endif
 
-  bfd_set_ardata(abfd, (struct artdata *) bfd_zalloc(abfd,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;
@@ -391,7 +439,6 @@ bfd_generic_archive_p (abfd)
     return 0;
   }
 
-  /* armap could be left ungc'd! FIXME -- potential storage leak */
   if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
     bfd_release(abfd, bfd_ardata (abfd));
     abfd->tdata = NULL;
@@ -406,6 +453,7 @@ boolean
 bfd_slurp_bsd_armap (abfd)
      bfd *abfd;
 {
+
   struct areltdata *mapdata;
   char nextname[17];
   unsigned int counter = 0;
@@ -413,6 +461,9 @@ bfd_slurp_bsd_armap (abfd)
   struct artdata *ardata = bfd_ardata (abfd);
   char *stringbase;
 
+  /* 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);
@@ -431,29 +482,35 @@ bfd_slurp_bsd_armap (abfd)
       if (raw_armap == NULL) {
          bfd_error = no_memory;
   byebye:
+         bfd_release (abfd, (PTR)mapdata);
          return false;
       }
 
       if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
          mapdata->parsed_size) {
          bfd_error = malformed_archive;
+         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;
+      /* 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;
@@ -471,15 +528,12 @@ bfd_slurp_coff_armap (abfd)
   char *stringbase;
   unsigned int stringsize;
   carsym *carsyms;
+  int result;
 
-  if (bfd_read ((PTR)&nextname, 1, 1, abfd) != 1) {
-  bfd_seek (abfd, -1L, SEEK_CUR);
-    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;
@@ -489,18 +543,21 @@ bfd_slurp_coff_armap (abfd)
   if (mapdata == NULL) return false;
 
   raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
-  if (raw_armap == NULL) {
+
+  if (raw_armap == NULL) 
+      {
     bfd_error = no_memory;
   byebye:
-
+    bfd_release (abfd, (PTR)mapdata);
     return false;
   }
 
+  /* read in the raw map */
   if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
       mapdata->parsed_size) {
     bfd_error = malformed_archive;
   oops:
-
+    bfd_release (abfd, (PTR)raw_armap);
     goto byebye;
   }
 
@@ -541,18 +598,24 @@ bfd_slurp_coff_armap (abfd)
   /* Pad to an even boundary if you have to */
   ardata->first_file_filepos += (ardata->first_file_filepos) %2;
 
+  /* 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
@@ -562,50 +625,56 @@ _bfd_slurp_extended_name_table (abfd)
   char nextname[17];
   struct areltdata *namedata;
 
+  /* 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 = bfd_zalloc(abfd,namedata->parsed_size);
-  if (bfd_ardata (abfd)->extended_names == NULL) {
-    bfd_error = no_memory;
-  byebye:
-
-    return false;
-  }
-
-  if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
-               namedata->parsed_size, abfd) != namedata->parsed_size) {
-    bfd_error = malformed_archive;
+    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;
+    }
 
-    bfd_ardata (abfd)->extended_names = NULL;
-    goto byebye;
-  }
+    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;
+    }
 
-  /* It appears that the extended names are newline-padded, not null padded.
-     */
-  {
-    char *temp = bfd_ardata (abfd)->extended_names;
-    for (; *temp != '\0'; ++temp)
-      if (*temp == '\n') *temp = '\0';
-  }
+    /* 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;
-
-
-}
+    /* 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;
 }
 
@@ -788,17 +857,17 @@ bfd_generic_stat_arch_elt (abfd, buf)
 void
 bfd_dont_truncate_arname (abfd, pathname, arhdr)
      bfd *abfd;
-     char *pathname;
+     CONST char *pathname;
      char *arhdr;
 {
-  /* This interacts unpleasantly with ar's quick-append option.
+  /* 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;
-  char *filename = strrchr (pathname, '/');
+  CONST char *filename = strrchr (pathname, '/');
   int maxlen = ar_maxnamelen (abfd);
 
   if (filename == NULL)
@@ -819,12 +888,12 @@ bfd_dont_truncate_arname (abfd, pathname, arhdr)
 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);
 
 
@@ -857,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)
@@ -889,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;
@@ -901,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.
@@ -961,7 +1029,7 @@ _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);
 
@@ -973,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;
@@ -996,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;
@@ -1057,8 +1123,8 @@ compute_and_write_armap (arch, elength)
                                                    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;
@@ -1079,9 +1145,6 @@ compute_and_write_armap (arch, elength)
   return true;
 }
 
-\f
- /* FIXME -- have to byte-swap this */
-
 boolean
 bsd_write_armap (arch, elength, map, orl_count, stridx)
      bfd *arch;
@@ -1095,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;
@@ -1110,35 +1173,38 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
   stat (arch->filename, &statbuf);
   memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
   sprintf (hdr.ar_name, RANLIBMAG);
-  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
   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);
 
@@ -1205,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
@@ -1222,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);
@@ -1230,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.032543 seconds and 4 git commands to generate.