1 /*** archive.c -- an attempt at combining the machine-independent parts of
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Diddler.
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 o - all archive elements start on an even boundary, newline padded;
25 o - all arch headers are char *;
26 o - all arch headers are the same size (across architectures).
40 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
43 /* We keep a cache of archive filepointers to archive elements to
44 speed up searching the archive by filepos. We only add an entry to
45 the cache when we actually read one. We also don't sort the cache;
46 it's short enough to search linearly.
47 Note that the pointers here point to the front of the ar_hdr, not
48 to the front of the contents!
53 struct ar_cache *next;
56 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
57 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
59 #define arch_hdr(bfd) ((struct ar_hdr *) \
60 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
65 _bfd_generic_mkarchive (abfd)
68 abfd->tdata = bfd_zalloc(abfd, sizeof (struct artdata));
70 if (abfd->tdata == NULL) {
71 bfd_error = no_memory;
74 bfd_ardata(abfd)->cache = 0;
79 bfd_get_next_mapent (abfd, prev, entry)
84 if (!bfd_has_map (abfd)) {
85 bfd_error = invalid_operation;
86 return BFD_NO_MORE_SYMBOLS;
89 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
90 else if (++prev >= (symindex)(bfd_ardata (abfd)->symdef_count))
91 return BFD_NO_MORE_SYMBOLS;
93 *entry = (bfd_ardata (abfd)->symdefs + prev);
98 /* To be called by backends only */
100 _bfd_create_empty_archive_element_shell (obfd)
105 nbfd = new_bfd_contained_in(obfd);
107 bfd_error = no_memory;
114 bfd_set_archive_head (output_archive, new_head)
115 bfd *output_archive, *new_head;
118 output_archive->archive_head = new_head;
123 look_for_bfd_in_cache (arch_bfd, filepos)
127 struct ar_cache *current;
129 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
130 current = current->next)
131 if (current->ptr == filepos) return current->arelt;
136 /* Kind of stupid to call cons for each one, but we don't do too many */
138 add_bfd_to_cache (arch_bfd, filepos, new_elt)
139 bfd *arch_bfd, *new_elt;
142 struct ar_cache *new_cache = ((struct ar_cache *)bfd_zalloc(arch_bfd,sizeof (struct ar_cache)));
144 if (new_cache == NULL) {
145 bfd_error = no_memory;
149 new_cache->ptr = filepos;
150 new_cache->arelt = new_elt;
151 new_cache->next = (struct ar_cache *)NULL;
152 if (bfd_ardata (arch_bfd)->cache == NULL)
153 bfd_ardata (arch_bfd)->cache = new_cache;
155 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
157 for (; current->next != NULL; current = current->next);
158 current->next = new_cache;
166 /* The name begins with space. Hence the rest of the name is an index into
170 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.
204 char *hdrp = (char *) &hdr;
205 unsigned int parsed_size;
206 struct areltdata *ared;
207 char *filename = NULL;
208 unsigned int namelen = 0;
209 unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
212 if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
213 != sizeof (struct ar_hdr)) {
214 bfd_error = no_more_archived_files;
217 if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
218 bfd_error = malformed_archive;
223 parsed_size = strtol (hdr.ar_size, NULL, 10);
225 bfd_error = malformed_archive;
229 /* extract the filename from the archive */
230 if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
231 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
232 if (filename == NULL) {
233 bfd_error = malformed_archive;
239 /* We judge the end of the name by looking for a space or a
244 while (namelen < (unsigned)ar_maxnamelen(abfd) &&
245 ( hdr.ar_name[namelen] != 0 &&
246 hdr.ar_name[namelen] != ' ' &&
247 hdr.ar_name[namelen] != ar_padchar(abfd))) {
251 allocsize += namelen + 1;
254 allocptr = bfd_zalloc(abfd, allocsize);
255 if (allocptr == NULL) {
256 bfd_error = no_memory;
260 ared = (struct areltdata *) allocptr;
262 ared->arch_header = allocptr + sizeof (struct areltdata);
263 memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
264 ared->parsed_size = parsed_size;
266 if (filename != NULL) ared->filename = filename;
268 ared->filename = allocptr + (sizeof (struct areltdata) +
269 sizeof (struct ar_hdr));
271 memcpy (ared->filename, hdr.ar_name, namelen);
272 ared->filename[namelen] = '\0';
279 get_elt_at_filepos (archive, filepos)
283 struct areltdata *new_areldata;
286 n_nfd = look_for_bfd_in_cache (archive, filepos);
287 if (n_nfd) return n_nfd;
289 if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
290 bfd_error = system_call_error;
294 if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
296 n_nfd = _bfd_create_empty_archive_element_shell (archive);
300 n_nfd->origin = bfd_tell (archive);
301 n_nfd->arelt_data = (PTR) new_areldata;
302 n_nfd->filename = new_areldata->filename;
304 if (add_bfd_to_cache (archive, filepos, n_nfd))
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 filestart = last_file->origin +size + size %2;
357 return get_elt_at_filepos (archive, filestart);
362 bfd_generic_archive_p (abfd)
365 char armag[SARMAG+1];
367 if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
368 bfd_error = wrong_format;
373 if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
375 if (strncmp (armag, ARMAG, SARMAG)) return 0;
378 bfd_set_ardata(abfd, (struct artdata *) bfd_zalloc(abfd,sizeof (struct artdata)));
380 if (bfd_ardata (abfd) == NULL) {
381 bfd_error = no_memory;
385 bfd_ardata (abfd)->first_file_filepos = SARMAG;
387 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
388 bfd_release(abfd, bfd_ardata (abfd));
393 /* armap could be left ungc'd! FIXME -- potential storage leak */
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 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
416 /* The archive has at least 16 bytes in it */
417 bfd_seek (abfd, -16L, SEEK_CUR);
419 if (strncmp (nextname, "__.SYMDEF ", 16)) {
420 bfd_has_map (abfd) = false;
424 mapdata = snarf_ar_hdr (abfd);
425 if (mapdata == NULL) return false;
427 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
428 if (raw_armap == NULL) {
429 bfd_error = no_memory;
434 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
435 mapdata->parsed_size) {
436 bfd_error = malformed_archive;
440 ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
443 ardata->symdefs = (carsym *) rbase;
444 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
446 for (;counter < (unsigned)( ardata->symdef_count); counter++) {
447 struct symdef *sym = ((struct symdef *) rbase) + counter;
448 sym->s.name = sym->s.string_offset + stringbase;
451 ardata->first_file_filepos = bfd_tell (abfd);
452 /* Pad to an even boundary if you have to */
453 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
454 bfd_has_map (abfd) = true;
459 /* Returns false on error, true otherwise */
461 bfd_slurp_coff_armap (abfd)
464 struct areltdata *mapdata;
466 int *raw_armap, *rawptr;
467 struct artdata *ardata = bfd_ardata (abfd);
469 unsigned int stringsize;
472 if (bfd_read ((PTR)&nextname, 1, 1, abfd) != 1) {
473 bfd_seek (abfd, -1L, SEEK_CUR);
474 bfd_has_map(abfd) = false;
477 bfd_seek (abfd, -1L, SEEK_CUR);
479 if (nextname != '/') {
480 /* Actually I think this is an error for a COFF archive */
481 bfd_has_map (abfd) = false;
485 mapdata = snarf_ar_hdr (abfd);
486 if (mapdata == NULL) return false;
488 raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
489 if (raw_armap == NULL) {
490 bfd_error = no_memory;
496 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
497 mapdata->parsed_size) {
498 bfd_error = malformed_archive;
504 /* The coff armap must be read sequentially. So we construct a bsd-style
505 one in core all at once, for simplicity. */
507 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
510 unsigned int nsymz = *raw_armap;
511 unsigned int carsym_size = (nsymz * sizeof (carsym));
512 unsigned int ptrsize = (4 * nsymz);
514 ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
515 if (ardata->symdefs == NULL) {
516 bfd_error = no_memory;
519 carsyms = ardata->symdefs;
521 stringbase = ((char *) ardata->symdefs) + carsym_size;
522 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
525 /* OK, build the carsyms */
526 for (i = 0; i < nsymz; i++)
528 rawptr = raw_armap + i + 1;
529 carsyms->file_offset = *rawptr;
530 carsyms->name = stringbase;
531 for (; *(stringbase++););
536 ardata->symdef_count = *raw_armap;
537 ardata->first_file_filepos = bfd_tell (abfd);
538 /* Pad to an even boundary if you have to */
539 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
541 bfd_has_map (abfd) = true;
546 /** Extended name table.
548 Normally archives support only 14-character filenames. Intel has extended
549 the format: longer names are stored in a special element (the first in the
550 archive, or second if there is an armap); the name in the ar_hdr is replaced
551 by <space><index into filename element>. Index is the P.R. of an int (radix:
554 /* Returns false on error, true otherwise */
556 _bfd_slurp_extended_name_table (abfd)
560 struct areltdata *namedata;
562 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
564 bfd_seek (abfd, -16L, SEEK_CUR);
566 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
567 bfd_ardata (abfd)->extended_names = NULL;
571 namedata = snarf_ar_hdr (abfd);
572 if (namedata == NULL) return false;
575 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
576 if (bfd_ardata (abfd)->extended_names == NULL) {
577 bfd_error = no_memory;
583 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
584 namedata->parsed_size, abfd) != namedata->parsed_size) {
585 bfd_error = malformed_archive;
587 bfd_ardata (abfd)->extended_names = NULL;
591 /* It appears that the extended names are newline-padded, not null padded.
594 char *temp = bfd_ardata (abfd)->extended_names;
595 for (; *temp != '\0'; ++temp)
596 if (*temp == '\n') *temp = '\0';
599 /* Pad to an even boundary if you have to */
600 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
601 bfd_ardata (abfd)->first_file_filepos +=
602 (bfd_ardata (abfd)->first_file_filepos) %2;
610 char *normalize(file)
613 char * filename = strrchr(file, '/');
614 if (filename != (char *)NULL) {
623 /* Follows archive_head and produces an extended name table if necessary.
624 Returns (in tabloc) a pointer to an extended name table, and in tablen
625 the length of the table. If it makes an entry it clobbers the filename
626 so that the element may be written without further massage.
627 Returns true if it ran successfully, false if something went wrong.
628 A successful return may still involve a zero-length tablen!
631 bfd_construct_extended_name_table (abfd, tabloc, tablen)
634 unsigned int *tablen;
636 unsigned int maxname = abfd->xvec->ar_max_namelen;
637 unsigned int total_namelen = 0;
643 /* Figure out how long the table should be */
644 for (current = abfd->archive_head; current != NULL; current = current->next){
645 unsigned int thislen = strlen (normalize(current->filename));
646 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
649 if (total_namelen == 0) return true;
651 *tabloc = bfd_zalloc (abfd,total_namelen);
652 if (*tabloc == NULL) {
653 bfd_error = no_memory;
657 *tablen = total_namelen;
660 for (current = abfd->archive_head; current != NULL; current =
662 char *normal =normalize( current->filename);
663 unsigned int thislen = strlen (normal);
664 if (thislen > maxname) {
665 /* Works for now; may need to be re-engineered if we encounter an oddball
666 archive format and want to generalise this hack. */
667 struct ar_hdr *hdr = arch_hdr(current);
668 strcpy (strptr, normal);
669 strptr[thislen] = '\n';
670 hdr->ar_name[0] = ' ';
671 /* We know there will always be enough room (one of the few cases
672 where you may safely use sprintf). */
673 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
674 /* Kinda Kludgy. We should just use the returned value of sprintf
675 but not all implementations get this right */
677 char *temp = hdr->ar_name +2;
678 for (; temp < hdr->ar_name + maxname; temp++)
679 if (*temp == '\0') *temp = ' ';
681 strptr += thislen + 1;
688 /** A couple of functions for creating ar_hdrs */
690 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
691 The filename must refer to a filename in the filesystem.
692 The filename field of the ar_hdr will NOT be initialized
696 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
698 CONST char *filename)
701 struct areltdata *ared;
706 if (stat (filename, &status) != 0) {
707 bfd_error = system_call_error;
711 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
712 sizeof (struct areltdata));
714 bfd_error = no_memory;
717 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
719 /* ar headers are space padded, not null padded! */
721 temp1 = temp + sizeof (struct ar_hdr) - 2;
722 for (; temp < temp1; *(temp++) = ' ');
723 strncpy (hdr->ar_fmag, ARFMAG, 2);
725 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
726 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
727 sprintf ((hdr->ar_uid), "%d", status.st_uid);
728 sprintf ((hdr->ar_gid), "%d", status.st_gid);
729 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
730 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
731 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
732 understand how these C losers could design such a ramshackle bunch of
735 temp1 = temp + sizeof (struct ar_hdr) - 2;
736 for (; temp < temp1; temp++) {
737 if (*temp == '\0') *temp = ' ';
739 strncpy (hdr->ar_fmag, ARFMAG, 2);
740 ared->parsed_size = status.st_size;
741 ared->arch_header = (char *) hdr;
747 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
752 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
756 /* Analogous to stat call */
758 bfd_generic_stat_arch_elt (abfd, buf)
765 if (abfd->arelt_data == NULL) {
766 bfd_error = invalid_operation;
770 hdr = arch_hdr (abfd);
772 #define foo(arelt, stelt, size) \
773 buf->stelt = strtol (hdr->arelt, &aloser, size); \
774 if (aloser == hdr->arelt) return -1;
776 foo (ar_date, st_mtime, 10);
777 foo (ar_uid, st_uid, 10);
778 foo (ar_gid, st_gid, 10);
779 foo (ar_mode, st_mode, 8);
780 foo (ar_size, st_size, 10);
786 bfd_dont_truncate_arname (abfd, pathname, arhdr)
791 /* This interacts unpleasantly with ar's quick-append option.
792 Fortunately ic960 users will never use that option. Fixing this
793 is very hard; fortunately I know how to do it and will do so once
794 intel's release is out the door. */
796 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
798 char *filename = strrchr (pathname, '/');
799 int maxlen = ar_maxnamelen (abfd);
801 if (filename == NULL)
806 length = strlen (filename);
808 if (length <= maxlen)
809 memcpy (hdr->ar_name, filename, length);
811 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
817 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
822 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
824 char *filename = strrchr (pathname, '/');
825 int maxlen = ar_maxnamelen (abfd);
828 if (filename == NULL)
833 length = strlen (filename);
835 if (length <= maxlen)
836 memcpy (hdr->ar_name, filename, length);
838 /* pathname: meet procrustes */
839 memcpy (hdr->ar_name, filename, maxlen);
843 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
846 /* Store name into ar header. Truncates the name to fit.
847 1> strip pathname to be just the basename.
848 2> if it's short enuf to fit, stuff it in.
849 3> If it doesn't end with .o, truncate it to fit
850 4> truncate it before the .o, append .o, stuff THAT in.
853 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
855 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
860 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
862 char *filename = strrchr (pathname, '/');
863 int maxlen = ar_maxnamelen (abfd);
865 if (filename == NULL)
870 length = strlen (filename);
872 if (length <= maxlen)
873 memcpy (hdr->ar_name, filename, length);
874 else { /* pathname: meet procrustes */
875 memcpy (hdr->ar_name, filename, maxlen);
876 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
877 hdr->ar_name[maxlen - 2] = '.';
878 hdr->ar_name[maxlen - 1] = 'o';
883 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
887 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
889 /* The bfd is open for write and has its format set to bfd_archive */
891 _bfd_write_archive_contents (arch)
896 unsigned int elength = 0;
897 boolean makemap = bfd_has_map (arch);
898 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
902 /* Verify the viability of all entries; if any of them live in the
903 filesystem (as opposed to living in an archive open for input)
904 then construct a fresh ar_hdr for them.
906 for (current = arch->archive_head; current; current = current->next) {
907 if (bfd_write_p (current)) {
908 bfd_error = invalid_operation;
911 if (!current->arelt_data) {
912 current->arelt_data =
913 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
914 if (!current->arelt_data) return false;
916 /* Put in the file name */
918 BFD_SEND (arch, _bfd_truncate_arname,(arch,
920 (char *) arch_hdr(current)));
925 if (makemap) { /* don't bother if we won't make a map! */
926 if ((bfd_check_format (current, bfd_object))
927 #if 0 /* FIXME -- these are not set correctly */
928 && ((bfd_get_file_flags (current) & HAS_SYMS))
935 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
938 bfd_seek (arch, 0, SEEK_SET);
940 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
942 bfd_write (ARMAG, 1, SARMAG, arch);
945 if (makemap && hasobjects) {
947 if (compute_and_write_armap (arch, elength) != true) {
955 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
956 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
957 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
958 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
959 for (i = 0; i < sizeof (struct ar_hdr); i++)
960 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
961 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
962 bfd_write (etable, 1, elength, arch);
963 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
967 for (current = arch->archive_head; current; current = current->next) {
968 char buffer[DEFAULT_BUFFERSIZE];
969 unsigned int remaining = arelt_size (current);
970 struct ar_hdr *hdr = arch_hdr(current);
971 /* write ar header */
973 if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
975 bfd_error = system_call_error;
978 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
981 unsigned int amt = DEFAULT_BUFFERSIZE;
982 if (amt > remaining) {
985 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
986 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
989 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
994 /* Note that the namidx for the first symbol is 0 */
999 compute_and_write_armap (arch, elength)
1001 unsigned int elength;
1004 file_ptr elt_no = 0;
1006 int orl_max = 15000; /* fine initial default */
1008 int stridx = 0; /* string index */
1010 /* Dunno if this is the best place for this info... */
1011 if (elength != 0) elength += sizeof (struct ar_hdr);
1012 elength += elength %2 ;
1014 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1016 bfd_error = no_memory;
1020 /* Map over each element */
1021 for (current = arch->archive_head;
1022 current != (bfd *)NULL;
1023 current = current->next, elt_no++)
1025 if ((bfd_check_format (current, bfd_object) == true)
1026 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1028 unsigned int storage;
1029 unsigned int symcount;
1030 unsigned int src_count;
1032 storage = get_symtab_upper_bound (current);
1035 syms = (asymbol **) bfd_zalloc (arch,storage);
1037 bfd_error = no_memory; /* FIXME -- memory leak */
1040 symcount = bfd_canonicalize_symtab (current, syms);
1043 /* Now map over all the symbols, picking out the ones we want */
1044 for (src_count = 0; src_count <symcount; src_count++) {
1045 flagword flags = (syms[src_count])->flags;
1046 if ((flags & BSF_GLOBAL) ||
1047 (flags & BSF_FORT_COMM)) {
1049 /* This symbol will go into the archive header */
1050 if (orl_count == orl_max)
1053 map = (struct orl *) bfd_realloc (arch, (char *) map,
1054 orl_max * sizeof (struct orl));
1057 (map[orl_count]).name = &((syms[src_count])->name);
1058 (map[orl_count]).pos = elt_no;
1059 (map[orl_count]).namidx = stridx;
1061 stridx += strlen ((syms[src_count])->name) + 1;
1068 /* OK, now we have collected all the data, let's write them out */
1069 if (!BFD_SEND (arch, write_armap,
1070 (arch, elength, map, orl_count, stridx))) {
1080 /* FIXME -- have to byte-swap this */
1083 bsd_write_armap (arch, elength, map, orl_count, stridx)
1085 unsigned int elength;
1090 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1091 unsigned int stringsize = stridx + 4;
1092 unsigned int mapsize = stringsize + ranlibsize;
1094 bfd *current = arch->archive_head;
1095 int last_eltno = 0; /* last element arch seen */
1099 struct stat statbuf;
1101 int padit = mapsize & 1;
1103 if (padit) mapsize ++;
1105 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1107 stat (arch->filename, &statbuf);
1108 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1109 sprintf (hdr.ar_name, "__.SYMDEF");
1110 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1111 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1112 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1113 for (i = 0; i < sizeof (struct ar_hdr); i++)
1114 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1115 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1117 temp = orl_count /* + 4 */;
1118 bfd_write (&temp, 1, sizeof (temp), arch);
1120 for (count = 0; count < orl_count; count++) {
1122 struct symdef *outp = &outs;
1124 if ((map[count]).pos != last_eltno) {
1125 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1126 firstreal += firstreal % 2;
1127 last_eltno = (map[count]).pos;
1128 current = current->next;
1131 outs.s.string_offset = ((map[count]).namidx) +4;
1132 outs.file_offset = firstreal;
1133 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1136 /* now write the strings themselves */
1138 bfd_write (&temp, 1, sizeof (temp), arch);
1139 for (count = 0; count < orl_count; count++)
1140 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1142 /* The spec sez this should be a newline. But in order to be
1143 bug-compatible for sun's ar we use a null. */
1145 bfd_write("\0",1,1,arch);
1151 /* A coff armap looks like :
1153 struct ar_hdr with name = '/'
1155 offset of file for symbol 0
1156 offset of file for symbol 1
1158 offset of file for symbol n-1
1167 coff_write_armap (arch, elength, map, orl_count, stridx)
1169 unsigned int elength;
1174 unsigned int ranlibsize = (orl_count * 4) + 4;
1175 unsigned int stringsize = stridx;
1176 unsigned int mapsize = stringsize + ranlibsize;
1177 file_ptr archive_member_file_ptr;
1178 bfd *current = arch->archive_head;
1179 int last_eltno = 0; /* last element arch seen */
1183 int padit = mapsize & 1;
1185 if (padit) mapsize ++;
1187 archive_member_file_ptr =
1188 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1190 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1191 hdr.ar_name[0] = '/';
1192 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1193 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1194 /* This, at least, is what Intel coff sets the values to.: */
1195 sprintf ((hdr.ar_uid), "%d", 0);
1196 sprintf ((hdr.ar_gid), "%d", 0);
1197 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1198 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1200 for (i = 0; i < sizeof (struct ar_hdr); i++)
1201 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1203 /* Write the ar header for this item and the number of symbols */
1205 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1206 bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1208 /* Two passes, first write the file offsets for each symbol -
1209 remembering that each offset is on a two byte boundary
1212 for (count = 0; count < orl_count; count++) {
1213 while ((map[count]).pos != last_eltno) {
1214 /* If this is the first time we've seen a ref to this archive
1215 then remember it's size */
1216 archive_member_file_ptr +=
1217 arelt_size (current) + sizeof (struct ar_hdr);
1218 archive_member_file_ptr += archive_member_file_ptr % 2;
1219 current = current->next;
1222 bfd_write (&archive_member_file_ptr,
1224 sizeof (archive_member_file_ptr),
1228 /* now write the strings themselves */
1229 for (count = 0; count < orl_count; count++) {
1230 bfd_write (*((map[count]).name),
1232 strlen (*((map[count]).name))+1, arch);
1235 /* The spec sez this should be a newline. But in order to be
1236 bug-compatible for arc960 we use a null. */
1238 bfd_write("\0",1,1,arch);