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