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