1 /*** archive.c -- an attempt at combining the machine-independent parts of
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Diddler.
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 o - all archive elements start on an even boundary, newline padded;
25 o - all arch headers are char *;
26 o - all arch headers are the same size (across architectures).
31 * Revision 1.2 1991/04/03 22:09:43 steve
34 * Revision 1.1.1.1 1991/03/21 21:10:42 gumby
35 * Back from Intel with Steve
37 * Revision 1.1 1991/03/21 21:10:42 gumby
40 * Revision 1.3 1991/03/16 05:55:25 rich
43 * Revision 1.2 1991/03/15 18:15:50 rich
44 * *** empty log message ***
46 * Revision 1.7 1991/03/08 04:18:02 rich
47 * *** empty log message ***
49 * Revision 1.6 1991/03/07 21:55:31 sac
50 * Added primitive file caching, a file open only for input and
51 * less than BFD_INCORE_FILE_SIZE will be malloced and read in
54 * Revision 1.5 1991/03/05 16:31:12 sac
66 /* We keep a cache of archive filepointers to archive elements to
67 speed up searching the archive by filepos. We only add an entry to
68 the cache when we actually read one. We also don't sort the cache;
69 it's short enough to search linearly.
70 Note that the pointers here point to the front of the ar_hdr, not
71 to the front of the contents!
76 struct ar_cache
*next
;
79 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
80 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
82 #define arch_hdr(bfd) ((struct ar_hdr *) \
83 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
88 _bfd_generic_mkarchive (abfd
)
91 abfd
->tdata
=(void *) zalloc (sizeof (struct artdata
));
93 if (abfd
->tdata
== NULL
) {
94 bfd_error
= no_memory
;
97 bfd_ardata(abfd
)->cache
= 0;
102 bfd_get_next_mapent (abfd
, prev
, entry
)
107 if (!bfd_has_map (abfd
)) {
108 bfd_error
= invalid_operation
;
109 return BFD_NO_MORE_SYMBOLS
;
112 if (prev
== BFD_NO_MORE_SYMBOLS
) prev
= 0;
113 else if (++prev
>= (symindex
)(bfd_ardata (abfd
)->symdef_count
))
114 return BFD_NO_MORE_SYMBOLS
;
116 *entry
= (bfd_ardata (abfd
)->symdefs
+ prev
);
121 /* To be called by backends only */
123 _bfd_create_empty_archive_element_shell (obfd
)
128 nbfd
= new_bfd_contained_in(obfd
);
130 bfd_error
= no_memory
;
137 bfd_set_archive_head (output_archive
, new_head
)
138 bfd
*output_archive
, *new_head
;
141 output_archive
->archive_head
= new_head
;
146 look_for_bfd_in_cache (arch_bfd
, filepos
)
150 struct ar_cache
*current
;
152 for (current
= bfd_ardata (arch_bfd
)->cache
; current
!= NULL
;
153 current
= current
->next
)
154 if (current
->ptr
== filepos
) return current
->arelt
;
159 /* Kind of stupid to call cons for each one, but we don't do too many */
161 add_bfd_to_cache (arch_bfd
, filepos
, new_elt
)
162 bfd
*arch_bfd
, *new_elt
;
165 struct ar_cache
*new_cache
= ((struct ar_cache
*)
166 zalloc (sizeof (struct ar_cache
)));
168 if (new_cache
== NULL
) {
169 bfd_error
= no_memory
;
173 new_cache
->ptr
= filepos
;
174 new_cache
->arelt
= new_elt
;
175 new_cache
->next
= (struct ar_cache
*)NULL
;
176 if (bfd_ardata (arch_bfd
)->cache
== NULL
)
177 bfd_ardata (arch_bfd
)->cache
= new_cache
;
179 struct ar_cache
*current
= bfd_ardata (arch_bfd
)->cache
;
181 for (; current
->next
!= NULL
; current
= current
->next
);
182 current
->next
= new_cache
;
190 /* The name begins with space. Hence the rest of the name is an index into
194 get_extended_arelt_filename (arch
, name
)
199 unsigned long index
= 0;
201 /* Should extract string so that I can guarantee not to overflow into
202 the next region, but I"m too lazy. */
204 index
= strtol (name
, NULL
, 10);
206 bfd_error
= malformed_archive
;
210 return bfd_ardata (arch
)->extended_names
+ index
;
213 /* This functions reads an arch header and returns an areltdata pointer, or
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.
228 char *hdrp
= (char *) &hdr
;
229 unsigned int parsed_size
;
230 struct areltdata
*ared
;
231 char *filename
= NULL
;
232 unsigned int namelen
= 0;
233 unsigned int allocsize
= sizeof (struct areltdata
) + sizeof (struct ar_hdr
);
236 if (bfd_read ((void *)hdrp
, 1, sizeof (struct ar_hdr
), abfd
)
237 != sizeof (struct ar_hdr
)) {
238 bfd_error
= no_more_archived_files
;
241 if (strncmp ((hdr
.ar_fmag
), ARFMAG
, 2)) {
242 bfd_error
= malformed_archive
;
247 parsed_size
= strtol (hdr
.ar_size
, NULL
, 10);
249 bfd_error
= malformed_archive
;
253 /* extract the filename from the archive */
254 if (hdr
.ar_name
[0] == ' ' && bfd_ardata (abfd
)->extended_names
!= NULL
) {
255 filename
= get_extended_arelt_filename (abfd
, hdr
.ar_name
);
256 if (filename
== NULL
) {
257 bfd_error
= malformed_archive
;
263 /* We judge the end of the name by looking for a space or a
268 while (namelen
< (unsigned)ar_maxnamelen(abfd
) &&
269 ( hdr
.ar_name
[namelen
] != 0 &&
270 hdr
.ar_name
[namelen
] != ' ' &&
271 hdr
.ar_name
[namelen
] != ar_padchar(abfd
))) {
275 allocsize
+= namelen
+ 1;
278 allocptr
= zalloc (allocsize
);
279 if (allocptr
== NULL
) {
280 bfd_error
= no_memory
;
284 ared
= (struct areltdata
*) allocptr
;
286 ared
->arch_header
= allocptr
+ sizeof (struct areltdata
);
287 memcpy ((char *) ared
->arch_header
, &hdr
, sizeof (struct ar_hdr
));
288 ared
->parsed_size
= parsed_size
;
290 if (filename
!= NULL
) ared
->filename
= filename
;
292 ared
->filename
= allocptr
+ (sizeof (struct areltdata
) +
293 sizeof (struct ar_hdr
));
295 memcpy (ared
->filename
, hdr
.ar_name
, namelen
);
296 ared
->filename
[namelen
] = '\0';
303 get_elt_at_filepos (archive
, filepos
)
307 struct areltdata
*new_areldata
;
310 n_nfd
= look_for_bfd_in_cache (archive
, filepos
);
311 if (n_nfd
) return n_nfd
;
313 if (0 > bfd_seek (archive
, filepos
, SEEK_SET
)) {
314 bfd_error
= system_call_error
;
318 if ((new_areldata
= snarf_ar_hdr (archive
)) == NULL
) return NULL
;
320 n_nfd
= _bfd_create_empty_archive_element_shell (archive
);
325 n_nfd
->origin
= bfd_tell (archive
);
326 n_nfd
->arelt_data
= (void *) new_areldata
;
327 n_nfd
->filename
= new_areldata
->filename
;
329 if (add_bfd_to_cache (archive
, filepos
, n_nfd
))
339 bfd_get_elt_at_index (abfd
, index
)
345 (abfd
, (bfd_ardata (abfd
)->symdefs
+ index
)->file_offset
);
349 /* If you've got an archive, call this to read each subfile. */
351 bfd_openr_next_archived_file (archive
, last_file
)
352 bfd
*archive
, *last_file
;
355 if ((bfd_get_format (archive
) != bfd_archive
) ||
356 (archive
->direction
== write_direction
)) {
357 bfd_error
= invalid_operation
;
362 return BFD_SEND (archive
,
363 openr_next_archived_file
,
369 bfd
*bfd_generic_openr_next_archived_file(archive
, last_file
)
376 filestart
= bfd_ardata (archive
)->first_file_filepos
;
378 unsigned int size
= arelt_size(last_file
);
379 filestart
= last_file
->origin
+size
+ size
%2;
384 return get_elt_at_filepos (archive
, filestart
);
389 bfd_generic_archive_p (abfd
)
392 char armag
[SARMAG
+1];
394 if (bfd_read ((void *)armag
, 1, SARMAG
, abfd
) != SARMAG
) {
395 bfd_error
= wrong_format
;
399 if (strncmp (armag
, ARMAG
, SARMAG
)) return 0;
401 bfd_set_ardata(abfd
, (struct artdata
*) zalloc (sizeof (struct artdata
)));
403 if (bfd_ardata (abfd
) == NULL
) {
404 bfd_error
= no_memory
;
408 bfd_ardata (abfd
)->first_file_filepos
= SARMAG
;
410 if (!BFD_SEND (abfd
, _bfd_slurp_armap
, (abfd
))) {
411 free (bfd_ardata (abfd
));
416 /* armap could be left ungc'd! FIXME -- potential storage leak */
417 if (!BFD_SEND (abfd
, _bfd_slurp_extended_name_table
, (abfd
))) {
418 free (bfd_ardata (abfd
));
426 /* Returns false on error, true otherwise */
428 bfd_slurp_bsd_armap (abfd
)
431 struct areltdata
*mapdata
;
433 unsigned int counter
= 0;
434 int *raw_armap
, *rbase
;
435 struct artdata
*ardata
= bfd_ardata (abfd
);
438 if (bfd_read ((void *)nextname
, 1, 16, abfd
) == 16) {
439 /* The archive has at least 16 bytes in it */
440 bfd_seek (abfd
, -16L, SEEK_CUR
);
442 if (strncmp (nextname
, "__.SYMDEF ", 16)) {
443 bfd_has_map (abfd
) = false;
447 mapdata
= snarf_ar_hdr (abfd
);
448 if (mapdata
== NULL
) return false;
450 raw_armap
= (int *) zalloc (mapdata
->parsed_size
);
451 if (raw_armap
== NULL
) {
452 bfd_error
= no_memory
;
458 if (bfd_read ((void *)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
459 mapdata
->parsed_size
) {
460 bfd_error
= malformed_archive
;
465 ardata
->symdef_count
= *(raw_armap
) / sizeof (struct symdef
);
468 ardata
->symdefs
= (carsym
*) rbase
;
469 stringbase
= ((char *) (ardata
->symdefs
+ ardata
->symdef_count
)) + 4;
471 for (;counter
< (unsigned)( ardata
->symdef_count
); counter
++) {
472 struct symdef
*sym
= ((struct symdef
*) rbase
) + counter
;
473 sym
->s
.name
= sym
->s
.string_offset
+ stringbase
;
476 ardata
->first_file_filepos
= bfd_tell (abfd
);
477 /* Pad to an even boundary if you have to */
478 ardata
->first_file_filepos
+= (ardata
-> first_file_filepos
) %2;
480 bfd_has_map (abfd
) = true;
485 /* Returns false on error, true otherwise */
487 bfd_slurp_coff_armap (abfd
)
490 struct areltdata
*mapdata
;
492 int *raw_armap
, *rawptr
;
493 struct artdata
*ardata
= bfd_ardata (abfd
);
495 unsigned int stringsize
;
498 if (bfd_read ((void *)&nextname
, 1, 1, abfd
) != 1) {
499 bfd_has_map(abfd
) = false;
503 if (nextname
!= '/') {
504 /* Actually I think this is an error for a COFF archive */
505 bfd_has_map (abfd
) = false;
509 bfd_seek (abfd
, -1L, SEEK_CUR
);
510 mapdata
= snarf_ar_hdr (abfd
);
511 if (mapdata
== NULL
) return false;
513 raw_armap
= (int *) zalloc (mapdata
->parsed_size
);
514 if (raw_armap
== NULL
) {
515 bfd_error
= no_memory
;
521 if (bfd_read ((void *)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
522 mapdata
->parsed_size
) {
523 bfd_error
= malformed_archive
;
529 /* The coff armap must be read sequentially. So we construct a bsd-style
530 one in core all at once, for simplicity. */
532 stringsize
= mapdata
->parsed_size
- (4 * (*raw_armap
)) - 4;
535 unsigned int nsymz
= *raw_armap
;
536 unsigned int carsym_size
= (nsymz
* sizeof (carsym
));
537 unsigned int ptrsize
= (4 * nsymz
);
539 ardata
->symdefs
= (carsym
*) zalloc (carsym_size
+ stringsize
+ 1);
540 if (ardata
->symdefs
== NULL
) {
541 bfd_error
= no_memory
;
544 carsyms
= ardata
->symdefs
;
546 stringbase
= ((char *) ardata
->symdefs
) + carsym_size
;
547 memcpy (stringbase
, (char*)raw_armap
+ ptrsize
+ 4, stringsize
);
550 /* OK, build the carsyms */
551 for (i
= 0; i
< nsymz
; i
++)
553 rawptr
= raw_armap
+ i
+ 1;
554 carsyms
->file_offset
= *rawptr
;
555 carsyms
->name
= stringbase
;
556 for (; *(stringbase
++););
561 ardata
->symdef_count
= *raw_armap
;
562 ardata
->first_file_filepos
= bfd_tell (abfd
);
563 /* Pad to an even boundary if you have to */
564 ardata
->first_file_filepos
+= (ardata
->first_file_filepos
) %2;
567 bfd_has_map (abfd
) = true;
572 /** Extended name table.
574 Normally archives support only 14-character filenames. Intel has extended
575 the format: longer names are stored in a special element (the first in the
576 archive, or second if there is an armap); the name in the ar_hdr is replaced
577 by <space><index into filename element>. Index is the P.R. of an int (radix:
580 /* Returns false on error, true otherwise */
582 _bfd_slurp_extended_name_table (abfd
)
586 struct areltdata
*namedata
;
588 if (bfd_read ((void *)nextname
, 1, 16, abfd
) == 16) {
590 bfd_seek (abfd
, -16L, SEEK_CUR
);
592 if (strncmp (nextname
, "ARFILENAMES/ ", 16)) {
593 bfd_ardata (abfd
)->extended_names
= NULL
;
597 namedata
= snarf_ar_hdr (abfd
);
598 if (namedata
== NULL
) return false;
601 bfd_ardata (abfd
)->extended_names
= zalloc (namedata
->parsed_size
);
602 if (bfd_ardata (abfd
)->extended_names
== NULL
) {
603 bfd_error
= no_memory
;
609 if (bfd_read ((void*)bfd_ardata (abfd
)->extended_names
, 1,
610 namedata
->parsed_size
, abfd
) != namedata
->parsed_size
) {
611 bfd_error
= malformed_archive
;
612 free (bfd_ardata (abfd
)->extended_names
);
613 bfd_ardata (abfd
)->extended_names
= NULL
;
617 /* Pad to an even boundary if you have to */
618 bfd_ardata (abfd
)->first_file_filepos
= bfd_tell (abfd
);
619 bfd_ardata (abfd
)->first_file_filepos
+=
620 (bfd_ardata (abfd
)->first_file_filepos
) %2;
628 char *normalize(file
)
631 char * filename
= strrchr(file
, '/');
632 if (filename
!= (char *)NULL
) {
641 /* Follows archive_head and produces an extended name table if necessary.
642 Returns (in tabloc) a pointer to an extended name table, and in tablen
643 the length of the table. If it makes an entry it clobbers the filename
644 so that the element may be written without further massage.
645 Returns true if it ran successfully, false if something went wrong.
646 A successful return may still involve a zero-length tablen!
649 bfd_construct_extended_name_table (abfd
, tabloc
, tablen
)
652 unsigned int *tablen
;
654 unsigned int maxname
= abfd
->xvec
->ar_max_namelen
;
655 unsigned int total_namelen
= 0;
661 /* Figure out how long the table should be */
662 for (current
= abfd
->archive_head
; current
!= NULL
; current
= current
->next
){
663 unsigned int thislen
= strlen (normalize(current
->filename
));
664 if (thislen
> maxname
) total_namelen
+= thislen
+ 1; /* leave room for \0 */
667 if (total_namelen
== 0) return true;
669 *tabloc
= zalloc (total_namelen
);
670 if (*tabloc
== NULL
) {
671 bfd_error
= no_memory
;
675 *tablen
= total_namelen
;
678 for (current
= abfd
->archive_head
; current
!= NULL
; current
=
680 char *normal
=normalize( current
->filename
);
681 unsigned int thislen
= strlen (normal
);
682 if (thislen
> maxname
) {
683 strcpy (strptr
, normal
);
684 current
->filename
[0] = ' ';
685 /* We know there will always be enough room (one of the few cases
686 where you may safely use sprintf). */
687 sprintf ((current
->filename
) + 1, "-%o", (unsigned) (strptr
- *tabloc
));
689 strptr
+= thislen
+ 1;
696 /** A couple of functions for creating ar_hdrs */
698 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
699 The filename must refer to a filename in the filesystem.
700 The filename field of the ar_hdr will NOT be initialized
704 bfd_ar_hdr_from_filesystem (filename
)
708 struct areltdata
*ared
;
713 if (stat (filename
, &status
) != 0) {
714 bfd_error
= system_call_error
;
718 ared
= (struct areltdata
*) zalloc (sizeof (struct ar_hdr
) +
719 sizeof (struct areltdata
));
721 bfd_error
= no_memory
;
724 hdr
= (struct ar_hdr
*) (((char *) ared
) + sizeof (struct areltdata
));
726 /* ar headers are space padded, not null padded! */
728 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
729 for (; temp
< temp1
; *(temp
++) = ' ');
730 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
732 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
733 sprintf ((hdr
->ar_date
), "%-12ld", status
.st_mtime
);
734 sprintf ((hdr
->ar_uid
), "%d", status
.st_uid
);
735 sprintf ((hdr
->ar_gid
), "%d", status
.st_gid
);
736 sprintf ((hdr
->ar_mode
), "%-8o", (unsigned) status
.st_mode
);
737 sprintf ((hdr
->ar_size
), "%-10ld", status
.st_size
);
738 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
739 understand how these C losers could design such a ramshackle bunch of
742 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
743 for (; temp
< temp1
; temp
++) {
744 if (*temp
== '\0') *temp
= ' ';
746 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
747 ared
->parsed_size
= status
.st_size
;
748 ared
->arch_header
= (char *) hdr
;
754 bfd_special_undocumented_glue (filename
)
758 return (struct ar_hdr
*) bfd_ar_hdr_from_filesystem (filename
) -> arch_header
;
762 /* Analogous to stat call */
764 bfd_generic_stat_arch_elt (abfd
, buf
)
771 if (abfd
->arelt_data
== NULL
) {
772 bfd_error
= invalid_operation
;
776 hdr
= arch_hdr (abfd
);
778 #define foo(arelt, stelt, size) \
779 buf->stelt = strtol (hdr->arelt, &aloser, size); \
780 if (aloser == hdr->arelt) return -1;
782 foo (ar_date
, st_mtime
, 10);
783 foo (ar_uid
, st_uid
, 10);
784 foo (ar_gid
, st_gid
, 10);
785 foo (ar_mode
, st_mode
, 8);
786 foo (ar_size
, st_size
, 10);
791 /* Don't do anything -- it'll be taken care of later */
793 bfd_dont_truncate_arname (ignore_abfd
, ignore_filename
, ignore_arhdr
)
795 char *ignore_filename
;
798 /* FIXME -- Actually this is incorrect. If the name is short we
799 should insert into the header; only if it is long should we do
802 Anyway, this interacts unpleasantly with ar's quick-append option,
803 for now just be compatible with the old system */
809 bfd_bsd_truncate_arname (abfd
, pathname
, arhdr
)
814 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
816 char *filename
= strrchr (pathname
, '/');
817 int maxlen
= ar_maxnamelen (abfd
);
820 if (filename
== NULL
)
825 length
= strlen (filename
);
827 if (length
<= maxlen
)
828 memcpy (hdr
->ar_name
, filename
, length
);
830 /* pathname: meet procrustes */
831 memcpy (hdr
->ar_name
, filename
, maxlen
);
835 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
838 /* Store name into ar header. Truncates the name to fit.
839 1> strip pathname to be just the basename.
840 2> if it's short enuf to fit, stuff it in.
841 3> If it doesn't end with .o, truncate it to fit
842 4> truncate it before the .o, append .o, stuff THAT in.
845 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
847 bfd_gnu_truncate_arname (abfd
, pathname
, arhdr
)
852 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
854 char *filename
= strrchr (pathname
, '/');
855 int maxlen
= ar_maxnamelen (abfd
);
857 if (filename
== NULL
)
862 length
= strlen (filename
);
864 if (length
<= maxlen
)
865 memcpy (hdr
->ar_name
, filename
, length
);
866 else { /* pathname: meet procrustes */
867 memcpy (hdr
->ar_name
, filename
, maxlen
);
868 if ((filename
[length
- 2] == '.') && (filename
[length
- 1] == 'o')) {
869 hdr
->ar_name
[maxlen
- 2] = '.';
870 hdr
->ar_name
[maxlen
- 1] = 'o';
875 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
879 PROTO (boolean
, compute_and_write_armap
, (bfd
*arch
, unsigned int elength
));
881 /* The bfd is open for write and has its format set to bfd_archive */
883 _bfd_write_archive_contents (arch
)
888 unsigned int elength
= 0;
889 boolean makemap
= bfd_has_map (arch
);
890 boolean hasobjects
= false; /* if no .o's, don't bother to make a map */
894 /* Verify the viability of all entries; if any of them live in the
895 filesystem (as opposed to living in an archive open for input)
896 then construct a fresh ar_hdr for them.
898 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
899 if (bfd_write_p (current
)) {
900 bfd_error
= invalid_operation
;
903 if (!current
->arelt_data
) {
904 current
->arelt_data
=
905 (void *) bfd_ar_hdr_from_filesystem (current
->filename
);
906 if (!current
->arelt_data
) return false;
908 /* Put in the file name */
910 BFD_SEND (arch
, _bfd_truncate_arname
,(arch
,
912 (char *) arch_hdr(current
)));
917 if (makemap
) { /* don't bother if we won't make a map! */
918 if ((bfd_check_format (current
, bfd_object
))
919 #if 0 /* FIXME -- these are not set correctly */
920 && ((bfd_get_file_flags (current
) & HAS_SYMS
))
927 if (!bfd_construct_extended_name_table (arch
, &etable
, &elength
))
930 bfd_seek (arch
, 0, SEEK_SET
);
931 bfd_write (ARMAG
, 1, SARMAG
, arch
);
933 if (makemap
&& hasobjects
) {
935 if (compute_and_write_armap (arch
, elength
) != true) {
936 if (etable
) free (etable
);
944 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
945 sprintf (&(hdr
.ar_name
[0]), "ARFILENAMES/");
946 sprintf (&(hdr
.ar_size
[0]), "%-10d", (int) elength
);
947 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
948 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
949 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
950 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
951 bfd_write (etable
, 1, elength
, arch
);
952 if ((elength
% 2) == 1) bfd_write ("\n", 1, 1, arch
);
953 if (etable
) free (etable
);
956 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
957 char buffer
[DEFAULT_BUFFERSIZE
];
958 unsigned int remaining
= arelt_size (current
);
959 struct ar_hdr
*hdr
= arch_hdr(current
);
960 /* write ar header */
962 if (bfd_write (hdr
, 1, sizeof(*hdr
), arch
) != sizeof(*hdr
)) {
964 bfd_error
= system_call_error
;
967 if (bfd_seek (current
, 0L, SEEK_SET
) != 0L) goto syserr
;
970 unsigned int amt
= DEFAULT_BUFFERSIZE
;
971 if (amt
> remaining
) {
974 if (bfd_read (buffer
, amt
, 1, current
) != amt
) goto syserr
;
975 if (bfd_write (buffer
, amt
, 1, arch
) != amt
) goto syserr
;
978 if ((arelt_size (current
) % 2) == 1) bfd_write ("\n", 1, 1, arch
);
983 /* Note that the namidx for the first symbol is 0 */
988 compute_and_write_armap (arch
, elength
)
990 unsigned int elength
;
995 int orl_max
= 15000; /* fine initial default */
997 int stridx
= 0; /* string index */
999 /* Dunno if this is the best place for this info... */
1000 if (elength
!= 0) elength
+= sizeof (struct ar_hdr
);
1001 elength
+= elength
%2 ;
1003 map
= (struct orl
*) zalloc (orl_max
* sizeof (struct orl
));
1005 bfd_error
= no_memory
;
1009 /* Map over each element */
1010 for (current
= arch
->archive_head
;
1011 current
!= (bfd
*)NULL
;
1012 current
= current
->next
, elt_no
++)
1014 if ((bfd_check_format (current
, bfd_object
) == true)
1015 && ((bfd_get_file_flags (current
) & HAS_SYMS
))) {
1017 unsigned int storage
;
1018 unsigned int symcount
;
1019 unsigned int src_count
;
1021 storage
= get_symtab_upper_bound (current
);
1024 syms
= (asymbol
**) zalloc (storage
);
1026 bfd_error
= no_memory
; /* FIXME -- memory leak */
1029 symcount
= bfd_canonicalize_symtab (current
, syms
);
1032 /* Now map over all the symbols, picking out the ones we want */
1033 for (src_count
= 0; src_count
<symcount
; src_count
++) {
1034 flagword flags
= (syms
[src_count
])->flags
;
1035 if ((flags
& BSF_GLOBAL
) ||
1036 (flags
& BSF_FORT_COMM
)) {
1038 /* This symbol will go into the archive header */
1039 if (orl_count
== orl_max
)
1042 map
= (struct orl
*) realloc ((char *) map
,
1043 orl_max
* sizeof (struct orl
));
1046 (map
[orl_count
]).name
= &((syms
[src_count
])->name
);
1047 (map
[orl_count
]).pos
= elt_no
;
1048 (map
[orl_count
]).namidx
= stridx
;
1050 stridx
+= strlen ((syms
[src_count
])->name
) + 1;
1057 /* OK, now we have collected all the data, let's write them out */
1058 if (!BFD_SEND (arch
, write_armap
,
1059 (arch
, elength
, map
, orl_count
, stridx
))) {
1069 /* FIXME -- have to byte-swap this */
1072 bsd_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1074 unsigned int elength
;
1079 unsigned int ranlibsize
= (orl_count
* sizeof (struct ranlib
)) + 4;
1080 unsigned int stringsize
= stridx
+ 4;
1081 unsigned int mapsize
= stringsize
+ ranlibsize
;
1083 bfd
*current
= arch
->archive_head
;
1084 int last_eltno
= 0; /* last element arch seen */
1088 struct stat statbuf
;
1090 int padit
= mapsize
& 1;
1092 if (padit
) mapsize
++;
1094 firstreal
= mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1096 fstat (arch
->iostream
, &statbuf
); /* FIXME -- descriptor must be open! */
1097 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1098 sprintf (hdr
.ar_name
, "__.SYMDEF");
1099 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1100 sprintf (hdr
.ar_date
, "%ld", statbuf
.st_mtime
);
1101 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1102 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1103 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1104 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1106 temp
= orl_count
/* + 4 */;
1107 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1109 for (count
= 0; count
< orl_count
; count
++) {
1111 struct symdef
*outp
= &outs
;
1113 if ((map
[count
]).pos
!= last_eltno
) {
1114 firstreal
+= arelt_size (current
) + sizeof (struct ar_hdr
);
1115 firstreal
+= firstreal
% 2;
1116 last_eltno
= (map
[count
]).pos
;
1117 current
= current
->next
;
1120 outs
.s
.string_offset
= ((map
[count
]).namidx
) +4;
1121 outs
.file_offset
= firstreal
;
1122 bfd_write ((char *)outp
, 1, sizeof (outs
), arch
);
1125 /* now write the strings themselves */
1127 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1128 for (count
= 0; count
< orl_count
; count
++)
1129 bfd_write (*((map
[count
]).name
), 1, strlen (*((map
[count
]).name
))+1, arch
);
1131 /* The spec sez this should be a newline. But in order to be
1132 bug-compatible for sun's ar we use a null. */
1134 bfd_write("\0",1,1,arch
);
1140 /* A coff armap looks like :
1142 struct ar_hdr with name = '/'
1144 offset of file for symbol 0
1145 offset of file for symbol 1
1147 offset of file for symbol n-1
1156 coff_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1158 unsigned int elength
;
1163 unsigned int ranlibsize
= (orl_count
* 4) + 4;
1164 unsigned int stringsize
= stridx
;
1165 unsigned int mapsize
= stringsize
+ ranlibsize
;
1166 file_ptr archive_member_file_ptr
;
1167 bfd
*current
= arch
->archive_head
;
1168 int last_eltno
= 0; /* last element arch seen */
1171 struct stat statbuf
;
1173 int padit
= mapsize
& 1;
1175 if (padit
) mapsize
++;
1177 archive_member_file_ptr
=
1178 mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1180 fstat (arch
->iostream
, &statbuf
); /* FIXME -- descriptor must be open! */
1181 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1182 hdr
.ar_name
[0] = '/';
1183 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1184 sprintf (hdr
.ar_date
, "%ld", statbuf
.st_mtime
);
1185 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1187 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1188 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1190 /* Write the ar header for this item and the number of symbols */
1192 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1193 bfd_write (&orl_count
, 1, sizeof (orl_count
), arch
);
1195 /* Two passes, first write the file offsets for each symbol -
1196 remembering that each offset is on a two byte boundary
1199 for (count
= 0; count
< orl_count
; count
++) {
1200 while ((map
[count
]).pos
!= last_eltno
) {
1201 /* If this is the first time we've seen a ref to this archive
1202 then remember it's size */
1203 archive_member_file_ptr
+=
1204 arelt_size (current
) + sizeof (struct ar_hdr
);
1205 archive_member_file_ptr
+= archive_member_file_ptr
% 2;
1206 current
= current
->next
;
1209 bfd_write (&archive_member_file_ptr
,
1211 sizeof (archive_member_file_ptr
),
1215 /* now write the strings themselves */
1216 for (count
= 0; count
< orl_count
; count
++) {
1217 bfd_write (*((map
[count
]).name
),
1219 strlen (*((map
[count
]).name
))+1, arch
);
1222 /* The spec sez this should be a newline. But in order to be
1223 bug-compatible for arc960 we use a null. */
1225 bfd_write("\0",1,1,arch
);