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).
39 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
42 /* We keep a cache of archive filepointers to archive elements to
43 speed up searching the archive by filepos. We only add an entry to
44 the cache when we actually read one. We also don't sort the cache;
45 it's short enough to search linearly.
46 Note that the pointers here point to the front of the ar_hdr, not
47 to the front of the contents!
52 struct ar_cache
*next
;
55 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
56 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
58 #define arch_hdr(bfd) ((struct ar_hdr *) \
59 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
62 _bfd_generic_mkarchive (abfd
)
65 set_tdata (abfd
, bfd_zalloc(abfd
, sizeof (struct artdata
)));
67 if (bfd_ardata (abfd
) == NULL
) {
68 bfd_error
= no_memory
;
71 bfd_ardata(abfd
)->cache
= 0;
76 bfd_get_next_mapent (abfd
, prev
, entry
)
81 if (!bfd_has_map (abfd
)) {
82 bfd_error
= invalid_operation
;
83 return BFD_NO_MORE_SYMBOLS
;
86 if (prev
== BFD_NO_MORE_SYMBOLS
) prev
= 0;
87 else if (++prev
>= bfd_ardata (abfd
)->symdef_count
)
88 return BFD_NO_MORE_SYMBOLS
;
90 *entry
= (bfd_ardata (abfd
)->symdefs
+ prev
);
95 /* To be called by backends only */
97 _bfd_create_empty_archive_element_shell (obfd
)
102 nbfd
= new_bfd_contained_in(obfd
);
104 bfd_error
= no_memory
;
111 bfd_set_archive_head (output_archive
, new_head
)
112 bfd
*output_archive
, *new_head
;
115 output_archive
->archive_head
= new_head
;
120 look_for_bfd_in_cache (arch_bfd
, filepos
)
124 struct ar_cache
*current
;
126 for (current
= bfd_ardata (arch_bfd
)->cache
; current
!= NULL
;
127 current
= current
->next
)
128 if (current
->ptr
== filepos
) return current
->arelt
;
133 /* Kind of stupid to call cons for each one, but we don't do too many */
135 add_bfd_to_cache (arch_bfd
, filepos
, new_elt
)
136 bfd
*arch_bfd
, *new_elt
;
139 struct ar_cache
*new_cache
= (struct ar_cache
*)
140 bfd_zalloc(arch_bfd
, sizeof (struct ar_cache
));
142 if (new_cache
== NULL
) {
143 bfd_error
= no_memory
;
147 new_cache
->ptr
= filepos
;
148 new_cache
->arelt
= new_elt
;
149 new_cache
->next
= (struct ar_cache
*)NULL
;
150 if (bfd_ardata (arch_bfd
)->cache
== NULL
)
151 bfd_ardata (arch_bfd
)->cache
= new_cache
;
153 struct ar_cache
*current
= bfd_ardata (arch_bfd
)->cache
;
155 for (; current
->next
!= NULL
; current
= current
->next
);
156 current
->next
= new_cache
;
164 /* The name begins with space. Hence the rest of the name is an index into
168 get_extended_arelt_filename (arch
, name
)
172 unsigned long index
= 0;
174 /* Should extract string so that I can guarantee not to overflow into
175 the next region, but I"m too lazy. */
177 index
= strtol (name
, NULL
, 10);
179 bfd_error
= malformed_archive
;
183 return bfd_ardata (arch
)->extended_names
+ index
;
186 /* This functions reads an arch header and returns an areltdata pointer, or
189 Presumes the file pointer is already in the right place (ie pointing
190 to the ar_hdr in the file). Moves the file pointer; on success it
191 should be pointing to the front of the file contents; on failure it
192 could have been moved arbitrarily.
201 char *hdrp
= (char *) &hdr
;
202 unsigned int parsed_size
;
203 struct areltdata
*ared
;
204 char *filename
= NULL
;
205 unsigned int namelen
= 0;
206 unsigned int allocsize
= sizeof (struct areltdata
) + sizeof (struct ar_hdr
);
209 if (bfd_read ((PTR
)hdrp
, 1, sizeof (struct ar_hdr
), abfd
)
210 != sizeof (struct ar_hdr
)) {
211 bfd_error
= no_more_archived_files
;
214 if (strncmp ((hdr
.ar_fmag
), ARFMAG
, 2)) {
215 bfd_error
= malformed_archive
;
220 parsed_size
= strtol (hdr
.ar_size
, NULL
, 10);
222 bfd_error
= malformed_archive
;
226 /* extract the filename from the archive */
227 if (hdr
.ar_name
[0] == ' ' && bfd_ardata (abfd
)->extended_names
!= NULL
) {
228 filename
= get_extended_arelt_filename (abfd
, hdr
.ar_name
);
229 if (filename
== NULL
) {
230 bfd_error
= malformed_archive
;
236 /* We judge the end of the name by looking for a space or a
241 while (namelen
< (unsigned)ar_maxnamelen(abfd
) &&
242 ( hdr
.ar_name
[namelen
] != 0 &&
243 hdr
.ar_name
[namelen
] != ' ' &&
244 hdr
.ar_name
[namelen
] != ar_padchar(abfd
))) {
248 allocsize
+= namelen
+ 1;
251 allocptr
= bfd_zalloc(abfd
, allocsize
);
252 if (allocptr
== NULL
) {
253 bfd_error
= no_memory
;
257 ared
= (struct areltdata
*) allocptr
;
259 ared
->arch_header
= allocptr
+ sizeof (struct areltdata
);
260 memcpy ((char *) ared
->arch_header
, &hdr
, sizeof (struct ar_hdr
));
261 ared
->parsed_size
= parsed_size
;
263 if (filename
!= NULL
) ared
->filename
= filename
;
265 ared
->filename
= allocptr
+ (sizeof (struct areltdata
) +
266 sizeof (struct ar_hdr
));
268 memcpy (ared
->filename
, hdr
.ar_name
, namelen
);
269 ared
->filename
[namelen
] = '\0';
276 get_elt_at_filepos (archive
, filepos
)
280 struct areltdata
*new_areldata
;
283 n_nfd
= look_for_bfd_in_cache (archive
, filepos
);
284 if (n_nfd
) return n_nfd
;
286 if (0 > bfd_seek (archive
, filepos
, SEEK_SET
)) {
287 bfd_error
= system_call_error
;
291 if ((new_areldata
= snarf_ar_hdr (archive
)) == NULL
) return NULL
;
293 n_nfd
= _bfd_create_empty_archive_element_shell (archive
);
295 bfd_release (archive
, (PTR
)new_areldata
);
298 n_nfd
->origin
= bfd_tell (archive
);
299 n_nfd
->arelt_data
= (PTR
) new_areldata
;
300 n_nfd
->filename
= new_areldata
->filename
;
302 if (add_bfd_to_cache (archive
, filepos
, n_nfd
))
306 bfd_release (archive
, (PTR
)n_nfd
);
307 bfd_release (archive
, (PTR
)new_areldata
);
312 bfd_get_elt_at_index (abfd
, index
)
318 (abfd
, (bfd_ardata (abfd
)->symdefs
+ index
)->file_offset
);
322 /* If you've got an archive, call this to read each subfile. */
324 bfd_openr_next_archived_file (archive
, last_file
)
325 bfd
*archive
, *last_file
;
328 if ((bfd_get_format (archive
) != bfd_archive
) ||
329 (archive
->direction
== write_direction
)) {
330 bfd_error
= invalid_operation
;
335 return BFD_SEND (archive
,
336 openr_next_archived_file
,
342 bfd
*bfd_generic_openr_next_archived_file(archive
, last_file
)
349 filestart
= bfd_ardata (archive
)->first_file_filepos
;
351 unsigned int size
= arelt_size(last_file
);
352 /* Pad to an even boundary... */
353 filestart
= last_file
->origin
+ size
+ size
%2;
356 return get_elt_at_filepos (archive
, filestart
);
361 bfd_generic_archive_p (abfd
)
364 char armag
[SARMAG
+1];
366 if (bfd_read ((PTR
)armag
, 1, SARMAG
, abfd
) != SARMAG
) {
367 bfd_error
= wrong_format
;
372 if (strncmp (armag
, BFD_GNU960_ARMAG(abfd
), SARMAG
)) return 0;
374 if (strncmp (armag
, ARMAG
, SARMAG
)) return 0;
377 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
378 involves a cast, we can't do it as the left operand of assignment. */
379 set_tdata (abfd
, 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 if (!BFD_SEND (abfd
, _bfd_slurp_extended_name_table
, (abfd
))) {
395 bfd_release(abfd
, bfd_ardata (abfd
));
403 /* Returns false on error, true otherwise */
405 bfd_slurp_bsd_armap (abfd
)
408 struct areltdata
*mapdata
;
410 unsigned int counter
= 0;
411 int *raw_armap
, *rbase
;
412 struct artdata
*ardata
= bfd_ardata (abfd
);
415 /* FIXME, if the read fails, this routine quietly returns "true"!!
416 It should probably do that if the read gives 0 bytes (empty archive),
417 but fail for any other size... */
418 if (bfd_read ((PTR
)nextname
, 1, 16, abfd
) == 16) {
419 /* The archive has at least 16 bytes in it */
420 bfd_seek (abfd
, -16L, SEEK_CUR
);
422 /* This should be using RANLIBMAG, but at least it can be grepped for
424 if (strncmp (nextname
, "__.SYMDEF ", 16)) {
425 bfd_has_map (abfd
) = false;
429 mapdata
= snarf_ar_hdr (abfd
);
430 if (mapdata
== NULL
) return false;
432 raw_armap
= (int *) bfd_zalloc(abfd
,mapdata
->parsed_size
);
433 if (raw_armap
== NULL
) {
434 bfd_error
= no_memory
;
436 bfd_release (abfd
, (PTR
)mapdata
);
440 if (bfd_read ((PTR
)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
441 mapdata
->parsed_size
) {
442 bfd_error
= malformed_archive
;
443 bfd_release (abfd
, (PTR
)raw_armap
);
447 ardata
->symdef_count
= *raw_armap
/ sizeof (struct symdef
);
450 ardata
->symdefs
= (carsym
*) rbase
;
451 stringbase
= ((char *) (ardata
->symdefs
+ ardata
->symdef_count
)) + 4;
453 for (;counter
< ardata
->symdef_count
; counter
++) {
454 struct symdef
*sym
= ((struct symdef
*) rbase
) + counter
;
455 sym
->s
.name
= sym
->s
.string_offset
+ stringbase
;
458 ardata
->first_file_filepos
= bfd_tell (abfd
);
459 /* Pad to an even boundary if you have to */
460 ardata
->first_file_filepos
+= (ardata
-> first_file_filepos
) %2;
461 /* FIXME, we should provide some way to free raw_ardata when
462 we are done using the strings from it. For now, it seems
463 to be allocated on an obstack anyway... */
464 bfd_has_map (abfd
) = true;
469 /* Returns false on error, true otherwise */
471 bfd_slurp_coff_armap (abfd
)
474 struct areltdata
*mapdata
;
476 int *raw_armap
, *rawptr
;
477 struct artdata
*ardata
= bfd_ardata (abfd
);
479 unsigned int stringsize
;
483 result
= bfd_read ((PTR
)&nextname
, 1, 1, abfd
);
484 bfd_seek (abfd
, -1L, SEEK_CUR
);
486 if (result
!= 1 || nextname
!= '/') {
487 /* Actually I think this is an error for a COFF archive */
488 bfd_has_map (abfd
) = false;
492 mapdata
= snarf_ar_hdr (abfd
);
493 if (mapdata
== NULL
) return false;
495 raw_armap
= (int *) bfd_alloc(abfd
,mapdata
->parsed_size
);
496 if (raw_armap
== NULL
) {
497 bfd_error
= no_memory
;
499 bfd_release (abfd
, (PTR
)mapdata
);
503 if (bfd_read ((PTR
)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
504 mapdata
->parsed_size
) {
505 bfd_error
= malformed_archive
;
507 bfd_release (abfd
, (PTR
)raw_armap
);
511 /* The coff armap must be read sequentially. So we construct a bsd-style
512 one in core all at once, for simplicity. */
514 stringsize
= mapdata
->parsed_size
- (4 * (*raw_armap
)) - 4;
517 unsigned int nsymz
= *raw_armap
;
518 unsigned int carsym_size
= (nsymz
* sizeof (carsym
));
519 unsigned int ptrsize
= (4 * nsymz
);
521 ardata
->symdefs
= (carsym
*) bfd_zalloc(abfd
,carsym_size
+ stringsize
+ 1);
522 if (ardata
->symdefs
== NULL
) {
523 bfd_error
= no_memory
;
526 carsyms
= ardata
->symdefs
;
528 stringbase
= ((char *) ardata
->symdefs
) + carsym_size
;
529 memcpy (stringbase
, (char*)raw_armap
+ ptrsize
+ 4, stringsize
);
532 /* OK, build the carsyms */
533 for (i
= 0; i
< nsymz
; i
++)
535 rawptr
= raw_armap
+ i
+ 1;
536 carsyms
->file_offset
= *rawptr
;
537 carsyms
->name
= stringbase
;
538 for (; *(stringbase
++););
543 ardata
->symdef_count
= *raw_armap
;
544 ardata
->first_file_filepos
= bfd_tell (abfd
);
545 /* Pad to an even boundary if you have to */
546 ardata
->first_file_filepos
+= (ardata
->first_file_filepos
) %2;
547 bfd_release (abfd
, (PTR
)raw_armap
);
548 bfd_release (abfd
, (PTR
)mapdata
);
549 bfd_has_map (abfd
) = true;
553 /** Extended name table.
555 Normally archives support only 14-character filenames. Intel has extended
556 the format: longer names are stored in a special element (the first in the
557 archive, or second if there is an armap); the name in the ar_hdr is replaced
558 by <space><index into filename element>. Index is the P.R. of an int (radix:
561 /* Returns false on error, true otherwise */
563 _bfd_slurp_extended_name_table (abfd
)
567 struct areltdata
*namedata
;
569 /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
570 we probably don't want to return true. */
571 if (bfd_read ((PTR
)nextname
, 1, 16, abfd
) == 16) {
573 bfd_seek (abfd
, -16L, SEEK_CUR
);
575 if (strncmp (nextname
, "ARFILENAMES/ ", 16)) {
576 bfd_ardata (abfd
)->extended_names
= NULL
;
580 namedata
= snarf_ar_hdr (abfd
);
581 if (namedata
== NULL
) return false;
583 bfd_ardata (abfd
)->extended_names
= bfd_zalloc(abfd
,namedata
->parsed_size
);
584 if (bfd_ardata (abfd
)->extended_names
== NULL
) {
585 bfd_error
= no_memory
;
587 bfd_release (abfd
, (PTR
)namedata
);
591 if (bfd_read ((PTR
)bfd_ardata (abfd
)->extended_names
, 1,
592 namedata
->parsed_size
, abfd
) != namedata
->parsed_size
) {
593 bfd_error
= malformed_archive
;
594 bfd_release (abfd
, (PTR
)(bfd_ardata (abfd
)->extended_names
));
595 bfd_ardata (abfd
)->extended_names
= NULL
;
599 /* It appears that the extended names are newline-padded, not null padded.
602 char *temp
= bfd_ardata (abfd
)->extended_names
;
603 for (; *temp
!= '\0'; ++temp
)
604 if (*temp
== '\n') *temp
= '\0';
607 /* Pad to an even boundary if you have to */
608 bfd_ardata (abfd
)->first_file_filepos
= bfd_tell (abfd
);
609 bfd_ardata (abfd
)->first_file_filepos
+=
610 (bfd_ardata (abfd
)->first_file_filepos
) %2;
612 /* FIXME, we can't release namedata here because it was allocated
613 below extended_names on the obstack... */
614 /* bfd_release (abfd, namedata); */
620 char *normalize(file
)
623 char * filename
= strrchr(file
, '/');
624 if (filename
!= (char *)NULL
) {
633 /* Follows archive_head and produces an extended name table if necessary.
634 Returns (in tabloc) a pointer to an extended name table, and in tablen
635 the length of the table. If it makes an entry it clobbers the filename
636 so that the element may be written without further massage.
637 Returns true if it ran successfully, false if something went wrong.
638 A successful return may still involve a zero-length tablen!
641 bfd_construct_extended_name_table (abfd
, tabloc
, tablen
)
644 unsigned int *tablen
;
646 unsigned int maxname
= abfd
->xvec
->ar_max_namelen
;
647 unsigned int total_namelen
= 0;
653 /* Figure out how long the table should be */
654 for (current
= abfd
->archive_head
; current
!= NULL
; current
= current
->next
){
655 unsigned int thislen
= strlen (normalize(current
->filename
));
656 if (thislen
> maxname
) total_namelen
+= thislen
+ 1; /* leave room for \n */
659 if (total_namelen
== 0) return true;
661 *tabloc
= bfd_zalloc (abfd
,total_namelen
);
662 if (*tabloc
== NULL
) {
663 bfd_error
= no_memory
;
667 *tablen
= total_namelen
;
670 for (current
= abfd
->archive_head
; current
!= NULL
; current
=
672 char *normal
=normalize( current
->filename
);
673 unsigned int thislen
= strlen (normal
);
674 if (thislen
> maxname
) {
675 /* Works for now; may need to be re-engineered if we encounter an oddball
676 archive format and want to generalise this hack. */
677 struct ar_hdr
*hdr
= arch_hdr(current
);
678 strcpy (strptr
, normal
);
679 strptr
[thislen
] = '\n';
680 hdr
->ar_name
[0] = ' ';
681 /* We know there will always be enough room (one of the few cases
682 where you may safely use sprintf). */
683 sprintf ((hdr
->ar_name
) + 1, "%-o", (unsigned) (strptr
- *tabloc
));
684 /* Kinda Kludgy. We should just use the returned value of sprintf
685 but not all implementations get this right */
687 char *temp
= hdr
->ar_name
+2;
688 for (; temp
< hdr
->ar_name
+ maxname
; temp
++)
689 if (*temp
== '\0') *temp
= ' ';
691 strptr
+= thislen
+ 1;
698 /** A couple of functions for creating ar_hdrs */
700 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
701 The filename must refer to a filename in the filesystem.
702 The filename field of the ar_hdr will NOT be initialized
706 DEFUN(bfd_ar_hdr_from_filesystem
, (abfd
,filename
),
708 CONST
char *filename
)
711 struct areltdata
*ared
;
716 if (stat (filename
, &status
) != 0) {
717 bfd_error
= system_call_error
;
721 ared
= (struct areltdata
*) bfd_zalloc(abfd
, sizeof (struct ar_hdr
) +
722 sizeof (struct areltdata
));
724 bfd_error
= no_memory
;
727 hdr
= (struct ar_hdr
*) (((char *) ared
) + sizeof (struct areltdata
));
729 /* ar headers are space padded, not null padded! */
731 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
732 for (; temp
< temp1
; *(temp
++) = ' ');
733 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
735 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
736 sprintf ((hdr
->ar_date
), "%-12ld", status
.st_mtime
);
737 sprintf ((hdr
->ar_uid
), "%d", status
.st_uid
);
738 sprintf ((hdr
->ar_gid
), "%d", status
.st_gid
);
739 sprintf ((hdr
->ar_mode
), "%-8o", (unsigned) status
.st_mode
);
740 sprintf ((hdr
->ar_size
), "%-10ld", status
.st_size
);
741 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
742 understand how these C losers could design such a ramshackle bunch of
745 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
746 for (; temp
< temp1
; temp
++) {
747 if (*temp
== '\0') *temp
= ' ';
749 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
750 ared
->parsed_size
= status
.st_size
;
751 ared
->arch_header
= (char *) hdr
;
757 DEFUN(bfd_special_undocumented_glue
, (abfd
, filename
),
762 return (struct ar_hdr
*) bfd_ar_hdr_from_filesystem (abfd
, filename
) -> arch_header
;
766 /* Analogous to stat call */
768 bfd_generic_stat_arch_elt (abfd
, buf
)
775 if (abfd
->arelt_data
== NULL
) {
776 bfd_error
= invalid_operation
;
780 hdr
= arch_hdr (abfd
);
782 #define foo(arelt, stelt, size) \
783 buf->stelt = strtol (hdr->arelt, &aloser, size); \
784 if (aloser == hdr->arelt) return -1;
786 foo (ar_date
, st_mtime
, 10);
787 foo (ar_uid
, st_uid
, 10);
788 foo (ar_gid
, st_gid
, 10);
789 foo (ar_mode
, st_mode
, 8);
790 foo (ar_size
, st_size
, 10);
796 bfd_dont_truncate_arname (abfd
, pathname
, arhdr
)
798 CONST
char *pathname
;
801 /* FIXME: This interacts unpleasantly with ar's quick-append option.
802 Fortunately ic960 users will never use that option. Fixing this
803 is very hard; fortunately I know how to do it and will do so once
804 intel's release is out the door. */
806 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
808 CONST
char *filename
= strrchr (pathname
, '/');
809 int maxlen
= ar_maxnamelen (abfd
);
811 if (filename
== NULL
)
816 length
= strlen (filename
);
818 if (length
<= maxlen
)
819 memcpy (hdr
->ar_name
, filename
, length
);
821 if (length
< maxlen
) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
827 bfd_bsd_truncate_arname (abfd
, pathname
, arhdr
)
829 CONST
char *pathname
;
832 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
834 CONST
char *filename
= strrchr (pathname
, '/');
835 int maxlen
= ar_maxnamelen (abfd
);
838 if (filename
== NULL
)
843 length
= strlen (filename
);
845 if (length
<= maxlen
)
846 memcpy (hdr
->ar_name
, filename
, length
);
848 /* pathname: meet procrustes */
849 memcpy (hdr
->ar_name
, filename
, maxlen
);
853 if (length
< maxlen
) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
856 /* Store name into ar header. Truncates the name to fit.
857 1> strip pathname to be just the basename.
858 2> if it's short enuf to fit, stuff it in.
859 3> If it doesn't end with .o, truncate it to fit
860 4> truncate it before the .o, append .o, stuff THAT in.
863 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
865 bfd_gnu_truncate_arname (abfd
, pathname
, arhdr
)
867 CONST
char *pathname
;
870 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
872 CONST
char *filename
= strrchr (pathname
, '/');
873 int maxlen
= ar_maxnamelen (abfd
);
875 if (filename
== NULL
)
880 length
= strlen (filename
);
882 if (length
<= maxlen
)
883 memcpy (hdr
->ar_name
, filename
, length
);
884 else { /* pathname: meet procrustes */
885 memcpy (hdr
->ar_name
, filename
, maxlen
);
886 if ((filename
[length
- 2] == '.') && (filename
[length
- 1] == 'o')) {
887 hdr
->ar_name
[maxlen
- 2] = '.';
888 hdr
->ar_name
[maxlen
- 1] = 'o';
893 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
897 PROTO (boolean
, compute_and_write_armap
, (bfd
*arch
, unsigned int elength
));
899 /* The bfd is open for write and has its format set to bfd_archive */
901 _bfd_write_archive_contents (arch
)
906 unsigned int elength
= 0;
907 boolean makemap
= bfd_has_map (arch
);
908 boolean hasobjects
= false; /* if no .o's, don't bother to make a map */
911 /* Verify the viability of all entries; if any of them live in the
912 filesystem (as opposed to living in an archive open for input)
913 then construct a fresh ar_hdr for them.
915 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
916 if (bfd_write_p (current
)) {
917 bfd_error
= invalid_operation
;
920 if (!current
->arelt_data
) {
921 current
->arelt_data
=
922 (PTR
) bfd_ar_hdr_from_filesystem (arch
, current
->filename
);
923 if (!current
->arelt_data
) return false;
925 /* Put in the file name */
927 BFD_SEND (arch
, _bfd_truncate_arname
,(arch
,
929 (char *) arch_hdr(current
)));
934 if (makemap
) { /* don't bother if we won't make a map! */
935 if ((bfd_check_format (current
, bfd_object
))
936 #if 0 /* FIXME -- these are not set correctly */
937 && ((bfd_get_file_flags (current
) & HAS_SYMS
))
944 if (!bfd_construct_extended_name_table (arch
, &etable
, &elength
))
947 bfd_seek (arch
, 0, SEEK_SET
);
949 bfd_write (BFD_GNU960_ARMAG(arch
), 1, SARMAG
, arch
);
951 bfd_write (ARMAG
, 1, SARMAG
, arch
);
954 if (makemap
&& hasobjects
) {
956 if (compute_and_write_armap (arch
, elength
) != true) {
964 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
965 sprintf (&(hdr
.ar_name
[0]), "ARFILENAMES/");
966 sprintf (&(hdr
.ar_size
[0]), "%-10d", (int) elength
);
967 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
968 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
969 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
970 bfd_write ((char *)&hdr
, 1, sizeof (struct ar_hdr
), arch
);
971 bfd_write (etable
, 1, elength
, arch
);
972 if ((elength
% 2) == 1) bfd_write ("\n", 1, 1, arch
);
976 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
977 char buffer
[DEFAULT_BUFFERSIZE
];
978 unsigned int remaining
= arelt_size (current
);
979 struct ar_hdr
*hdr
= arch_hdr(current
);
980 /* write ar header */
982 if (bfd_write ((char *)hdr
, 1, sizeof(*hdr
), arch
) != sizeof(*hdr
)) {
984 bfd_error
= system_call_error
;
987 if (bfd_seek (current
, 0L, SEEK_SET
) != 0L) goto syserr
;
990 unsigned int amt
= DEFAULT_BUFFERSIZE
;
991 if (amt
> remaining
) {
994 if (bfd_read (buffer
, amt
, 1, current
) != amt
) goto syserr
;
995 if (bfd_write (buffer
, amt
, 1, arch
) != amt
) goto syserr
;
998 if ((arelt_size (current
) % 2) == 1) bfd_write ("\n", 1, 1, arch
);
1003 /* Note that the namidx for the first symbol is 0 */
1006 compute_and_write_armap (arch
, elength
)
1008 unsigned int elength
;
1011 file_ptr elt_no
= 0;
1013 int orl_max
= 15000; /* fine initial default */
1015 int stridx
= 0; /* string index */
1017 /* Dunno if this is the best place for this info... */
1018 if (elength
!= 0) elength
+= sizeof (struct ar_hdr
);
1019 elength
+= elength
%2 ;
1021 map
= (struct orl
*) bfd_zalloc (arch
,orl_max
* sizeof (struct orl
));
1023 bfd_error
= no_memory
;
1027 /* Map over each element */
1028 for (current
= arch
->archive_head
;
1029 current
!= (bfd
*)NULL
;
1030 current
= current
->next
, elt_no
++)
1032 if ((bfd_check_format (current
, bfd_object
) == true)
1033 && ((bfd_get_file_flags (current
) & HAS_SYMS
))) {
1035 unsigned int storage
;
1036 unsigned int symcount
;
1037 unsigned int src_count
;
1039 storage
= get_symtab_upper_bound (current
);
1042 syms
= (asymbol
**) bfd_zalloc (arch
,storage
);
1044 bfd_error
= no_memory
; /* FIXME -- memory leak */
1047 symcount
= bfd_canonicalize_symtab (current
, syms
);
1050 /* Now map over all the symbols, picking out the ones we want */
1051 for (src_count
= 0; src_count
<symcount
; src_count
++) {
1052 flagword flags
= (syms
[src_count
])->flags
;
1053 if ((flags
& BSF_GLOBAL
) ||
1054 (flags
& BSF_FORT_COMM
)) {
1056 /* This symbol will go into the archive header */
1057 if (orl_count
== orl_max
)
1060 map
= (struct orl
*) bfd_realloc (arch
, (char *) map
,
1061 orl_max
* sizeof (struct orl
));
1064 (map
[orl_count
]).name
= &((syms
[src_count
])->name
);
1065 (map
[orl_count
]).pos
= elt_no
;
1066 (map
[orl_count
]).namidx
= stridx
;
1068 stridx
+= strlen ((syms
[src_count
])->name
) + 1;
1075 /* OK, now we have collected all the data, let's write them out */
1076 if (!BFD_SEND (arch
, write_armap
,
1077 (arch
, elength
, map
, orl_count
, stridx
))) {
1087 /* FIXME -- have to byte-swap this */
1090 bsd_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1092 unsigned int elength
;
1097 unsigned int ranlibsize
= (orl_count
* sizeof (struct ranlib
)) + 4;
1098 unsigned int stringsize
= stridx
+ 4;
1099 unsigned int mapsize
= stringsize
+ ranlibsize
;
1101 bfd
*current
= arch
->archive_head
;
1102 int last_eltno
= 0; /* last element arch seen */
1106 struct stat statbuf
;
1108 int padit
= mapsize
& 1;
1110 if (padit
) mapsize
++;
1112 firstreal
= mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1114 stat (arch
->filename
, &statbuf
);
1115 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1116 sprintf (hdr
.ar_name
, RANLIBMAG
);
1117 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1118 sprintf (hdr
.ar_date
, "%ld", statbuf
.st_mtime
);
1119 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1120 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1121 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1122 bfd_write ((char *)&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1124 /* FIXME, this needs to be byte-swapped! */
1125 temp
= orl_count
/* + 4 */;
1126 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1128 for (count
= 0; count
< orl_count
; count
++) {
1130 struct symdef
*outp
= &outs
;
1132 if ((map
[count
]).pos
!= last_eltno
) {
1133 firstreal
+= arelt_size (current
) + sizeof (struct ar_hdr
);
1134 firstreal
+= firstreal
% 2;
1135 last_eltno
= (map
[count
]).pos
;
1136 current
= current
->next
;
1139 outs
.s
.string_offset
= ((map
[count
]).namidx
) +4;
1140 outs
.file_offset
= firstreal
;
1141 bfd_write ((char *)outp
, 1, sizeof (outs
), arch
);
1144 /* now write the strings themselves */
1145 /* FIXME, this needs to be byte-swapped! */
1147 bfd_write ((PTR
)&temp
, 1, sizeof (temp
), arch
);
1148 for (count
= 0; count
< orl_count
; count
++)
1149 bfd_write (*((map
[count
]).name
), 1, strlen (*((map
[count
]).name
))+1, arch
);
1151 /* The spec sez this should be a newline. But in order to be
1152 bug-compatible for sun's ar we use a null. */
1154 bfd_write("\0",1,1,arch
);
1160 /* A coff armap looks like :
1162 struct ar_hdr with name = '/'
1164 offset of file for symbol 0
1165 offset of file for symbol 1
1167 offset of file for symbol n-1
1176 coff_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1178 unsigned int elength
;
1183 unsigned int ranlibsize
= (orl_count
* 4) + 4;
1184 unsigned int stringsize
= stridx
;
1185 unsigned int mapsize
= stringsize
+ ranlibsize
;
1186 file_ptr archive_member_file_ptr
;
1187 bfd
*current
= arch
->archive_head
;
1188 int last_eltno
= 0; /* last element arch seen */
1192 int padit
= mapsize
& 1;
1194 if (padit
) mapsize
++;
1196 archive_member_file_ptr
=
1197 mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1199 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1200 hdr
.ar_name
[0] = '/';
1201 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1202 sprintf (hdr
.ar_date
, "%ld", (long)time (NULL
));
1203 /* This, at least, is what Intel coff sets the values to.: */
1204 sprintf ((hdr
.ar_uid
), "%d", 0);
1205 sprintf ((hdr
.ar_gid
), "%d", 0);
1206 sprintf ((hdr
.ar_mode
), "%-7o",(unsigned ) 0);
1207 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1209 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1210 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1212 /* Write the ar header for this item and the number of symbols */
1214 bfd_write ((PTR
)&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1215 /* FIXME, this needs to be byte-swapped */
1216 bfd_write ((PTR
)&orl_count
, 1, sizeof (orl_count
), arch
);
1218 /* Two passes, first write the file offsets for each symbol -
1219 remembering that each offset is on a two byte boundary
1222 for (count
= 0; count
< orl_count
; count
++) {
1223 while ((map
[count
]).pos
!= last_eltno
) {
1224 /* If this is the first time we've seen a ref to this archive
1225 then remember it's size */
1226 archive_member_file_ptr
+=
1227 arelt_size (current
) + sizeof (struct ar_hdr
);
1228 archive_member_file_ptr
+= archive_member_file_ptr
% 2;
1229 current
= current
->next
;
1232 /* FIXME, this needs to be byte-swapped */
1233 bfd_write ((PTR
)&archive_member_file_ptr
,
1235 sizeof (archive_member_file_ptr
),
1239 /* now write the strings themselves */
1240 for (count
= 0; count
< orl_count
; count
++) {
1241 bfd_write ((PTR
)*((map
[count
]).name
),
1243 strlen (*((map
[count
]).name
))+1, arch
);
1246 /* The spec sez this should be a newline. But in order to be
1247 bug-compatible for arc960 we use a null. */
1249 bfd_write("\0",1,1,arch
);