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
)
175 unsigned long index
= 0;
177 /* Should extract string so that I can guarantee not to overflow into
178 the next region, but I"m too lazy. */
180 index
= strtol (name
, NULL
, 10);
182 bfd_error
= malformed_archive
;
186 return bfd_ardata (arch
)->extended_names
+ index
;
189 /* This functions reads an arch header and returns an areltdata pointer, or
192 Presumes the file pointer is already in the right place (ie pointing
193 to the ar_hdr in the file). Moves the file pointer; on success it
194 should be pointing to the front of the file contents; on failure it
195 could have been moved arbitrarily.
207 char *hdrp
= (char *) &hdr
;
208 unsigned int parsed_size
;
209 struct areltdata
*ared
;
210 char *filename
= NULL
;
211 unsigned int namelen
= 0;
212 unsigned int allocsize
= sizeof (struct areltdata
) + sizeof (struct ar_hdr
);
215 if (bfd_read ((PTR
)hdrp
, 1, sizeof (struct ar_hdr
), abfd
)
216 != sizeof (struct ar_hdr
)) {
217 bfd_error
= no_more_archived_files
;
220 if (strncmp ((hdr
.ar_fmag
), ARFMAG
, 2)) {
221 bfd_error
= malformed_archive
;
226 parsed_size
= strtol (hdr
.ar_size
, NULL
, 10);
228 bfd_error
= malformed_archive
;
232 /* extract the filename from the archive */
233 if (hdr
.ar_name
[0] == ' ' && bfd_ardata (abfd
)->extended_names
!= NULL
) {
234 filename
= get_extended_arelt_filename (abfd
, hdr
.ar_name
);
235 if (filename
== NULL
) {
236 bfd_error
= malformed_archive
;
242 /* We judge the end of the name by looking for a space or a
247 while (namelen
< (unsigned)ar_maxnamelen(abfd
) &&
248 ( hdr
.ar_name
[namelen
] != 0 &&
249 hdr
.ar_name
[namelen
] != ' ' &&
250 hdr
.ar_name
[namelen
] != ar_padchar(abfd
))) {
254 allocsize
+= namelen
+ 1;
257 allocptr
= bfd_zalloc(abfd
, allocsize
);
258 if (allocptr
== NULL
) {
259 bfd_error
= no_memory
;
263 ared
= (struct areltdata
*) allocptr
;
265 ared
->arch_header
= allocptr
+ sizeof (struct areltdata
);
266 memcpy ((char *) ared
->arch_header
, &hdr
, sizeof (struct ar_hdr
));
267 ared
->parsed_size
= parsed_size
;
269 if (filename
!= NULL
) ared
->filename
= filename
;
271 ared
->filename
= allocptr
+ (sizeof (struct areltdata
) +
272 sizeof (struct ar_hdr
));
274 memcpy (ared
->filename
, hdr
.ar_name
, namelen
);
275 ared
->filename
[namelen
] = '\0';
282 get_elt_at_filepos (archive
, filepos
)
286 struct areltdata
*new_areldata
;
289 n_nfd
= look_for_bfd_in_cache (archive
, filepos
);
290 if (n_nfd
) return n_nfd
;
292 if (0 > bfd_seek (archive
, filepos
, SEEK_SET
)) {
293 bfd_error
= system_call_error
;
297 if ((new_areldata
= snarf_ar_hdr (archive
)) == NULL
) return NULL
;
299 n_nfd
= _bfd_create_empty_archive_element_shell (archive
);
301 bfd_release (archive
, (PTR
)new_areldata
);
304 n_nfd
->origin
= bfd_tell (archive
);
305 n_nfd
->arelt_data
= (PTR
) new_areldata
;
306 n_nfd
->filename
= new_areldata
->filename
;
308 if (add_bfd_to_cache (archive
, filepos
, n_nfd
))
312 bfd_release (archive
, (PTR
)n_nfd
);
313 bfd_release (archive
, (PTR
)new_areldata
);
318 bfd_get_elt_at_index (abfd
, index
)
324 (abfd
, (bfd_ardata (abfd
)->symdefs
+ index
)->file_offset
);
328 /* If you've got an archive, call this to read each subfile. */
330 bfd_openr_next_archived_file (archive
, last_file
)
331 bfd
*archive
, *last_file
;
334 if ((bfd_get_format (archive
) != bfd_archive
) ||
335 (archive
->direction
== write_direction
)) {
336 bfd_error
= invalid_operation
;
341 return BFD_SEND (archive
,
342 openr_next_archived_file
,
348 bfd
*bfd_generic_openr_next_archived_file(archive
, last_file
)
355 filestart
= bfd_ardata (archive
)->first_file_filepos
;
357 unsigned int size
= arelt_size(last_file
);
358 /* Pad to an even boundary... */
359 filestart
= last_file
->origin
+ size
+ size
%2;
362 return get_elt_at_filepos (archive
, filestart
);
367 bfd_generic_archive_p (abfd
)
370 char armag
[SARMAG
+1];
372 if (bfd_read ((PTR
)armag
, 1, SARMAG
, abfd
) != SARMAG
) {
373 bfd_error
= wrong_format
;
378 if (strncmp (armag
, BFD_GNU960_ARMAG(abfd
), SARMAG
)) return 0;
380 if (strncmp (armag
, ARMAG
, SARMAG
)) return 0;
383 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
384 involves a cast, we can't do it as the left operand of assignment. */
385 set_tdata (abfd
, bfd_zalloc(abfd
,sizeof (struct artdata
)));
387 if (bfd_ardata (abfd
) == NULL
) {
388 bfd_error
= no_memory
;
392 bfd_ardata (abfd
)->first_file_filepos
= SARMAG
;
394 if (!BFD_SEND (abfd
, _bfd_slurp_armap
, (abfd
))) {
395 bfd_release(abfd
, bfd_ardata (abfd
));
400 if (!BFD_SEND (abfd
, _bfd_slurp_extended_name_table
, (abfd
))) {
401 bfd_release(abfd
, bfd_ardata (abfd
));
409 /* Returns false on error, true otherwise */
411 bfd_slurp_bsd_armap (abfd
)
415 struct areltdata
*mapdata
;
417 unsigned int counter
= 0;
418 int *raw_armap
, *rbase
;
419 struct artdata
*ardata
= bfd_ardata (abfd
);
422 /* FIXME, if the read fails, this routine quietly returns "true"!!
423 It should probably do that if the read gives 0 bytes (empty archive),
424 but fail for any other size... */
425 if (bfd_read ((PTR
)nextname
, 1, 16, abfd
) == 16) {
426 /* The archive has at least 16 bytes in it */
427 bfd_seek (abfd
, -16L, SEEK_CUR
);
429 /* This should be using RANLIBMAG, but at least it can be grepped for
431 if (strncmp (nextname
, "__.SYMDEF ", 16)) {
432 bfd_has_map (abfd
) = false;
436 mapdata
= snarf_ar_hdr (abfd
);
437 if (mapdata
== NULL
) return false;
439 raw_armap
= (int *) bfd_zalloc(abfd
,mapdata
->parsed_size
);
440 if (raw_armap
== NULL
) {
441 bfd_error
= no_memory
;
443 bfd_release (abfd
, (PTR
)mapdata
);
447 if (bfd_read ((PTR
)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
448 mapdata
->parsed_size
) {
449 bfd_error
= malformed_archive
;
450 bfd_release (abfd
, (PTR
)raw_armap
);
454 ardata
->symdef_count
= bfd_h_get_32(abfd
, raw_armap
) / sizeof (struct symdef
);
457 ardata
->symdefs
= (carsym
*) rbase
;
458 stringbase
= ((char *) (ardata
->symdefs
+ ardata
->symdef_count
)) + 4;
460 for (;counter
< ardata
->symdef_count
; counter
++) {
461 struct symdef
*sym
= ((struct symdef
*) rbase
) + counter
;
462 sym
->s
.name
= bfd_h_get_32(abfd
, &(sym
->s
.string_offset
)) + stringbase
;
463 sym
->file_offset
= bfd_h_get_32(abfd
, &(sym
->file_offset
));
466 ardata
->first_file_filepos
= bfd_tell (abfd
);
467 /* Pad to an even boundary if you have to */
468 ardata
->first_file_filepos
+= (ardata
-> first_file_filepos
) %2;
469 /* FIXME, we should provide some way to free raw_ardata when
470 we are done using the strings from it. For now, it seems
471 to be allocated on an obstack anyway... */
472 bfd_has_map (abfd
) = true;
477 /* Returns false on error, true otherwise */
479 bfd_slurp_coff_armap (abfd
)
482 struct areltdata
*mapdata
;
484 int *raw_armap
, *rawptr
;
485 struct artdata
*ardata
= bfd_ardata (abfd
);
487 unsigned int stringsize
;
491 result
= bfd_read ((PTR
)&nextname
, 1, 1, abfd
);
492 bfd_seek (abfd
, -1L, SEEK_CUR
);
494 if (result
!= 1 || nextname
!= '/') {
495 /* Actually I think this is an error for a COFF archive */
496 bfd_has_map (abfd
) = false;
500 mapdata
= snarf_ar_hdr (abfd
);
501 if (mapdata
== NULL
) return false;
503 raw_armap
= (int *) bfd_alloc(abfd
,mapdata
->parsed_size
);
504 if (raw_armap
== NULL
) {
505 bfd_error
= no_memory
;
507 bfd_release (abfd
, (PTR
)mapdata
);
511 if (bfd_read ((PTR
)raw_armap
, 1, mapdata
->parsed_size
, abfd
) !=
512 mapdata
->parsed_size
) {
513 bfd_error
= malformed_archive
;
515 bfd_release (abfd
, (PTR
)raw_armap
);
519 /* The coff armap must be read sequentially. So we construct a bsd-style
520 one in core all at once, for simplicity. */
522 stringsize
= mapdata
->parsed_size
- (4 * (*raw_armap
)) - 4;
525 unsigned int nsymz
= *raw_armap
;
526 unsigned int carsym_size
= (nsymz
* sizeof (carsym
));
527 unsigned int ptrsize
= (4 * nsymz
);
529 ardata
->symdefs
= (carsym
*) bfd_zalloc(abfd
,carsym_size
+ stringsize
+ 1);
530 if (ardata
->symdefs
== NULL
) {
531 bfd_error
= no_memory
;
534 carsyms
= ardata
->symdefs
;
536 stringbase
= ((char *) ardata
->symdefs
) + carsym_size
;
537 memcpy (stringbase
, (char*)raw_armap
+ ptrsize
+ 4, stringsize
);
540 /* OK, build the carsyms */
541 for (i
= 0; i
< nsymz
; i
++)
543 rawptr
= raw_armap
+ i
+ 1;
544 carsyms
->file_offset
= *rawptr
;
545 carsyms
->name
= stringbase
;
546 for (; *(stringbase
++););
551 ardata
->symdef_count
= *raw_armap
;
552 ardata
->first_file_filepos
= bfd_tell (abfd
);
553 /* Pad to an even boundary if you have to */
554 ardata
->first_file_filepos
+= (ardata
->first_file_filepos
) %2;
555 bfd_release (abfd
, (PTR
)raw_armap
);
556 bfd_release (abfd
, (PTR
)mapdata
);
557 bfd_has_map (abfd
) = true;
561 /** Extended name table.
563 Normally archives support only 14-character filenames. Intel has extended
564 the format: longer names are stored in a special element (the first in the
565 archive, or second if there is an armap); the name in the ar_hdr is replaced
566 by <space><index into filename element>. Index is the P.R. of an int (radix:
569 /* Returns false on error, true otherwise */
571 _bfd_slurp_extended_name_table (abfd
)
575 struct areltdata
*namedata
;
577 /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
578 we probably don't want to return true. */
579 if (bfd_read ((PTR
)nextname
, 1, 16, abfd
) == 16) {
581 bfd_seek (abfd
, -16L, SEEK_CUR
);
583 if (strncmp (nextname
, "ARFILENAMES/ ", 16)) {
584 bfd_ardata (abfd
)->extended_names
= NULL
;
588 namedata
= snarf_ar_hdr (abfd
);
589 if (namedata
== NULL
) return false;
591 bfd_ardata (abfd
)->extended_names
= bfd_zalloc(abfd
,namedata
->parsed_size
);
592 if (bfd_ardata (abfd
)->extended_names
== NULL
) {
593 bfd_error
= no_memory
;
595 bfd_release (abfd
, (PTR
)namedata
);
599 if (bfd_read ((PTR
)bfd_ardata (abfd
)->extended_names
, 1,
600 namedata
->parsed_size
, abfd
) != namedata
->parsed_size
) {
601 bfd_error
= malformed_archive
;
602 bfd_release (abfd
, (PTR
)(bfd_ardata (abfd
)->extended_names
));
603 bfd_ardata (abfd
)->extended_names
= NULL
;
607 /* It appears that the extended names are newline-padded, not null padded.
610 char *temp
= bfd_ardata (abfd
)->extended_names
;
611 for (; *temp
!= '\0'; ++temp
)
612 if (*temp
== '\n') *temp
= '\0';
615 /* Pad to an even boundary if you have to */
616 bfd_ardata (abfd
)->first_file_filepos
= bfd_tell (abfd
);
617 bfd_ardata (abfd
)->first_file_filepos
+=
618 (bfd_ardata (abfd
)->first_file_filepos
) %2;
620 /* FIXME, we can't release namedata here because it was allocated
621 below extended_names on the obstack... */
622 /* bfd_release (abfd, namedata); */
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 \n */
667 if (total_namelen
== 0) return true;
669 *tabloc
= bfd_zalloc (abfd
,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 /* Works for now; may need to be re-engineered if we encounter an oddball
684 archive format and want to generalise this hack. */
685 struct ar_hdr
*hdr
= arch_hdr(current
);
686 strcpy (strptr
, normal
);
687 strptr
[thislen
] = '\n';
688 hdr
->ar_name
[0] = ' ';
689 /* We know there will always be enough room (one of the few cases
690 where you may safely use sprintf). */
691 sprintf ((hdr
->ar_name
) + 1, "%-o", (unsigned) (strptr
- *tabloc
));
692 /* Kinda Kludgy. We should just use the returned value of sprintf
693 but not all implementations get this right */
695 char *temp
= hdr
->ar_name
+2;
696 for (; temp
< hdr
->ar_name
+ maxname
; temp
++)
697 if (*temp
== '\0') *temp
= ' ';
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 DEFUN(bfd_ar_hdr_from_filesystem
, (abfd
,filename
),
716 CONST
char *filename
)
719 struct areltdata
*ared
;
724 if (stat (filename
, &status
) != 0) {
725 bfd_error
= system_call_error
;
729 ared
= (struct areltdata
*) bfd_zalloc(abfd
, sizeof (struct ar_hdr
) +
730 sizeof (struct areltdata
));
732 bfd_error
= no_memory
;
735 hdr
= (struct ar_hdr
*) (((char *) ared
) + sizeof (struct areltdata
));
737 /* ar headers are space padded, not null padded! */
739 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
740 for (; temp
< temp1
; *(temp
++) = ' ');
741 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
743 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
744 sprintf ((hdr
->ar_date
), "%-12ld", status
.st_mtime
);
745 sprintf ((hdr
->ar_uid
), "%d", status
.st_uid
);
746 sprintf ((hdr
->ar_gid
), "%d", status
.st_gid
);
747 sprintf ((hdr
->ar_mode
), "%-8o", (unsigned) status
.st_mode
);
748 sprintf ((hdr
->ar_size
), "%-10ld", status
.st_size
);
749 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
750 understand how these C losers could design such a ramshackle bunch of
753 temp1
= temp
+ sizeof (struct ar_hdr
) - 2;
754 for (; temp
< temp1
; temp
++) {
755 if (*temp
== '\0') *temp
= ' ';
757 strncpy (hdr
->ar_fmag
, ARFMAG
, 2);
758 ared
->parsed_size
= status
.st_size
;
759 ared
->arch_header
= (char *) hdr
;
765 DEFUN(bfd_special_undocumented_glue
, (abfd
, filename
),
770 return (struct ar_hdr
*) bfd_ar_hdr_from_filesystem (abfd
, filename
) -> arch_header
;
774 /* Analogous to stat call */
776 bfd_generic_stat_arch_elt (abfd
, buf
)
783 if (abfd
->arelt_data
== NULL
) {
784 bfd_error
= invalid_operation
;
788 hdr
= arch_hdr (abfd
);
790 #define foo(arelt, stelt, size) \
791 buf->stelt = strtol (hdr->arelt, &aloser, size); \
792 if (aloser == hdr->arelt) return -1;
794 foo (ar_date
, st_mtime
, 10);
795 foo (ar_uid
, st_uid
, 10);
796 foo (ar_gid
, st_gid
, 10);
797 foo (ar_mode
, st_mode
, 8);
798 foo (ar_size
, st_size
, 10);
804 bfd_dont_truncate_arname (abfd
, pathname
, arhdr
)
806 CONST
char *pathname
;
809 /* FIXME: This interacts unpleasantly with ar's quick-append option.
810 Fortunately ic960 users will never use that option. Fixing this
811 is very hard; fortunately I know how to do it and will do so once
812 intel's release is out the door. */
814 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
816 CONST
char *filename
= strrchr (pathname
, '/');
817 int maxlen
= ar_maxnamelen (abfd
);
819 if (filename
== NULL
)
824 length
= strlen (filename
);
826 if (length
<= maxlen
)
827 memcpy (hdr
->ar_name
, filename
, length
);
829 if (length
< maxlen
) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
835 bfd_bsd_truncate_arname (abfd
, pathname
, arhdr
)
837 CONST
char *pathname
;
840 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
842 CONST
char *filename
= strrchr (pathname
, '/');
843 int maxlen
= ar_maxnamelen (abfd
);
846 if (filename
== NULL
)
851 length
= strlen (filename
);
853 if (length
<= maxlen
)
854 memcpy (hdr
->ar_name
, filename
, length
);
856 /* pathname: meet procrustes */
857 memcpy (hdr
->ar_name
, filename
, maxlen
);
861 if (length
< maxlen
) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
864 /* Store name into ar header. Truncates the name to fit.
865 1> strip pathname to be just the basename.
866 2> if it's short enuf to fit, stuff it in.
867 3> If it doesn't end with .o, truncate it to fit
868 4> truncate it before the .o, append .o, stuff THAT in.
871 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
873 bfd_gnu_truncate_arname (abfd
, pathname
, arhdr
)
875 CONST
char *pathname
;
878 struct ar_hdr
*hdr
= (struct ar_hdr
*) arhdr
;
880 CONST
char *filename
= strrchr (pathname
, '/');
881 int maxlen
= ar_maxnamelen (abfd
);
883 if (filename
== NULL
)
888 length
= strlen (filename
);
890 if (length
<= maxlen
)
891 memcpy (hdr
->ar_name
, filename
, length
);
892 else { /* pathname: meet procrustes */
893 memcpy (hdr
->ar_name
, filename
, maxlen
);
894 if ((filename
[length
- 2] == '.') && (filename
[length
- 1] == 'o')) {
895 hdr
->ar_name
[maxlen
- 2] = '.';
896 hdr
->ar_name
[maxlen
- 1] = 'o';
901 if (length
< 16) (hdr
->ar_name
)[length
] = ar_padchar (abfd
);
905 PROTO (boolean
, compute_and_write_armap
, (bfd
*arch
, unsigned int elength
));
907 /* The bfd is open for write and has its format set to bfd_archive */
909 _bfd_write_archive_contents (arch
)
914 unsigned int elength
= 0;
915 boolean makemap
= bfd_has_map (arch
);
916 boolean hasobjects
= false; /* if no .o's, don't bother to make a map */
919 /* Verify the viability of all entries; if any of them live in the
920 filesystem (as opposed to living in an archive open for input)
921 then construct a fresh ar_hdr for them.
923 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
924 if (bfd_write_p (current
)) {
925 bfd_error
= invalid_operation
;
928 if (!current
->arelt_data
) {
929 current
->arelt_data
=
930 (PTR
) bfd_ar_hdr_from_filesystem (arch
, current
->filename
);
931 if (!current
->arelt_data
) return false;
933 /* Put in the file name */
935 BFD_SEND (arch
, _bfd_truncate_arname
,(arch
,
937 (char *) arch_hdr(current
)));
942 if (makemap
) { /* don't bother if we won't make a map! */
943 if ((bfd_check_format (current
, bfd_object
))
944 #if 0 /* FIXME -- these are not set correctly */
945 && ((bfd_get_file_flags (current
) & HAS_SYMS
))
952 if (!bfd_construct_extended_name_table (arch
, &etable
, &elength
))
955 bfd_seek (arch
, 0, SEEK_SET
);
957 bfd_write (BFD_GNU960_ARMAG(arch
), 1, SARMAG
, arch
);
959 bfd_write (ARMAG
, 1, SARMAG
, arch
);
962 if (makemap
&& hasobjects
) {
964 if (compute_and_write_armap (arch
, elength
) != true) {
972 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
973 sprintf (&(hdr
.ar_name
[0]), "ARFILENAMES/");
974 sprintf (&(hdr
.ar_size
[0]), "%-10d", (int) elength
);
975 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
976 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
977 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
978 bfd_write ((char *)&hdr
, 1, sizeof (struct ar_hdr
), arch
);
979 bfd_write (etable
, 1, elength
, arch
);
980 if ((elength
% 2) == 1) bfd_write ("\n", 1, 1, arch
);
984 for (current
= arch
->archive_head
; current
; current
= current
->next
) {
985 char buffer
[DEFAULT_BUFFERSIZE
];
986 unsigned int remaining
= arelt_size (current
);
987 struct ar_hdr
*hdr
= arch_hdr(current
);
988 /* write ar header */
990 if (bfd_write ((char *)hdr
, 1, sizeof(*hdr
), arch
) != sizeof(*hdr
)) {
992 bfd_error
= system_call_error
;
995 if (bfd_seek (current
, 0L, SEEK_SET
) != 0L) goto syserr
;
998 unsigned int amt
= DEFAULT_BUFFERSIZE
;
999 if (amt
> remaining
) {
1002 if (bfd_read (buffer
, amt
, 1, current
) != amt
) goto syserr
;
1003 if (bfd_write (buffer
, amt
, 1, arch
) != amt
) goto syserr
;
1006 if ((arelt_size (current
) % 2) == 1) bfd_write ("\n", 1, 1, arch
);
1011 /* Note that the namidx for the first symbol is 0 */
1014 compute_and_write_armap (arch
, elength
)
1016 unsigned int elength
;
1019 file_ptr elt_no
= 0;
1021 int orl_max
= 15000; /* fine initial default */
1023 int stridx
= 0; /* string index */
1025 /* Dunno if this is the best place for this info... */
1026 if (elength
!= 0) elength
+= sizeof (struct ar_hdr
);
1027 elength
+= elength
%2 ;
1029 map
= (struct orl
*) bfd_zalloc (arch
,orl_max
* sizeof (struct orl
));
1031 bfd_error
= no_memory
;
1035 /* Map over each element */
1036 for (current
= arch
->archive_head
;
1037 current
!= (bfd
*)NULL
;
1038 current
= current
->next
, elt_no
++)
1040 if ((bfd_check_format (current
, bfd_object
) == true)
1041 && ((bfd_get_file_flags (current
) & HAS_SYMS
))) {
1043 unsigned int storage
;
1044 unsigned int symcount
;
1045 unsigned int src_count
;
1047 storage
= get_symtab_upper_bound (current
);
1050 syms
= (asymbol
**) bfd_zalloc (arch
,storage
);
1052 bfd_error
= no_memory
; /* FIXME -- memory leak */
1055 symcount
= bfd_canonicalize_symtab (current
, syms
);
1058 /* Now map over all the symbols, picking out the ones we want */
1059 for (src_count
= 0; src_count
<symcount
; src_count
++) {
1060 flagword flags
= (syms
[src_count
])->flags
;
1061 if ((flags
& BSF_GLOBAL
) ||
1062 (flags
& BSF_FORT_COMM
)) {
1064 /* This symbol will go into the archive header */
1065 if (orl_count
== orl_max
)
1068 map
= (struct orl
*) bfd_realloc (arch
, (char *) map
,
1069 orl_max
* sizeof (struct orl
));
1072 (map
[orl_count
]).name
= (char **) &((syms
[src_count
])->name
);
1073 (map
[orl_count
]).pos
= (file_ptr
) current
;
1074 (map
[orl_count
]).namidx
= stridx
;
1076 stridx
+= strlen ((syms
[src_count
])->name
) + 1;
1083 /* OK, now we have collected all the data, let's write them out */
1084 if (!BFD_SEND (arch
, write_armap
,
1085 (arch
, elength
, map
, orl_count
, stridx
))) {
1095 bsd_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1097 unsigned int elength
;
1102 unsigned int ranlibsize
= (orl_count
* sizeof (struct ranlib
)) + 4;
1103 unsigned int stringsize
= stridx
+ 4;
1104 unsigned int mapsize
= stringsize
+ ranlibsize
;
1106 bfd
*current
= arch
->archive_head
;
1107 bfd
*last_elt
= current
; /* last element arch seen */
1111 struct stat statbuf
;
1113 int padit
= mapsize
& 1;
1115 if (padit
) mapsize
++;
1117 firstreal
= mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1119 stat (arch
->filename
, &statbuf
);
1120 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1121 sprintf (hdr
.ar_name
, RANLIBMAG
);
1122 sprintf (hdr
.ar_date
, "%ld", statbuf
.st_mtime
);
1123 sprintf (hdr
.ar_uid
, "%d", getuid());
1124 sprintf (hdr
.ar_gid
, "%d", getgid());
1125 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1126 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1127 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1128 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1129 bfd_write ((char *)&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1130 bfd_h_put_32(arch
, ranlibsize
, &temp
);
1131 bfd_write (&temp
, 1, sizeof (temp
), arch
);
1133 for (count
= 0; count
< orl_count
; count
++) {
1135 struct symdef
*outp
= &outs
;
1137 if (((bfd
*)(map
[count
]).pos
) != last_elt
) {
1139 firstreal
+= arelt_size (current
) + sizeof (struct ar_hdr
);
1140 firstreal
+= firstreal
% 2;
1141 current
= current
->next
;
1142 } while (current
!= (bfd
*)(map
[count
]).pos
);
1143 } /* if new archive element */
1146 bfd_h_put_32(arch
, ((map
[count
]).namidx
), &outs
.s
.string_offset
);
1147 bfd_h_put_32(arch
, firstreal
, &outs
.file_offset
);
1148 bfd_write ((char *)outp
, 1, sizeof (outs
), arch
);
1151 /* now write the strings themselves */
1152 bfd_h_put_32(arch
, stridx
, &temp
);
1153 bfd_write ((PTR
)&temp
, 1, sizeof (temp
), arch
);
1154 for (count
= 0; count
< orl_count
; count
++)
1155 bfd_write (*((map
[count
]).name
), 1, strlen (*((map
[count
]).name
))+1, arch
);
1157 /* The spec sez this should be a newline. But in order to be
1158 bug-compatible for sun's ar we use a null. */
1160 bfd_write("\0",1,1,arch
);
1166 /* A coff armap looks like :
1168 struct ar_hdr with name = '/'
1170 offset of file for symbol 0
1171 offset of file for symbol 1
1173 offset of file for symbol n-1
1182 coff_write_armap (arch
, elength
, map
, orl_count
, stridx
)
1184 unsigned int elength
;
1189 unsigned int ranlibsize
= (orl_count
* 4) + 4;
1190 unsigned int stringsize
= stridx
;
1191 unsigned int mapsize
= stringsize
+ ranlibsize
;
1192 file_ptr archive_member_file_ptr
;
1193 bfd
*current
= arch
->archive_head
;
1194 int last_eltno
= 0; /* last element arch seen */
1198 int padit
= mapsize
& 1;
1200 if (padit
) mapsize
++;
1202 archive_member_file_ptr
=
1203 mapsize
+ elength
+ sizeof (struct ar_hdr
) + SARMAG
;
1205 memset ((char *)(&hdr
), 0, sizeof (struct ar_hdr
));
1206 hdr
.ar_name
[0] = '/';
1207 sprintf (hdr
.ar_size
, "%-10d", (int) mapsize
);
1208 sprintf (hdr
.ar_date
, "%ld", (long)time (NULL
));
1209 /* This, at least, is what Intel coff sets the values to.: */
1210 sprintf ((hdr
.ar_uid
), "%d", 0);
1211 sprintf ((hdr
.ar_gid
), "%d", 0);
1212 sprintf ((hdr
.ar_mode
), "%-7o",(unsigned ) 0);
1213 hdr
.ar_fmag
[0] = '`'; hdr
.ar_fmag
[1] = '\n';
1215 for (i
= 0; i
< sizeof (struct ar_hdr
); i
++)
1216 if (((char *)(&hdr
))[i
] == '\0') (((char *)(&hdr
))[i
]) = ' ';
1218 /* Write the ar header for this item and the number of symbols */
1220 bfd_write ((PTR
)&hdr
, 1, sizeof (struct ar_hdr
), arch
);
1221 /* FIXME, this needs to be byte-swapped */
1222 bfd_write ((PTR
)&orl_count
, 1, sizeof (orl_count
), arch
);
1224 /* Two passes, first write the file offsets for each symbol -
1225 remembering that each offset is on a two byte boundary
1228 for (count
= 0; count
< orl_count
; count
++) {
1229 while ((map
[count
]).pos
!= last_eltno
) {
1230 /* If this is the first time we've seen a ref to this archive
1231 then remember it's size */
1232 archive_member_file_ptr
+=
1233 arelt_size (current
) + sizeof (struct ar_hdr
);
1234 archive_member_file_ptr
+= archive_member_file_ptr
% 2;
1235 current
= current
->next
;
1238 /* FIXME, this needs to be byte-swapped */
1239 bfd_write ((PTR
)&archive_member_file_ptr
,
1241 sizeof (archive_member_file_ptr
),
1245 /* now write the strings themselves */
1246 for (count
= 0; count
< orl_count
; count
++) {
1247 bfd_write ((PTR
)*((map
[count
]).name
),
1249 strlen (*((map
[count
]).name
))+1, arch
);
1252 /* The spec sez this should be a newline. But in order to be
1253 bug-compatible for arc960 we use a null. */
1255 bfd_write("\0",1,1,arch
);