3 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Diddler.
7 BFD is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
12 BFD is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with BFD; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 @setfilename archive-info
26 Gumby, you promised to write this bit...
28 Archives are supported in bfd in @code{archive.c}.
30 An archive is represented internally just like another bfd, with a
31 pointer to a chain of contained bfds. Archives can be created by
32 opening bfds, linking them together and attatching them as children to
33 another bfd and then closing the parent bfd.
38 o - all archive elements start on an even boundary, newline padded;
39 o - all arch headers are char *;
40 o - all arch headers are the same size (across architectures).
52 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
55 /* We keep a cache of archive filepointers to archive elements to
56 speed up searching the archive by filepos. We only add an entry to
57 the cache when we actually read one. We also don't sort the cache;
58 it's short enough to search linearly.
59 Note that the pointers here point to the front of the ar_hdr, not
60 to the front of the contents!
65 struct ar_cache *next;
68 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
69 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
71 #define arch_hdr(bfd) ((struct ar_hdr *) \
72 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
75 _bfd_generic_mkarchive (abfd)
78 set_tdata (abfd, bfd_zalloc(abfd, sizeof (struct artdata)));
80 if (bfd_ardata (abfd) == NULL) {
81 bfd_error = no_memory;
84 bfd_ardata(abfd)->cache = 0;
88 /*proto* bfd_get_next_mapent
90 *; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
93 bfd_get_next_mapent (abfd, prev, entry)
98 if (!bfd_has_map (abfd)) {
99 bfd_error = invalid_operation;
100 return BFD_NO_MORE_SYMBOLS;
103 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
104 else if (++prev >= bfd_ardata (abfd)->symdef_count)
105 return BFD_NO_MORE_SYMBOLS;
107 *entry = (bfd_ardata (abfd)->symdefs + prev);
112 /* To be called by backends only */
114 _bfd_create_empty_archive_element_shell (obfd)
119 nbfd = new_bfd_contained_in(obfd);
121 bfd_error = no_memory;
127 /*proto* bfd_set_archive_head
128 Used whilst processing archives. Sets the head of the chain of bfds
129 contained in an archive to @var{new_head}. (see chapter on archives)
130 *; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
134 DEFUN(bfd_set_archive_head,(output_archive, new_head),
135 bfd *output_archive AND
139 output_archive->archive_head = new_head;
144 look_for_bfd_in_cache (arch_bfd, filepos)
148 struct ar_cache *current;
150 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
151 current = current->next)
152 if (current->ptr == filepos) return current->arelt;
157 /* Kind of stupid to call cons for each one, but we don't do too many */
159 add_bfd_to_cache (arch_bfd, filepos, new_elt)
160 bfd *arch_bfd, *new_elt;
163 struct ar_cache *new_cache = (struct ar_cache *)
164 bfd_zalloc(arch_bfd, sizeof (struct ar_cache));
166 if (new_cache == NULL) {
167 bfd_error = no_memory;
171 new_cache->ptr = filepos;
172 new_cache->arelt = new_elt;
173 new_cache->next = (struct ar_cache *)NULL;
174 if (bfd_ardata (arch_bfd)->cache == NULL)
175 bfd_ardata (arch_bfd)->cache = new_cache;
177 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
179 for (; current->next != NULL; current = current->next);
180 current->next = new_cache;
188 /* The name begins with space. Hence the rest of the name is an index into
192 get_extended_arelt_filename (arch, name)
199 unsigned long index = 0;
201 /* Should extract string so that I can guarantee not to overflow into
202 the next region, but I"m too lazy. */
204 index = strtol (name, NULL, 10);
206 bfd_error = malformed_archive;
210 return bfd_ardata (arch)->extended_names + index;
213 /* This functions reads an arch header and returns an areltdata pointer, or
216 Presumes the file pointer is already in the right place (ie pointing
217 to the ar_hdr in the file). Moves the file pointer; on success it
218 should be pointing to the front of the file contents; on failure it
219 could have been moved arbitrarily.
231 char *hdrp = (char *) &hdr;
232 unsigned int parsed_size;
233 struct areltdata *ared;
234 char *filename = NULL;
235 unsigned int namelen = 0;
236 unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
239 if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
240 != sizeof (struct ar_hdr)) {
241 bfd_error = no_more_archived_files;
244 if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
245 bfd_error = malformed_archive;
250 parsed_size = strtol (hdr.ar_size, NULL, 10);
252 bfd_error = malformed_archive;
256 /* extract the filename from the archive - there are two ways to
257 specify an extendend name table, either the first char of the
258 name is a space, or it's a slash */
259 if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
260 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
261 if (filename == NULL) {
262 bfd_error = malformed_archive;
268 /* We judge the end of the name by looking for a space or a
273 while (namelen < (unsigned)ar_maxnamelen(abfd) &&
274 ( hdr.ar_name[namelen] != 0 &&
275 hdr.ar_name[namelen] != ' ' &&
276 hdr.ar_name[namelen] != ar_padchar(abfd))) {
280 allocsize += namelen + 1;
283 allocptr = bfd_zalloc(abfd, allocsize);
284 if (allocptr == NULL) {
285 bfd_error = no_memory;
289 ared = (struct areltdata *) allocptr;
291 ared->arch_header = allocptr + sizeof (struct areltdata);
292 memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
293 ared->parsed_size = parsed_size;
295 if (filename != NULL) ared->filename = filename;
297 ared->filename = allocptr + (sizeof (struct areltdata) +
298 sizeof (struct ar_hdr));
300 memcpy (ared->filename, hdr.ar_name, namelen);
301 ared->filename[namelen] = '\0';
308 get_elt_at_filepos (archive, filepos)
312 struct areltdata *new_areldata;
315 n_nfd = look_for_bfd_in_cache (archive, filepos);
316 if (n_nfd) return n_nfd;
318 if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
319 bfd_error = system_call_error;
323 if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
325 n_nfd = _bfd_create_empty_archive_element_shell (archive);
327 bfd_release (archive, (PTR)new_areldata);
330 n_nfd->origin = bfd_tell (archive);
331 n_nfd->arelt_data = (PTR) new_areldata;
332 n_nfd->filename = new_areldata->filename;
334 if (add_bfd_to_cache (archive, filepos, n_nfd))
338 bfd_release (archive, (PTR)n_nfd);
339 bfd_release (archive, (PTR)new_areldata);
344 bfd_get_elt_at_index (abfd, index)
350 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
354 /*proto* bfd_openr_next_archived_file
355 Initially provided a bfd containing an archive and NULL, opens a bfd
356 on the first contained element and returns that. Subsequent calls to
357 bfd_openr_next_archived_file should pass the archive and the previous
358 return value to return a created bfd to the next contained element.
359 NULL is returned when there are no more.
361 *; PROTO(bfd*, bfd_openr_next_archived_file,
362 (bfd *archive, bfd *previous));
367 DEFUN(bfd_openr_next_archived_file,(archive, last_file),
372 if ((bfd_get_format (archive) != bfd_archive) ||
373 (archive->direction == write_direction)) {
374 bfd_error = invalid_operation;
379 return BFD_SEND (archive,
380 openr_next_archived_file,
386 bfd *bfd_generic_openr_next_archived_file(archive, last_file)
393 filestart = bfd_ardata (archive)->first_file_filepos;
395 unsigned int size = arelt_size(last_file);
396 /* Pad to an even boundary... */
397 filestart = last_file->origin + size + size%2;
400 return get_elt_at_filepos (archive, filestart);
405 bfd_generic_archive_p (abfd)
408 char armag[SARMAG+1];
410 if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
411 bfd_error = wrong_format;
416 if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
418 if (strncmp (armag, ARMAG, SARMAG)) return 0;
421 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
422 involves a cast, we can't do it as the left operand of assignment. */
423 set_tdata (abfd, bfd_zalloc(abfd,sizeof (struct artdata)));
425 if (bfd_ardata (abfd) == NULL) {
426 bfd_error = no_memory;
430 bfd_ardata (abfd)->first_file_filepos = SARMAG;
432 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
433 bfd_release(abfd, bfd_ardata (abfd));
438 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
439 bfd_release(abfd, bfd_ardata (abfd));
447 /* Returns false on error, true otherwise */
449 bfd_slurp_bsd_armap (abfd)
453 struct areltdata *mapdata;
455 unsigned int counter = 0;
456 int *raw_armap, *rbase;
457 struct artdata *ardata = bfd_ardata (abfd);
460 /* FIXME, if the read fails, this routine quietly returns "true"!!
461 It should probably do that if the read gives 0 bytes (empty archive),
462 but fail for any other size... */
463 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
464 /* The archive has at least 16 bytes in it */
465 bfd_seek (abfd, -16L, SEEK_CUR);
467 /* This should be using RANLIBMAG, but at least it can be grepped for
469 if (strncmp (nextname, "__.SYMDEF ", 16)) {
470 bfd_has_map (abfd) = false;
474 mapdata = snarf_ar_hdr (abfd);
475 if (mapdata == NULL) return false;
477 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
478 if (raw_armap == NULL) {
479 bfd_error = no_memory;
481 bfd_release (abfd, (PTR)mapdata);
485 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
486 mapdata->parsed_size) {
487 bfd_error = malformed_archive;
488 bfd_release (abfd, (PTR)raw_armap);
492 ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
495 ardata->symdefs = (carsym *) rbase;
496 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
498 for (;counter < ardata->symdef_count; counter++) {
499 struct symdef *sym = ((struct symdef *) rbase) + counter;
500 sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
501 sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
504 ardata->first_file_filepos = bfd_tell (abfd);
505 /* Pad to an even boundary if you have to */
506 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
507 /* FIXME, we should provide some way to free raw_ardata when
508 we are done using the strings from it. For now, it seems
509 to be allocated on an obstack anyway... */
510 bfd_has_map (abfd) = true;
515 /* Returns false on error, true otherwise */
517 bfd_slurp_coff_armap (abfd)
520 struct areltdata *mapdata;
522 int *raw_armap, *rawptr;
523 struct artdata *ardata = bfd_ardata (abfd);
525 unsigned int stringsize;
529 result = bfd_read ((PTR)&nextname, 1, 1, abfd);
530 bfd_seek (abfd, -1L, SEEK_CUR);
532 if (result != 1 || nextname != '/') {
533 /* Actually I think this is an error for a COFF archive */
534 bfd_has_map (abfd) = false;
538 mapdata = snarf_ar_hdr (abfd);
539 if (mapdata == NULL) return false;
541 raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
543 if (raw_armap == NULL)
545 bfd_error = no_memory;
547 bfd_release (abfd, (PTR)mapdata);
551 /* read in the raw map */
552 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
553 mapdata->parsed_size) {
554 bfd_error = malformed_archive;
556 bfd_release (abfd, (PTR)raw_armap);
560 /* The coff armap must be read sequentially. So we construct a bsd-style
561 one in core all at once, for simplicity. */
563 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
566 unsigned int nsymz = *raw_armap;
567 unsigned int carsym_size = (nsymz * sizeof (carsym));
568 unsigned int ptrsize = (4 * nsymz);
570 ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
571 if (ardata->symdefs == NULL) {
572 bfd_error = no_memory;
575 carsyms = ardata->symdefs;
577 stringbase = ((char *) ardata->symdefs) + carsym_size;
578 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
581 /* OK, build the carsyms */
582 for (i = 0; i < nsymz; i++)
584 rawptr = raw_armap + i + 1;
585 carsyms->file_offset = *rawptr;
586 carsyms->name = stringbase;
587 for (; *(stringbase++););
592 ardata->symdef_count = *raw_armap;
593 ardata->first_file_filepos = bfd_tell (abfd);
594 /* Pad to an even boundary if you have to */
595 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
597 /* We'd like to release these allocations, but we have allocated stuff
598 since then (using the same obstack, if bfd_release is obstack based).
599 So they will stick around until the bfd is closed. */
600 /* bfd_release (abfd, (PTR)raw_armap);
601 bfd_release (abfd, (PTR)mapdata); */
602 bfd_has_map (abfd) = true;
606 /** Extended name table.
608 Normally archives support only 14-character filenames.
610 Intel has extended the format: longer names are stored in a special
611 element (the first in the archive, or second if there is an armap);
612 the name in the ar_hdr is replaced by <space><index into filename
613 element>. Index is the P.R. of an int (radix: 8). Data General have
614 extended the format by using the prefix // for the special element */
616 /* Returns false on error, true otherwise */
618 _bfd_slurp_extended_name_table (abfd)
622 struct areltdata *namedata;
624 /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
625 we probably don't want to return true. */
626 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
628 bfd_seek (abfd, -16L, SEEK_CUR);
630 if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
631 strncmp (nextname, "// ", 16) != 0)
633 bfd_ardata (abfd)->extended_names = NULL;
637 namedata = snarf_ar_hdr (abfd);
638 if (namedata == NULL) return false;
640 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
641 if (bfd_ardata (abfd)->extended_names == NULL) {
642 bfd_error = no_memory;
644 bfd_release (abfd, (PTR)namedata);
648 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
649 namedata->parsed_size, abfd) != namedata->parsed_size) {
650 bfd_error = malformed_archive;
651 bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
652 bfd_ardata (abfd)->extended_names = NULL;
656 /* Since the archive is supposed to be printable if it contains
657 text, the entries in the list are newline-padded, not null
658 padded. We'll fix that there.. */
660 char *temp = bfd_ardata (abfd)->extended_names;
661 for (; *temp != '\0'; ++temp)
662 if (*temp == '\n') *temp = '\0';
665 /* Pad to an even boundary if you have to */
666 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
667 bfd_ardata (abfd)->first_file_filepos +=
668 (bfd_ardata (abfd)->first_file_filepos) %2;
670 /* FIXME, we can't release namedata here because it was allocated
671 below extended_names on the obstack... */
672 /* bfd_release (abfd, namedata); */
678 char *normalize(file)
681 char * filename = strrchr(file, '/');
682 if (filename != (char *)NULL) {
691 /* Follows archive_head and produces an extended name table if necessary.
692 Returns (in tabloc) a pointer to an extended name table, and in tablen
693 the length of the table. If it makes an entry it clobbers the filename
694 so that the element may be written without further massage.
695 Returns true if it ran successfully, false if something went wrong.
696 A successful return may still involve a zero-length tablen!
699 bfd_construct_extended_name_table (abfd, tabloc, tablen)
702 unsigned int *tablen;
704 unsigned int maxname = abfd->xvec->ar_max_namelen;
705 unsigned int total_namelen = 0;
711 /* Figure out how long the table should be */
712 for (current = abfd->archive_head; current != NULL; current = current->next){
713 unsigned int thislen = strlen (normalize(current->filename));
714 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
717 if (total_namelen == 0) return true;
719 *tabloc = bfd_zalloc (abfd,total_namelen);
720 if (*tabloc == NULL) {
721 bfd_error = no_memory;
725 *tablen = total_namelen;
728 for (current = abfd->archive_head; current != NULL; current =
730 char *normal =normalize( current->filename);
731 unsigned int thislen = strlen (normal);
732 if (thislen > maxname) {
733 /* Works for now; may need to be re-engineered if we encounter an oddball
734 archive format and want to generalise this hack. */
735 struct ar_hdr *hdr = arch_hdr(current);
736 strcpy (strptr, normal);
737 strptr[thislen] = '\n';
738 hdr->ar_name[0] = ' ';
739 /* We know there will always be enough room (one of the few cases
740 where you may safely use sprintf). */
741 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
742 /* Kinda Kludgy. We should just use the returned value of sprintf
743 but not all implementations get this right */
745 char *temp = hdr->ar_name +2;
746 for (; temp < hdr->ar_name + maxname; temp++)
747 if (*temp == '\0') *temp = ' ';
749 strptr += thislen + 1;
756 /** A couple of functions for creating ar_hdrs */
758 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
759 The filename must refer to a filename in the filesystem.
760 The filename field of the ar_hdr will NOT be initialized
764 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
766 CONST char *filename)
769 struct areltdata *ared;
774 if (stat (filename, &status) != 0) {
775 bfd_error = system_call_error;
779 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
780 sizeof (struct areltdata));
782 bfd_error = no_memory;
785 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
787 /* ar headers are space padded, not null padded! */
789 temp1 = temp + sizeof (struct ar_hdr) - 2;
790 for (; temp < temp1; *(temp++) = ' ');
791 strncpy (hdr->ar_fmag, ARFMAG, 2);
793 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
794 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
795 sprintf ((hdr->ar_uid), "%d", status.st_uid);
796 sprintf ((hdr->ar_gid), "%d", status.st_gid);
797 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
798 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
799 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
800 understand how these C losers could design such a ramshackle bunch of
803 temp1 = temp + sizeof (struct ar_hdr) - 2;
804 for (; temp < temp1; temp++) {
805 if (*temp == '\0') *temp = ' ';
807 strncpy (hdr->ar_fmag, ARFMAG, 2);
808 ared->parsed_size = status.st_size;
809 ared->arch_header = (char *) hdr;
815 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
820 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
824 /* Analogous to stat call */
826 bfd_generic_stat_arch_elt (abfd, buf)
833 if (abfd->arelt_data == NULL) {
834 bfd_error = invalid_operation;
838 hdr = arch_hdr (abfd);
840 #define foo(arelt, stelt, size) \
841 buf->stelt = strtol (hdr->arelt, &aloser, size); \
842 if (aloser == hdr->arelt) return -1;
844 foo (ar_date, st_mtime, 10);
845 foo (ar_uid, st_uid, 10);
846 foo (ar_gid, st_gid, 10);
847 foo (ar_mode, st_mode, 8);
848 foo (ar_size, st_size, 10);
854 bfd_dont_truncate_arname (abfd, pathname, arhdr)
856 CONST char *pathname;
859 /* FIXME: This interacts unpleasantly with ar's quick-append option.
860 Fortunately ic960 users will never use that option. Fixing this
861 is very hard; fortunately I know how to do it and will do so once
862 intel's release is out the door. */
864 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
866 CONST char *filename = strrchr (pathname, '/');
867 int maxlen = ar_maxnamelen (abfd);
869 if (filename == NULL)
874 length = strlen (filename);
876 if (length <= maxlen)
877 memcpy (hdr->ar_name, filename, length);
879 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
885 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
887 CONST char *pathname;
890 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
892 CONST char *filename = strrchr (pathname, '/');
893 int maxlen = ar_maxnamelen (abfd);
896 if (filename == NULL)
901 length = strlen (filename);
903 if (length <= maxlen)
904 memcpy (hdr->ar_name, filename, length);
906 /* pathname: meet procrustes */
907 memcpy (hdr->ar_name, filename, maxlen);
911 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
914 /* Store name into ar header. Truncates the name to fit.
915 1> strip pathname to be just the basename.
916 2> if it's short enuf to fit, stuff it in.
917 3> If it doesn't end with .o, truncate it to fit
918 4> truncate it before the .o, append .o, stuff THAT in.
921 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
923 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
925 CONST char *pathname;
928 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
930 CONST char *filename = strrchr (pathname, '/');
931 int maxlen = ar_maxnamelen (abfd);
933 if (filename == NULL)
938 length = strlen (filename);
940 if (length <= maxlen)
941 memcpy (hdr->ar_name, filename, length);
942 else { /* pathname: meet procrustes */
943 memcpy (hdr->ar_name, filename, maxlen);
944 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
945 hdr->ar_name[maxlen - 2] = '.';
946 hdr->ar_name[maxlen - 1] = 'o';
951 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
955 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
957 /* The bfd is open for write and has its format set to bfd_archive */
959 _bfd_write_archive_contents (arch)
964 unsigned int elength = 0;
965 boolean makemap = bfd_has_map (arch);
966 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
969 /* Verify the viability of all entries; if any of them live in the
970 filesystem (as opposed to living in an archive open for input)
971 then construct a fresh ar_hdr for them.
973 for (current = arch->archive_head; current; current = current->next) {
974 if (bfd_write_p (current)) {
975 bfd_error = invalid_operation;
978 if (!current->arelt_data) {
979 current->arelt_data =
980 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
981 if (!current->arelt_data) return false;
983 /* Put in the file name */
985 BFD_SEND (arch, _bfd_truncate_arname,(arch,
987 (char *) arch_hdr(current)));
992 if (makemap) { /* don't bother if we won't make a map! */
993 if ((bfd_check_format (current, bfd_object))
994 #if 0 /* FIXME -- these are not set correctly */
995 && ((bfd_get_file_flags (current) & HAS_SYMS))
1002 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
1005 bfd_seek (arch, 0, SEEK_SET);
1007 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
1009 bfd_write (ARMAG, 1, SARMAG, arch);
1012 if (makemap && hasobjects) {
1014 if (compute_and_write_armap (arch, elength) != true) {
1022 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1023 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
1024 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
1025 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1026 for (i = 0; i < sizeof (struct ar_hdr); i++)
1027 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1028 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1029 bfd_write (etable, 1, elength, arch);
1030 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
1034 for (current = arch->archive_head; current; current = current->next) {
1035 char buffer[DEFAULT_BUFFERSIZE];
1036 unsigned int remaining = arelt_size (current);
1037 struct ar_hdr *hdr = arch_hdr(current);
1038 /* write ar header */
1040 if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
1042 bfd_error = system_call_error;
1045 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
1048 unsigned int amt = DEFAULT_BUFFERSIZE;
1049 if (amt > remaining) {
1052 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
1053 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
1056 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1061 /* Note that the namidx for the first symbol is 0 */
1064 compute_and_write_armap (arch, elength)
1066 unsigned int elength;
1069 file_ptr elt_no = 0;
1071 int orl_max = 15000; /* fine initial default */
1073 int stridx = 0; /* string index */
1075 /* Dunno if this is the best place for this info... */
1076 if (elength != 0) elength += sizeof (struct ar_hdr);
1077 elength += elength %2 ;
1079 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1081 bfd_error = no_memory;
1085 /* Map over each element */
1086 for (current = arch->archive_head;
1087 current != (bfd *)NULL;
1088 current = current->next, elt_no++)
1090 if ((bfd_check_format (current, bfd_object) == true)
1091 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1093 unsigned int storage;
1094 unsigned int symcount;
1095 unsigned int src_count;
1097 storage = get_symtab_upper_bound (current);
1100 syms = (asymbol **) bfd_zalloc (arch,storage);
1102 bfd_error = no_memory; /* FIXME -- memory leak */
1105 symcount = bfd_canonicalize_symtab (current, syms);
1108 /* Now map over all the symbols, picking out the ones we want */
1109 for (src_count = 0; src_count <symcount; src_count++) {
1110 flagword flags = (syms[src_count])->flags;
1111 if ((flags & BSF_GLOBAL) ||
1112 (flags & BSF_FORT_COMM)) {
1114 /* This symbol will go into the archive header */
1115 if (orl_count == orl_max)
1118 map = (struct orl *) bfd_realloc (arch, (char *) map,
1119 orl_max * sizeof (struct orl));
1122 (map[orl_count]).name = (char **) &((syms[src_count])->name);
1123 (map[orl_count]).pos = (file_ptr) current;
1124 (map[orl_count]).namidx = stridx;
1126 stridx += strlen ((syms[src_count])->name) + 1;
1133 /* OK, now we have collected all the data, let's write them out */
1134 if (!BFD_SEND (arch, write_armap,
1135 (arch, elength, map, orl_count, stridx))) {
1145 bsd_write_armap (arch, elength, map, orl_count, stridx)
1147 unsigned int elength;
1152 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1153 unsigned int stringsize = stridx + 4;
1154 unsigned int mapsize = stringsize + ranlibsize;
1156 bfd *current = arch->archive_head;
1157 bfd *last_elt = current; /* last element arch seen */
1161 struct stat statbuf;
1163 int padit = mapsize & 1;
1165 if (padit) mapsize ++;
1167 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1169 stat (arch->filename, &statbuf);
1170 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1171 sprintf (hdr.ar_name, RANLIBMAG);
1172 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1173 sprintf (hdr.ar_uid, "%d", getuid());
1174 sprintf (hdr.ar_gid, "%d", getgid());
1175 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1176 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1177 for (i = 0; i < sizeof (struct ar_hdr); i++)
1178 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1179 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1180 bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
1181 bfd_write (&temp, 1, sizeof (temp), arch);
1183 for (count = 0; count < orl_count; count++) {
1185 struct symdef *outp = &outs;
1187 if (((bfd *)(map[count]).pos) != last_elt) {
1189 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1190 firstreal += firstreal % 2;
1191 current = current->next;
1192 } while (current != (bfd *)(map[count]).pos);
1193 } /* if new archive element */
1196 bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
1197 bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
1198 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1201 /* now write the strings themselves */
1202 bfd_h_put_32(arch, stridx, (PTR)&temp);
1203 bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
1204 for (count = 0; count < orl_count; count++)
1205 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1207 /* The spec sez this should be a newline. But in order to be
1208 bug-compatible for sun's ar we use a null. */
1210 bfd_write("\0",1,1,arch);
1216 /* A coff armap looks like :
1218 struct ar_hdr with name = '/'
1220 offset of file for symbol 0
1221 offset of file for symbol 1
1223 offset of file for symbol n-1
1232 coff_write_armap (arch, elength, map, orl_count, stridx)
1234 unsigned int elength;
1239 unsigned int ranlibsize = (orl_count * 4) + 4;
1240 unsigned int stringsize = stridx;
1241 unsigned int mapsize = stringsize + ranlibsize;
1242 file_ptr archive_member_file_ptr;
1243 bfd *current = arch->archive_head;
1244 int last_eltno = 0; /* last element arch seen */
1248 int padit = mapsize & 1;
1250 if (padit) mapsize ++;
1252 archive_member_file_ptr =
1253 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1255 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1256 hdr.ar_name[0] = '/';
1257 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1258 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1259 /* This, at least, is what Intel coff sets the values to.: */
1260 sprintf ((hdr.ar_uid), "%d", 0);
1261 sprintf ((hdr.ar_gid), "%d", 0);
1262 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1263 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1265 for (i = 0; i < sizeof (struct ar_hdr); i++)
1266 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1268 /* Write the ar header for this item and the number of symbols */
1270 bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
1271 /* FIXME, this needs to be byte-swapped */
1272 bfd_write ((PTR)&orl_count, 1, sizeof (orl_count), arch);
1274 /* Two passes, first write the file offsets for each symbol -
1275 remembering that each offset is on a two byte boundary
1278 for (count = 0; count < orl_count; count++) {
1279 while ((map[count]).pos != last_eltno) {
1280 /* If this is the first time we've seen a ref to this archive
1281 then remember it's size */
1282 archive_member_file_ptr +=
1283 arelt_size (current) + sizeof (struct ar_hdr);
1284 archive_member_file_ptr += archive_member_file_ptr % 2;
1285 current = current->next;
1288 /* FIXME, this needs to be byte-swapped */
1289 bfd_write ((PTR)&archive_member_file_ptr,
1291 sizeof (archive_member_file_ptr),
1295 /* now write the strings themselves */
1296 for (count = 0; count < orl_count; count++) {
1297 bfd_write ((PTR)*((map[count]).name),
1299 strlen (*((map[count]).name))+1, arch);
1302 /* The spec sez this should be a newline. But in order to be
1303 bug-compatible for arc960 we use a null. */
1305 bfd_write("\0",1,1,arch);