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.4 1991/04/04 17:55:47 steve
32 * *** empty log message ***
34 * Revision 1.3 1991/04/04 14:56:42 gumby
37 * Revision 1.2 1991/04/03 22:09:43 steve
40 * Revision 1.1.1.1 1991/03/21 21:10:42 gumby
41 * Back from Intel with Steve
43 * Revision 1.1 1991/03/21 21:10:42 gumby
46 * Revision 1.3 1991/03/16 05:55:25 rich
49 * Revision 1.2 1991/03/15 18:15:50 rich
50 * *** empty log message ***
52 * Revision 1.7 1991/03/08 04:18:02 rich
53 * *** empty log message ***
55 * Revision 1.6 1991/03/07 21:55:31 sac
56 * Added primitive file caching, a file open only for input and
57 * less than BFD_INCORE_FILE_SIZE will be malloced and read in
60 * Revision 1.5 1991/03/05 16:31:12 sac
72 /* We keep a cache of archive filepointers to archive elements to
73 speed up searching the archive by filepos. We only add an entry to
74 the cache when we actually read one. We also don't sort the cache;
75 it's short enough to search linearly.
76 Note that the pointers here point to the front of the ar_hdr, not
77 to the front of the contents!
82 struct ar_cache
*next
;
85 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
86 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
88 #define arch_hdr(bfd) ((struct ar_hdr *) \
89 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
94 _bfd_generic_mkarchive (abfd
)
97 abfd
->tdata
=(void *) zalloc (sizeof (struct artdata
));
99 if (abfd
->tdata
== NULL
) {
100 bfd_error
= no_memory
;
103 bfd_ardata(abfd
)->cache
= 0;
108 bfd_get_next_mapent (abfd
, prev
, entry
)
113 if (!bfd_has_map (abfd
)) {
114 bfd_error
= invalid_operation
;
115 return BFD_NO_MORE_SYMBOLS
;
118 if (prev
== BFD_NO_MORE_SYMBOLS
) prev
= 0;
119 else if (++prev
>= (symindex
)(bfd_ardata (abfd
)->symdef_count
))
120 return BFD_NO_MORE_SYMBOLS
;
122 *entry
= (bfd_ardata (abfd
)->symdefs
+ prev
);
127 /* To be called by backends only */
129 _bfd_create_empty_archive_element_shell (obfd
)
134 nbfd
= new_bfd_contained_in(obfd
);
136 bfd_error
= no_memory
;
143 bfd_set_archive_head (output_archive
, new_head
)
144 bfd
*output_archive
, *new_head
;
147 output_archive
->archive_head
= new_head
;
152 look_for_bfd_in_cache (arch_bfd
, filepos
)
156 struct ar_cache
*current
;
158 for (current
= bfd_ardata (arch_bfd
)->cache
; current
!= NULL
;
159 current
= current
->next
)
160 if (current
->ptr
== filepos
) return current
->arelt
;
165 /* Kind of stupid to call cons for each one, but we don't do too many */
167 add_bfd_to_cache (arch_bfd
, filepos
, new_elt
)
168 bfd
*arch_bfd
, *new_elt
;
171 struct ar_cache
*new_cache
= ((struct ar_cache
*)
172 zalloc (sizeof (struct ar_cache
)));
174 if (new_cache
== NULL
) {
175 bfd_error
= no_memory
;
179 new_cache
->ptr
= filepos
;
180 new_cache
->arelt
= new_elt
;
181 new_cache
->next
= (struct ar_cache
*)NULL
;
182 if (bfd_ardata (arch_bfd
)->cache
== NULL
)
183 bfd_ardata (arch_bfd
)->cache
= new_cache
;
185 struct ar_cache
*current
= bfd_ardata (arch_bfd
)->cache
;
187 for (; current
->next
!= NULL
; current
= current
->next
);
188 current
->next
= new_cache
;
196 /* The name begins with space. Hence the rest of the name is an index into
200 get_extended_arelt_filename (arch
, name
)
205 unsigned long index
= 0;
207 /* Should extract string so that I can guarantee not to overflow into
208 the next region, but I"m too lazy. */
210 index
= strtol (name
, NULL
, 10);
212 bfd_error
= malformed_archive
;
216 return bfd_ardata (arch
)->extended_names
+ index
;
219 /* This functions reads an arch header and returns an areltdata pointer, or
222 Presumes the file pointer is already in the right place (ie pointing
223 to the ar_hdr in the file). Moves the file pointer; on success it
224 should be pointing to the front of the file contents; on failure it
225 could have been moved arbitrarily.
234 char *hdrp
= (char *) &hdr
;
235 unsigned int parsed_size
;
236 struct areltdata
*ared
;
237 char *filename
= NULL
;
238 unsigned int namelen
= 0;
239 unsigned int allocsize
= sizeof (struct areltdata
) + sizeof (struct ar_hdr
);
242 if (bfd_read ((void *)hdrp
, 1, sizeof (struct ar_hdr
), abfd
)
243 != sizeof (struct ar_hdr
)) {
244 bfd_error
= no_more_archived_files
;
247 if (strncmp ((hdr
.ar_fmag
), ARFMAG
, 2)) {
248 bfd_error
= malformed_archive
;
253 parsed_size
= strtol (hdr
.ar_size
, NULL
, 10);
255 bfd_error
= malformed_archive
;
259 /* extract the filename from the archive */
260 if (hdr
.ar_name
[0] == ' ' && bfd_ardata (abfd
)->extended_names
!= NULL
) {
261 filename
= get_extended_arelt_filename (abfd
, hdr
.ar_name
);
262 if (filename
== NULL
) {
263 bfd_error
= malformed_archive
;
269 /* We judge the end of the name by looking for a space or a
274 while (namelen
< (unsigned)ar_maxnamelen(abfd
) &&
275 ( hdr
.ar_name
[namelen
] != 0 &&
276 hdr
.ar_name
[namelen
] != ' ' &&
277 hdr
.ar_name
[namelen
] != ar_padchar(abfd
))) {
281 allocsize
+= namelen
+ 1;
284 allocptr
= zalloc (allocsize
);
285 if (allocptr
== NULL
) {
286 bfd_error
= no_memory
;
290 ared
= (struct areltdata
*) allocptr
;
292 ared
->arch_header
= allocptr
+ sizeof (struct areltdata
);
293 memcpy ((char *) ared
->arch_header
, &hdr
, sizeof (struct ar_hdr
));
294 ared
->parsed_size
= parsed_size
;
296 if (filename
!= NULL
) ared
->filename
= filename
;
298 ared
->filename
= allocptr
+ (sizeof (struct areltdata
) +
299 sizeof (struct ar_hdr
));
301 memcpy (ared
->filename
, hdr
.ar_name
, namelen
);
302 ared
->filename
[namelen
] = '\0';
309 get_elt_at_filepos (archive
, filepos
)
313 struct areltdata
*new_areldata
;
316 n_nfd
= look_for_bfd_in_cache (archive
, filepos
);
317 if (n_nfd
) return n_nfd
;
319 if (0 > bfd_seek (archive
, filepos
, SEEK_SET
)) {
320 bfd_error
= system_call_error
;
324 if ((new_areldata
= snarf_ar_hdr (archive
)) == NULL
) return NULL
;
326 n_nfd
= _bfd_create_empty_archive_element_shell (archive
);
331 n_nfd
->origin
= bfd_tell (archive
);
332 n_nfd
->arelt_data
= (void *) new_areldata
;
333 n_nfd
->filename
= new_areldata
->filename
;
335 if (add_bfd_to_cache (archive
, filepos
, n_nfd
))
345 bfd_get_elt_at_index (abfd
, index
)
351 (abfd
, (bfd_ardata (abfd
)->symdefs
+ index
)->file_offset
);
355 /* If you've got an archive, call this to read each subfile. */
357 bfd_openr_next_archived_file (archive
, last_file
)
358 bfd
*archive
, *last_file
;
361 if ((bfd_get_format (archive
) != bfd_archive
) ||
362 (archive
->direction
== write_direction
)) {
363 bfd_error
= invalid_operation
;
368 return BFD_SEND (archive
,
369 openr_next_archived_file
,
375 bfd
*bfd_generic_openr_next_archived_file(archive
, last_file
)
382 filestart
= bfd_ardata (archive
)->first_file_filepos
;
384 unsigned int size
= arelt_size(last_file
);
385 filestart
= last_file
->origin
+size
+ size
%2;
390 return get_elt_at_filepos (archive
, filestart
);
395 bfd_generic_archive_p (abfd
)
398 char armag
[SARMAG
+1];
400 if (bfd_read ((void *)armag
, 1, SARMAG
, abfd
) != SARMAG
) {
401 bfd_error
= wrong_format
;
405 if (strncmp (armag
, ARMAG
, SARMAG
)) return 0;
407 bfd_set_ardata(abfd
, (struct artdata
*) zalloc (sizeof (struct artdata
)));
409 if (bfd_ardata (abfd
) == NULL
) {
410 bfd_error
= no_memory
;
414 bfd_ardata (abfd
)->first_file_filepos
= SARMAG
;
416 if (!BFD_SEND (abfd
, _bfd_slurp_armap
, (abfd
))) {
417 free (bfd_ardata (abfd
));
422 /* armap could be left ungc'd! FIXME -- potential storage leak */
423 if (!BFD_SEND (abfd
, _bfd_slurp_extended_name_table
, (abfd
))) {
424 free (bfd_ardata (abfd
));
432 /* Returns false on error, true otherwise */
434 bfd_slurp_bsd_armap (abfd
)
437 struct areltdata
*mapdata
;
439 unsigned int counter
= 0;
440 int *raw_armap
, *rbase
;
441 struct artdata
*ardata
= bfd_ardata (abfd
);
444 if (bfd_read ((void *)nextname
, 1, 16, abfd
) == 16) {
445 /* The archive has at least 16 bytes in it */
446 bfd_seek (abfd
, -16L, SEEK_CUR
);
448 if (strncmp (nextname
, "__.SYMDEF ", 16)) {
449 bfd_has_map (abfd
) = false;
453 mapdata
= snarf_ar_hdr (abfd
);
454 if (mapdata
== NULL
) return false;
456 raw_armap
= (int *) zalloc (mapdata
->parsed_size
);
457 if (raw_armap
== NULL
) {
458 bfd_error
= no_memory
;
464 if (bfd_read ((void *)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
465 mapdata
->parsed_size
) {
466 bfd_error
= malformed_archive
;
471 ardata
->symdef_count
= *(raw_armap
) / sizeof (struct symdef
);
474 ardata
->symdefs
= (carsym
*) rbase
;
475 stringbase
= ((char *) (ardata
->symdefs
+ ardata
->symdef_count
)) + 4;
477 for (;counter
< (unsigned)( ardata
->symdef_count
); counter
++) {
478 struct symdef
*sym
= ((struct symdef
*) rbase
) + counter
;
479 sym
->s
.name
= sym
->s
.string_offset
+ stringbase
;
482 ardata
->first_file_filepos
= bfd_tell (abfd
);
483 /* Pad to an even boundary if you have to */
484 ardata
->first_file_filepos
+= (ardata
-> first_file_filepos
) %2;
486 bfd_has_map (abfd
) = true;
491 /* Returns false on error, true otherwise */
493 bfd_slurp_coff_armap (abfd
)
496 struct areltdata
*mapdata
;
498 int *raw_armap
, *rawptr
;
499 struct artdata
*ardata
= bfd_ardata (abfd
);
501 unsigned int stringsize
;
504 if (bfd_read ((void *)&nextname
, 1, 1, abfd
) != 1) {
505 bfd_seek (abfd
, -1L, SEEK_CUR
);
506 bfd_has_map(abfd
) = false;
509 bfd_seek (abfd
, -1L, SEEK_CUR
);
511 if (nextname
!= '/') {
512 /* Actually I think this is an error for a COFF archive */
513 bfd_has_map (abfd
) = false;
517 mapdata
= snarf_ar_hdr (abfd
);
518 if (mapdata
== NULL
) return false;
520 raw_armap
= (int *) zalloc (mapdata
->parsed_size
);
521 if (raw_armap
== NULL
) {
522 bfd_error
= no_memory
;
528 if (bfd_read ((void *)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
529 mapdata
->parsed_size
) {
530 bfd_error
= malformed_archive
;
536 /* The coff armap must be read sequentially. So we construct a bsd-style
537 one in core all at once, for simplicity. */
539 stringsize
= mapdata
->parsed_size
- (4 * (*raw_armap
)) - 4;
542 unsigned int nsymz
= *raw_armap
;
543 unsigned int carsym_size
= (nsymz
* sizeof (carsym
));
544 unsigned int ptrsize
= (4 * nsymz
);
546 ardata
->symdefs
= (carsym
*) zalloc (carsym_size
+ stringsize
+ 1);
547 if (ardata
->symdefs
== NULL
) {
548 bfd_error
= no_memory
;
551 carsyms
= ardata
->symdefs
;
553 stringbase
= ((char *) ardata
->symdefs
) + carsym_size
;
554 memcpy (stringbase
, (char*)raw_armap
+ ptrsize
+ 4, stringsize
);
557 /* OK, build the carsyms */
558 for (i
= 0; i
< nsymz
; i
++)
560 rawptr
= raw_armap
+ i
+ 1;
561 carsyms
->file_offset
= *rawptr
;
562 carsyms
->name
= stringbase
;
563 for (; *(stringbase
++););
568 ardata
->symdef_count
= *raw_armap
;
569 ardata
->first_file_filepos
= bfd_tell (abfd
);
570 /* Pad to an even boundary if you have to */
571 ardata
->first_file_filepos
+= (ardata
->first_file_filepos
) %2;
574 bfd_has_map (abfd
) = true;
579 /** Extended name table.
581 Normally archives support only 14-character filenames. Intel has extended
582 the format: longer names are stored in a special element (the first in the
583 archive, or second if there is an armap); the name in the ar_hdr is replaced
584 by <space><index into filename element>. Index is the P.R. of an int (radix:
587 /* Returns false on error, true otherwise */
589 _bfd_slurp_extended_name_table (abfd
)
593 struct areltdata
*namedata
;
595 if (bfd_read ((void *)nextname
, 1, 16, abfd
) == 16) {
597 bfd_seek (abfd
, -16L, SEEK_CUR
);
599 if (strncmp (nextname
, "ARFILENAMES/ ", 16)) {
600 bfd_ardata (abfd
)->extended_names
= NULL
;
604 namedata
= snarf_ar_hdr (abfd
);
605 if (namedata
== NULL
) return false;
608 bfd_ardata (abfd
)->extended_names
= zalloc (namedata
->parsed_size
);
609 if (bfd_ardata (abfd
)->extended_names
== NULL
) {
610 bfd_error
= no_memory
;
616 if (bfd_read ((void*)bfd_ardata (abfd
)->extended_names
, 1,
617 namedata
->parsed_size
, abfd
) != namedata
->parsed_size
) {
618 bfd_error
= malformed_archive
;
619 free (bfd_ardata (abfd
)->extended_names
);
620 bfd_ardata (abfd
)->extended_names
= NULL
;
624 /* Pad to an even boundary if you have to */
625 bfd_ardata (abfd
)->first_file_filepos
= bfd_tell (abfd
);
626 bfd_ardata (abfd
)->first_file_filepos
+=
627 (bfd_ardata (abfd
)->first_file_filepos
) %2;
635 char *normalize(file
)
638 char * filename
= strrchr(file
, '/');
639 if (filename
!= (char *)NULL
) {
648 /* Follows archive_head and produces an extended name table if necessary.
649 Returns (in tabloc) a pointer to an extended name table, and in tablen
650 the length of the table. If it makes an entry it clobbers the filename
651 so that the element may be written without further massage.
652 Returns true if it ran successfully, false if something went wrong.
653 A successful return may still involve a zero-length tablen!
656 bfd_construct_extended_name_table (abfd
, tabloc
, tablen
)
659 unsigned int *tablen
;
661 unsigned int maxname
= abfd
->xvec
->ar_max_namelen
;
662 unsigned int total_namelen
= 0;
668 /* Figure out how long the table should be */
669 for (current
= abfd
->archive_head
; current
!= NULL
; current
= current
->next
){
670 unsigned int thislen
= strlen (normalize(current
->filename
));
671 if (thislen
> maxname
) total_namelen
+= thislen
+ 1; /* leave room for \0 */
674 if (total_namelen
== 0) return true;
676 *tabloc
= zalloc (total_namelen
);
677 if (*tabloc
== NULL
) {
678 bfd_error
= no_memory
;
682 *tablen
= total_namelen
;
685 for (current
= abfd
->archive_head
; current
!= NULL
; current
=
687 char *normal
=normalize( current
->filename
);
688 unsigned int thislen
= strlen (normal
);
689 if (thislen
> maxname
) {
690 /* Works for now; may need to be re-engineered if we encounter an oddball
691 archive format and want to generalise this hack. */
692 struct ar_hdr
*hdr
= arch_hdr(current
);
693 strcpy (strptr
, normal
);
694 hdr
->ar_name
[0] = ' ';
695 /* We know there will always be enough room (one of the few cases
696 where you may safely use sprintf). */
697 sprintf ((hdr
->ar_name
) + 1, "%-o", (unsigned) (strptr
- *tabloc
));
699 strptr
+= thislen
+ 1;
706 /** A couple of functions for creating ar_hdrs */
708 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
709 The filename must refer to a filename in the filesystem.
710 The filename field of the ar_hdr will NOT be initialized
714 bfd_ar_hdr_from_filesystem (filename
)
718 struct areltdata
*ared
;
723 if (stat (filename
, &status
) != 0) {
724 bfd_error
= system_call_error
;
728 ared
= (struct areltdata
*) zalloc (sizeof (struct ar_hdr
) +
729 sizeof (struct areltdata
));
731 bfd_error
= no_memory
;
734 hdr
= (struct ar_hdr
*) (((char *) ared
) + sizeof (struct areltdata
));
736 /* ar headers are space padded, not null padded! */
738 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
739 for (; temp
< temp1
; *(temp
++) = ' ');
740 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
742 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
743 sprintf ((hdr
->ar_date
), "%-12ld", status
.st_mtime
);
744 sprintf ((hdr
->ar_uid
), "%d", status
.st_uid
);
745 sprintf ((hdr
->ar_gid
), "%d", status
.st_gid
);
746 sprintf ((hdr
->ar_mode
), "%-8o", (unsigned) status
.st_mode
);
747 sprintf ((hdr
->ar_size
), "%-10ld", status
.st_size
);
748 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
749 understand how these C losers could design such a ramshackle bunch of
752 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
753 for (; temp
< temp1
; temp
++) {
754 if (*temp
== '\0') *temp
= ' ';
756 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
757 ared
->parsed_size
= status
.st_size
;
758 ared
->arch_header
= (char *) hdr
;
764 bfd_special_undocumented_glue (filename
)
768 return (struct ar_hdr
*) bfd_ar_hdr_from_filesystem (filename
) -> arch_header
;
772 /* Analogous to stat call */
774 bfd_generic_stat_arch_elt (abfd
, buf
)
781 if (abfd
->arelt_data
== NULL
) {
782 bfd_error
= invalid_operation
;
786 hdr
= arch_hdr (abfd
);
788 #define foo(arelt, stelt, size) \
789 buf->stelt = strtol (hdr->arelt, &aloser, size); \
790 if (aloser == hdr->arelt) return -1;
792 foo (ar_date
, st_mtime
, 10);
793 foo (ar_uid
, st_uid
, 10);
794 foo (ar_gid
, st_gid
, 10);
795 foo (ar_mode
, st_mode
, 8);
796 foo (ar_size
, st_size
, 10);
801 /* Don't do anything -- it'll be taken care of later */
803 bfd_dont_truncate_arname (ignore_abfd
, ignore_filename
, ignore_arhdr
)
805 char *ignore_filename
;
808 /* FIXME -- Actually this is incorrect. If the name is short we
809 should insert into the header; only if it is long should we do
812 Anyway, this interacts unpleasantly with ar's quick-append option,
813 for now just be compatible with the old system */
819 bfd_bsd_truncate_arname (abfd
, pathname
, arhdr
)
824 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
826 char *filename
= strrchr (pathname
, '/');
827 int maxlen
= ar_maxnamelen (abfd
);
830 if (filename
== NULL
)
835 length
= strlen (filename
);
837 if (length
<= maxlen
)
838 memcpy (hdr
->ar_name
, filename
, length
);
840 /* pathname: meet procrustes */
841 memcpy (hdr
->ar_name
, filename
, maxlen
);
845 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
848 /* Store name into ar header. Truncates the name to fit.
849 1> strip pathname to be just the basename.
850 2> if it's short enuf to fit, stuff it in.
851 3> If it doesn't end with .o, truncate it to fit
852 4> truncate it before the .o, append .o, stuff THAT in.
855 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
857 bfd_gnu_truncate_arname (abfd
, pathname
, arhdr
)
862 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
864 char *filename
= strrchr (pathname
, '/');
865 int maxlen
= ar_maxnamelen (abfd
);
867 if (filename
== NULL
)
872 length
= strlen (filename
);
874 if (length
<= maxlen
)
875 memcpy (hdr
->ar_name
, filename
, length
);
876 else { /* pathname: meet procrustes */
877 memcpy (hdr
->ar_name
, filename
, maxlen
);
878 if ((filename
[length
- 2] == '.') && (filename
[length
- 1] == 'o')) {
879 hdr
->ar_name
[maxlen
- 2] = '.';
880 hdr
->ar_name
[maxlen
- 1] = 'o';
885 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
889 PROTO (boolean
, compute_and_write_armap
, (bfd
*arch
, unsigned int elength
));
891 /* The bfd is open for write and has its format set to bfd_archive */
893 _bfd_write_archive_contents (arch
)
898 unsigned int elength
= 0;
899 boolean makemap
= bfd_has_map (arch
);
900 boolean hasobjects
= false; /* if no .o's, don't bother to make a map */
904 /* Verify the viability of all entries; if any of them live in the
905 filesystem (as opposed to living in an archive open for input)
906 then construct a fresh ar_hdr for them.
908 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
909 if (bfd_write_p (current
)) {
910 bfd_error
= invalid_operation
;
913 if (!current
->arelt_data
) {
914 current
->arelt_data
=
915 (void *) bfd_ar_hdr_from_filesystem (current
->filename
);
916 if (!current
->arelt_data
) return false;
918 /* Put in the file name */
920 BFD_SEND (arch
, _bfd_truncate_arname
,(arch
,
922 (char *) arch_hdr(current
)));
927 if (makemap
) { /* don't bother if we won't make a map! */
928 if ((bfd_check_format (current
, bfd_object
))
929 #if 0 /* FIXME -- these are not set correctly */
930 && ((bfd_get_file_flags (current
) & HAS_SYMS
))
937 if (!bfd_construct_extended_name_table (arch
, &etable
, &elength
))
940 bfd_seek (arch
, 0, SEEK_SET
);
941 bfd_write (ARMAG
, 1, SARMAG
, arch
);
943 if (makemap
&& hasobjects
) {
945 if (compute_and_write_armap (arch
, elength
) != true) {
946 if (etable
) free (etable
);
954 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
955 sprintf (&(hdr
.ar_name
[0]), "ARFILENAMES/");
956 sprintf (&(hdr
.ar_size
[0]), "%-10d", (int) elength
);
957 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
958 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
959 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
960 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
961 bfd_write (etable
, 1, elength
, arch
);
962 if ((elength
% 2) == 1) bfd_write ("\n", 1, 1, arch
);
963 if (etable
) free (etable
);
966 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
967 char buffer
[DEFAULT_BUFFERSIZE
];
968 unsigned int remaining
= arelt_size (current
);
969 struct ar_hdr
*hdr
= arch_hdr(current
);
970 /* write ar header */
972 if (bfd_write (hdr
, 1, sizeof(*hdr
), arch
) != sizeof(*hdr
)) {
974 bfd_error
= system_call_error
;
977 if (bfd_seek (current
, 0L, SEEK_SET
) != 0L) goto syserr
;
980 unsigned int amt
= DEFAULT_BUFFERSIZE
;
981 if (amt
> remaining
) {
984 if (bfd_read (buffer
, amt
, 1, current
) != amt
) goto syserr
;
985 if (bfd_write (buffer
, amt
, 1, arch
) != amt
) goto syserr
;
988 if ((arelt_size (current
) % 2) == 1) bfd_write ("\n", 1, 1, arch
);
993 /* Note that the namidx for the first symbol is 0 */
998 compute_and_write_armap (arch
, elength
)
1000 unsigned int elength
;
1003 file_ptr elt_no
= 0;
1005 int orl_max
= 15000; /* fine initial default */
1007 int stridx
= 0; /* string index */
1009 /* Dunno if this is the best place for this info... */
1010 if (elength
!= 0) elength
+= sizeof (struct ar_hdr
);
1011 elength
+= elength
%2 ;
1013 map
= (struct orl
*) zalloc (orl_max
* sizeof (struct orl
));
1015 bfd_error
= no_memory
;
1019 /* Map over each element */
1020 for (current
= arch
->archive_head
;
1021 current
!= (bfd
*)NULL
;
1022 current
= current
->next
, elt_no
++)
1024 if ((bfd_check_format (current
, bfd_object
) == true)
1025 && ((bfd_get_file_flags (current
) & HAS_SYMS
))) {
1027 unsigned int storage
;
1028 unsigned int symcount
;
1029 unsigned int src_count
;
1031 storage
= get_symtab_upper_bound (current
);
1034 syms
= (asymbol
**) zalloc (storage
);
1036 bfd_error
= no_memory
; /* FIXME -- memory leak */
1039 symcount
= bfd_canonicalize_symtab (current
, syms
);
1042 /* Now map over all the symbols, picking out the ones we want */
1043 for (src_count
= 0; src_count
<symcount
; src_count
++) {
1044 flagword flags
= (syms
[src_count
])->flags
;
1045 if ((flags
& BSF_GLOBAL
) ||
1046 (flags
& BSF_FORT_COMM
)) {
1048 /* This symbol will go into the archive header */
1049 if (orl_count
== orl_max
)
1052 map
= (struct orl
*) realloc ((char *) map
,
1053 orl_max
* sizeof (struct orl
));
1056 (map
[orl_count
]).name
= &((syms
[src_count
])->name
);
1057 (map
[orl_count
]).pos
= elt_no
;
1058 (map
[orl_count
]).namidx
= stridx
;
1060 stridx
+= strlen ((syms
[src_count
])->name
) + 1;
1067 /* OK, now we have collected all the data, let's write them out */
1068 if (!BFD_SEND (arch
, write_armap
,
1069 (arch
, elength
, map
, orl_count
, stridx
))) {
1079 /* FIXME -- have to byte-swap this */
1082 bsd_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1084 unsigned int elength
;
1089 unsigned int ranlibsize
= (orl_count
* sizeof (struct ranlib
)) + 4;
1090 unsigned int stringsize
= stridx
+ 4;
1091 unsigned int mapsize
= stringsize
+ ranlibsize
;
1093 bfd
*current
= arch
->archive_head
;
1094 int last_eltno
= 0; /* last element arch seen */
1098 struct stat statbuf
;
1100 int padit
= mapsize
& 1;
1102 if (padit
) mapsize
++;
1104 firstreal
= mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1106 fstat (arch
->iostream
, &statbuf
); /* FIXME -- descriptor must be open! */
1107 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1108 sprintf (hdr
.ar_name
, "__.SYMDEF");
1109 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1110 sprintf (hdr
.ar_date
, "%ld", statbuf
.st_mtime
);
1111 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1112 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1113 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1114 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1116 temp
= orl_count
/* + 4 */;
1117 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1119 for (count
= 0; count
< orl_count
; count
++) {
1121 struct symdef
*outp
= &outs
;
1123 if ((map
[count
]).pos
!= last_eltno
) {
1124 firstreal
+= arelt_size (current
) + sizeof (struct ar_hdr
);
1125 firstreal
+= firstreal
% 2;
1126 last_eltno
= (map
[count
]).pos
;
1127 current
= current
->next
;
1130 outs
.s
.string_offset
= ((map
[count
]).namidx
) +4;
1131 outs
.file_offset
= firstreal
;
1132 bfd_write ((char *)outp
, 1, sizeof (outs
), arch
);
1135 /* now write the strings themselves */
1137 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1138 for (count
= 0; count
< orl_count
; count
++)
1139 bfd_write (*((map
[count
]).name
), 1, strlen (*((map
[count
]).name
))+1, arch
);
1141 /* The spec sez this should be a newline. But in order to be
1142 bug-compatible for sun's ar we use a null. */
1144 bfd_write("\0",1,1,arch
);
1150 /* A coff armap looks like :
1152 struct ar_hdr with name = '/'
1154 offset of file for symbol 0
1155 offset of file for symbol 1
1157 offset of file for symbol n-1
1166 coff_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1168 unsigned int elength
;
1173 unsigned int ranlibsize
= (orl_count
* 4) + 4;
1174 unsigned int stringsize
= stridx
;
1175 unsigned int mapsize
= stringsize
+ ranlibsize
;
1176 file_ptr archive_member_file_ptr
;
1177 bfd
*current
= arch
->archive_head
;
1178 int last_eltno
= 0; /* last element arch seen */
1182 int padit
= mapsize
& 1;
1184 if (padit
) mapsize
++;
1186 archive_member_file_ptr
=
1187 mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1189 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1190 hdr
.ar_name
[0] = '/';
1191 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1192 sprintf (hdr
.ar_date
, "%ld", time (NULL
));
1193 /* This, at least, is what Intel coff sets the values to.: */
1194 sprintf ((hdr
.ar_uid
), "%d", 0);
1195 sprintf ((hdr
.ar_gid
), "%d", 0);
1196 sprintf ((hdr
.ar_mode
), "%-7o", 0);
1197 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1199 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1200 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1202 /* Write the ar header for this item and the number of symbols */
1204 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1205 bfd_write (&orl_count
, 1, sizeof (orl_count
), arch
);
1207 /* Two passes, first write the file offsets for each symbol -
1208 remembering that each offset is on a two byte boundary
1211 for (count
= 0; count
< orl_count
; count
++) {
1212 while ((map
[count
]).pos
!= last_eltno
) {
1213 /* If this is the first time we've seen a ref to this archive
1214 then remember it's size */
1215 archive_member_file_ptr
+=
1216 arelt_size (current
) + sizeof (struct ar_hdr
);
1217 archive_member_file_ptr
+= archive_member_file_ptr
% 2;
1218 current
= current
->next
;
1221 bfd_write (&archive_member_file_ptr
,
1223 sizeof (archive_member_file_ptr
),
1227 /* now write the strings themselves */
1228 for (count
= 0; count
< orl_count
; count
++) {
1229 bfd_write (*((map
[count
]).name
),
1231 strlen (*((map
[count
]).name
))+1, arch
);
1234 /* The spec sez this should be a newline. But in order to be
1235 bug-compatible for arc960 we use a null. */
1237 bfd_write("\0",1,1,arch
);