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