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