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