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