Minor format fixes.
[external/binutils.git] / bfd / archive.c
1 /*** archive.c -- an attempt at combining the machine-independent parts of
2   archives */
3
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5
6 This file is part of BFD, the Binary File Diddler.
7
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
11 any later version.
12
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING.  If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
21
22
23 /* Assumes:
24    o - all archive elements start on an even boundary, newline padded;
25    o - all arch headers are char *;
26    o - all arch headers are the same size (across architectures).
27 */
28
29 /* $Id$ 
30  * $Log$
31  * Revision 1.3  1991/04/04 14:56:42  gumby
32  * Minor format fixes.
33  *
34  * Revision 1.2  1991/04/03  22:09:43  steve
35  * Various noise
36  *
37  * Revision 1.1.1.1  1991/03/21  21:10:42  gumby
38  * Back from Intel with Steve
39  *
40  * Revision 1.1  1991/03/21  21:10:42  gumby
41  * Initial revision
42  *
43  * Revision 1.3  1991/03/16  05:55:25  rich
44  * pop
45  *
46  * Revision 1.2  1991/03/15  18:15:50  rich
47  * *** empty log message ***
48  *
49  * Revision 1.7  1991/03/08  04:18:02  rich
50  * *** empty log message ***
51  *
52  * Revision 1.6  1991/03/07  21:55:31  sac
53  * Added primitive file caching, a file open only for input and
54  * less than BFD_INCORE_FILE_SIZE will be malloced and read in
55  * only once.
56  *
57  * Revision 1.5  1991/03/05  16:31:12  sac
58  * lint
59  *
60  */
61
62
63 #include "sysdep.h"
64 #include "bfd.h"
65 #include "libbfd.h"
66 #include "ar.h"
67 #include "ranlib.h"
68
69 /* We keep a cache of archive filepointers to archive elements to
70    speed up searching the archive by filepos.  We only add an entry to
71    the cache when we actually read one.  We also don't sort the cache;
72    it's short enough to search linearly.
73    Note that the pointers here point to the front of the ar_hdr, not
74    to the front of the contents!
75 */
76 struct ar_cache {
77   file_ptr ptr;
78   bfd* arelt;
79   struct ar_cache *next;
80 };
81
82 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
83 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
84
85 #define arch_hdr(bfd) ((struct ar_hdr *)   \
86                        (((struct areltdata *)((bfd)->arelt_data))->arch_header))
87
88 \f
89
90 boolean
91 _bfd_generic_mkarchive (abfd)
92      bfd *abfd;
93 {
94   abfd->tdata =(void *) zalloc (sizeof (struct artdata));
95
96   if (abfd->tdata == NULL) {
97     bfd_error = no_memory;
98     return false;
99   }
100 bfd_ardata(abfd)->cache = 0;
101   return true;
102 }
103
104 symindex
105 bfd_get_next_mapent (abfd, prev, entry)
106      bfd *abfd;
107    symindex prev;
108      carsym **entry;
109 {
110   if (!bfd_has_map (abfd)) {
111     bfd_error = invalid_operation;
112     return BFD_NO_MORE_SYMBOLS;
113   }
114   
115   if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
116   else if (++prev >= (symindex)(bfd_ardata (abfd)->symdef_count))
117     return BFD_NO_MORE_SYMBOLS;
118
119   *entry = (bfd_ardata (abfd)->symdefs + prev);
120   return prev;
121 }
122
123
124 /* To be called by backends only */
125 bfd *
126 _bfd_create_empty_archive_element_shell (obfd)
127      bfd *obfd;
128 {
129   bfd *nbfd;
130
131   nbfd = new_bfd_contained_in(obfd);
132   if (nbfd == NULL) {
133     bfd_error = no_memory;
134     return NULL;
135   }
136   return nbfd;
137 }
138
139 boolean
140 bfd_set_archive_head (output_archive, new_head)
141      bfd *output_archive, *new_head;
142 {
143  
144   output_archive->archive_head = new_head;
145   return true;
146 }
147
148 bfd *
149 look_for_bfd_in_cache (arch_bfd, filepos)
150      bfd *arch_bfd;
151      file_ptr filepos;
152 {
153   struct ar_cache *current;
154
155   for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
156        current = current->next)
157     if (current->ptr == filepos) return current->arelt;
158
159   return NULL;
160 }
161
162 /* Kind of stupid to call cons for each one, but we don't do too many */
163 boolean
164 add_bfd_to_cache (arch_bfd, filepos, new_elt)
165      bfd *arch_bfd, *new_elt;
166      file_ptr filepos;
167 {
168   struct ar_cache *new_cache = ((struct ar_cache *)
169                                 zalloc (sizeof (struct ar_cache)));
170
171   if (new_cache == NULL) {
172     bfd_error = no_memory;
173     return false;
174   }
175
176   new_cache->ptr = filepos;
177   new_cache->arelt = new_elt;
178   new_cache->next = (struct ar_cache *)NULL;
179   if (bfd_ardata (arch_bfd)->cache == NULL)
180     bfd_ardata (arch_bfd)->cache = new_cache;
181   else {
182     struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
183
184     for (; current->next != NULL; current = current->next);
185     current->next = new_cache;
186   }
187     
188   return true;
189 }
190
191 \f
192
193 /* The name begins with space.  Hence the rest of the name is an index into
194    the string table. */
195
196 char *
197 get_extended_arelt_filename (arch, name)
198      bfd *arch;
199      char *name;
200 {
201     extern int errno;
202     unsigned long index = 0;
203
204     /* Should extract string so that I can guarantee not to overflow into
205        the next region, but I"m too lazy. */
206     errno = 0;
207     index = strtol (name, NULL, 10);
208     if (errno != 0) {
209         bfd_error = malformed_archive;
210         return NULL;
211     }
212
213     return bfd_ardata (arch)->extended_names + index;
214 }  
215
216 /* This functions reads an arch header and returns an areltdata pointer, or
217    NULL on error.
218
219    Presumes the file pointer is already in the right place (ie pointing
220    to the ar_hdr in the file).   Moves the file pointer; on success it
221    should be pointing to the front of the file contents; on failure it
222    could have been moved arbitrarily.
223 */
224
225 struct areltdata *
226 snarf_ar_hdr (abfd)
227      bfd *abfd;
228 {
229     extern int errno;
230     struct ar_hdr hdr;
231     char *hdrp = (char *) &hdr;
232     unsigned int parsed_size;
233     struct areltdata *ared;
234     char *filename = NULL;
235     unsigned int namelen = 0;
236     unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
237     char *allocptr;
238
239     if (bfd_read ((void *)hdrp, 1, sizeof (struct ar_hdr), abfd)
240         != sizeof (struct ar_hdr)) {
241         bfd_error = no_more_archived_files;
242         return NULL;
243     }
244     if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
245         bfd_error = malformed_archive;
246         return NULL;
247     }
248
249     errno = 0;
250     parsed_size = strtol (hdr.ar_size, NULL, 10);
251     if (errno != 0) {
252         bfd_error = malformed_archive;
253         return NULL;
254     }
255
256     /* extract the filename from the archive */
257     if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
258         filename = get_extended_arelt_filename (abfd, hdr.ar_name);
259         if (filename == NULL) {
260             bfd_error = malformed_archive;
261             return NULL;
262         }
263     } 
264     else 
265         {
266             /* We judge the end of the name by looking for a space or a
267                padchar */
268
269             namelen = 0;
270
271             while (namelen < (unsigned)ar_maxnamelen(abfd) &&
272                    ( hdr.ar_name[namelen] != 0 &&
273                     hdr.ar_name[namelen] != ' ' &&
274                     hdr.ar_name[namelen] != ar_padchar(abfd))) {
275                 namelen++;
276             }
277
278             allocsize += namelen + 1;
279         }
280
281     allocptr = zalloc (allocsize);
282     if (allocptr == NULL) {
283         bfd_error = no_memory;
284         return NULL;
285     }
286
287     ared = (struct areltdata *) allocptr;
288
289     ared->arch_header = allocptr + sizeof (struct areltdata);
290     memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
291     ared->parsed_size = parsed_size;
292
293     if (filename != NULL) ared->filename = filename;
294     else {
295         ared->filename = allocptr + (sizeof (struct areltdata) +
296                                      sizeof (struct ar_hdr));
297         if (namelen)
298             memcpy (ared->filename, hdr.ar_name, namelen);
299         ared->filename[namelen] = '\0';
300     }
301   
302     return ared;
303 }
304 \f
305 bfd *
306 get_elt_at_filepos (archive, filepos)
307      bfd *archive;
308      file_ptr filepos;
309 {
310   struct areltdata *new_areldata;
311   bfd *n_nfd;
312
313   n_nfd = look_for_bfd_in_cache (archive, filepos);
314   if (n_nfd) return n_nfd;
315
316   if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
317     bfd_error = system_call_error;
318     return NULL;
319   }
320
321   if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
322   
323   n_nfd = _bfd_create_empty_archive_element_shell (archive);
324   if (n_nfd == NULL) {
325     free (new_areldata);
326     return NULL;
327   }
328   n_nfd->origin = bfd_tell (archive);
329   n_nfd->arelt_data = (void *) new_areldata;
330   n_nfd->filename = new_areldata->filename;
331
332   if (add_bfd_to_cache (archive, filepos, n_nfd))
333     return n_nfd;
334
335   /* huh? */
336   free (new_areldata);
337   free (n_nfd);
338   return NULL;
339 }
340
341 bfd *
342 bfd_get_elt_at_index (abfd, index)
343      bfd *abfd;
344      int index;
345 {
346   bfd *result =
347     get_elt_at_filepos
348       (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
349   return result;
350 }
351
352 /* If you've got an archive, call this to read each subfile. */
353 bfd *
354 bfd_openr_next_archived_file (archive, last_file)
355      bfd *archive, *last_file;
356 {
357
358   if ((bfd_get_format (archive) != bfd_archive) ||
359       (archive->direction == write_direction)) {
360     bfd_error = invalid_operation;
361     return NULL;
362   }
363
364
365   return BFD_SEND (archive,
366                    openr_next_archived_file,
367                    (archive,
368                     last_file));
369
370 }
371
372 bfd *bfd_generic_openr_next_archived_file(archive, last_file)
373      bfd *archive;
374      bfd *last_file;
375 {
376   file_ptr filestart;
377
378   if (!last_file)
379     filestart = bfd_ardata (archive)->first_file_filepos;
380   else {
381   unsigned int size = arelt_size(last_file);
382     filestart = last_file->origin +size + size %2;
383 }
384
385
386
387   return get_elt_at_filepos (archive, filestart);
388 }
389 \f
390
391 bfd_target *
392 bfd_generic_archive_p (abfd)
393      bfd *abfd;
394 {
395   char armag[SARMAG+1];
396
397   if (bfd_read ((void *)armag, 1, SARMAG, abfd) != SARMAG) {
398     bfd_error = wrong_format;
399     return 0;
400   }
401
402   if (strncmp (armag, ARMAG, SARMAG)) return 0;
403
404   bfd_set_ardata(abfd, (struct artdata *) zalloc (sizeof (struct artdata)));
405
406   if (bfd_ardata (abfd)  == NULL) {
407     bfd_error = no_memory;
408     return 0;
409   }
410
411   bfd_ardata (abfd)->first_file_filepos = SARMAG;
412   
413   if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
414     free (bfd_ardata (abfd));
415     abfd->tdata = NULL;
416     return 0;
417   }
418
419   /* armap could be left ungc'd! FIXME -- potential storage leak */
420   if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
421     free (bfd_ardata (abfd));
422     abfd->tdata = NULL;
423     return 0;
424   }
425   
426   return abfd->xvec;
427 }
428
429 /* Returns false on error, true otherwise */
430 boolean
431 bfd_slurp_bsd_armap (abfd)
432      bfd *abfd;
433 {
434   struct areltdata *mapdata;
435   char nextname[17];
436   unsigned int counter = 0;
437   int *raw_armap, *rbase;
438   struct artdata *ardata = bfd_ardata (abfd);
439   char *stringbase;
440
441   if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
442       /* The archive has at least 16 bytes in it */
443       bfd_seek (abfd, -16L, SEEK_CUR);
444
445       if (strncmp (nextname, "__.SYMDEF       ", 16)) {
446           bfd_has_map (abfd) = false;
447           return true;
448       }
449
450       mapdata = snarf_ar_hdr (abfd);
451       if (mapdata == NULL) return false;
452
453       raw_armap = (int *) zalloc (mapdata->parsed_size);
454       if (raw_armap == NULL) {
455           bfd_error = no_memory;
456   byebye:
457           free (mapdata);
458           return false;
459       }
460
461       if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
462           mapdata->parsed_size) {
463           bfd_error = malformed_archive;
464           free (raw_armap);
465           goto byebye;
466       }
467
468       ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
469       ardata->cache = 0;
470       rbase = raw_armap+1;
471       ardata->symdefs = (carsym *) rbase;
472       stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
473
474       for (;counter < (unsigned)( ardata->symdef_count); counter++) {
475           struct symdef *sym = ((struct symdef *) rbase) + counter;
476           sym->s.name = sym->s.string_offset + stringbase;
477       }
478   
479       ardata->first_file_filepos = bfd_tell (abfd);
480       /* Pad to an even boundary if you have to */
481       ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
482       free (mapdata);
483       bfd_has_map (abfd) = true;
484   }
485   return true;
486 }
487
488 /* Returns false on error, true otherwise */
489 boolean
490 bfd_slurp_coff_armap (abfd)
491      bfd *abfd;
492 {
493   struct areltdata *mapdata;
494   char nextname;
495   int *raw_armap, *rawptr;
496   struct artdata *ardata = bfd_ardata (abfd);
497   char *stringbase;
498   unsigned int stringsize;
499   carsym *carsyms;
500
501   if (bfd_read ((void *)&nextname, 1, 1, abfd) != 1) {
502     bfd_has_map(abfd) = false;
503     return true;
504   }
505
506   if (nextname != '/') {
507     /* Actually I think this is an error for a COFF archive */
508     bfd_has_map (abfd) = false;
509     return true;
510   }
511
512   bfd_seek (abfd, -1L, SEEK_CUR);
513   mapdata = snarf_ar_hdr (abfd);
514   if (mapdata == NULL) return false;
515
516   raw_armap = (int *) zalloc (mapdata->parsed_size);
517   if (raw_armap == NULL) {
518     bfd_error = no_memory;
519   byebye:
520     free (mapdata);
521     return false;
522   }
523
524   if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
525       mapdata->parsed_size) {
526     bfd_error = malformed_archive;
527   oops:
528     free (raw_armap);
529     goto byebye;
530   }
531
532   /* The coff armap must be read sequentially.  So we construct a bsd-style
533      one in core all at once, for simplicity. */
534
535   stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
536
537   {
538     unsigned int nsymz = *raw_armap;
539     unsigned int carsym_size = (nsymz * sizeof (carsym));
540     unsigned int ptrsize = (4 * nsymz);
541     unsigned int i;
542     ardata->symdefs = (carsym *) zalloc (carsym_size + stringsize + 1);
543     if (ardata->symdefs == NULL) {
544       bfd_error = no_memory;
545       goto oops;
546     }
547     carsyms = ardata->symdefs;
548
549     stringbase = ((char *) ardata->symdefs) + carsym_size;
550     memcpy (stringbase, (char*)raw_armap + ptrsize + 4,  stringsize);
551
552
553     /* OK, build the carsyms */
554     for (i = 0; i < nsymz; i++) 
555       {
556         rawptr = raw_armap + i + 1;
557         carsyms->file_offset = *rawptr;
558         carsyms->name = stringbase;
559         for (; *(stringbase++););
560         carsyms++;
561       }
562     *stringbase = 0;
563   }
564   ardata->symdef_count = *raw_armap;
565   ardata->first_file_filepos = bfd_tell (abfd);
566   /* Pad to an even boundary if you have to */
567   ardata->first_file_filepos += (ardata->first_file_filepos) %2;
568   free (raw_armap);
569   free (mapdata);
570   bfd_has_map (abfd) = true;
571   return true;
572 }
573
574 \f
575 /** Extended name table.
576
577   Normally archives support only 14-character filenames.  Intel has extended
578   the format: longer names are stored in a special element (the first in the
579   archive, or second if there is an armap); the name in the ar_hdr is replaced
580   by <space><index into filename element>.  Index is the P.R. of an int (radix:
581   8). */
582
583 /* Returns false on error, true otherwise */
584 boolean
585 _bfd_slurp_extended_name_table (abfd)
586      bfd *abfd;
587 {
588   char nextname[17];
589   struct areltdata *namedata;
590
591   if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
592
593   bfd_seek (abfd, -16L, SEEK_CUR);
594
595   if (strncmp (nextname, "ARFILENAMES/    ", 16)) {
596     bfd_ardata (abfd)->extended_names = NULL;
597     return true;
598   }
599
600   namedata = snarf_ar_hdr (abfd);
601   if (namedata == NULL) return false;
602   
603   
604   bfd_ardata (abfd)->extended_names = zalloc (namedata->parsed_size);
605   if (bfd_ardata (abfd)->extended_names == NULL) {
606     bfd_error = no_memory;
607   byebye:
608     free (namedata);
609     return false;
610   }
611
612   if (bfd_read ((void*)bfd_ardata (abfd)->extended_names, 1,
613                 namedata->parsed_size, abfd) != namedata->parsed_size) {
614     bfd_error = malformed_archive;
615     free (bfd_ardata (abfd)->extended_names);
616     bfd_ardata (abfd)->extended_names = NULL;
617     goto byebye;
618   }
619
620   /* Pad to an even boundary if you have to */
621   bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
622   bfd_ardata (abfd)->first_file_filepos +=
623     (bfd_ardata (abfd)->first_file_filepos) %2;
624
625   free (namedata);
626 }
627   return true;
628 }
629
630 static
631 char *normalize(file)
632 char *file;
633 {
634     char *    filename = strrchr(file, '/');
635     if (filename != (char *)NULL) {
636         filename ++;
637     }
638     else {
639         filename = file;
640     }
641 return filename;
642 }
643
644 /* Follows archive_head and produces an extended name table if necessary.
645    Returns (in tabloc) a pointer to an extended name table, and in tablen
646    the length of the table.  If it makes an entry it clobbers the filename
647    so that the element may be written without further massage.
648    Returns true if it ran successfully, false if something went wrong.
649    A successful return may still involve a zero-length tablen!
650    */
651 boolean
652 bfd_construct_extended_name_table (abfd, tabloc, tablen)
653      bfd *abfd;
654      char **tabloc;
655      unsigned int *tablen;
656 {
657     unsigned int maxname = abfd->xvec->ar_max_namelen;
658     unsigned int total_namelen = 0;
659     bfd *current;
660     char *strptr;
661
662     *tablen = 0;
663   
664     /* Figure out how long the table should be */
665     for (current = abfd->archive_head; current != NULL; current = current->next){
666         unsigned int thislen = strlen (normalize(current->filename));
667         if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \0 */
668     }
669
670     if (total_namelen == 0) return true;
671
672     *tabloc = zalloc (total_namelen);
673     if (*tabloc == NULL) {
674         bfd_error = no_memory;
675         return false;
676     }
677
678     *tablen = total_namelen;
679     strptr = *tabloc;
680
681     for (current = abfd->archive_head; current != NULL; current =
682          current->next) {
683         char *normal =normalize( current->filename);
684         unsigned int thislen = strlen (normal);
685         if (thislen > maxname) {
686             strcpy (strptr, normal);
687             current->filename[0] = ' ';
688             /* We know there will always be enough room (one of the few cases
689                where you may safely use sprintf). */
690             sprintf ((current->filename) + 1, "-%o", (unsigned) (strptr - *tabloc));
691
692             strptr += thislen + 1;
693         }
694     }
695
696     return true;
697 }
698 \f
699 /** A couple of functions for creating ar_hdrs */
700
701 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
702    The filename must refer to a filename in the filesystem.
703    The filename field of the ar_hdr will NOT be initialized
704 */
705
706 struct areltdata *
707 bfd_ar_hdr_from_filesystem (filename)
708      char *filename;
709 {
710   struct stat status;
711   struct areltdata *ared;
712   struct ar_hdr *hdr;
713   char *temp, *temp1;
714
715
716   if (stat (filename, &status) != 0) {
717     bfd_error = system_call_error;
718     return NULL;
719   }
720
721   ared = (struct areltdata *) zalloc (sizeof (struct ar_hdr) +
722                                       sizeof (struct areltdata));
723   if (ared == NULL) {
724     bfd_error = no_memory;
725     return NULL;
726   }
727   hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
728
729   /* ar headers are space padded, not null padded! */
730   temp = (char *) hdr;
731   temp1 = temp + sizeof (struct ar_hdr) - 2;
732   for (; temp < temp1; *(temp++) = ' ');
733   strncpy (hdr->ar_fmag, ARFMAG, 2);
734   
735   /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
736   sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
737   sprintf ((hdr->ar_uid), "%d", status.st_uid);
738   sprintf ((hdr->ar_gid), "%d", status.st_gid);
739   sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
740   sprintf ((hdr->ar_size), "%-10ld", status.st_size);
741   /* Correct for a lossage in sprintf whereby it null-terminates.  I cannot
742      understand how these C losers could design such a ramshackle bunch of
743      IO operations */
744   temp = (char *) hdr;
745   temp1 = temp + sizeof (struct ar_hdr) - 2;
746   for (; temp < temp1; temp++) {
747     if (*temp == '\0') *temp = ' ';
748   }
749   strncpy (hdr->ar_fmag, ARFMAG, 2);
750   ared->parsed_size = status.st_size;
751   ared->arch_header = (char *) hdr;
752
753   return ared;
754 }
755
756 struct ar_hdr *
757 bfd_special_undocumented_glue (filename)
758      char *filename;
759 {
760
761   return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (filename) -> arch_header;
762 }
763
764
765 /* Analogous to stat call */
766 int
767 bfd_generic_stat_arch_elt (abfd, buf)
768      bfd *abfd;
769      struct stat *buf;
770 {
771   struct ar_hdr *hdr;
772   char *aloser;
773   
774   if (abfd->arelt_data == NULL) {
775     bfd_error = invalid_operation;
776     return -1;
777   }
778     
779   hdr = arch_hdr (abfd);
780
781 #define foo(arelt, stelt, size)  \
782   buf->stelt = strtol (hdr->arelt, &aloser, size); \
783   if (aloser == hdr->arelt) return -1;
784   
785   foo (ar_date, st_mtime, 10);
786   foo (ar_uid, st_uid, 10);
787   foo (ar_gid, st_gid, 10);
788   foo (ar_mode, st_mode, 8);
789   foo (ar_size, st_size, 10);
790
791   return 0;
792 }
793
794 /* Don't do anything -- it'll be taken care of later */
795 void
796 bfd_dont_truncate_arname (ignore_abfd, ignore_filename, ignore_arhdr)
797      bfd *ignore_abfd;
798      char *ignore_filename;
799      char *ignore_arhdr;
800 {
801   /* FIXME -- Actually this is incorrect.  If the name is short we
802     should insert into the header; only if it is long should we do
803     nothing.
804
805     Anyway, this interacts unpleasantly with ar's quick-append option,
806     for now just be compatible with the old system */
807
808   return;
809 }
810
811 void
812 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
813      bfd *abfd;
814      char *pathname;
815      char *arhdr;
816 {
817   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
818   int length;
819   char *filename = strrchr (pathname, '/');
820   int maxlen = ar_maxnamelen (abfd);
821
822
823   if (filename == NULL)
824     filename = pathname;
825   else
826     ++filename;
827
828   length = strlen (filename);
829
830   if (length <= maxlen)
831     memcpy (hdr->ar_name, filename, length);
832   else {
833     /* pathname: meet procrustes */
834     memcpy (hdr->ar_name, filename, maxlen);
835     length = maxlen;
836   }
837
838   if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
839 }
840
841 /* Store name into ar header.  Truncates the name to fit.
842    1> strip pathname to be just the basename.
843    2> if it's short enuf to fit, stuff it in.
844    3> If it doesn't end with .o, truncate it to fit
845    4> truncate it before the .o, append .o, stuff THAT in.
846 */
847
848 /* This is what gnu ar does.  It's better but incompatible with the bsd ar. */
849 void
850 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
851      bfd *abfd;
852      char *pathname;
853      char *arhdr;
854 {
855   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
856   int length;
857   char *filename = strrchr (pathname, '/');
858   int maxlen = ar_maxnamelen (abfd);
859         
860   if (filename == NULL)
861     filename = pathname;
862   else
863     ++filename;
864
865   length = strlen (filename);
866
867   if (length <= maxlen)
868     memcpy (hdr->ar_name, filename, length);
869   else {                        /* pathname: meet procrustes */
870     memcpy (hdr->ar_name, filename, maxlen);
871     if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
872       hdr->ar_name[maxlen - 2] = '.';
873       hdr->ar_name[maxlen - 1] = 'o';
874     }
875     length = maxlen;
876   }
877
878   if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
879 }
880 \f
881
882 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
883
884 /* The bfd is open for write and has its format set to bfd_archive */
885 boolean
886 _bfd_write_archive_contents (arch)
887      bfd *arch;
888 {
889   bfd *current;
890   char *etable = NULL;
891   unsigned int elength = 0;
892   boolean makemap = bfd_has_map (arch);
893   boolean hasobjects = false;   /* if no .o's, don't bother to make a map */
894   unsigned int i;
895
896
897   /* Verify the viability of all entries; if any of them live in the
898      filesystem (as opposed to living in an archive open for input)
899      then construct a fresh ar_hdr for them.
900      */
901   for (current = arch->archive_head; current; current = current->next) {
902     if (bfd_write_p (current)) {
903       bfd_error = invalid_operation;
904       return false;
905     }
906     if (!current->arelt_data) {
907       current->arelt_data =
908           (void *) bfd_ar_hdr_from_filesystem (current->filename);
909       if (!current->arelt_data) return false;
910
911       /* Put in the file name */
912     
913     BFD_SEND (arch, _bfd_truncate_arname,(arch, 
914                                           current->filename,
915                                          (char *) arch_hdr(current)));
916
917       
918     }
919
920     if (makemap) {              /* don't bother if we won't make a map! */
921       if ((bfd_check_format (current, bfd_object))
922 #if 0                           /* FIXME -- these are not set correctly */
923           && ((bfd_get_file_flags (current) & HAS_SYMS))
924 #endif
925           )
926         hasobjects = true;
927     }
928   }
929
930   if (!bfd_construct_extended_name_table (arch, &etable, &elength))
931     return false;
932
933   bfd_seek (arch, 0, SEEK_SET);
934   bfd_write (ARMAG, 1, SARMAG, arch);
935
936   if (makemap && hasobjects) {
937
938     if (compute_and_write_armap (arch, elength) != true) {
939       if (etable) free (etable);
940       return false;
941     }
942   }
943
944   if (elength != 0) {
945     struct ar_hdr hdr;
946
947     memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
948     sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
949     sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
950     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
951     for (i = 0; i < sizeof (struct ar_hdr); i++)
952       if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
953     bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
954     bfd_write (etable, 1, elength, arch);
955     if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
956     if (etable) free (etable);
957   }
958
959   for (current = arch->archive_head; current; current = current->next) {
960     char buffer[DEFAULT_BUFFERSIZE];
961     unsigned int remaining = arelt_size (current);
962     struct ar_hdr *hdr = arch_hdr(current);
963     /* write ar header */
964
965     if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
966     syserr:
967         bfd_error = system_call_error;
968         return false;
969       }
970     if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
971     while (remaining) 
972         {
973           unsigned int amt = DEFAULT_BUFFERSIZE;
974           if (amt > remaining) {
975             amt = remaining;
976           }
977           if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
978           if (bfd_write (buffer, amt, 1, arch)   != amt) goto syserr;
979           remaining -= amt;
980         }
981     if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
982   }
983 return true;
984 }
985 \f
986 /* Note that the namidx for the first symbol is 0 */
987
988   
989
990 boolean
991 compute_and_write_armap (arch, elength)
992      bfd *arch;
993      unsigned int elength;
994 {
995   bfd *current;
996   file_ptr elt_no = 0;
997   struct orl *map;
998   int orl_max = 15000;          /* fine initial default */
999   int orl_count = 0;
1000   int stridx = 0;               /* string index */
1001
1002   /* Dunno if this is the best place for this info... */
1003   if (elength != 0) elength += sizeof (struct ar_hdr);
1004   elength += elength %2 ;
1005
1006   map = (struct orl *) zalloc (orl_max * sizeof (struct orl));
1007   if (map == NULL) {
1008     bfd_error = no_memory;
1009     return false;
1010   }
1011
1012   /* Map over each element */
1013   for (current = arch->archive_head;
1014        current != (bfd *)NULL;
1015        current = current->next, elt_no++) 
1016       {
1017         if ((bfd_check_format (current, bfd_object) == true)
1018             && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1019           asymbol **syms;
1020           unsigned int storage;
1021           unsigned int symcount;
1022           unsigned int src_count;
1023
1024           storage = get_symtab_upper_bound (current);
1025           if (storage != 0) {
1026
1027             syms = (asymbol **) zalloc (storage);
1028             if (syms == NULL) {
1029               bfd_error = no_memory; /* FIXME -- memory leak */
1030               return false;
1031             }
1032             symcount = bfd_canonicalize_symtab (current, syms);
1033
1034
1035             /* Now map over all the symbols, picking out the ones we want */
1036             for (src_count = 0; src_count <symcount; src_count++) {
1037               flagword flags = (syms[src_count])->flags;
1038               if ((flags & BSF_GLOBAL) ||
1039                   (flags & BSF_FORT_COMM)) {
1040
1041                 /* This symbol will go into the archive header */
1042                 if (orl_count == orl_max) 
1043                     {
1044                       orl_max *= 2;
1045                       map = (struct orl *) realloc ((char *) map,
1046                                                     orl_max * sizeof (struct orl));
1047                     }
1048
1049                 (map[orl_count]).name = &((syms[src_count])->name);
1050                 (map[orl_count]).pos = elt_no;
1051                 (map[orl_count]).namidx = stridx;
1052
1053                 stridx += strlen ((syms[src_count])->name) + 1;
1054                 ++orl_count;
1055               }
1056             }
1057           }
1058         }
1059       }
1060   /* OK, now we have collected all the data, let's write them out */
1061   if (!BFD_SEND (arch, write_armap,
1062                  (arch, elength, map, orl_count, stridx))) {
1063     free (map);
1064     return false;
1065   }
1066
1067   free (map);
1068   return true;
1069 }
1070
1071 \f
1072  /* FIXME -- have to byte-swap this */
1073
1074 boolean
1075 bsd_write_armap (arch, elength, map, orl_count, stridx)
1076      bfd *arch;
1077      unsigned int elength;
1078      struct orl *map;
1079      int orl_count;
1080      int stridx;
1081 {
1082   unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1083   unsigned int stringsize = stridx + 4;
1084   unsigned int mapsize = stringsize + ranlibsize;
1085   file_ptr firstreal;
1086   bfd *current = arch->archive_head;
1087   int last_eltno = 0;           /* last element arch seen */
1088   int temp;
1089   int count;
1090   struct ar_hdr hdr;
1091   struct stat statbuf;
1092   unsigned int i;
1093   int padit = mapsize & 1;
1094   
1095   if (padit) mapsize ++;
1096
1097   firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1098
1099   fstat (arch->iostream, &statbuf); /* FIXME -- descriptor must be open! */
1100   memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1101   sprintf (hdr.ar_name, "__.SYMDEF");
1102   sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1103   sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);  
1104   hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1105   for (i = 0; i < sizeof (struct ar_hdr); i++)
1106     if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1107   bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1108
1109   temp = orl_count /* + 4 */;
1110   bfd_write (&temp, 1, sizeof (temp), arch);
1111   
1112   for (count = 0; count < orl_count; count++) {
1113     struct symdef outs;
1114     struct symdef *outp = &outs;
1115     
1116     if ((map[count]).pos != last_eltno) {
1117       firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1118       firstreal += firstreal % 2;
1119     last_eltno = (map[count]).pos;
1120       current = current->next;
1121     }
1122
1123     outs.s.string_offset = ((map[count]).namidx) +4;
1124     outs.file_offset = firstreal;
1125     bfd_write ((char *)outp, 1, sizeof (outs), arch);
1126   }
1127
1128   /* now write the strings themselves */
1129   temp = stridx + 4;
1130   bfd_write (&temp, 1, sizeof (temp), arch);
1131   for (count = 0; count < orl_count; count++)
1132     bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1133
1134   /* The spec sez this should be a newline.  But in order to be
1135      bug-compatible for sun's ar we use a null. */
1136   if (padit)
1137     bfd_write("\0",1,1,arch);
1138
1139   return true;
1140 }
1141 \f
1142
1143 /* A coff armap looks like :
1144  ARMAG
1145  struct ar_hdr with name = '/' 
1146  number of symbols
1147  offset of file for symbol 0
1148  offset of file for symbol 1
1149     ..
1150  offset of file for symbol n-1
1151  symbol name 0
1152  symbol name 1  
1153     ..
1154  symbol name n-1
1155
1156 */
1157   
1158 boolean
1159 coff_write_armap (arch, elength, map, orl_count, stridx)
1160      bfd *arch;
1161      unsigned int elength;
1162      struct orl *map;
1163      int orl_count;
1164      int stridx;
1165 {
1166     unsigned int ranlibsize = (orl_count * 4) + 4;
1167     unsigned int stringsize = stridx;
1168     unsigned int mapsize = stringsize + ranlibsize;
1169     file_ptr archive_member_file_ptr;
1170     bfd *current = arch->archive_head;
1171     int last_eltno = 0;         /* last element arch seen */
1172     int count;
1173     struct ar_hdr hdr;
1174     unsigned int i;
1175     int padit = mapsize & 1;
1176   
1177     if (padit) mapsize ++;
1178
1179     archive_member_file_ptr =
1180         mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1181
1182     memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1183     hdr.ar_name[0] = '/';
1184     sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1185     sprintf (hdr.ar_date, "%ld", time (NULL));
1186     /* This, at least, is what Intel coff sets the values to.: */
1187     sprintf ((hdr.ar_uid), "%d", 0);
1188     sprintf ((hdr.ar_gid), "%d", 0);
1189     sprintf ((hdr.ar_mode), "%-7o", 0);
1190     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1191
1192     for (i = 0; i < sizeof (struct ar_hdr); i++)
1193         if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1194
1195     /* Write the ar header for this item and the number of symbols */
1196
1197     bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1198     bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1199
1200     /* Two passes, first write the file offsets for each symbol -
1201        remembering that each offset is on a two byte boundary
1202        */
1203
1204     for (count = 0; count < orl_count; count++) {
1205         while ((map[count]).pos != last_eltno) {
1206             /* If this is the first time we've seen a ref to this archive
1207                then remember it's size */
1208             archive_member_file_ptr +=
1209                 arelt_size (current) + sizeof (struct ar_hdr);
1210             archive_member_file_ptr += archive_member_file_ptr % 2;
1211             current = current->next;
1212             last_eltno++;
1213         }
1214         bfd_write (&archive_member_file_ptr,
1215                    1,
1216                    sizeof (archive_member_file_ptr),
1217                    arch);
1218     }
1219
1220     /* now write the strings themselves */
1221     for (count = 0; count < orl_count; count++) {
1222         bfd_write (*((map[count]).name),
1223                    1,
1224                    strlen (*((map[count]).name))+1, arch);
1225
1226     }
1227     /* The spec sez this should be a newline.  But in order to be
1228        bug-compatible for arc960 we use a null. */
1229     if (padit)
1230         bfd_write("\0",1,1,arch);
1231
1232     return true;
1233 }