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