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