Minor cleanups suggested by CodeCenter.
[external/binutils.git] / bfd / archive.c
1 /* BFD back-end for archive files (libraries).
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Written by Cygnus Support.  Mostly Gumby Henkel-Wallace's fault.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /*
22 @setfilename archive-info
23 SECTION
24         Archives
25
26 DESCRIPTION
27         An archive (or library) is just another BFD.  It has a symbol
28         table, although there's not much a user program will do with it.
29
30         The big difference between an archive BFD and an ordinary BFD
31         is that the archive doesn't have sections.  Instead it has a
32         chain of BFDs that are considered its contents.  These BFDs can
33         be manipulated like any other.  The BFDs contained in an
34         archive opened for reading will all be opened for reading.  You
35         may put either input or output BFDs into an archive opened for
36         output; they will be handled correctly when the archive is closed.
37
38         Use <<bfd_openr_next_archived_file>> to step through
39         the contents of an archive opened for input.  You don't
40         have to read the entire archive if you don't want
41         to!  Read it until you find what you want.
42
43         Archive contents of output BFDs are chained through the
44         <<next>> pointer in a BFD.  The first one is findable through
45         the <<archive_head>> slot of the archive.  Set it with
46         <<bfd_set_archive_head>> (q.v.).  A given BFD may be in only one
47         open output archive at a time.
48
49         As expected, the BFD archive code is more general than the
50         archive code of any given environment.  BFD archives may
51         contain files of different formats (e.g., a.out and coff) and
52         even different architectures.  You may even place archives
53         recursively into archives!
54
55         This can cause unexpected confusion, since some archive
56         formats are more expressive than others.  For instance, Intel
57         COFF archives can preserve long filenames; SunOS a.out archives
58         cannot.  If you move a file from the first to the second
59         format and back again, the filename may be truncated.
60         Likewise, different a.out environments have different
61         conventions as to how they truncate filenames, whether they
62         preserve directory names in filenames, etc.  When
63         interoperating with native tools, be sure your files are
64         homogeneous.
65
66         Beware: most of these formats do not react well to the
67         presence of spaces in filenames.  We do the best we can, but
68         can't always handle this case due to restrictions in the format of
69         archives.  Many Unix utilities are braindead in regards to
70         spaces and such in filenames anyway, so this shouldn't be much
71         of a restriction.
72
73         Archives are supported in BFD in <<archive.c>>.
74
75 */
76
77 /* Assumes:
78    o - all archive elements start on an even boundary, newline padded;
79    o - all arch headers are char *;
80    o - all arch headers are the same size (across architectures).
81 */
82
83 /* Some formats provide a way to cram a long filename into the short
84    (16 chars) space provided by a BSD archive.  The trick is: make a
85    special "file" in the front of the archive, sort of like the SYMDEF
86    entry.  If the filename is too long to fit, put it in the extended
87    name table, and use its index as the filename.  To prevent
88    confusion prepend the index with a space.  This means you can't
89    have filenames that start with a space, but then again, many Unix
90    utilities can't handle that anyway.
91
92    This scheme unfortunately requires that you stand on your head in
93    order to write an archive since you need to put a magic file at the
94    front, and need to touch every entry to do so.  C'est la vie.
95
96    We support two variants of this idea:
97    The SVR4 format (extended name table is named "//"),
98    and an extended pseudo-BSD variant (extended name table is named
99    "ARFILENAMES/").  The origin of the latter format is uncertain.
100
101    BSD 4.4 uses a third scheme:  It writes a long filename
102    directly after the header.  This allows 'ar q' to work.
103    We currently can read BSD 4.4 archives, but not write them.
104 */
105
106 /* Summary of archive member names:
107
108  Symbol table (must be first):
109  "__.SYMDEF       " - Symbol table, Berkeley style, produced by ranlib.
110  "/               " - Symbol table, system 5 style.
111
112  Long name table (must be before regular file members):
113  "//              " - Long name table, System 5 R4 style.
114  "ARFILENAMES/    " - Long name table, non-standard extended BSD (not BSD 4.4).
115
116  Regular file members with short names:
117  "filename.o/     " - Regular file, System 5 style (embedded spaces ok).
118  "filename.o      " - Regular file, Berkeley style (no embedded spaces).
119
120  Regular files with long names (or embedded spaces, for BSD variants):
121  "/18             " - SVR4 style, name at offset 18 in name table.
122  "#1/23           " - Long name (or embedded paces) 23 characters long,
123                       BSD 4.4 style, full name follows header.
124                       Implemented for reading, not writing.
125  " 18             " - Long name 18 characters long, extended pseudo-BSD.
126  */
127
128 #include "bfd.h"
129 #include "sysdep.h"
130 #include "libbfd.h"
131 #include "aout/ar.h"
132 #include "aout/ranlib.h"
133 #include <errno.h>
134 #include <string.h>             /* For memchr, strrchr and friends */
135 #include <ctype.h>
136
137 #ifndef errno
138 extern int errno;
139 #endif
140
141 #ifdef GNU960
142 #define BFD_GNU960_ARMAG(abfd)  (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
143 #endif
144
145 /* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file
146    is included, then obstack.h, which thinks if offsetof is defined, it
147    doesn't need to include stddef.h.  */
148 /* Define offsetof for those systems which lack it */
149
150 #if !defined (offsetof)
151 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
152 #endif
153
154 /* We keep a cache of archive filepointers to archive elements to
155    speed up searching the archive by filepos.  We only add an entry to
156    the cache when we actually read one.  We also don't sort the cache;
157    it's generally short enough to search linearly.
158    Note that the pointers here point to the front of the ar_hdr, not
159    to the front of the contents!
160 */
161 struct ar_cache {
162   file_ptr ptr;
163   bfd* arelt;
164   struct ar_cache *next;
165 };
166
167 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
168 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
169
170 #define arch_eltdata(bfd) ((struct areltdata *)((bfd)->arelt_data))
171 #define arch_hdr(bfd) ((struct ar_hdr *)arch_eltdata(bfd)->arch_header)
172
173 /* Forward declarations of functions */
174
175 boolean
176 compute_and_write_armap PARAMS ((bfd *arch, unsigned int elength));
177
178 static boolean
179 bsd_update_armap_timestamp PARAMS ((bfd *arch));
180
181
182 \f
183 boolean
184 _bfd_generic_mkarchive (abfd)
185      bfd *abfd;
186 {
187   abfd->tdata.aout_ar_data = (struct artdata *)bfd_zalloc(abfd,
188                                                           sizeof (struct artdata));
189
190   if (bfd_ardata (abfd) == NULL) {
191       bfd_error = no_memory;
192       return false;
193     }
194   bfd_ardata(abfd)->cache = 0;
195   return true;
196 }
197
198 /*
199 FUNCTION
200         bfd_get_next_mapent
201
202 SYNOPSIS
203         symindex bfd_get_next_mapent(bfd *abfd, symindex previous, carsym **sym);
204
205 DESCRIPTION
206         Step through archive @var{abfd}'s symbol table (if it
207         has one).  Successively update @var{sym} with the next symbol's
208         information, returning that symbol's (internal) index into the
209         symbol table.
210
211         Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get
212         the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already
213         got the last one.
214
215         A <<carsym>> is a canonical archive symbol.  The only
216         user-visible element is its name, a null-terminated string.
217 */
218
219 symindex
220 DEFUN(bfd_get_next_mapent,(abfd, prev, entry),
221      bfd *abfd AND
222      symindex prev AND
223      carsym **entry)
224 {
225   if (!bfd_has_map (abfd)) {
226     bfd_error = invalid_operation;
227     return BFD_NO_MORE_SYMBOLS;
228   }
229   
230   if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
231   else if (++prev >= bfd_ardata (abfd)->symdef_count)
232     return BFD_NO_MORE_SYMBOLS;
233
234   *entry = (bfd_ardata (abfd)->symdefs + prev);
235   return prev;
236 }
237
238 /* To be called by backends only */
239
240 bfd *
241 _bfd_create_empty_archive_element_shell (obfd)
242      bfd *obfd;
243 {
244   bfd *nbfd;
245
246   nbfd = new_bfd_contained_in(obfd);
247   if (nbfd == NULL)
248     {
249       bfd_error = no_memory;
250       return NULL;
251     }
252   return nbfd;
253 }
254
255 /*
256 FUNCTION
257         bfd_set_archive_head
258
259 SYNOPSIS
260         boolean bfd_set_archive_head(bfd *output, bfd *new_head);
261
262 DESCRIPTION
263         Set the head of the chain of
264         BFDs contained in the archive @var{output} to @var{new_head}. 
265 */
266
267 boolean
268 DEFUN(bfd_set_archive_head,(output_archive, new_head),
269      bfd *output_archive AND 
270      bfd *new_head)
271 {
272
273   output_archive->archive_head = new_head;
274   return true;
275 }
276
277 bfd *
278 look_for_bfd_in_cache (arch_bfd, filepos)
279      bfd *arch_bfd;
280      file_ptr filepos;
281 {
282   struct ar_cache *current;
283
284   for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
285        current = current->next)
286     if (current->ptr == filepos) return current->arelt;
287
288   return NULL;
289 }
290
291 /* Kind of stupid to call cons for each one, but we don't do too many */
292 boolean
293 add_bfd_to_cache (arch_bfd, filepos, new_elt)
294      bfd *arch_bfd, *new_elt;
295      file_ptr filepos;
296 {
297   struct ar_cache *new_cache = (struct ar_cache *)
298                                 bfd_zalloc(arch_bfd, sizeof (struct ar_cache));
299
300   if (new_cache == NULL) {
301     bfd_error = no_memory;
302     return false;
303   }
304
305   new_cache->ptr = filepos;
306   new_cache->arelt = new_elt;
307   new_cache->next = (struct ar_cache *)NULL;
308   if (bfd_ardata (arch_bfd)->cache == NULL)
309     bfd_ardata (arch_bfd)->cache = new_cache;
310   else {
311     struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
312
313     while (current->next != NULL)
314       current = current->next;
315     current->next = new_cache;
316   }
317     
318   return true;
319 }
320
321 \f
322
323 /* The name begins with space.  Hence the rest of the name is an index into
324    the string table. */
325 char *
326 get_extended_arelt_filename (arch, name)
327      bfd *arch;
328      char *name;
329 {
330   unsigned long index = 0;
331
332   /* Should extract string so that I can guarantee not to overflow into
333      the next region, but I'm too lazy. */
334   errno = 0;
335   /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */
336   index = strtol (name+1, NULL, 10);
337   if (errno != 0) {
338       bfd_error = malformed_archive;
339       return NULL;
340     }
341
342   return bfd_ardata (arch)->extended_names + index;
343 }  
344
345 /* This functions reads an arch header and returns an areltdata pointer, or
346    NULL on error.
347
348    Presumes the file pointer is already in the right place (ie pointing
349    to the ar_hdr in the file).   Moves the file pointer; on success it
350    should be pointing to the front of the file contents; on failure it
351    could have been moved arbitrarily.
352 */
353
354 struct areltdata *
355 snarf_ar_hdr (abfd)
356      bfd *abfd;
357 {
358 #ifndef errno
359   extern int errno;
360 #endif
361
362     struct ar_hdr hdr;
363     char *hdrp = (char *) &hdr;
364     unsigned int parsed_size;
365     struct areltdata *ared;
366     char *filename = NULL;
367     unsigned int namelen = 0;
368     unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
369     char *allocptr = 0;
370
371     if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
372         != sizeof (struct ar_hdr)) {
373         bfd_error = no_more_archived_files;
374         return NULL;
375     }
376     if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
377         bfd_error = malformed_archive;
378         return NULL;
379     }
380
381     errno = 0;
382     parsed_size = strtol (hdr.ar_size, NULL, 10);
383     if (errno != 0) {
384         bfd_error = malformed_archive;
385         return NULL;
386     }
387
388     /* extract the filename from the archive - there are two ways to
389        specify an extendend name table, either the first char of the
390        name is a space, or it's a slash.  */
391     if ((hdr.ar_name[0] == '/'
392          || (hdr.ar_name[0] == ' '
393              && memchr (hdr.ar_name, '/', ar_maxnamelen(abfd)) == NULL))
394         && bfd_ardata (abfd)->extended_names != NULL) {
395         filename = get_extended_arelt_filename (abfd, hdr.ar_name);
396         if (filename == NULL) {
397             bfd_error = malformed_archive;
398             return NULL;
399         }
400     }
401     /* BSD4.4-style long filename.
402        Only implemented for reading, so far! */
403     else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1'
404              && hdr.ar_name[2] == '/' && isdigit(hdr.ar_name[3]))
405       {
406         /* BSD-4.4 extended name */
407         namelen = atoi (&hdr.ar_name[3]);
408         allocsize += namelen + 1;
409         parsed_size -= namelen;
410
411         allocptr = bfd_zalloc(abfd, allocsize);
412         if (allocptr == NULL) {
413           bfd_error = no_memory;
414           return NULL;
415         }
416         filename = allocptr
417           + (sizeof (struct areltdata) + sizeof (struct ar_hdr));
418         if (bfd_read (filename, 1, namelen, abfd) != namelen) {
419           bfd_error = no_more_archived_files;
420           return NULL;
421         }
422         filename[namelen] = '\0';
423       }
424     else 
425         {
426             /* We judge the end of the name by looking for '/' or ' '.
427                Note:  The SYSV format (terminated by '/') allows embedded
428                spaces, so only look for ' ' if we don't find '/'. */
429
430             namelen = 0;
431             while (hdr.ar_name[namelen] != '\0' &&
432                    hdr.ar_name[namelen] != '/') {
433                 namelen++;
434                 if (namelen == (unsigned)ar_maxnamelen(abfd)) {
435                     namelen = 0;
436                     while (hdr.ar_name[namelen] != ' '
437                            && namelen < (unsigned)ar_maxnamelen(abfd)) {
438                         namelen++;
439                     }
440                     break;
441                 }
442             }
443
444             allocsize += namelen + 1;
445         }
446
447     if (!allocptr) {
448       allocptr = bfd_zalloc(abfd, allocsize);
449       if (allocptr == NULL) {
450         bfd_error = no_memory;
451         return NULL;
452       }
453     }
454
455     ared = (struct areltdata *) allocptr;
456
457     ared->arch_header = allocptr + sizeof (struct areltdata);
458     memcpy ((char *) ared->arch_header, (char *) &hdr, sizeof (struct ar_hdr));
459     ared->parsed_size = parsed_size;
460
461     if (filename != NULL) ared->filename = filename;
462     else {
463         ared->filename = allocptr + (sizeof (struct areltdata) +
464                                      sizeof (struct ar_hdr));
465         if (namelen)
466             memcpy (ared->filename, hdr.ar_name, namelen);
467         ared->filename[namelen] = '\0';
468     }
469   
470     return ared;
471 }
472 \f
473 /* This is an internal function; it's mainly used when indexing
474    through the archive symbol table, but also used to get the next
475    element, since it handles the bookkeeping so nicely for us.
476 */
477
478 bfd *
479 get_elt_at_filepos (archive, filepos)
480      bfd *archive;
481      file_ptr filepos;
482 {
483   struct areltdata *new_areldata;
484   bfd *n_nfd;
485
486   n_nfd = look_for_bfd_in_cache (archive, filepos);
487   if (n_nfd)
488     return n_nfd;
489
490   if (0 > bfd_seek (archive, filepos, SEEK_SET))
491     {
492       bfd_error = system_call_error;
493       return NULL;
494     }
495
496   if ((new_areldata = snarf_ar_hdr (archive)) == NULL)
497     return NULL;
498   
499   n_nfd = _bfd_create_empty_archive_element_shell (archive);
500   if (n_nfd == NULL)
501     {
502       bfd_release (archive, (PTR)new_areldata);
503       return NULL;
504     }
505
506   n_nfd->origin = bfd_tell (archive);
507   n_nfd->arelt_data = (PTR) new_areldata;
508   n_nfd->filename = new_areldata->filename;
509
510   if (add_bfd_to_cache (archive, filepos, n_nfd))
511     return n_nfd;
512
513   /* huh? */
514   bfd_release (archive, (PTR)n_nfd);
515   bfd_release (archive, (PTR)new_areldata);
516   return NULL;
517 }
518
519 /*
520 FUNCTION
521         bfd_get_elt_at_index
522
523 SYNOPSIS
524         bfd *bfd_get_elt_at_index(bfd *archive, int index);
525
526 DESCRIPTION
527         Return the BFD which is referenced by the symbol in @var{archive}
528         indexed by @var{index}.  @var{index} should have been returned by
529         <<bfd_get_next_mapent>> (q.v.).
530
531 */
532 bfd *
533 DEFUN(bfd_get_elt_at_index,(abfd, index),
534      bfd *abfd AND
535      int index)
536 {
537   bfd *result =
538     get_elt_at_filepos
539       (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
540   return result;
541 }
542
543 /*
544 FUNCTION
545         bfd_openr_next_archived_file
546
547 SYNOPSIS
548         bfd *bfd_openr_next_archived_file(bfd *archive, bfd *previous);
549
550 DESCRIPTION
551         Provided a BFD, @var{archive}, containing an archive and NULL, open
552         an input BFD on the first contained element and returns that.
553         Subsequent calls should pass
554         the archive and the previous return value to return a created
555         BFD to the next contained element. NULL is returned when there
556         are no more.
557
558 */
559
560 bfd *
561 bfd_openr_next_archived_file (archive, last_file)
562      bfd *archive;
563      bfd *last_file;
564 {
565   if ((bfd_get_format (archive) != bfd_archive) ||
566       (archive->direction == write_direction))
567     {
568       bfd_error = invalid_operation;
569       return NULL;
570     }
571
572   return BFD_SEND (archive,
573                    openr_next_archived_file,
574                    (archive,
575                     last_file));
576 }
577
578 bfd *
579 bfd_generic_openr_next_archived_file (archive, last_file)
580      bfd *archive;
581      bfd *last_file;
582 {
583   file_ptr filestart;
584
585   if (!last_file)
586     filestart = bfd_ardata (archive)->first_file_filepos;
587   else {
588     unsigned int size = arelt_size(last_file);
589     /* Pad to an even boundary... 
590        Note that last_file->origin can be odd in the case of
591        BSD-4.4-style element with a long odd size. */
592     filestart = last_file->origin + size;
593     filestart += filestart % 2;
594   }
595
596   return get_elt_at_filepos (archive, filestart);
597 }
598
599
600 bfd_target *
601 bfd_generic_archive_p (abfd)
602      bfd *abfd;
603 {
604   char armag[SARMAG+1];
605
606   if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
607     bfd_error = wrong_format;
608     return 0;
609   }
610
611 #ifdef GNU960
612   if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
613 #else
614   if (strncmp (armag, ARMAG, SARMAG) &&
615       strncmp (armag, ARMAGB, SARMAG)) return 0;
616 #endif
617
618
619
620   /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
621      involves a cast, we can't do it as the left operand of assignment. */
622   abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc(abfd,sizeof (struct artdata));
623
624   if (bfd_ardata (abfd)  == NULL) {
625     bfd_error = no_memory;
626     return 0;
627   }
628
629   bfd_ardata (abfd)->first_file_filepos = SARMAG;
630   
631   if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
632     bfd_release(abfd, bfd_ardata (abfd));
633     abfd->tdata.aout_ar_data = NULL;
634     return 0;
635   }
636
637   if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
638     bfd_release(abfd, bfd_ardata (abfd));
639     abfd->tdata.aout_ar_data = NULL;
640     return 0;
641   }
642   
643   return abfd->xvec;
644 }
645
646 /* Returns false on error, true otherwise */
647 static boolean
648 DEFUN (do_slurp_bsd_armap, (abfd),
649        bfd *abfd)
650 {
651   struct areltdata *mapdata;
652   unsigned int counter = 0;
653   int *raw_armap, *rbase;
654   struct artdata *ardata = bfd_ardata (abfd);
655   char *stringbase;
656   unsigned int parsed_size;
657
658   mapdata = snarf_ar_hdr (abfd);
659   if (mapdata == NULL) return false;
660   parsed_size = mapdata->parsed_size;
661   bfd_release (abfd, (PTR)mapdata); /* Don't need it any more. */
662     
663   raw_armap = (int *) bfd_zalloc(abfd, parsed_size);
664   if (raw_armap == NULL) {
665       bfd_error = no_memory;
666       return false;
667   }
668     
669   if (bfd_read ((PTR)raw_armap, 1, parsed_size, abfd) != parsed_size) {
670       bfd_error = malformed_archive;
671     byebye:
672       bfd_release (abfd, (PTR)raw_armap);
673       return false;
674   }
675     
676   ardata->symdef_count = (bfd_h_get_32 (abfd, (bfd_byte *) raw_armap)
677                           / sizeof (struct symdef));
678     
679   if (ardata->symdef_count * sizeof (struct symdef)
680       > parsed_size - sizeof (*raw_armap)) {
681       /* Probably we're using the wrong byte ordering.  */
682       bfd_error = wrong_format;
683       goto byebye;
684   }
685   
686   ardata->cache = 0;
687   rbase = raw_armap+1;
688   ardata->symdefs = (carsym *) rbase;
689   stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
690   
691   for (;counter < ardata->symdef_count; counter++) {
692       struct symdef *sym = ((struct symdef *) rbase) + counter;
693       sym->s.name = (bfd_h_get_32 (abfd, (bfd_byte *) (&sym->s.string_offset))
694                      + stringbase);
695       sym->file_offset = bfd_h_get_32 (abfd,
696                                        (bfd_byte *) (&(sym->file_offset)));
697   }
698   
699   ardata->first_file_filepos = bfd_tell (abfd);
700   /* Pad to an even boundary if you have to */
701   ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
702   /* FIXME, we should provide some way to free raw_ardata when
703      we are done using the strings from it.  For now, it seems
704      to be allocated on an obstack anyway... */
705   bfd_has_map (abfd) = true;
706   return true;
707 }
708
709 /* Returns false on error, true otherwise */
710 static boolean
711 DEFUN (do_slurp_coff_armap, (abfd),
712        bfd *abfd)
713 {
714   struct areltdata *mapdata;
715   int *raw_armap, *rawptr;
716   struct artdata *ardata = bfd_ardata (abfd);
717   char *stringbase;
718   unsigned int stringsize;
719   unsigned int parsed_size;
720   carsym *carsyms;
721   unsigned int nsymz; /* Number of symbols in armap. */
722
723   bfd_vma (*swap) PARAMS ((bfd_byte*));
724   char int_buf[sizeof(long)];
725   unsigned int carsym_size, ptrsize, i;
726   
727   mapdata = snarf_ar_hdr (abfd);
728   if (mapdata == NULL) return false;
729   parsed_size = mapdata->parsed_size;
730   bfd_release (abfd, (PTR)mapdata); /* Don't need it any more. */
731
732   if (bfd_read ((PTR)int_buf, 1, 4, abfd) != 4) {
733     bfd_error = malformed_archive;
734     return false;
735   }
736   /* It seems that all numeric information in a coff archive is always
737      in big endian format, nomatter the host or target. */
738   swap = bfd_getb32;
739   nsymz = bfd_getb32((PTR)int_buf);
740   stringsize = parsed_size - (4 * nsymz) - 4;
741
742 #if 1
743   /* ... except that some archive formats are broken, and it may be our
744      fault - the i960 little endian coff sometimes has big and sometimes
745      little, because our tools changed.  Here's a horrible hack to clean
746      up the crap.  */
747   
748   if (stringsize > 0xfffff) {
749       /* This looks dangerous, let's do it the other way around */
750       nsymz = bfd_getl32((PTR)int_buf);
751       stringsize = parsed_size - (4 * nsymz) - 4;
752       swap = bfd_getl32;
753   }
754 #endif
755
756   /* The coff armap must be read sequentially.  So we construct a bsd-style
757      one in core all at once, for simplicity. */  
758   
759   carsym_size = (nsymz * sizeof (carsym));
760   ptrsize = (4 * nsymz);
761
762   ardata->symdefs = (carsym *) bfd_zalloc(abfd, carsym_size + stringsize + 1);
763   if (ardata->symdefs == NULL) {
764       bfd_error = no_memory;
765       return false;
766   }
767   carsyms = ardata->symdefs;
768   stringbase = ((char *) ardata->symdefs) + carsym_size;
769
770   /* Allocate and read in the raw offsets. */
771   raw_armap = (int *) bfd_alloc(abfd, ptrsize);
772   if (raw_armap == NULL) {
773       bfd_error = no_memory;
774       goto release_symdefs;
775   }
776   if (bfd_read ((PTR)raw_armap, 1, ptrsize, abfd) != ptrsize
777       || bfd_read ((PTR)stringbase, 1, stringsize, abfd) != stringsize) {
778     bfd_error = malformed_archive;
779     goto release_raw_armap;
780   }
781
782   /* OK, build the carsyms */
783   for (i = 0; i < nsymz; i++) {
784       rawptr = raw_armap + i;
785       carsyms->file_offset = swap((PTR)rawptr);
786       carsyms->name = stringbase;
787       stringbase += strlen (stringbase) + 1;
788       carsyms++;
789   }
790   *stringbase = 0;
791
792   ardata->symdef_count = nsymz;
793   ardata->first_file_filepos = bfd_tell (abfd);
794   /* Pad to an even boundary if you have to */
795   ardata->first_file_filepos += (ardata->first_file_filepos) %2;
796
797   bfd_has_map (abfd) = true;
798   bfd_release (abfd, (PTR)raw_armap);
799   return true;
800
801  release_raw_armap:
802   bfd_release (abfd, (PTR)raw_armap);
803  release_symdefs:
804   bfd_release (abfd, (PTR)(ardata)->symdefs);
805   return false;
806 }
807
808 /* This routine can handle either coff-style or bsd-style armaps.
809    Returns false on error, true otherwise */
810
811 boolean
812 bfd_slurp_armap (abfd)
813      bfd *abfd;
814 {
815   char nextname[17];
816   int i = bfd_read ((PTR)nextname, 1, 16, abfd);
817   
818   if (i == 0)
819       return true;
820   if (i != 16)
821       return false;
822
823   bfd_seek (abfd, (file_ptr) -16, SEEK_CUR);
824
825   if (!strncmp (nextname, "__.SYMDEF       ", 16))
826     return do_slurp_bsd_armap (abfd);
827   else if (!strncmp (nextname, "/               ", 16))
828     return do_slurp_coff_armap (abfd);
829
830   bfd_has_map (abfd) = false;
831   return true;
832 }
833 \f
834 /* Returns false on error, true otherwise */
835 /* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the
836    header is in a slightly different order and the map name is '/'. 
837    This flavour is used by hp300hpux. */
838 boolean
839 bfd_slurp_bsd_armap_f2 (abfd)  
840      bfd *abfd;
841 {
842   struct areltdata *mapdata;
843   char nextname[17];
844   unsigned int counter = 0;
845   int *raw_armap, *rbase;
846   struct artdata *ardata = bfd_ardata (abfd);
847   char *stringbase;
848   unsigned int stringsize;
849   int i = bfd_read ((PTR)nextname, 1, 16, abfd);
850
851   if (i == 0)
852     return true;
853   if (i != 16)
854     return false;
855
856   /* The archive has at least 16 bytes in it */
857   bfd_seek (abfd, -16L, SEEK_CUR);
858
859   if (!strncmp (nextname, "__.SYMDEF       ", 16))
860     return do_slurp_bsd_armap (abfd);
861
862   if (strncmp (nextname, "/               ", 16))
863     {
864       bfd_has_map (abfd) = false;
865       return true;
866     }
867
868   mapdata = snarf_ar_hdr (abfd);
869   if (mapdata == NULL) return false;
870
871   raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
872   if (raw_armap == NULL)
873     {
874       bfd_error = no_memory;
875     byebye:
876       bfd_release (abfd, (PTR)mapdata);
877       return false;
878     }
879
880   if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
881       mapdata->parsed_size)
882     {
883       bfd_error = malformed_archive;
884     byebyebye:
885       bfd_release (abfd, (PTR)raw_armap);
886       goto byebye;
887     }
888
889   ardata->symdef_count = bfd_h_get_16(abfd, (PTR)raw_armap);
890
891   if (ardata->symdef_count * sizeof (struct symdef)
892       > mapdata->parsed_size - sizeof (*raw_armap))
893     {
894       /* Probably we're using the wrong byte ordering.  */
895       bfd_error = wrong_format;
896       goto byebyebye;
897     }
898
899   ardata->cache = 0;
900
901   stringsize = bfd_h_get_32(abfd, (PTR)(((char*)raw_armap)+2));
902   /* skip sym count and string sz */
903   rbase = (int*)(((char*)raw_armap) + 6);
904   stringbase = (char *) rbase;
905   ardata->symdefs = (carsym *)(((char*) rbase) + stringsize);
906
907   for (;counter < ardata->symdef_count; counter++)
908     {
909       struct symdef *sym = ((struct symdef *) ardata->symdefs) + counter;
910       sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
911       sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
912     }
913
914   ardata->first_file_filepos = bfd_tell (abfd);
915   /* Pad to an even boundary if you have to */
916   ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
917   /* FIXME, we should provide some way to free raw_ardata when
918      we are done using the strings from it.  For now, it seems
919      to be allocated on an obstack anyway... */
920   bfd_has_map (abfd) = true;
921   return true;
922 }
923 \f
924 /** Extended name table.
925
926   Normally archives support only 14-character filenames.
927
928   Intel has extended the format: longer names are stored in a special
929   element (the first in the archive, or second if there is an armap);
930   the name in the ar_hdr is replaced by <space><index into filename
931   element>.  Index is the P.R. of an int (decimal).  Data General have
932   extended the format by using the prefix // for the special element */
933
934 /* Returns false on error, true otherwise */
935 boolean
936 _bfd_slurp_extended_name_table (abfd)
937      bfd *abfd;
938 {
939   char nextname[17];
940   struct areltdata *namedata;
941
942   /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
943      we probably don't want to return true.  */
944   if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
945
946     bfd_seek (abfd, (file_ptr) -16, SEEK_CUR);
947
948     if (strncmp (nextname, "ARFILENAMES/    ", 16) != 0 &&
949         strncmp (nextname, "//              ", 16) != 0) 
950         {
951       bfd_ardata (abfd)->extended_names = NULL;
952       return true;
953     }
954
955     namedata = snarf_ar_hdr (abfd);
956     if (namedata == NULL) return false;
957   
958     bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
959     if (bfd_ardata (abfd)->extended_names == NULL) {
960       bfd_error = no_memory;
961     byebye:
962       bfd_release (abfd, (PTR)namedata);
963       return false;
964     }
965
966     if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
967                   namedata->parsed_size, abfd) != namedata->parsed_size) {
968       bfd_error = malformed_archive;
969       bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
970       bfd_ardata (abfd)->extended_names = NULL;
971       goto byebye;
972     }
973
974     /* Since the archive is supposed to be printable if it contains
975        text, the entries in the list are newline-padded, not null
976        padded. In SVR4-style archives, the names also have a
977        trailing '/'.  We'll fix both problems here..  */
978       {
979         char *temp = bfd_ardata (abfd)->extended_names;
980         char *limit = temp + namedata->parsed_size;
981         for (; temp < limit; ++temp)
982           if (*temp == '\n')
983             temp[temp[-1] == '/' ? -1 : 0] = '\0';
984       }
985   
986     /* Pad to an even boundary if you have to */
987     bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
988     bfd_ardata (abfd)->first_file_filepos +=
989       (bfd_ardata (abfd)->first_file_filepos) %2;
990
991     /* FIXME, we can't release namedata here because it was allocated
992        below extended_names on the obstack... */
993     /* bfd_release (abfd, namedata); */
994   }
995   return true;
996 }
997
998 #ifdef VMS
999
1000 /* Return a copy of the stuff in the filename between any :]> and a
1001    semicolon */
1002 static CONST char *
1003 DEFUN(normalize,(file),
1004       CONST char *file)
1005 {
1006   CONST char *first;
1007   CONST char *last;
1008   char *copy;
1009
1010   first = file + strlen(file)-1;
1011   last = first+1;
1012
1013   while (first != file) 
1014   {
1015     if (*first == ';') 
1016      last = first;
1017     if (*first == ':' || *first == ']' ||*first == '>') 
1018     { 
1019       first++;
1020       break;
1021     }
1022     first --;
1023   }
1024   
1025
1026   copy = bfd_xmalloc(last - first + 1);
1027   memcpy(copy, first, last-first);
1028   copy[last-first] = 0;
1029
1030   return copy;
1031 }
1032
1033 #else
1034 static CONST char *
1035 DEFUN (normalize, (file),
1036        CONST char *file)
1037 {
1038   CONST char *    filename = strrchr(file, '/');
1039
1040   if (filename != (char *)NULL) {
1041       filename ++;
1042     }
1043   else {
1044       filename = file;
1045     }
1046   return filename;
1047 }
1048 #endif
1049 /* Follows archive_head and produces an extended name table if necessary.
1050    Returns (in tabloc) a pointer to an extended name table, and in tablen
1051    the length of the table.  If it makes an entry it clobbers the filename
1052    so that the element may be written without further massage.
1053    Returns true if it ran successfully, false if something went wrong.
1054    A successful return may still involve a zero-length tablen!
1055    */
1056 boolean
1057 DEFUN (bfd_construct_extended_name_table, (abfd, tabloc, tablen),
1058        bfd *abfd AND
1059        char **tabloc AND
1060        unsigned int *tablen)
1061 {
1062   unsigned int maxname = abfd->xvec->ar_max_namelen;
1063   unsigned int total_namelen = 0;
1064   bfd *current;
1065   char *strptr;
1066
1067   *tablen = 0;
1068   
1069   /* Figure out how long the table should be */
1070   for (current = abfd->archive_head; current != NULL; current = current->next){
1071     unsigned int thislen = strlen (normalize(current->filename));
1072     if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
1073   }
1074
1075   if (total_namelen == 0) return true;
1076
1077   *tabloc = bfd_zalloc (abfd,total_namelen);
1078   if (*tabloc == NULL) {
1079     bfd_error = no_memory;
1080     return false;
1081   }
1082
1083   *tablen = total_namelen;
1084   strptr = *tabloc;
1085
1086   for (current = abfd->archive_head; current != NULL; current =
1087        current->next) {
1088     CONST char *normal =normalize( current->filename);
1089     unsigned int thislen = strlen (normal);
1090     if (thislen > maxname) {
1091       /* Works for now; may need to be re-engineered if we encounter an oddball
1092          archive format and want to generalise this hack. */
1093       struct ar_hdr *hdr = arch_hdr(current);
1094       strcpy (strptr, normal);
1095       strptr[thislen] = '\n';
1096       hdr->ar_name[0] = ' ';
1097       /* We know there will always be enough room (one of the few cases
1098          where you may safely use sprintf). */
1099       sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc));
1100       /* Kinda Kludgy.   We should just use the returned value of sprintf
1101          but not all implementations get this right */
1102         {
1103           char *temp = hdr->ar_name +2; 
1104           for (; temp < hdr->ar_name + maxname; temp++)
1105             if (*temp == '\0') *temp = ' ';
1106         }
1107       strptr += thislen + 1;
1108     }
1109   }
1110
1111   return true;
1112 }
1113 \f
1114 /** A couple of functions for creating ar_hdrs */
1115
1116 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
1117    The filename must refer to a filename in the filesystem.
1118    The filename field of the ar_hdr will NOT be initialized
1119 */
1120
1121 struct areltdata *
1122 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
1123       bfd* abfd AND
1124       CONST char *filename)
1125 {
1126   struct stat status;
1127   struct areltdata *ared;
1128   struct ar_hdr *hdr;
1129   char *temp, *temp1;
1130
1131
1132   if (stat (filename, &status) != 0) {
1133     bfd_error = system_call_error;
1134     return NULL;
1135   }
1136
1137   ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
1138                                       sizeof (struct areltdata));
1139   if (ared == NULL) {
1140     bfd_error = no_memory;
1141     return NULL;
1142   }
1143   hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
1144
1145   /* ar headers are space padded, not null padded! */
1146   memset (hdr, ' ', sizeof (struct ar_hdr));
1147
1148   strncpy (hdr->ar_fmag, ARFMAG, 2);
1149   
1150   /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
1151   sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
1152   sprintf ((hdr->ar_uid), "%d", status.st_uid);
1153   sprintf ((hdr->ar_gid), "%d", status.st_gid);
1154   sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
1155   sprintf ((hdr->ar_size), "%-10ld", status.st_size);
1156   /* Correct for a lossage in sprintf whereby it null-terminates.  I cannot
1157      understand how these C losers could design such a ramshackle bunch of
1158      IO operations */
1159   temp = (char *) hdr;
1160   temp1 = temp + sizeof (struct ar_hdr) - 2;
1161   for (; temp < temp1; temp++) {
1162     if (*temp == '\0') *temp = ' ';
1163   }
1164   strncpy (hdr->ar_fmag, ARFMAG, 2);
1165   ared->parsed_size = status.st_size;
1166   ared->arch_header = (char *) hdr;
1167
1168   return ared;
1169 }
1170
1171 /* This is magic required by the "ar" program.  Since it's
1172     undocumented, it's undocumented.   You may think that it would
1173     take a strong stomach to write this, and it does, but it takes
1174     even a stronger stomach to try to code around such a thing!
1175 */
1176
1177 struct ar_hdr *
1178 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
1179       bfd *abfd AND
1180       char *filename)
1181 {
1182   struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename);
1183   if (ar_elt == NULL)
1184       return NULL;
1185   return (struct ar_hdr *) ar_elt->arch_header;
1186 }
1187
1188
1189 /* Analogous to stat call */
1190 int
1191 bfd_generic_stat_arch_elt (abfd, buf)
1192      bfd *abfd;
1193      struct stat *buf;
1194 {
1195   struct ar_hdr *hdr;
1196   char *aloser;
1197   
1198   if (abfd->arelt_data == NULL) {
1199     bfd_error = invalid_operation;
1200     return -1;
1201   }
1202     
1203   hdr = arch_hdr (abfd);
1204
1205 #define foo(arelt, stelt, size)  \
1206   buf->stelt = strtol (hdr->arelt, &aloser, size); \
1207   if (aloser == hdr->arelt) return -1;
1208   
1209   foo (ar_date, st_mtime, 10);
1210   foo (ar_uid, st_uid, 10);
1211   foo (ar_gid, st_gid, 10);
1212   foo (ar_mode, st_mode, 8);
1213
1214   buf->st_size = arch_eltdata (abfd)->parsed_size;
1215
1216   return 0;
1217 }
1218
1219 void
1220 bfd_dont_truncate_arname (abfd, pathname, arhdr)
1221      bfd *abfd;
1222      CONST char *pathname;
1223      char *arhdr;
1224 {
1225   /* FIXME: This interacts unpleasantly with ar's quick-append option.
1226      Fortunately ic960 users will never use that option.  Fixing this
1227      is very hard; fortunately I know how to do it and will do so once
1228      intel's release is out the door. */
1229    
1230   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1231   int length;
1232   CONST char *filename = normalize(pathname);
1233   int maxlen = ar_maxnamelen (abfd);
1234
1235   length = strlen (filename);
1236
1237   if (length <= maxlen)
1238     memcpy (hdr->ar_name, filename, length);
1239
1240   if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
1241   return;
1242
1243 }
1244
1245 void
1246 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
1247      bfd *abfd;
1248      CONST char *pathname;
1249      char *arhdr;
1250 {
1251   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1252   int length;
1253   CONST char *filename = strrchr (pathname, '/');
1254   int maxlen = ar_maxnamelen (abfd);
1255
1256
1257   if (filename == NULL)
1258     filename = pathname;
1259   else
1260     ++filename;
1261
1262   length = strlen (filename);
1263
1264   if (length <= maxlen)
1265     memcpy (hdr->ar_name, filename, length);
1266   else {
1267     /* pathname: meet procrustes */
1268     memcpy (hdr->ar_name, filename, maxlen);
1269     length = maxlen;
1270   }
1271
1272   if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
1273 }
1274
1275 /* Store name into ar header.  Truncates the name to fit.
1276    1> strip pathname to be just the basename.
1277    2> if it's short enuf to fit, stuff it in.
1278    3> If it doesn't end with .o, truncate it to fit
1279    4> truncate it before the .o, append .o, stuff THAT in.
1280 */
1281
1282 /* This is what gnu ar does.  It's better but incompatible with the bsd ar. */
1283 void
1284 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
1285      bfd *abfd;
1286      CONST char *pathname;
1287      char *arhdr;
1288 {
1289   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1290   int length;
1291   CONST char *filename = strrchr (pathname, '/');
1292   int maxlen = ar_maxnamelen (abfd);
1293         
1294   if (filename == NULL)
1295     filename = pathname;
1296   else
1297     ++filename;
1298
1299   length = strlen (filename);
1300
1301   if (length <= maxlen)
1302     memcpy (hdr->ar_name, filename, length);
1303   else {                        /* pathname: meet procrustes */
1304     memcpy (hdr->ar_name, filename, maxlen);
1305     if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
1306       hdr->ar_name[maxlen - 2] = '.';
1307       hdr->ar_name[maxlen - 1] = 'o';
1308     }
1309     length = maxlen;
1310   }
1311
1312   if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
1313 }
1314 \f
1315
1316 /* The BFD is open for write and has its format set to bfd_archive */
1317 boolean
1318 _bfd_write_archive_contents (arch)
1319      bfd *arch;
1320 {
1321   bfd *current;
1322   char *etable = NULL;
1323   unsigned int elength = 0;
1324   boolean makemap = bfd_has_map (arch);
1325   boolean hasobjects = false;   /* if no .o's, don't bother to make a map */
1326   unsigned int i;
1327   int tries;
1328
1329   /* Verify the viability of all entries; if any of them live in the
1330      filesystem (as opposed to living in an archive open for input)
1331      then construct a fresh ar_hdr for them.
1332      */
1333   for (current = arch->archive_head; current; current = current->next) {
1334     if (bfd_write_p (current)) {
1335       bfd_error = invalid_operation;
1336       return false;
1337     }
1338     if (!current->arelt_data) {
1339       current->arelt_data =
1340           (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
1341       if (!current->arelt_data) return false;
1342
1343       /* Put in the file name */
1344     
1345     BFD_SEND (arch, _bfd_truncate_arname,(arch, 
1346                                           current->filename,
1347                                          (char *) arch_hdr(current)));
1348
1349       
1350     }
1351
1352     if (makemap) {              /* don't bother if we won't make a map! */
1353       if ((bfd_check_format (current, bfd_object))
1354 #if 0                           /* FIXME -- these are not set correctly */
1355           && ((bfd_get_file_flags (current) & HAS_SYMS))
1356 #endif
1357           )
1358         hasobjects = true;
1359     }
1360   }
1361
1362   if (!bfd_construct_extended_name_table (arch, &etable, &elength))
1363     return false;
1364
1365   bfd_seek (arch, (file_ptr) 0, SEEK_SET);
1366 #ifdef GNU960
1367   bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
1368 #else
1369   bfd_write (ARMAG, 1, SARMAG, arch);
1370 #endif
1371
1372   if (makemap && hasobjects) {
1373
1374     if (compute_and_write_armap (arch, elength) != true) {
1375       return false;
1376     }
1377   }
1378
1379   if (elength != 0) {
1380     struct ar_hdr hdr;
1381
1382     memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1383     sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
1384     sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
1385     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1386     for (i = 0; i < sizeof (struct ar_hdr); i++)
1387       if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1388     bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1389     bfd_write (etable, 1, elength, arch);
1390     if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
1391
1392   }
1393
1394   for (current = arch->archive_head; current; current = current->next) {
1395     char buffer[DEFAULT_BUFFERSIZE];
1396     unsigned int remaining = arelt_size (current);
1397     struct ar_hdr *hdr = arch_hdr(current);
1398     /* write ar header */
1399
1400     if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
1401     syserr:
1402         bfd_error = system_call_error;
1403         return false;
1404       }
1405     if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) goto syserr;
1406     while (remaining) 
1407         {
1408           unsigned int amt = DEFAULT_BUFFERSIZE;
1409           if (amt > remaining) {
1410             amt = remaining;
1411           }
1412           errno = 0;
1413           if (bfd_read (buffer, amt, 1, current) != amt) {
1414               if (errno) goto syserr;
1415               /* Looks like a truncated archive. */
1416               bfd_error = malformed_archive;
1417               return false;
1418           }
1419           if (bfd_write (buffer, amt, 1, arch)   != amt) goto syserr;
1420           remaining -= amt;
1421         }
1422     if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1423   }
1424
1425   /* Verify the timestamp in the archive file.  If it would
1426      not be accepted by the linker, rewrite it until it would be.
1427      If anything odd happens, break out and just return. 
1428      (The Berkeley linker checks the timestamp and refuses to read the
1429      table-of-contents if it is >60 seconds less than the file's
1430      modified-time.  That painful hack requires this painful hack.  */
1431
1432   tries = 1;
1433   do {
1434     /* FIXME!  This kludge is to avoid adding a member to the xvec,
1435        while generating a small patch for Adobe.  FIXME!  The
1436        update_armap_timestamp function call should be in the xvec,
1437        thus:
1438
1439                 if (bfd_update_armap_timestamp (arch) == true) break;
1440                      ^
1441
1442        Instead, we check whether in a BSD archive, and call directly. */
1443
1444     if (arch->xvec->write_armap != bsd_write_armap)
1445         break;
1446     if (bsd_update_armap_timestamp(arch) == true)  /* FIXME!!!  Vector it */
1447         break;
1448     if (tries > 0)
1449         fprintf (stderr,
1450            "Warning: writing archive was slow: rewriting timestamp\n");
1451   } while (++tries < 6 );
1452
1453   return true;
1454 }
1455 \f
1456 /* Note that the namidx for the first symbol is 0 */
1457
1458 boolean
1459 compute_and_write_armap (arch, elength)
1460      bfd *arch;
1461      unsigned int elength;
1462 {
1463     bfd *current;
1464     file_ptr elt_no = 0;
1465     struct orl *map;
1466     int orl_max = 15000;        /* fine initial default */
1467     int orl_count = 0;
1468     int stridx = 0;             /* string index */
1469
1470     /* Dunno if this is the best place for this info... */
1471     if (elength != 0) elength += sizeof (struct ar_hdr);
1472     elength += elength %2 ;
1473
1474     map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1475     if (map == NULL) {
1476             bfd_error = no_memory;
1477             return false;
1478         }
1479
1480     /* Drop all the files called __.SYMDEF, we're going to make our
1481        own */
1482     while (arch->archive_head   &&
1483            strcmp(arch->archive_head->filename,"__.SYMDEF") == 0) 
1484     {
1485         arch->archive_head = arch->archive_head->next;
1486     }
1487     /* Map over each element */
1488     for (current = arch->archive_head;
1489          current != (bfd *)NULL;
1490          current = current->next, elt_no++) 
1491     {
1492         if ((bfd_check_format (current, bfd_object) == true)
1493             && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1494                 asymbol **syms;
1495                 unsigned int storage;
1496                 unsigned int symcount;
1497                 unsigned int src_count;
1498
1499                 storage = get_symtab_upper_bound (current);
1500                 if (storage != 0) {
1501
1502                         syms = (asymbol **) bfd_zalloc (arch,storage);
1503                         if (syms == NULL) {
1504                                 bfd_error = no_memory; /* FIXME -- memory leak */
1505                                 return false;
1506                             }
1507                         symcount = bfd_canonicalize_symtab (current, syms);
1508
1509
1510                         /* Now map over all the symbols, picking out the ones we want */
1511                         for (src_count = 0; src_count <symcount; src_count++) {
1512                                 flagword flags =
1513                                  (syms[src_count])->flags;
1514                                 asection  *sec =
1515                                  syms[src_count]->section;
1516                                 
1517                                 if ((flags & BSF_GLOBAL ||
1518                                      flags & BSF_WEAK ||
1519                                      flags & BSF_INDIRECT ||
1520                                      bfd_is_com_section (sec))
1521                                     && (sec != &bfd_und_section)) {
1522
1523                                         /* This symbol will go into the archive header */
1524                                         if (orl_count == orl_max) 
1525                                         {
1526                                             orl_max *= 2;
1527                                             map = (struct orl *) bfd_realloc (arch, (char *) map,
1528                                                                               orl_max * sizeof (struct orl));
1529                                         }
1530
1531                                         (map[orl_count]).name = (char **) &((syms[src_count])->name);
1532                                         (map[orl_count]).pos = (file_ptr) current;
1533                                         (map[orl_count]).namidx = stridx;
1534
1535                                         stridx += strlen ((syms[src_count])->name) + 1;
1536                                         ++orl_count;
1537                                     }
1538                             }
1539                     }
1540             }
1541     }
1542     /* OK, now we have collected all the data, let's write them out */
1543     if (!BFD_SEND (arch, write_armap,
1544                    (arch, elength, map, orl_count, stridx))) {
1545
1546             return false;
1547         }
1548
1549
1550     return true;
1551 }
1552
1553 boolean
1554 bsd_write_armap (arch, elength, map, orl_count, stridx)
1555      bfd *arch;
1556      unsigned int elength;
1557      struct orl *map;
1558      unsigned int orl_count;
1559      int stridx;
1560 {
1561   int padit = stridx & 1;
1562   unsigned int ranlibsize = orl_count * sizeof (struct ranlib);
1563   unsigned int stringsize = stridx + padit;
1564   /* Include 8 bytes to store ranlibsize and stringsize in output. */
1565   unsigned int mapsize = ranlibsize + stringsize + 8;
1566   file_ptr firstreal;
1567   bfd *current = arch->archive_head;
1568   bfd *last_elt = current;      /* last element arch seen */
1569   int temp;
1570   int count;
1571   struct ar_hdr hdr;
1572   struct stat statbuf;
1573   unsigned int i;
1574
1575   firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1576
1577   stat (arch->filename, &statbuf);
1578   memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1579   sprintf (hdr.ar_name, RANLIBMAG);
1580   /* Remember the timestamp, to keep it holy.  But fudge it a little.  */
1581   bfd_ardata(arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
1582   bfd_ardata(arch)->armap_datepos = SARMAG + 
1583                                       offsetof(struct ar_hdr, ar_date[0]);
1584   sprintf (hdr.ar_date, "%ld", bfd_ardata(arch)->armap_timestamp);  
1585   sprintf (hdr.ar_uid, "%d", getuid());
1586   sprintf (hdr.ar_gid, "%d", getgid());
1587   sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1588   hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1589   for (i = 0; i < sizeof (struct ar_hdr); i++)
1590    if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1591   bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1592   bfd_h_put_32(arch, (bfd_vma) ranlibsize, (PTR)&temp);
1593   bfd_write (&temp, 1, sizeof (temp), arch);
1594   
1595   for (count = 0; count < orl_count; count++) {
1596     struct symdef outs;
1597     struct symdef *outp = &outs;
1598     
1599     if (((bfd *)(map[count]).pos) != last_elt) {
1600       do {
1601         firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1602         firstreal += firstreal % 2;
1603         current = current->next;
1604       } while (current != (bfd *)(map[count]).pos);
1605     }                           /* if new archive element */
1606
1607     last_elt = current;
1608     bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
1609     bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
1610     bfd_write ((char *)outp, 1, sizeof (outs), arch);
1611   }
1612
1613   /* now write the strings themselves */
1614   bfd_h_put_32(arch, stringsize, (PTR)&temp);
1615   bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
1616   for (count = 0; count < orl_count; count++)
1617    bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1618
1619   /* The spec sez this should be a newline.  But in order to be
1620      bug-compatible for sun's ar we use a null. */
1621   if (padit)
1622    bfd_write("",1,1,arch);
1623
1624   return true;
1625 }
1626
1627
1628 /* At the end of archive file handling, update the timestamp in the
1629    file, so the linker will accept it.  
1630
1631    Return true if the timestamp was OK, or an unusual problem happened.
1632    Return false if we updated the timestamp.  */
1633
1634 static boolean
1635 bsd_update_armap_timestamp (arch)
1636      bfd *arch;
1637 {
1638   struct stat archstat;
1639   struct ar_hdr hdr;
1640   int i;
1641
1642   /* Flush writes, get last-write timestamp from file, and compare it
1643      to the timestamp IN the file.  */
1644   bfd_flush (arch);
1645   if (bfd_stat (arch, &archstat) == -1) {
1646     perror ("Reading archive file mod timestamp");
1647     return true;                /* Can't read mod time for some reason */
1648   }
1649   if (archstat.st_mtime <= bfd_ardata(arch)->armap_timestamp)
1650     return true;                /* OK by the linker's rules */
1651
1652   /* Update the timestamp.  */
1653   bfd_ardata(arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;
1654
1655   /* Prepare an ASCII version suitable for writing.  */
1656   memset (hdr.ar_date, 0, sizeof (hdr.ar_date));
1657   sprintf (hdr.ar_date, "%ld", bfd_ardata(arch)->armap_timestamp);  
1658   for (i = 0; i < sizeof (hdr.ar_date); i++)
1659    if (hdr.ar_date[i] == '\0')
1660      (hdr.ar_date)[i] = ' ';
1661
1662   /* Write it into the file.  */
1663   bfd_seek (arch, bfd_ardata(arch)->armap_datepos, SEEK_SET);
1664   if (bfd_write (hdr.ar_date, sizeof(hdr.ar_date), 1, arch) 
1665       != sizeof(hdr.ar_date)) {
1666     perror ("Writing updated armap timestamp");
1667     return true;                /* Some error while writing */
1668   }
1669
1670   return false;                 /* We updated the timestamp successfully.  */
1671 }
1672 \f
1673
1674 /* A coff armap looks like :
1675  lARMAG
1676  struct ar_hdr with name = '/' 
1677  number of symbols
1678  offset of file for symbol 0
1679  offset of file for symbol 1
1680
1681  offset of file for symbol n-1
1682  symbol name 0
1683  symbol name 1  
1684  
1685  symbol name n-1
1686
1687 */
1688
1689 boolean
1690 coff_write_armap (arch, elength, map, symbol_count, stridx)
1691      bfd *arch;
1692      unsigned int elength;
1693      struct orl *map;
1694      unsigned int symbol_count;
1695      int stridx;
1696 {
1697     /* The size of the ranlib is the number of exported symbols in the
1698        archive * the number of bytes in a int, + an int for the count */
1699
1700     unsigned int ranlibsize = (symbol_count * 4) + 4;
1701     unsigned int stringsize = stridx;
1702     unsigned int mapsize = stringsize + ranlibsize;
1703     file_ptr archive_member_file_ptr;
1704     bfd *current = arch->archive_head;
1705     int count;
1706     struct ar_hdr hdr;
1707     unsigned int i;
1708     int padit = mapsize & 1;
1709   
1710     if (padit) mapsize ++;
1711
1712     /* work out where the first object file will go in the archive */
1713     archive_member_file_ptr =   mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1714
1715     memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1716     hdr.ar_name[0] = '/';
1717     sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1718     sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1719     /* This, at least, is what Intel coff sets the values to.: */
1720     sprintf ((hdr.ar_uid), "%d", 0);
1721     sprintf ((hdr.ar_gid), "%d", 0);
1722     sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1723     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1724
1725     for (i = 0; i < sizeof (struct ar_hdr); i++)
1726      if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1727
1728     /* Write the ar header for this item and the number of symbols */
1729
1730   
1731     bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
1732
1733     bfd_write_bigendian_4byte_int(arch, symbol_count);
1734
1735     /* Two passes, first write the file offsets for each symbol -
1736        remembering that each offset is on a two byte boundary.  */
1737
1738     /* Write out the file offset for the file associated with each
1739        symbol, and remember to keep the offsets padded out.  */
1740
1741     current = arch->archive_head;
1742     count = 0;
1743     while (current != (bfd *)NULL && count < symbol_count) {
1744         /* For each symbol which is used defined in this object, write out
1745            the object file's address in the archive */
1746     
1747         while (((bfd *)(map[count]).pos) == current) {
1748             bfd_write_bigendian_4byte_int(arch, archive_member_file_ptr);
1749             count++;
1750         }
1751         /* Add size of this archive entry */
1752         archive_member_file_ptr += arelt_size (current) + sizeof (struct
1753                                                                   ar_hdr);
1754         /* remember aboout the even alignment */
1755         archive_member_file_ptr += archive_member_file_ptr % 2;
1756         current = current->next;
1757     }  
1758
1759
1760
1761     /* now write the strings themselves */
1762     for (count = 0; count < symbol_count; count++) {
1763         bfd_write ((PTR)*((map[count]).name),
1764                    1,
1765                    strlen (*((map[count]).name))+1, arch);
1766
1767     }
1768     /* The spec sez this should be a newline.  But in order to be
1769        bug-compatible for arc960 we use a null. */
1770     if (padit)
1771      bfd_write("",1,1,arch);
1772
1773     return true;
1774 }