2 /*** archive.c -- an attempt at combining the machine-independent parts of
5 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
7 This file is part of BFD, the Binary File Diddler.
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)
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.
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. */
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).
41 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
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!
54 struct ar_cache
*next
;
57 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
58 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
60 #define arch_hdr(bfd) ((struct ar_hdr *) \
61 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
66 _bfd_generic_mkarchive (abfd
)
69 abfd
->tdata
= bfd_zalloc(abfd
, sizeof (struct artdata
));
71 if (abfd
->tdata
== NULL
) {
72 bfd_error
= no_memory
;
75 bfd_ardata(abfd
)->cache
= 0;
80 bfd_get_next_mapent (abfd
, prev
, entry
)
85 if (!bfd_has_map (abfd
)) {
86 bfd_error
= invalid_operation
;
87 return BFD_NO_MORE_SYMBOLS
;
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
;
94 *entry
= (bfd_ardata (abfd
)->symdefs
+ prev
);
99 /* To be called by backends only */
101 _bfd_create_empty_archive_element_shell (obfd
)
106 nbfd
= new_bfd_contained_in(obfd
);
108 bfd_error
= no_memory
;
115 bfd_set_archive_head (output_archive
, new_head
)
116 bfd
*output_archive
, *new_head
;
119 output_archive
->archive_head
= new_head
;
124 look_for_bfd_in_cache (arch_bfd
, filepos
)
128 struct ar_cache
*current
;
130 for (current
= bfd_ardata (arch_bfd
)->cache
; current
!= NULL
;
131 current
= current
->next
)
132 if (current
->ptr
== filepos
) return current
->arelt
;
137 /* Kind of stupid to call cons for each one, but we don't do too many */
139 add_bfd_to_cache (arch_bfd
, filepos
, new_elt
)
140 bfd
*arch_bfd
, *new_elt
;
143 struct ar_cache
*new_cache
= ((struct ar_cache
*)bfd_zalloc(arch_bfd
,sizeof (struct ar_cache
)));
145 if (new_cache
== NULL
) {
146 bfd_error
= no_memory
;
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
;
156 struct ar_cache
*current
= bfd_ardata (arch_bfd
)->cache
;
158 for (; current
->next
!= NULL
; current
= current
->next
);
159 current
->next
= new_cache
;
167 /* The name begins with space. Hence the rest of the name is an index into
171 get_extended_arelt_filename (arch
, name
)
176 unsigned long index
= 0;
178 /* Should extract string so that I can guarantee not to overflow into
179 the next region, but I"m too lazy. */
181 index
= strtol (name
, NULL
, 10);
183 bfd_error
= malformed_archive
;
187 return bfd_ardata (arch
)->extended_names
+ index
;
190 /* This functions reads an arch header and returns an areltdata pointer, or
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.
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
);
213 if (bfd_read ((PTR
)hdrp
, 1, sizeof (struct ar_hdr
), abfd
)
214 != sizeof (struct ar_hdr
)) {
215 bfd_error
= no_more_archived_files
;
218 if (strncmp ((hdr
.ar_fmag
), ARFMAG
, 2)) {
219 bfd_error
= malformed_archive
;
224 parsed_size
= strtol (hdr
.ar_size
, NULL
, 10);
226 bfd_error
= malformed_archive
;
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
;
240 /* We judge the end of the name by looking for a space or a
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
))) {
252 allocsize
+= namelen
+ 1;
255 allocptr
= bfd_zalloc(abfd
, allocsize
);
256 if (allocptr
== NULL
) {
257 bfd_error
= no_memory
;
261 ared
= (struct areltdata
*) allocptr
;
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
;
267 if (filename
!= NULL
) ared
->filename
= filename
;
269 ared
->filename
= allocptr
+ (sizeof (struct areltdata
) +
270 sizeof (struct ar_hdr
));
272 memcpy (ared
->filename
, hdr
.ar_name
, namelen
);
273 ared
->filename
[namelen
] = '\0';
280 get_elt_at_filepos (archive
, filepos
)
284 struct areltdata
*new_areldata
;
287 n_nfd
= look_for_bfd_in_cache (archive
, filepos
);
288 if (n_nfd
) return n_nfd
;
290 if (0 > bfd_seek (archive
, filepos
, SEEK_SET
)) {
291 bfd_error
= system_call_error
;
295 if ((new_areldata
= snarf_ar_hdr (archive
)) == NULL
) return NULL
;
297 n_nfd
= _bfd_create_empty_archive_element_shell (archive
);
301 n_nfd
->origin
= bfd_tell (archive
);
302 n_nfd
->arelt_data
= (PTR
) new_areldata
;
303 n_nfd
->filename
= new_areldata
->filename
;
305 if (add_bfd_to_cache (archive
, filepos
, n_nfd
))
313 bfd_get_elt_at_index (abfd
, index
)
319 (abfd
, (bfd_ardata (abfd
)->symdefs
+ index
)->file_offset
);
323 /* If you've got an archive, call this to read each subfile. */
325 bfd_openr_next_archived_file (archive
, last_file
)
326 bfd
*archive
, *last_file
;
329 if ((bfd_get_format (archive
) != bfd_archive
) ||
330 (archive
->direction
== write_direction
)) {
331 bfd_error
= invalid_operation
;
336 return BFD_SEND (archive
,
337 openr_next_archived_file
,
343 bfd
*bfd_generic_openr_next_archived_file(archive
, last_file
)
350 filestart
= bfd_ardata (archive
)->first_file_filepos
;
352 unsigned int size
= arelt_size(last_file
);
353 filestart
= last_file
->origin
+size
+ size
%2;
358 return get_elt_at_filepos (archive
, filestart
);
363 bfd_generic_archive_p (abfd
)
366 char armag
[SARMAG
+1];
368 if (bfd_read ((PTR
)armag
, 1, SARMAG
, abfd
) != SARMAG
) {
369 bfd_error
= wrong_format
;
374 if (strncmp (armag
, BFD_GNU960_ARMAG(abfd
), SARMAG
)) return 0;
376 if (strncmp (armag
, ARMAG
, SARMAG
)) return 0;
379 bfd_set_ardata(abfd
, (struct artdata
*) bfd_zalloc(abfd
,sizeof (struct artdata
)));
381 if (bfd_ardata (abfd
) == NULL
) {
382 bfd_error
= no_memory
;
386 bfd_ardata (abfd
)->first_file_filepos
= SARMAG
;
388 if (!BFD_SEND (abfd
, _bfd_slurp_armap
, (abfd
))) {
389 bfd_release(abfd
, bfd_ardata (abfd
));
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
));
404 /* Returns false on error, true otherwise */
406 bfd_slurp_bsd_armap (abfd
)
409 struct areltdata
*mapdata
;
411 unsigned int counter
= 0;
412 int *raw_armap
, *rbase
;
413 struct artdata
*ardata
= bfd_ardata (abfd
);
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
);
420 if (strncmp (nextname
, "__.SYMDEF ", 16)) {
421 bfd_has_map (abfd
) = false;
425 mapdata
= snarf_ar_hdr (abfd
);
426 if (mapdata
== NULL
) return false;
428 raw_armap
= (int *) bfd_zalloc(abfd
,mapdata
->parsed_size
);
429 if (raw_armap
== NULL
) {
430 bfd_error
= no_memory
;
435 if (bfd_read ((PTR
)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
436 mapdata
->parsed_size
) {
437 bfd_error
= malformed_archive
;
441 ardata
->symdef_count
= *(raw_armap
) / sizeof (struct symdef
);
444 ardata
->symdefs
= (carsym
*) rbase
;
445 stringbase
= ((char *) (ardata
->symdefs
+ ardata
->symdef_count
)) + 4;
447 for (;counter
< (unsigned)( ardata
->symdef_count
); counter
++) {
448 struct symdef
*sym
= ((struct symdef
*) rbase
) + counter
;
449 sym
->s
.name
= sym
->s
.string_offset
+ stringbase
;
452 ardata
->first_file_filepos
= bfd_tell (abfd
);
453 /* Pad to an even boundary if you have to */
454 ardata
->first_file_filepos
+= (ardata
-> first_file_filepos
) %2;
455 bfd_has_map (abfd
) = true;
460 /* Returns false on error, true otherwise */
462 bfd_slurp_coff_armap (abfd
)
465 struct areltdata
*mapdata
;
467 int *raw_armap
, *rawptr
;
468 struct artdata
*ardata
= bfd_ardata (abfd
);
470 unsigned int stringsize
;
473 if (bfd_read ((PTR
)&nextname
, 1, 1, abfd
) != 1) {
474 bfd_seek (abfd
, -1L, SEEK_CUR
);
475 bfd_has_map(abfd
) = false;
478 bfd_seek (abfd
, -1L, SEEK_CUR
);
480 if (nextname
!= '/') {
481 /* Actually I think this is an error for a COFF archive */
482 bfd_has_map (abfd
) = false;
486 mapdata
= snarf_ar_hdr (abfd
);
487 if (mapdata
== NULL
) return false;
489 raw_armap
= (int *) bfd_alloc(abfd
,mapdata
->parsed_size
);
490 if (raw_armap
== NULL
) {
491 bfd_error
= no_memory
;
497 if (bfd_read ((PTR
)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
498 mapdata
->parsed_size
) {
499 bfd_error
= malformed_archive
;
505 /* The coff armap must be read sequentially. So we construct a bsd-style
506 one in core all at once, for simplicity. */
508 stringsize
= mapdata
->parsed_size
- (4 * (*raw_armap
)) - 4;
511 unsigned int nsymz
= *raw_armap
;
512 unsigned int carsym_size
= (nsymz
* sizeof (carsym
));
513 unsigned int ptrsize
= (4 * nsymz
);
515 ardata
->symdefs
= (carsym
*) bfd_zalloc(abfd
,carsym_size
+ stringsize
+ 1);
516 if (ardata
->symdefs
== NULL
) {
517 bfd_error
= no_memory
;
520 carsyms
= ardata
->symdefs
;
522 stringbase
= ((char *) ardata
->symdefs
) + carsym_size
;
523 memcpy (stringbase
, (char*)raw_armap
+ ptrsize
+ 4, stringsize
);
526 /* OK, build the carsyms */
527 for (i
= 0; i
< nsymz
; i
++)
529 rawptr
= raw_armap
+ i
+ 1;
530 carsyms
->file_offset
= *rawptr
;
531 carsyms
->name
= stringbase
;
532 for (; *(stringbase
++););
537 ardata
->symdef_count
= *raw_armap
;
538 ardata
->first_file_filepos
= bfd_tell (abfd
);
539 /* Pad to an even boundary if you have to */
540 ardata
->first_file_filepos
+= (ardata
->first_file_filepos
) %2;
542 bfd_has_map (abfd
) = true;
547 /** Extended name table.
549 Normally archives support only 14-character filenames. Intel has extended
550 the format: longer names are stored in a special element (the first in the
551 archive, or second if there is an armap); the name in the ar_hdr is replaced
552 by <space><index into filename element>. Index is the P.R. of an int (radix:
555 /* Returns false on error, true otherwise */
557 _bfd_slurp_extended_name_table (abfd
)
561 struct areltdata
*namedata
;
563 if (bfd_read ((PTR
)nextname
, 1, 16, abfd
) == 16) {
565 bfd_seek (abfd
, -16L, SEEK_CUR
);
567 if (strncmp (nextname
, "ARFILENAMES/ ", 16)) {
568 bfd_ardata (abfd
)->extended_names
= NULL
;
572 namedata
= snarf_ar_hdr (abfd
);
573 if (namedata
== NULL
) return false;
576 bfd_ardata (abfd
)->extended_names
= bfd_zalloc(abfd
,namedata
->parsed_size
);
577 if (bfd_ardata (abfd
)->extended_names
== NULL
) {
578 bfd_error
= no_memory
;
584 if (bfd_read ((PTR
)bfd_ardata (abfd
)->extended_names
, 1,
585 namedata
->parsed_size
, abfd
) != namedata
->parsed_size
) {
586 bfd_error
= malformed_archive
;
588 bfd_ardata (abfd
)->extended_names
= NULL
;
592 /* It appears that the extended names are newline-padded, not null padded.
595 char *temp
= bfd_ardata (abfd
)->extended_names
;
596 for (; *temp
!= '\0'; ++temp
)
597 if (*temp
== '\n') *temp
= '\0';
600 /* Pad to an even boundary if you have to */
601 bfd_ardata (abfd
)->first_file_filepos
= bfd_tell (abfd
);
602 bfd_ardata (abfd
)->first_file_filepos
+=
603 (bfd_ardata (abfd
)->first_file_filepos
) %2;
611 char *normalize(file
)
614 char * filename
= strrchr(file
, '/');
615 if (filename
!= (char *)NULL
) {
624 /* Follows archive_head and produces an extended name table if necessary.
625 Returns (in tabloc) a pointer to an extended name table, and in tablen
626 the length of the table. If it makes an entry it clobbers the filename
627 so that the element may be written without further massage.
628 Returns true if it ran successfully, false if something went wrong.
629 A successful return may still involve a zero-length tablen!
632 bfd_construct_extended_name_table (abfd
, tabloc
, tablen
)
635 unsigned int *tablen
;
637 unsigned int maxname
= abfd
->xvec
->ar_max_namelen
;
638 unsigned int total_namelen
= 0;
644 /* Figure out how long the table should be */
645 for (current
= abfd
->archive_head
; current
!= NULL
; current
= current
->next
){
646 unsigned int thislen
= strlen (normalize(current
->filename
));
647 if (thislen
> maxname
) total_namelen
+= thislen
+ 1; /* leave room for \n */
650 if (total_namelen
== 0) return true;
652 *tabloc
= bfd_zalloc (abfd
,total_namelen
);
653 if (*tabloc
== NULL
) {
654 bfd_error
= no_memory
;
658 *tablen
= total_namelen
;
661 for (current
= abfd
->archive_head
; current
!= NULL
; current
=
663 char *normal
=normalize( current
->filename
);
664 unsigned int thislen
= strlen (normal
);
665 if (thislen
> maxname
) {
666 /* Works for now; may need to be re-engineered if we encounter an oddball
667 archive format and want to generalise this hack. */
668 struct ar_hdr
*hdr
= arch_hdr(current
);
669 strcpy (strptr
, normal
);
670 strptr
[thislen
] = '\n';
671 hdr
->ar_name
[0] = ' ';
672 /* We know there will always be enough room (one of the few cases
673 where you may safely use sprintf). */
674 sprintf ((hdr
->ar_name
) + 1, "%-o", (unsigned) (strptr
- *tabloc
));
675 /* Kinda Kludgy. We should just use the returned value of sprintf
676 but not all implementations get this right */
678 char *temp
= hdr
->ar_name
+2;
679 for (; temp
< hdr
->ar_name
+ maxname
; temp
++)
680 if (*temp
== '\0') *temp
= ' ';
682 strptr
+= thislen
+ 1;
689 /** A couple of functions for creating ar_hdrs */
691 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
692 The filename must refer to a filename in the filesystem.
693 The filename field of the ar_hdr will NOT be initialized
697 DEFUN(bfd_ar_hdr_from_filesystem
, (abfd
,filename
),
699 CONST
char *filename
)
702 struct areltdata
*ared
;
707 if (stat (filename
, &status
) != 0) {
708 bfd_error
= system_call_error
;
712 ared
= (struct areltdata
*) bfd_zalloc(abfd
, sizeof (struct ar_hdr
) +
713 sizeof (struct areltdata
));
715 bfd_error
= no_memory
;
718 hdr
= (struct ar_hdr
*) (((char *) ared
) + sizeof (struct areltdata
));
720 /* ar headers are space padded, not null padded! */
722 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
723 for (; temp
< temp1
; *(temp
++) = ' ');
724 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
726 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
727 sprintf ((hdr
->ar_date
), "%-12ld", status
.st_mtime
);
728 sprintf ((hdr
->ar_uid
), "%d", status
.st_uid
);
729 sprintf ((hdr
->ar_gid
), "%d", status
.st_gid
);
730 sprintf ((hdr
->ar_mode
), "%-8o", (unsigned) status
.st_mode
);
731 sprintf ((hdr
->ar_size
), "%-10ld", status
.st_size
);
732 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
733 understand how these C losers could design such a ramshackle bunch of
736 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
737 for (; temp
< temp1
; temp
++) {
738 if (*temp
== '\0') *temp
= ' ';
740 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
741 ared
->parsed_size
= status
.st_size
;
742 ared
->arch_header
= (char *) hdr
;
748 DEFUN(bfd_special_undocumented_glue
, (abfd
, filename
),
753 return (struct ar_hdr
*) bfd_ar_hdr_from_filesystem (abfd
, filename
) -> arch_header
;
757 /* Analogous to stat call */
759 bfd_generic_stat_arch_elt (abfd
, buf
)
766 if (abfd
->arelt_data
== NULL
) {
767 bfd_error
= invalid_operation
;
771 hdr
= arch_hdr (abfd
);
773 #define foo(arelt, stelt, size) \
774 buf->stelt = strtol (hdr->arelt, &aloser, size); \
775 if (aloser == hdr->arelt) return -1;
777 foo (ar_date
, st_mtime
, 10);
778 foo (ar_uid
, st_uid
, 10);
779 foo (ar_gid
, st_gid
, 10);
780 foo (ar_mode
, st_mode
, 8);
781 foo (ar_size
, st_size
, 10);
787 bfd_dont_truncate_arname (abfd
, pathname
, arhdr
)
792 /* This interacts unpleasantly with ar's quick-append option.
793 Fortunately ic960 users will never use that option. Fixing this
794 is very hard; fortunately I know how to do it and will do so once
795 intel's release is out the door. */
797 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
799 char *filename
= strrchr (pathname
, '/');
800 int maxlen
= ar_maxnamelen (abfd
);
802 if (filename
== NULL
)
807 length
= strlen (filename
);
809 if (length
<= maxlen
)
810 memcpy (hdr
->ar_name
, filename
, length
);
812 if (length
< maxlen
) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
818 bfd_bsd_truncate_arname (abfd
, pathname
, arhdr
)
823 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
825 char *filename
= strrchr (pathname
, '/');
826 int maxlen
= ar_maxnamelen (abfd
);
829 if (filename
== NULL
)
834 length
= strlen (filename
);
836 if (length
<= maxlen
)
837 memcpy (hdr
->ar_name
, filename
, length
);
839 /* pathname: meet procrustes */
840 memcpy (hdr
->ar_name
, filename
, maxlen
);
844 if (length
< maxlen
) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
847 /* Store name into ar header. Truncates the name to fit.
848 1> strip pathname to be just the basename.
849 2> if it's short enuf to fit, stuff it in.
850 3> If it doesn't end with .o, truncate it to fit
851 4> truncate it before the .o, append .o, stuff THAT in.
854 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
856 bfd_gnu_truncate_arname (abfd
, pathname
, arhdr
)
861 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
863 char *filename
= strrchr (pathname
, '/');
864 int maxlen
= ar_maxnamelen (abfd
);
866 if (filename
== NULL
)
871 length
= strlen (filename
);
873 if (length
<= maxlen
)
874 memcpy (hdr
->ar_name
, filename
, length
);
875 else { /* pathname: meet procrustes */
876 memcpy (hdr
->ar_name
, filename
, maxlen
);
877 if ((filename
[length
- 2] == '.') && (filename
[length
- 1] == 'o')) {
878 hdr
->ar_name
[maxlen
- 2] = '.';
879 hdr
->ar_name
[maxlen
- 1] = 'o';
884 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
888 PROTO (boolean
, compute_and_write_armap
, (bfd
*arch
, unsigned int elength
));
890 /* The bfd is open for write and has its format set to bfd_archive */
892 _bfd_write_archive_contents (arch
)
897 unsigned int elength
= 0;
898 boolean makemap
= bfd_has_map (arch
);
899 boolean hasobjects
= false; /* if no .o's, don't bother to make a map */
903 /* Verify the viability of all entries; if any of them live in the
904 filesystem (as opposed to living in an archive open for input)
905 then construct a fresh ar_hdr for them.
907 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
908 if (bfd_write_p (current
)) {
909 bfd_error
= invalid_operation
;
912 if (!current
->arelt_data
) {
913 current
->arelt_data
=
914 (PTR
) bfd_ar_hdr_from_filesystem (arch
, current
->filename
);
915 if (!current
->arelt_data
) return false;
917 /* Put in the file name */
919 BFD_SEND (arch
, _bfd_truncate_arname
,(arch
,
921 (char *) arch_hdr(current
)));
926 if (makemap
) { /* don't bother if we won't make a map! */
927 if ((bfd_check_format (current
, bfd_object
))
928 #if 0 /* FIXME -- these are not set correctly */
929 && ((bfd_get_file_flags (current
) & HAS_SYMS
))
936 if (!bfd_construct_extended_name_table (arch
, &etable
, &elength
))
939 bfd_seek (arch
, 0, SEEK_SET
);
941 bfd_write (BFD_GNU960_ARMAG(arch
), 1, SARMAG
, arch
);
943 bfd_write (ARMAG
, 1, SARMAG
, arch
);
946 if (makemap
&& hasobjects
) {
948 if (compute_and_write_armap (arch
, elength
) != true) {
956 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
957 sprintf (&(hdr
.ar_name
[0]), "ARFILENAMES/");
958 sprintf (&(hdr
.ar_size
[0]), "%-10d", (int) elength
);
959 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
960 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
961 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
962 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
963 bfd_write (etable
, 1, elength
, arch
);
964 if ((elength
% 2) == 1) bfd_write ("\n", 1, 1, arch
);
968 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
969 char buffer
[DEFAULT_BUFFERSIZE
];
970 unsigned int remaining
= arelt_size (current
);
971 struct ar_hdr
*hdr
= arch_hdr(current
);
972 /* write ar header */
974 if (bfd_write (hdr
, 1, sizeof(*hdr
), arch
) != sizeof(*hdr
)) {
976 bfd_error
= system_call_error
;
979 if (bfd_seek (current
, 0L, SEEK_SET
) != 0L) goto syserr
;
982 unsigned int amt
= DEFAULT_BUFFERSIZE
;
983 if (amt
> remaining
) {
986 if (bfd_read (buffer
, amt
, 1, current
) != amt
) goto syserr
;
987 if (bfd_write (buffer
, amt
, 1, arch
) != amt
) goto syserr
;
990 if ((arelt_size (current
) % 2) == 1) bfd_write ("\n", 1, 1, arch
);
995 /* Note that the namidx for the first symbol is 0 */
1000 compute_and_write_armap (arch
, elength
)
1002 unsigned int elength
;
1005 file_ptr elt_no
= 0;
1007 int orl_max
= 15000; /* fine initial default */
1009 int stridx
= 0; /* string index */
1011 /* Dunno if this is the best place for this info... */
1012 if (elength
!= 0) elength
+= sizeof (struct ar_hdr
);
1013 elength
+= elength
%2 ;
1015 map
= (struct orl
*) bfd_zalloc (arch
,orl_max
* sizeof (struct orl
));
1017 bfd_error
= no_memory
;
1021 /* Map over each element */
1022 for (current
= arch
->archive_head
;
1023 current
!= (bfd
*)NULL
;
1024 current
= current
->next
, elt_no
++)
1026 if ((bfd_check_format (current
, bfd_object
) == true)
1027 && ((bfd_get_file_flags (current
) & HAS_SYMS
))) {
1029 unsigned int storage
;
1030 unsigned int symcount
;
1031 unsigned int src_count
;
1033 storage
= get_symtab_upper_bound (current
);
1036 syms
= (asymbol
**) bfd_zalloc (arch
,storage
);
1038 bfd_error
= no_memory
; /* FIXME -- memory leak */
1041 symcount
= bfd_canonicalize_symtab (current
, syms
);
1044 /* Now map over all the symbols, picking out the ones we want */
1045 for (src_count
= 0; src_count
<symcount
; src_count
++) {
1046 flagword flags
= (syms
[src_count
])->flags
;
1047 if ((flags
& BSF_GLOBAL
) ||
1048 (flags
& BSF_FORT_COMM
)) {
1050 /* This symbol will go into the archive header */
1051 if (orl_count
== orl_max
)
1054 map
= (struct orl
*) bfd_realloc (arch
, (char *) map
,
1055 orl_max
* sizeof (struct orl
));
1058 (map
[orl_count
]).name
= &((syms
[src_count
])->name
);
1059 (map
[orl_count
]).pos
= elt_no
;
1060 (map
[orl_count
]).namidx
= stridx
;
1062 stridx
+= strlen ((syms
[src_count
])->name
) + 1;
1069 /* OK, now we have collected all the data, let's write them out */
1070 if (!BFD_SEND (arch
, write_armap
,
1071 (arch
, elength
, map
, orl_count
, stridx
))) {
1081 /* FIXME -- have to byte-swap this */
1084 bsd_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1086 unsigned int elength
;
1091 unsigned int ranlibsize
= (orl_count
* sizeof (struct ranlib
)) + 4;
1092 unsigned int stringsize
= stridx
+ 4;
1093 unsigned int mapsize
= stringsize
+ ranlibsize
;
1095 bfd
*current
= arch
->archive_head
;
1096 int last_eltno
= 0; /* last element arch seen */
1100 struct stat statbuf
;
1102 int padit
= mapsize
& 1;
1104 if (padit
) mapsize
++;
1106 firstreal
= mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1108 stat (arch
->filename
, &statbuf
);
1109 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1110 sprintf (hdr
.ar_name
, "__.SYMDEF");
1111 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1112 sprintf (hdr
.ar_date
, "%ld", statbuf
.st_mtime
);
1113 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1114 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1115 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1116 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1118 temp
= orl_count
/* + 4 */;
1119 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1121 for (count
= 0; count
< orl_count
; count
++) {
1123 struct symdef
*outp
= &outs
;
1125 if ((map
[count
]).pos
!= last_eltno
) {
1126 firstreal
+= arelt_size (current
) + sizeof (struct ar_hdr
);
1127 firstreal
+= firstreal
% 2;
1128 last_eltno
= (map
[count
]).pos
;
1129 current
= current
->next
;
1132 outs
.s
.string_offset
= ((map
[count
]).namidx
) +4;
1133 outs
.file_offset
= firstreal
;
1134 bfd_write ((char *)outp
, 1, sizeof (outs
), arch
);
1137 /* now write the strings themselves */
1139 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1140 for (count
= 0; count
< orl_count
; count
++)
1141 bfd_write (*((map
[count
]).name
), 1, strlen (*((map
[count
]).name
))+1, arch
);
1143 /* The spec sez this should be a newline. But in order to be
1144 bug-compatible for sun's ar we use a null. */
1146 bfd_write("\0",1,1,arch
);
1152 /* A coff armap looks like :
1154 struct ar_hdr with name = '/'
1156 offset of file for symbol 0
1157 offset of file for symbol 1
1159 offset of file for symbol n-1
1168 coff_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1170 unsigned int elength
;
1175 unsigned int ranlibsize
= (orl_count
* 4) + 4;
1176 unsigned int stringsize
= stridx
;
1177 unsigned int mapsize
= stringsize
+ ranlibsize
;
1178 file_ptr archive_member_file_ptr
;
1179 bfd
*current
= arch
->archive_head
;
1180 int last_eltno
= 0; /* last element arch seen */
1184 int padit
= mapsize
& 1;
1186 if (padit
) mapsize
++;
1188 archive_member_file_ptr
=
1189 mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1191 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1192 hdr
.ar_name
[0] = '/';
1193 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1194 sprintf (hdr
.ar_date
, "%ld", (long)time (NULL
));
1195 /* This, at least, is what Intel coff sets the values to.: */
1196 sprintf ((hdr
.ar_uid
), "%d", 0);
1197 sprintf ((hdr
.ar_gid
), "%d", 0);
1198 sprintf ((hdr
.ar_mode
), "%-7o",(unsigned ) 0);
1199 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1201 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1202 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1204 /* Write the ar header for this item and the number of symbols */
1206 bfd_write (&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1207 bfd_write (&orl_count
, 1, sizeof (orl_count
), arch
);
1209 /* Two passes, first write the file offsets for each symbol -
1210 remembering that each offset is on a two byte boundary
1213 for (count
= 0; count
< orl_count
; count
++) {
1214 while ((map
[count
]).pos
!= last_eltno
) {
1215 /* If this is the first time we've seen a ref to this archive
1216 then remember it's size */
1217 archive_member_file_ptr
+=
1218 arelt_size (current
) + sizeof (struct ar_hdr
);
1219 archive_member_file_ptr
+= archive_member_file_ptr
% 2;
1220 current
= current
->next
;
1223 bfd_write (&archive_member_file_ptr
,
1225 sizeof (archive_member_file_ptr
),
1229 /* now write the strings themselves */
1230 for (count
= 0; count
< orl_count
; count
++) {
1231 bfd_write (*((map
[count
]).name
),
1233 strlen (*((map
[count
]).name
))+1, arch
);
1236 /* The spec sez this should be a newline. But in order to be
1237 bug-compatible for arc960 we use a null. */
1239 bfd_write("\0",1,1,arch
);