I think this gets symdefs right for at least sunos. Also now swaps
[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   int i;
415   struct areltdata *mapdata;
416   char nextname[17];
417   unsigned int counter = 0;
418   int *raw_armap, *rbase;
419   struct artdata *ardata = bfd_ardata (abfd);
420   char *stringbase;
421
422   /* FIXME, if the read fails, this routine quietly returns "true"!!
423      It should probably do that if the read gives 0 bytes (empty archive),
424      but fail for any other size... */
425   if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
426       /* The archive has at least 16 bytes in it */
427       bfd_seek (abfd, -16L, SEEK_CUR);
428
429       /* This should be using RANLIBMAG, but at least it can be grepped for
430          in this comment.  */
431       if (strncmp (nextname, "__.SYMDEF       ", 16)) {
432           bfd_has_map (abfd) = false;
433           return true;
434       }
435
436       mapdata = snarf_ar_hdr (abfd);
437       if (mapdata == NULL) return false;
438
439       raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
440       if (raw_armap == NULL) {
441           bfd_error = no_memory;
442   byebye:
443           bfd_release (abfd, (PTR)mapdata);
444           return false;
445       }
446
447       if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
448           mapdata->parsed_size) {
449           bfd_error = malformed_archive;
450           bfd_release (abfd, (PTR)raw_armap);
451           goto byebye;
452       }
453
454       ardata->symdef_count = bfd_h_get_32(abfd, raw_armap) / sizeof (struct symdef);
455       ardata->cache = 0;
456       rbase = raw_armap+1;
457       ardata->symdefs = (carsym *) rbase;
458       stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
459
460       for (;counter < ardata->symdef_count; counter++) {
461           struct symdef *sym = ((struct symdef *) rbase) + counter;
462           sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase;
463           sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset));
464       }
465   
466       ardata->first_file_filepos = bfd_tell (abfd);
467       /* Pad to an even boundary if you have to */
468       ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
469       /* FIXME, we should provide some way to free raw_ardata when
470          we are done using the strings from it.  For now, it seems
471          to be allocated on an obstack anyway... */
472       bfd_has_map (abfd) = true;
473   }
474   return true;
475 }
476
477 /* Returns false on error, true otherwise */
478 boolean
479 bfd_slurp_coff_armap (abfd)
480      bfd *abfd;
481 {
482   struct areltdata *mapdata;
483   char nextname;
484   int *raw_armap, *rawptr;
485   struct artdata *ardata = bfd_ardata (abfd);
486   char *stringbase;
487   unsigned int stringsize;
488   carsym *carsyms;
489   int result;
490
491   result = bfd_read ((PTR)&nextname, 1, 1, abfd);
492   bfd_seek (abfd, -1L, SEEK_CUR);
493
494   if (result != 1 || nextname != '/') {
495     /* Actually I think this is an error for a COFF archive */
496     bfd_has_map (abfd) = false;
497     return true;
498   }
499
500   mapdata = snarf_ar_hdr (abfd);
501   if (mapdata == NULL) return false;
502
503   raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
504   if (raw_armap == NULL) {
505     bfd_error = no_memory;
506   byebye:
507     bfd_release (abfd, (PTR)mapdata);
508     return false;
509   }
510
511   if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
512       mapdata->parsed_size) {
513     bfd_error = malformed_archive;
514   oops:
515     bfd_release (abfd, (PTR)raw_armap);
516     goto byebye;
517   }
518
519   /* The coff armap must be read sequentially.  So we construct a bsd-style
520      one in core all at once, for simplicity. */
521
522   stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
523
524   {
525     unsigned int nsymz = *raw_armap;
526     unsigned int carsym_size = (nsymz * sizeof (carsym));
527     unsigned int ptrsize = (4 * nsymz);
528     unsigned int i;
529     ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
530     if (ardata->symdefs == NULL) {
531       bfd_error = no_memory;
532       goto oops;
533     }
534     carsyms = ardata->symdefs;
535
536     stringbase = ((char *) ardata->symdefs) + carsym_size;
537     memcpy (stringbase, (char*)raw_armap + ptrsize + 4,  stringsize);
538
539
540     /* OK, build the carsyms */
541     for (i = 0; i < nsymz; i++) 
542       {
543         rawptr = raw_armap + i + 1;
544         carsyms->file_offset = *rawptr;
545         carsyms->name = stringbase;
546         for (; *(stringbase++););
547         carsyms++;
548       }
549     *stringbase = 0;
550   }
551   ardata->symdef_count = *raw_armap;
552   ardata->first_file_filepos = bfd_tell (abfd);
553   /* Pad to an even boundary if you have to */
554   ardata->first_file_filepos += (ardata->first_file_filepos) %2;
555   bfd_release (abfd, (PTR)raw_armap);
556   bfd_release (abfd, (PTR)mapdata);
557   bfd_has_map (abfd) = true;
558   return true;
559 }
560 \f
561 /** Extended name table.
562
563   Normally archives support only 14-character filenames.  Intel has extended
564   the format: longer names are stored in a special element (the first in the
565   archive, or second if there is an armap); the name in the ar_hdr is replaced
566   by <space><index into filename element>.  Index is the P.R. of an int (radix:
567   8). */
568
569 /* Returns false on error, true otherwise */
570 boolean
571 _bfd_slurp_extended_name_table (abfd)
572      bfd *abfd;
573 {
574   char nextname[17];
575   struct areltdata *namedata;
576
577   /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
578      we probably don't want to return true.  */
579   if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
580
581   bfd_seek (abfd, -16L, SEEK_CUR);
582
583   if (strncmp (nextname, "ARFILENAMES/    ", 16)) {
584     bfd_ardata (abfd)->extended_names = NULL;
585     return true;
586   }
587
588   namedata = snarf_ar_hdr (abfd);
589   if (namedata == NULL) return false;
590   
591   bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
592   if (bfd_ardata (abfd)->extended_names == NULL) {
593     bfd_error = no_memory;
594   byebye:
595     bfd_release (abfd, (PTR)namedata);
596     return false;
597   }
598
599   if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
600                 namedata->parsed_size, abfd) != namedata->parsed_size) {
601     bfd_error = malformed_archive;
602     bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
603     bfd_ardata (abfd)->extended_names = NULL;
604     goto byebye;
605   }
606
607   /* It appears that the extended names are newline-padded, not null padded.
608      */
609   {
610     char *temp = bfd_ardata (abfd)->extended_names;
611     for (; *temp != '\0'; ++temp)
612       if (*temp == '\n') *temp = '\0';
613   }
614   
615   /* Pad to an even boundary if you have to */
616   bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
617   bfd_ardata (abfd)->first_file_filepos +=
618     (bfd_ardata (abfd)->first_file_filepos) %2;
619
620   /* FIXME, we can't release namedata here because it was allocated
621      below extended_names on the obstack... */
622   /* bfd_release (abfd, namedata); */
623 }
624   return true;
625 }
626
627 static
628 char *normalize(file)
629 char *file;
630 {
631     char *    filename = strrchr(file, '/');
632     if (filename != (char *)NULL) {
633         filename ++;
634     }
635     else {
636         filename = file;
637     }
638 return filename;
639 }
640
641 /* Follows archive_head and produces an extended name table if necessary.
642    Returns (in tabloc) a pointer to an extended name table, and in tablen
643    the length of the table.  If it makes an entry it clobbers the filename
644    so that the element may be written without further massage.
645    Returns true if it ran successfully, false if something went wrong.
646    A successful return may still involve a zero-length tablen!
647    */
648 boolean
649 bfd_construct_extended_name_table (abfd, tabloc, tablen)
650      bfd *abfd;
651      char **tabloc;
652      unsigned int *tablen;
653 {
654   unsigned int maxname = abfd->xvec->ar_max_namelen;
655   unsigned int total_namelen = 0;
656   bfd *current;
657   char *strptr;
658
659   *tablen = 0;
660   
661   /* Figure out how long the table should be */
662   for (current = abfd->archive_head; current != NULL; current = current->next){
663     unsigned int thislen = strlen (normalize(current->filename));
664     if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
665   }
666
667   if (total_namelen == 0) return true;
668
669   *tabloc = bfd_zalloc (abfd,total_namelen);
670   if (*tabloc == NULL) {
671     bfd_error = no_memory;
672     return false;
673   }
674
675   *tablen = total_namelen;
676   strptr = *tabloc;
677
678   for (current = abfd->archive_head; current != NULL; current =
679        current->next) {
680     char *normal =normalize( current->filename);
681     unsigned int thislen = strlen (normal);
682     if (thislen > maxname) {
683       /* Works for now; may need to be re-engineered if we encounter an oddball
684          archive format and want to generalise this hack. */
685       struct ar_hdr *hdr = arch_hdr(current);
686       strcpy (strptr, normal);
687       strptr[thislen] = '\n';
688       hdr->ar_name[0] = ' ';
689       /* We know there will always be enough room (one of the few cases
690          where you may safely use sprintf). */
691       sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
692       /* Kinda Kludgy.   We should just use the returned value of sprintf
693          but not all implementations get this right */
694         {
695           char *temp = hdr->ar_name +2; 
696           for (; temp < hdr->ar_name + maxname; temp++)
697             if (*temp == '\0') *temp = ' ';
698         }
699       strptr += thislen + 1;
700     }
701   }
702
703   return true;
704 }
705 \f
706 /** A couple of functions for creating ar_hdrs */
707
708 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
709    The filename must refer to a filename in the filesystem.
710    The filename field of the ar_hdr will NOT be initialized
711 */
712
713 struct areltdata *
714 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
715       bfd* abfd AND
716       CONST char *filename)
717 {
718   struct stat status;
719   struct areltdata *ared;
720   struct ar_hdr *hdr;
721   char *temp, *temp1;
722
723
724   if (stat (filename, &status) != 0) {
725     bfd_error = system_call_error;
726     return NULL;
727   }
728
729   ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
730                                       sizeof (struct areltdata));
731   if (ared == NULL) {
732     bfd_error = no_memory;
733     return NULL;
734   }
735   hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
736
737   /* ar headers are space padded, not null padded! */
738   temp = (char *) hdr;
739   temp1 = temp + sizeof (struct ar_hdr) - 2;
740   for (; temp < temp1; *(temp++) = ' ');
741   strncpy (hdr->ar_fmag, ARFMAG, 2);
742   
743   /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
744   sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
745   sprintf ((hdr->ar_uid), "%d", status.st_uid);
746   sprintf ((hdr->ar_gid), "%d", status.st_gid);
747   sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
748   sprintf ((hdr->ar_size), "%-10ld", status.st_size);
749   /* Correct for a lossage in sprintf whereby it null-terminates.  I cannot
750      understand how these C losers could design such a ramshackle bunch of
751      IO operations */
752   temp = (char *) hdr;
753   temp1 = temp + sizeof (struct ar_hdr) - 2;
754   for (; temp < temp1; temp++) {
755     if (*temp == '\0') *temp = ' ';
756   }
757   strncpy (hdr->ar_fmag, ARFMAG, 2);
758   ared->parsed_size = status.st_size;
759   ared->arch_header = (char *) hdr;
760
761   return ared;
762 }
763
764 struct ar_hdr *
765 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
766       bfd *abfd AND
767       char *filename)
768 {
769
770   return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
771 }
772
773
774 /* Analogous to stat call */
775 int
776 bfd_generic_stat_arch_elt (abfd, buf)
777      bfd *abfd;
778      struct stat *buf;
779 {
780   struct ar_hdr *hdr;
781   char *aloser;
782   
783   if (abfd->arelt_data == NULL) {
784     bfd_error = invalid_operation;
785     return -1;
786   }
787     
788   hdr = arch_hdr (abfd);
789
790 #define foo(arelt, stelt, size)  \
791   buf->stelt = strtol (hdr->arelt, &aloser, size); \
792   if (aloser == hdr->arelt) return -1;
793   
794   foo (ar_date, st_mtime, 10);
795   foo (ar_uid, st_uid, 10);
796   foo (ar_gid, st_gid, 10);
797   foo (ar_mode, st_mode, 8);
798   foo (ar_size, st_size, 10);
799
800   return 0;
801 }
802
803 void
804 bfd_dont_truncate_arname (abfd, pathname, arhdr)
805      bfd *abfd;
806      CONST char *pathname;
807      char *arhdr;
808 {
809   /* FIXME: This interacts unpleasantly with ar's quick-append option.
810      Fortunately ic960 users will never use that option.  Fixing this
811      is very hard; fortunately I know how to do it and will do so once
812      intel's release is out the door. */
813    
814   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
815   int length;
816   CONST char *filename = strrchr (pathname, '/');
817   int maxlen = ar_maxnamelen (abfd);
818
819   if (filename == NULL)
820     filename = pathname;
821   else
822     ++filename;
823
824   length = strlen (filename);
825
826   if (length <= maxlen)
827     memcpy (hdr->ar_name, filename, length);
828
829   if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
830   return;
831
832 }
833
834 void
835 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
836      bfd *abfd;
837      CONST char *pathname;
838      char *arhdr;
839 {
840   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
841   int length;
842   CONST char *filename = strrchr (pathname, '/');
843   int maxlen = ar_maxnamelen (abfd);
844
845
846   if (filename == NULL)
847     filename = pathname;
848   else
849     ++filename;
850
851   length = strlen (filename);
852
853   if (length <= maxlen)
854     memcpy (hdr->ar_name, filename, length);
855   else {
856     /* pathname: meet procrustes */
857     memcpy (hdr->ar_name, filename, maxlen);
858     length = maxlen;
859   }
860
861   if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
862 }
863
864 /* Store name into ar header.  Truncates the name to fit.
865    1> strip pathname to be just the basename.
866    2> if it's short enuf to fit, stuff it in.
867    3> If it doesn't end with .o, truncate it to fit
868    4> truncate it before the .o, append .o, stuff THAT in.
869 */
870
871 /* This is what gnu ar does.  It's better but incompatible with the bsd ar. */
872 void
873 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
874      bfd *abfd;
875      CONST char *pathname;
876      char *arhdr;
877 {
878   struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
879   int length;
880   CONST char *filename = strrchr (pathname, '/');
881   int maxlen = ar_maxnamelen (abfd);
882         
883   if (filename == NULL)
884     filename = pathname;
885   else
886     ++filename;
887
888   length = strlen (filename);
889
890   if (length <= maxlen)
891     memcpy (hdr->ar_name, filename, length);
892   else {                        /* pathname: meet procrustes */
893     memcpy (hdr->ar_name, filename, maxlen);
894     if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
895       hdr->ar_name[maxlen - 2] = '.';
896       hdr->ar_name[maxlen - 1] = 'o';
897     }
898     length = maxlen;
899   }
900
901   if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
902 }
903 \f
904
905 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
906
907 /* The bfd is open for write and has its format set to bfd_archive */
908 boolean
909 _bfd_write_archive_contents (arch)
910      bfd *arch;
911 {
912   bfd *current;
913   char *etable = NULL;
914   unsigned int elength = 0;
915   boolean makemap = bfd_has_map (arch);
916   boolean hasobjects = false;   /* if no .o's, don't bother to make a map */
917   unsigned int i;
918
919   /* Verify the viability of all entries; if any of them live in the
920      filesystem (as opposed to living in an archive open for input)
921      then construct a fresh ar_hdr for them.
922      */
923   for (current = arch->archive_head; current; current = current->next) {
924     if (bfd_write_p (current)) {
925       bfd_error = invalid_operation;
926       return false;
927     }
928     if (!current->arelt_data) {
929       current->arelt_data =
930           (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
931       if (!current->arelt_data) return false;
932
933       /* Put in the file name */
934     
935     BFD_SEND (arch, _bfd_truncate_arname,(arch, 
936                                           current->filename,
937                                          (char *) arch_hdr(current)));
938
939       
940     }
941
942     if (makemap) {              /* don't bother if we won't make a map! */
943       if ((bfd_check_format (current, bfd_object))
944 #if 0                           /* FIXME -- these are not set correctly */
945           && ((bfd_get_file_flags (current) & HAS_SYMS))
946 #endif
947           )
948         hasobjects = true;
949     }
950   }
951
952   if (!bfd_construct_extended_name_table (arch, &etable, &elength))
953     return false;
954
955   bfd_seek (arch, 0, SEEK_SET);
956 #ifdef GNU960
957   bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
958 #else
959   bfd_write (ARMAG, 1, SARMAG, arch);
960 #endif
961
962   if (makemap && hasobjects) {
963
964     if (compute_and_write_armap (arch, elength) != true) {
965       return false;
966     }
967   }
968
969   if (elength != 0) {
970     struct ar_hdr hdr;
971
972     memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
973     sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
974     sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
975     hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
976     for (i = 0; i < sizeof (struct ar_hdr); i++)
977       if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
978     bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
979     bfd_write (etable, 1, elength, arch);
980     if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
981
982   }
983
984   for (current = arch->archive_head; current; current = current->next) {
985     char buffer[DEFAULT_BUFFERSIZE];
986     unsigned int remaining = arelt_size (current);
987     struct ar_hdr *hdr = arch_hdr(current);
988     /* write ar header */
989
990     if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
991     syserr:
992         bfd_error = system_call_error;
993         return false;
994       }
995     if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
996     while (remaining) 
997         {
998           unsigned int amt = DEFAULT_BUFFERSIZE;
999           if (amt > remaining) {
1000             amt = remaining;
1001           }
1002           if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
1003           if (bfd_write (buffer, amt, 1, arch)   != amt) goto syserr;
1004           remaining -= amt;
1005         }
1006     if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1007   }
1008 return true;
1009 }
1010 \f
1011 /* Note that the namidx for the first symbol is 0 */
1012
1013 boolean
1014 compute_and_write_armap (arch, elength)
1015      bfd *arch;
1016      unsigned int elength;
1017 {
1018   bfd *current;
1019   file_ptr elt_no = 0;
1020   struct orl *map;
1021   int orl_max = 15000;          /* fine initial default */
1022   int orl_count = 0;
1023   int stridx = 0;               /* string index */
1024
1025   /* Dunno if this is the best place for this info... */
1026   if (elength != 0) elength += sizeof (struct ar_hdr);
1027   elength += elength %2 ;
1028
1029   map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1030   if (map == NULL) {
1031     bfd_error = no_memory;
1032     return false;
1033   }
1034
1035   /* Map over each element */
1036   for (current = arch->archive_head;
1037        current != (bfd *)NULL;
1038        current = current->next, elt_no++) 
1039       {
1040         if ((bfd_check_format (current, bfd_object) == true)
1041             && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1042           asymbol **syms;
1043           unsigned int storage;
1044           unsigned int symcount;
1045           unsigned int src_count;
1046
1047           storage = get_symtab_upper_bound (current);
1048           if (storage != 0) {
1049
1050             syms = (asymbol **) bfd_zalloc (arch,storage);
1051             if (syms == NULL) {
1052               bfd_error = no_memory; /* FIXME -- memory leak */
1053               return false;
1054             }
1055             symcount = bfd_canonicalize_symtab (current, syms);
1056
1057
1058             /* Now map over all the symbols, picking out the ones we want */
1059             for (src_count = 0; src_count <symcount; src_count++) {
1060               flagword flags = (syms[src_count])->flags;
1061               if ((flags & BSF_GLOBAL) ||
1062                   (flags & BSF_FORT_COMM)) {
1063
1064                 /* This symbol will go into the archive header */
1065                 if (orl_count == orl_max) 
1066                     {
1067                       orl_max *= 2;
1068                       map = (struct orl *) bfd_realloc (arch, (char *) map,
1069                                                     orl_max * sizeof (struct orl));
1070                     }
1071
1072                 (map[orl_count]).name = (char **) &((syms[src_count])->name);
1073                 (map[orl_count]).pos = (file_ptr) current;
1074                 (map[orl_count]).namidx = stridx;
1075
1076                 stridx += strlen ((syms[src_count])->name) + 1;
1077                 ++orl_count;
1078               }
1079             }
1080           }
1081         }
1082       }
1083   /* OK, now we have collected all the data, let's write them out */
1084   if (!BFD_SEND (arch, write_armap,
1085                  (arch, elength, map, orl_count, stridx))) {
1086
1087     return false;
1088   }
1089
1090
1091   return true;
1092 }
1093
1094 boolean
1095 bsd_write_armap (arch, elength, map, orl_count, stridx)
1096      bfd *arch;
1097      unsigned int elength;
1098      struct orl *map;
1099      int orl_count;
1100      int stridx;
1101 {
1102   unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1103   unsigned int stringsize = stridx + 4;
1104   unsigned int mapsize = stringsize + ranlibsize;
1105   file_ptr firstreal;
1106   bfd *current = arch->archive_head;
1107   bfd *last_elt = current;              /* last element arch seen */
1108   int temp;
1109   int count;
1110   struct ar_hdr hdr;
1111   struct stat statbuf;
1112   unsigned int i;
1113   int padit = mapsize & 1;
1114   
1115   if (padit) mapsize ++;
1116
1117   firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1118
1119   stat (arch->filename, &statbuf);
1120   memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1121   sprintf (hdr.ar_name, RANLIBMAG);
1122   sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);  
1123   sprintf (hdr.ar_uid, "%d", getuid());
1124   sprintf (hdr.ar_gid, "%d", getgid());
1125   sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1126   hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1127   for (i = 0; i < sizeof (struct ar_hdr); i++)
1128     if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1129   bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1130   bfd_h_put_32(arch, ranlibsize, &temp);
1131   bfd_write (&temp, 1, sizeof (temp), arch);
1132   
1133   for (count = 0; count < orl_count; count++) {
1134     struct symdef outs;
1135     struct symdef *outp = &outs;
1136     
1137     if (((bfd *)(map[count]).pos) != last_elt) {
1138             do {
1139                     firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1140                     firstreal += firstreal % 2;
1141                     current = current->next;
1142             } while (current != (bfd *)(map[count]).pos);
1143     } /* if new archive element */
1144
1145     last_elt = current;
1146     bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset);
1147     bfd_h_put_32(arch, firstreal, &outs.file_offset);
1148     bfd_write ((char *)outp, 1, sizeof (outs), arch);
1149   }
1150
1151   /* now write the strings themselves */
1152   bfd_h_put_32(arch, stridx, &temp);
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 }