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 /* This should be using RANLIBMAG, but at least it can be grepped for
422 if (strncmp (nextname, "__.SYMDEF ", 16)) {
423 bfd_has_map (abfd) = false;
427 mapdata = snarf_ar_hdr (abfd);
428 if (mapdata == NULL) return false;
430 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
431 if (raw_armap == NULL) {
432 bfd_error = no_memory;
437 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
438 mapdata->parsed_size) {
439 bfd_error = malformed_archive;
443 ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
446 ardata->symdefs = (carsym *) rbase;
447 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
449 for (;counter < (unsigned)( ardata->symdef_count); counter++) {
450 struct symdef *sym = ((struct symdef *) rbase) + counter;
451 sym->s.name = sym->s.string_offset + stringbase;
454 ardata->first_file_filepos = bfd_tell (abfd);
455 /* Pad to an even boundary if you have to */
456 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
457 bfd_has_map (abfd) = true;
462 /* Returns false on error, true otherwise */
464 bfd_slurp_coff_armap (abfd)
467 struct areltdata *mapdata;
469 int *raw_armap, *rawptr;
470 struct artdata *ardata = bfd_ardata (abfd);
472 unsigned int stringsize;
475 if (bfd_read ((PTR)&nextname, 1, 1, abfd) != 1) {
476 bfd_seek (abfd, -1L, SEEK_CUR);
477 bfd_has_map(abfd) = false;
480 bfd_seek (abfd, -1L, SEEK_CUR);
482 if (nextname != '/') {
483 /* Actually I think this is an error for a COFF archive */
484 bfd_has_map (abfd) = false;
488 mapdata = snarf_ar_hdr (abfd);
489 if (mapdata == NULL) return false;
491 raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
492 if (raw_armap == NULL) {
493 bfd_error = no_memory;
499 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
500 mapdata->parsed_size) {
501 bfd_error = malformed_archive;
507 /* The coff armap must be read sequentially. So we construct a bsd-style
508 one in core all at once, for simplicity. */
510 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
513 unsigned int nsymz = *raw_armap;
514 unsigned int carsym_size = (nsymz * sizeof (carsym));
515 unsigned int ptrsize = (4 * nsymz);
517 ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
518 if (ardata->symdefs == NULL) {
519 bfd_error = no_memory;
522 carsyms = ardata->symdefs;
524 stringbase = ((char *) ardata->symdefs) + carsym_size;
525 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
528 /* OK, build the carsyms */
529 for (i = 0; i < nsymz; i++)
531 rawptr = raw_armap + i + 1;
532 carsyms->file_offset = *rawptr;
533 carsyms->name = stringbase;
534 for (; *(stringbase++););
539 ardata->symdef_count = *raw_armap;
540 ardata->first_file_filepos = bfd_tell (abfd);
541 /* Pad to an even boundary if you have to */
542 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
544 bfd_has_map (abfd) = true;
549 /** Extended name table.
551 Normally archives support only 14-character filenames. Intel has extended
552 the format: longer names are stored in a special element (the first in the
553 archive, or second if there is an armap); the name in the ar_hdr is replaced
554 by <space><index into filename element>. Index is the P.R. of an int (radix:
557 /* Returns false on error, true otherwise */
559 _bfd_slurp_extended_name_table (abfd)
563 struct areltdata *namedata;
565 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
567 bfd_seek (abfd, -16L, SEEK_CUR);
569 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
570 bfd_ardata (abfd)->extended_names = NULL;
574 namedata = snarf_ar_hdr (abfd);
575 if (namedata == NULL) return false;
578 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
579 if (bfd_ardata (abfd)->extended_names == NULL) {
580 bfd_error = no_memory;
586 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
587 namedata->parsed_size, abfd) != namedata->parsed_size) {
588 bfd_error = malformed_archive;
590 bfd_ardata (abfd)->extended_names = NULL;
594 /* It appears that the extended names are newline-padded, not null padded.
597 char *temp = bfd_ardata (abfd)->extended_names;
598 for (; *temp != '\0'; ++temp)
599 if (*temp == '\n') *temp = '\0';
602 /* Pad to an even boundary if you have to */
603 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
604 bfd_ardata (abfd)->first_file_filepos +=
605 (bfd_ardata (abfd)->first_file_filepos) %2;
613 char *normalize(file)
616 char * filename = strrchr(file, '/');
617 if (filename != (char *)NULL) {
626 /* Follows archive_head and produces an extended name table if necessary.
627 Returns (in tabloc) a pointer to an extended name table, and in tablen
628 the length of the table. If it makes an entry it clobbers the filename
629 so that the element may be written without further massage.
630 Returns true if it ran successfully, false if something went wrong.
631 A successful return may still involve a zero-length tablen!
634 bfd_construct_extended_name_table (abfd, tabloc, tablen)
637 unsigned int *tablen;
639 unsigned int maxname = abfd->xvec->ar_max_namelen;
640 unsigned int total_namelen = 0;
646 /* Figure out how long the table should be */
647 for (current = abfd->archive_head; current != NULL; current = current->next){
648 unsigned int thislen = strlen (normalize(current->filename));
649 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
652 if (total_namelen == 0) return true;
654 *tabloc = bfd_zalloc (abfd,total_namelen);
655 if (*tabloc == NULL) {
656 bfd_error = no_memory;
660 *tablen = total_namelen;
663 for (current = abfd->archive_head; current != NULL; current =
665 char *normal =normalize( current->filename);
666 unsigned int thislen = strlen (normal);
667 if (thislen > maxname) {
668 /* Works for now; may need to be re-engineered if we encounter an oddball
669 archive format and want to generalise this hack. */
670 struct ar_hdr *hdr = arch_hdr(current);
671 strcpy (strptr, normal);
672 strptr[thislen] = '\n';
673 hdr->ar_name[0] = ' ';
674 /* We know there will always be enough room (one of the few cases
675 where you may safely use sprintf). */
676 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
677 /* Kinda Kludgy. We should just use the returned value of sprintf
678 but not all implementations get this right */
680 char *temp = hdr->ar_name +2;
681 for (; temp < hdr->ar_name + maxname; temp++)
682 if (*temp == '\0') *temp = ' ';
684 strptr += thislen + 1;
691 /** A couple of functions for creating ar_hdrs */
693 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
694 The filename must refer to a filename in the filesystem.
695 The filename field of the ar_hdr will NOT be initialized
699 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
701 CONST char *filename)
704 struct areltdata *ared;
709 if (stat (filename, &status) != 0) {
710 bfd_error = system_call_error;
714 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
715 sizeof (struct areltdata));
717 bfd_error = no_memory;
720 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
722 /* ar headers are space padded, not null padded! */
724 temp1 = temp + sizeof (struct ar_hdr) - 2;
725 for (; temp < temp1; *(temp++) = ' ');
726 strncpy (hdr->ar_fmag, ARFMAG, 2);
728 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
729 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
730 sprintf ((hdr->ar_uid), "%d", status.st_uid);
731 sprintf ((hdr->ar_gid), "%d", status.st_gid);
732 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
733 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
734 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
735 understand how these C losers could design such a ramshackle bunch of
738 temp1 = temp + sizeof (struct ar_hdr) - 2;
739 for (; temp < temp1; temp++) {
740 if (*temp == '\0') *temp = ' ';
742 strncpy (hdr->ar_fmag, ARFMAG, 2);
743 ared->parsed_size = status.st_size;
744 ared->arch_header = (char *) hdr;
750 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
755 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
759 /* Analogous to stat call */
761 bfd_generic_stat_arch_elt (abfd, buf)
768 if (abfd->arelt_data == NULL) {
769 bfd_error = invalid_operation;
773 hdr = arch_hdr (abfd);
775 #define foo(arelt, stelt, size) \
776 buf->stelt = strtol (hdr->arelt, &aloser, size); \
777 if (aloser == hdr->arelt) return -1;
779 foo (ar_date, st_mtime, 10);
780 foo (ar_uid, st_uid, 10);
781 foo (ar_gid, st_gid, 10);
782 foo (ar_mode, st_mode, 8);
783 foo (ar_size, st_size, 10);
789 bfd_dont_truncate_arname (abfd, pathname, arhdr)
794 /* This interacts unpleasantly with ar's quick-append option.
795 Fortunately ic960 users will never use that option. Fixing this
796 is very hard; fortunately I know how to do it and will do so once
797 intel's release is out the door. */
799 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
801 char *filename = strrchr (pathname, '/');
802 int maxlen = ar_maxnamelen (abfd);
804 if (filename == NULL)
809 length = strlen (filename);
811 if (length <= maxlen)
812 memcpy (hdr->ar_name, filename, length);
814 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
820 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
825 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
827 char *filename = strrchr (pathname, '/');
828 int maxlen = ar_maxnamelen (abfd);
831 if (filename == NULL)
836 length = strlen (filename);
838 if (length <= maxlen)
839 memcpy (hdr->ar_name, filename, length);
841 /* pathname: meet procrustes */
842 memcpy (hdr->ar_name, filename, maxlen);
846 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
849 /* Store name into ar header. Truncates the name to fit.
850 1> strip pathname to be just the basename.
851 2> if it's short enuf to fit, stuff it in.
852 3> If it doesn't end with .o, truncate it to fit
853 4> truncate it before the .o, append .o, stuff THAT in.
856 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
858 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
863 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
865 char *filename = strrchr (pathname, '/');
866 int maxlen = ar_maxnamelen (abfd);
868 if (filename == NULL)
873 length = strlen (filename);
875 if (length <= maxlen)
876 memcpy (hdr->ar_name, filename, length);
877 else { /* pathname: meet procrustes */
878 memcpy (hdr->ar_name, filename, maxlen);
879 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
880 hdr->ar_name[maxlen - 2] = '.';
881 hdr->ar_name[maxlen - 1] = 'o';
886 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
890 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
892 /* The bfd is open for write and has its format set to bfd_archive */
894 _bfd_write_archive_contents (arch)
899 unsigned int elength = 0;
900 boolean makemap = bfd_has_map (arch);
901 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
905 /* Verify the viability of all entries; if any of them live in the
906 filesystem (as opposed to living in an archive open for input)
907 then construct a fresh ar_hdr for them.
909 for (current = arch->archive_head; current; current = current->next) {
910 if (bfd_write_p (current)) {
911 bfd_error = invalid_operation;
914 if (!current->arelt_data) {
915 current->arelt_data =
916 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
917 if (!current->arelt_data) return false;
919 /* Put in the file name */
921 BFD_SEND (arch, _bfd_truncate_arname,(arch,
923 (char *) arch_hdr(current)));
928 if (makemap) { /* don't bother if we won't make a map! */
929 if ((bfd_check_format (current, bfd_object))
930 #if 0 /* FIXME -- these are not set correctly */
931 && ((bfd_get_file_flags (current) & HAS_SYMS))
938 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
941 bfd_seek (arch, 0, SEEK_SET);
943 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
945 bfd_write (ARMAG, 1, SARMAG, arch);
948 if (makemap && hasobjects) {
950 if (compute_and_write_armap (arch, elength) != true) {
958 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
959 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
960 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
961 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
962 for (i = 0; i < sizeof (struct ar_hdr); i++)
963 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
964 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
965 bfd_write (etable, 1, elength, arch);
966 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
970 for (current = arch->archive_head; current; current = current->next) {
971 char buffer[DEFAULT_BUFFERSIZE];
972 unsigned int remaining = arelt_size (current);
973 struct ar_hdr *hdr = arch_hdr(current);
974 /* write ar header */
976 if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
978 bfd_error = system_call_error;
981 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
984 unsigned int amt = DEFAULT_BUFFERSIZE;
985 if (amt > remaining) {
988 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
989 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
992 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
997 /* Note that the namidx for the first symbol is 0 */
1002 compute_and_write_armap (arch, elength)
1004 unsigned int elength;
1007 file_ptr elt_no = 0;
1009 int orl_max = 15000; /* fine initial default */
1011 int stridx = 0; /* string index */
1013 /* Dunno if this is the best place for this info... */
1014 if (elength != 0) elength += sizeof (struct ar_hdr);
1015 elength += elength %2 ;
1017 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1019 bfd_error = no_memory;
1023 /* Map over each element */
1024 for (current = arch->archive_head;
1025 current != (bfd *)NULL;
1026 current = current->next, elt_no++)
1028 if ((bfd_check_format (current, bfd_object) == true)
1029 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1031 unsigned int storage;
1032 unsigned int symcount;
1033 unsigned int src_count;
1035 storage = get_symtab_upper_bound (current);
1038 syms = (asymbol **) bfd_zalloc (arch,storage);
1040 bfd_error = no_memory; /* FIXME -- memory leak */
1043 symcount = bfd_canonicalize_symtab (current, syms);
1046 /* Now map over all the symbols, picking out the ones we want */
1047 for (src_count = 0; src_count <symcount; src_count++) {
1048 flagword flags = (syms[src_count])->flags;
1049 if ((flags & BSF_GLOBAL) ||
1050 (flags & BSF_FORT_COMM)) {
1052 /* This symbol will go into the archive header */
1053 if (orl_count == orl_max)
1056 map = (struct orl *) bfd_realloc (arch, (char *) map,
1057 orl_max * sizeof (struct orl));
1060 (map[orl_count]).name = &((syms[src_count])->name);
1061 (map[orl_count]).pos = elt_no;
1062 (map[orl_count]).namidx = stridx;
1064 stridx += strlen ((syms[src_count])->name) + 1;
1071 /* OK, now we have collected all the data, let's write them out */
1072 if (!BFD_SEND (arch, write_armap,
1073 (arch, elength, map, orl_count, stridx))) {
1083 /* FIXME -- have to byte-swap this */
1086 bsd_write_armap (arch, elength, map, orl_count, stridx)
1088 unsigned int elength;
1093 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1094 unsigned int stringsize = stridx + 4;
1095 unsigned int mapsize = stringsize + ranlibsize;
1097 bfd *current = arch->archive_head;
1098 int last_eltno = 0; /* last element arch seen */
1102 struct stat statbuf;
1104 int padit = mapsize & 1;
1106 if (padit) mapsize ++;
1108 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1110 stat (arch->filename, &statbuf);
1111 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1112 sprintf (hdr.ar_name, RANLIBMAG);
1113 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1114 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1115 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1116 for (i = 0; i < sizeof (struct ar_hdr); i++)
1117 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1118 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1120 temp = orl_count /* + 4 */;
1121 bfd_write (&temp, 1, sizeof (temp), arch);
1123 for (count = 0; count < orl_count; count++) {
1125 struct symdef *outp = &outs;
1127 if ((map[count]).pos != last_eltno) {
1128 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1129 firstreal += firstreal % 2;
1130 last_eltno = (map[count]).pos;
1131 current = current->next;
1134 outs.s.string_offset = ((map[count]).namidx) +4;
1135 outs.file_offset = firstreal;
1136 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1139 /* now write the strings themselves */
1141 bfd_write (&temp, 1, sizeof (temp), arch);
1142 for (count = 0; count < orl_count; count++)
1143 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1145 /* The spec sez this should be a newline. But in order to be
1146 bug-compatible for sun's ar we use a null. */
1148 bfd_write("\0",1,1,arch);
1154 /* A coff armap looks like :
1156 struct ar_hdr with name = '/'
1158 offset of file for symbol 0
1159 offset of file for symbol 1
1161 offset of file for symbol n-1
1170 coff_write_armap (arch, elength, map, orl_count, stridx)
1172 unsigned int elength;
1177 unsigned int ranlibsize = (orl_count * 4) + 4;
1178 unsigned int stringsize = stridx;
1179 unsigned int mapsize = stringsize + ranlibsize;
1180 file_ptr archive_member_file_ptr;
1181 bfd *current = arch->archive_head;
1182 int last_eltno = 0; /* last element arch seen */
1186 int padit = mapsize & 1;
1188 if (padit) mapsize ++;
1190 archive_member_file_ptr =
1191 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1193 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1194 hdr.ar_name[0] = '/';
1195 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1196 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1197 /* This, at least, is what Intel coff sets the values to.: */
1198 sprintf ((hdr.ar_uid), "%d", 0);
1199 sprintf ((hdr.ar_gid), "%d", 0);
1200 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1201 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1203 for (i = 0; i < sizeof (struct ar_hdr); i++)
1204 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1206 /* Write the ar header for this item and the number of symbols */
1208 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1209 bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1211 /* Two passes, first write the file offsets for each symbol -
1212 remembering that each offset is on a two byte boundary
1215 for (count = 0; count < orl_count; count++) {
1216 while ((map[count]).pos != last_eltno) {
1217 /* If this is the first time we've seen a ref to this archive
1218 then remember it's size */
1219 archive_member_file_ptr +=
1220 arelt_size (current) + sizeof (struct ar_hdr);
1221 archive_member_file_ptr += archive_member_file_ptr % 2;
1222 current = current->next;
1225 bfd_write (&archive_member_file_ptr,
1227 sizeof (archive_member_file_ptr),
1231 /* now write the strings themselves */
1232 for (count = 0; count < orl_count; count++) {
1233 bfd_write (*((map[count]).name),
1235 strlen (*((map[count]).name))+1, arch);
1238 /* The spec sez this should be a newline. But in order to be
1239 bug-compatible for arc960 we use a null. */
1241 bfd_write("\0",1,1,arch);