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).
31 * Revision 1.1 1991/03/21 21:10:42 gumby
34 * Revision 1.3 1991/03/16 05:55:25 rich
37 * Revision 1.2 1991/03/15 18:15:50 rich
38 * *** empty log message ***
40 * Revision 1.7 1991/03/08 04:18:02 rich
41 * *** empty log message ***
43 * Revision 1.6 1991/03/07 21:55:31 sac
44 * Added primitive file caching, a file open only for input and
45 * less than BFD_INCORE_FILE_SIZE will be malloced and read in
48 * Revision 1.5 1991/03/05 16:31:12 sac
60 /* We keep a cache of archive filepointers to archive elements to
61 speed up searching the archive by filepos. We only add an entry to
62 the cache when we actually read one. We also don't sort the cache;
63 it's short enough to search linearly.
64 Note that the pointers here point to the front of the ar_hdr, not
65 to the front of the contents!
70 struct ar_cache *next;
73 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
74 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
76 #define arch_hdr(bfd) ((struct ar_hdr *) \
77 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
82 _bfd_generic_mkarchive (abfd)
85 abfd->tdata =(void *) zalloc (sizeof (struct artdata));
87 if (abfd->tdata == NULL) {
88 bfd_error = no_memory;
91 bfd_ardata(abfd)->cache = 0;
96 bfd_get_next_mapent (abfd, prev, entry)
101 if (!bfd_has_map (abfd)) {
102 bfd_error = invalid_operation;
103 return BFD_NO_MORE_SYMBOLS;
106 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
107 else if (++prev >= (symindex)(bfd_ardata (abfd)->symdef_count))
108 return BFD_NO_MORE_SYMBOLS;
110 *entry = (bfd_ardata (abfd)->symdefs + prev);
115 /* To be called by backends only */
117 _bfd_create_empty_archive_element_shell (obfd)
122 nbfd = new_bfd_contained_in(obfd);
124 bfd_error = no_memory;
131 bfd_set_archive_head (output_archive, new_head)
132 bfd *output_archive, *new_head;
135 output_archive->archive_head = new_head;
140 look_for_bfd_in_cache (arch_bfd, filepos)
144 struct ar_cache *current;
146 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
147 current = current->next)
148 if (current->ptr == filepos) return current->arelt;
153 /* Kind of stupid to call cons for each one, but we don't do too many */
155 add_bfd_to_cache (arch_bfd, filepos, new_elt)
156 bfd *arch_bfd, *new_elt;
159 struct ar_cache *new_cache = ((struct ar_cache *)
160 zalloc (sizeof (struct ar_cache)));
162 if (new_cache == NULL) {
163 bfd_error = no_memory;
167 new_cache->ptr = filepos;
168 new_cache->arelt = new_elt;
169 new_cache->next = (struct ar_cache *)NULL;
170 if (bfd_ardata (arch_bfd)->cache == NULL)
171 bfd_ardata (arch_bfd)->cache = new_cache;
173 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
175 for (; current->next != NULL; current = current->next);
176 current->next = new_cache;
184 /* The name begins with space. Hence the rest of the name is an index into
188 get_extended_arelt_filename (arch, name)
193 unsigned long index = 0;
195 /* Should extract string so that I can guarantee not to overflow into
196 the next region, but I"m too lazy. */
198 index = strtol (name, NULL, 10);
200 bfd_error = malformed_archive;
204 return bfd_ardata (arch)->extended_names + index;
207 /* This functions reads an arch header and returns an areltdata pointer, or
210 Presumes the file pointer is already in the right place (ie pointing
211 to the ar_hdr in the file). Moves the file pointer; on success it
212 should be pointing to the front of the file contents; on failure it
213 could have been moved arbitrarily.
222 char *hdrp = (char *) &hdr;
223 unsigned int parsed_size;
224 struct areltdata *ared;
225 char *filename = NULL;
226 unsigned int namelen = 0;
227 unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
230 if (bfd_read ((void *)hdrp, 1, sizeof (struct ar_hdr), abfd)
231 != sizeof (struct ar_hdr)) {
232 bfd_error = no_more_archived_files;
235 if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
236 bfd_error = malformed_archive;
241 parsed_size = strtol (hdr.ar_size, NULL, 10);
243 bfd_error = malformed_archive;
247 /* extract the filename from the archive */
248 if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
249 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
250 if (filename == NULL) {
251 bfd_error = malformed_archive;
257 /* We judge the end of the name by looking for a space or a
262 while (namelen < ar_maxnamelen(abfd) &&
263 ( hdr.ar_name[namelen] != 0 &&
264 hdr.ar_name[namelen] != ' ' &&
265 hdr.ar_name[namelen] != ar_padchar(abfd))) {
269 allocsize += namelen + 1;
272 allocptr = zalloc (allocsize);
273 if (allocptr == NULL) {
274 bfd_error = no_memory;
278 ared = (struct areltdata *) allocptr;
280 ared->arch_header = allocptr + sizeof (struct areltdata);
281 memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
282 ared->parsed_size = parsed_size;
284 if (filename != NULL) ared->filename = filename;
286 ared->filename = allocptr + (sizeof (struct areltdata) +
287 sizeof (struct ar_hdr));
289 memcpy (ared->filename, hdr.ar_name, namelen);
290 ared->filename[namelen] = '\0';
297 get_elt_at_filepos (archive, filepos)
301 struct areltdata *new_areldata;
304 n_nfd = look_for_bfd_in_cache (archive, filepos);
305 if (n_nfd) return n_nfd;
307 if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
308 bfd_error = system_call_error;
312 if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
314 n_nfd = _bfd_create_empty_archive_element_shell (archive);
319 n_nfd->origin = bfd_tell (archive);
320 n_nfd->arelt_data = (void *) new_areldata;
321 n_nfd->filename = new_areldata->filename;
323 if (add_bfd_to_cache (archive, filepos, n_nfd))
333 bfd_get_elt_at_index (abfd, index)
339 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
343 /* If you've got an archive, call this to read each subfile. */
345 bfd_openr_next_archived_file (archive, last_file)
346 bfd *archive, *last_file;
349 if ((bfd_get_format (archive) != bfd_archive) ||
350 (archive->direction == write_direction)) {
351 bfd_error = invalid_operation;
356 return BFD_SEND (archive,
357 openr_next_archived_file,
363 bfd *bfd_generic_openr_next_archived_file(archive, last_file)
370 filestart = bfd_ardata (archive)->first_file_filepos;
372 unsigned int size = arelt_size(last_file);
373 filestart = last_file->origin +size + size %2;
378 return get_elt_at_filepos (archive, filestart);
383 bfd_generic_archive_p (abfd)
386 char armag[SARMAG+1];
388 if (bfd_read ((void *)armag, 1, SARMAG, abfd) != SARMAG) {
389 bfd_error = wrong_format;
393 if (strncmp (armag, ARMAG, SARMAG)) return 0;
395 bfd_set_ardata(abfd, (struct artdata *) zalloc (sizeof (struct artdata)));
397 if (bfd_ardata (abfd) == NULL) {
398 bfd_error = no_memory;
402 bfd_ardata (abfd)->first_file_filepos = SARMAG;
404 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
405 free (bfd_ardata (abfd));
410 /* armap could be left ungc'd! FIXME -- potential storage leak */
411 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
412 free (bfd_ardata (abfd));
420 /* Returns false on error, true otherwise */
422 bfd_slurp_bsd_armap (abfd)
425 struct areltdata *mapdata;
427 unsigned int counter = 0;
428 int *raw_armap, *rbase;
429 struct artdata *ardata = bfd_ardata (abfd);
432 if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
433 /* The archive has at least 16 bytes in it */
434 bfd_seek (abfd, -16L, SEEK_CUR);
436 if (strncmp (nextname, "__.SYMDEF ", 16)) {
437 bfd_has_map (abfd) = false;
441 mapdata = snarf_ar_hdr (abfd);
442 if (mapdata == NULL) return false;
444 raw_armap = (int *) zalloc (mapdata->parsed_size);
445 if (raw_armap == NULL) {
446 bfd_error = no_memory;
452 if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
453 mapdata->parsed_size) {
454 bfd_error = malformed_archive;
459 ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
462 ardata->symdefs = (carsym *) rbase;
463 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
465 for (;counter < (unsigned)( ardata->symdef_count); counter++) {
466 struct symdef *sym = ((struct symdef *) rbase) + counter;
467 sym->s.name = sym->s.string_offset + stringbase;
470 ardata->first_file_filepos = bfd_tell (abfd);
471 /* Pad to an even boundary if you have to */
472 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
474 bfd_has_map (abfd) = true;
479 /* Returns false on error, true otherwise */
481 bfd_slurp_coff_armap (abfd)
484 struct areltdata *mapdata;
486 int *raw_armap, *rawptr;
487 struct artdata *ardata = bfd_ardata (abfd);
489 unsigned int stringsize;
492 if (bfd_read ((void *)&nextname, 1, 1, abfd) != 1) {
493 bfd_has_map(abfd) = false;
497 if (nextname != '/') {
498 /* Actually I think this is an error for a COFF archive */
499 bfd_has_map (abfd) = false;
503 bfd_seek (abfd, -1L, SEEK_CUR);
504 mapdata = snarf_ar_hdr (abfd);
505 if (mapdata == NULL) return false;
507 raw_armap = (int *) zalloc (mapdata->parsed_size);
508 if (raw_armap == NULL) {
509 bfd_error = no_memory;
515 if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
516 mapdata->parsed_size) {
517 bfd_error = malformed_archive;
523 /* The coff armap must be read sequentially. So we construct a bsd-style
524 one in core all at once, for simplicity. */
526 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
529 unsigned int nsymz = *raw_armap;
530 unsigned int carsym_size = (nsymz * sizeof (carsym));
531 unsigned int ptrsize = (4 * nsymz);
533 ardata->symdefs = (carsym *) zalloc (carsym_size + stringsize + 1);
534 if (ardata->symdefs == NULL) {
535 bfd_error = no_memory;
538 carsyms = ardata->symdefs;
540 stringbase = ((char *) ardata->symdefs) + carsym_size;
541 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
544 /* OK, build the carsyms */
545 for (i = 0; i < nsymz; i++)
547 rawptr = raw_armap + i + 1;
548 carsyms->file_offset = *rawptr;
549 carsyms->name = stringbase;
550 for (; *(stringbase++););
555 ardata->symdef_count = *raw_armap;
556 ardata->first_file_filepos = bfd_tell (abfd);
557 /* Pad to an even boundary if you have to */
558 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
561 bfd_has_map (abfd) = true;
566 /** Extended name table.
568 Normally archives support only 14-character filenames. Intel has extended
569 the format: longer names are stored in a special element (the first in the
570 archive, or second if there is an armap); the name in the ar_hdr is replaced
571 by <space><index into filename element>. Index is the P.R. of an int (radix:
574 /* Returns false on error, true otherwise */
576 _bfd_slurp_extended_name_table (abfd)
580 struct areltdata *namedata;
582 if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
584 bfd_seek (abfd, -16L, SEEK_CUR);
586 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
587 bfd_ardata (abfd)->extended_names = NULL;
591 namedata = snarf_ar_hdr (abfd);
592 if (namedata == NULL) return false;
595 bfd_ardata (abfd)->extended_names = zalloc (namedata->parsed_size);
596 if (bfd_ardata (abfd)->extended_names == NULL) {
597 bfd_error = no_memory;
603 if (bfd_read ((void*)bfd_ardata (abfd)->extended_names, 1,
604 namedata->parsed_size, abfd) != namedata->parsed_size) {
605 bfd_error = malformed_archive;
606 free (bfd_ardata (abfd)->extended_names);
607 bfd_ardata (abfd)->extended_names = NULL;
611 /* Pad to an even boundary if you have to */
612 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
613 bfd_ardata (abfd)->first_file_filepos +=
614 (bfd_ardata (abfd)->first_file_filepos) %2;
622 char *normalize(file)
625 char * filename = strrchr(file, '/');
626 if (filename != (char *)NULL) {
635 /* Follows archive_head and produces an extended name table if necessary.
636 Returns (in tabloc) a pointer to an extended name table, and in tablen
637 the length of the table. If it makes an entry it clobbers the filename
638 so that the element may be written without further massage.
639 Returns true if it ran successfully, false if something went wrong.
640 A successful return may still involve a zero-length tablen!
643 bfd_construct_extended_name_table (abfd, tabloc, tablen)
646 unsigned int *tablen;
648 unsigned int maxname = abfd->xvec->ar_max_namelen;
649 unsigned int total_namelen = 0;
655 /* Figure out how long the table should be */
656 for (current = abfd->archive_head; current != NULL; current = current->next){
657 unsigned int thislen = strlen (normalize(current->filename));
658 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \0 */
661 if (total_namelen == 0) return true;
663 *tabloc = zalloc (total_namelen);
664 if (*tabloc == NULL) {
665 bfd_error = no_memory;
669 *tablen = total_namelen;
672 for (current = abfd->archive_head; current != NULL; current =
674 char *normal =normalize( current->filename);
675 unsigned int thislen = strlen (normal);
676 if (thislen > maxname) {
677 strcpy (strptr, normal);
678 current->filename[0] = ' ';
679 /* We know there will always be enough room (one of the few cases
680 where you may safely use sprintf). */
681 sprintf ((current->filename) + 1, "-%o", (unsigned) (strptr - *tabloc));
683 strptr += thislen + 1;
690 /** A couple of functions for creating ar_hdrs */
692 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
693 The filename must refer to a filename in the filesystem.
694 The filename field of the ar_hdr will NOT be initialized
698 bfd_ar_hdr_from_filesystem (filename)
702 struct areltdata *ared;
707 if (stat (filename, &status) != 0) {
708 bfd_error = system_call_error;
712 ared = (struct areltdata *) zalloc (sizeof (struct ar_hdr) +
713 sizeof (struct areltdata));
715 bfd_error = no_memory;
718 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
720 /* ar headers are space padded, not null padded! */
722 temp1 = temp + sizeof (struct ar_hdr) - 2;
723 for (; temp < temp1; *(temp++) = ' ');
724 strncpy (hdr->ar_fmag, ARFMAG, 2);
726 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
727 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
728 sprintf ((hdr->ar_uid), "%d", status.st_uid);
729 sprintf ((hdr->ar_gid), "%d", status.st_gid);
730 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
731 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
732 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
733 understand how these C losers could design such a ramshackle bunch of
736 temp1 = temp + sizeof (struct ar_hdr) - 2;
737 for (; temp < temp1; temp++) {
738 if (*temp == '\0') *temp = ' ';
740 strncpy (hdr->ar_fmag, ARFMAG, 2);
741 ared->parsed_size = status.st_size;
742 ared->arch_header = (char *) hdr;
748 bfd_special_undocumented_glue (filename)
752 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (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);
785 /* Don't do anything -- it'll be taken care of later */
787 bfd_dont_truncate_arname (ignore_abfd, ignore_filename, ignore_arhdr)
789 char *ignore_filename;
792 /* FIXME -- Actually this is incorrect. If the name is short we
793 should insert into the header; only if it is long should we do
796 Anyway, this interacts unpleasantly with ar's quick-append option,
797 for now just be compatible with the old system */
803 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
808 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
810 char *filename = strrchr (pathname, '/');
811 int maxlen = ar_maxnamelen (abfd);
814 if (filename == NULL)
819 length = strlen (filename);
821 if (length <= maxlen)
822 memcpy (hdr->ar_name, filename, length);
824 /* pathname: meet procrustes */
825 memcpy (hdr->ar_name, filename, maxlen);
829 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
832 /* Store name into ar header. Truncates the name to fit.
833 1> strip pathname to be just the basename.
834 2> if it's short enuf to fit, stuff it in.
835 3> If it doesn't end with .o, truncate it to fit
836 4> truncate it before the .o, append .o, stuff THAT in.
839 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
841 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
846 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
848 char *filename = strrchr (pathname, '/');
849 int maxlen = ar_maxnamelen (abfd);
851 if (filename == NULL)
856 length = strlen (filename);
858 if (length <= maxlen)
859 memcpy (hdr->ar_name, filename, length);
860 else { /* pathname: meet procrustes */
861 memcpy (hdr->ar_name, filename, maxlen);
862 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
863 hdr->ar_name[maxlen - 2] = '.';
864 hdr->ar_name[maxlen - 1] = 'o';
869 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
873 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
875 /* The bfd is open for write and has its format set to bfd_archive */
877 _bfd_write_archive_contents (arch)
882 unsigned int elength = 0;
883 boolean makemap = bfd_has_map (arch);
884 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
888 /* Verify the viability of all entries; if any of them live in the
889 filesystem (as opposed to living in an archive open for input)
890 then construct a fresh ar_hdr for them.
892 for (current = arch->archive_head; current; current = current->next) {
893 if (bfd_write_p (current)) {
894 bfd_error = invalid_operation;
897 if (!current->arelt_data) {
898 current->arelt_data =
899 (void *) bfd_ar_hdr_from_filesystem (current->filename);
900 if (!current->arelt_data) return false;
902 /* Put in the file name */
904 BFD_SEND (arch, _bfd_truncate_arname,(arch,
911 if (makemap) { /* don't bother if we won't make a map! */
912 if ((bfd_check_format (current, bfd_object))
913 #if 0 /* FIXME -- these are not set correctly */
914 && ((bfd_get_file_flags (current) & HAS_SYMS))
921 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
924 bfd_seek (arch, 0, SEEK_SET);
925 bfd_write (ARMAG, 1, SARMAG, arch);
927 if (makemap && hasobjects) {
929 if (compute_and_write_armap (arch, elength) != true) {
930 if (etable) free (etable);
938 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
939 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
940 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
941 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
942 for (i = 0; i < sizeof (struct ar_hdr); i++)
943 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
944 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
945 bfd_write (etable, 1, elength, arch);
946 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
947 if (etable) free (etable);
950 for (current = arch->archive_head; current; current = current->next) {
951 char buffer[DEFAULT_BUFFERSIZE];
952 unsigned int remaining = arelt_size (current);
953 struct ar_hdr *hdr = arch_hdr(current);
954 /* write ar header */
956 if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
958 bfd_error = system_call_error;
961 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
963 unsigned int amt = ((remaining <= DEFAULT_BUFFERSIZE) ? remaining :
966 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
967 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
970 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
975 /* Note that the namidx for the first symbol is 0 */
980 compute_and_write_armap (arch, elength)
982 unsigned int elength;
987 int orl_max = 15000; /* fine initial default */
989 int stridx = 0; /* string index */
991 /* Dunno if this is the best place for this info... */
992 if (elength != 0) elength += sizeof (struct ar_hdr);
993 elength += elength %2 ;
995 map = (struct orl *) zalloc (orl_max * sizeof (struct orl));
997 bfd_error = no_memory;
1001 /* Map over each element */
1002 for (current = arch->archive_head;
1003 current != (bfd *)NULL;
1004 current = current->next, elt_no++)
1006 if ((bfd_check_format (current, bfd_object) == true)
1007 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1009 unsigned int storage;
1010 unsigned int symcount;
1011 unsigned int src_count;
1013 storage = get_symtab_upper_bound (current);
1016 fprintf (stderr, "%s: Symflags set but there are none?\n",
1017 bfd_get_filename (current));
1020 syms = (asymbol **) zalloc (storage);
1022 bfd_error = no_memory; /* FIXME -- memory leak */
1025 symcount = bfd_canonicalize_symtab (current, syms);
1026 if (symcount == 0) goto nosymz;
1028 /* Now map over all the symbols, picking out the ones we want */
1029 for (src_count = 0; src_count <symcount; src_count++) {
1030 flagword flags = (syms[src_count])->flags;
1031 if ((flags & BSF_GLOBAL) ||
1032 (flags & BSF_FORT_COMM)) {
1034 /* This symbol will go into the archive header */
1035 if (orl_count == orl_max)
1038 map = (struct orl *) realloc ((char *) map,
1039 orl_max * sizeof (struct orl));
1042 (map[orl_count]).name = &((syms[src_count])->name);
1043 (map[orl_count]).pos = elt_no;
1044 (map[orl_count]).namidx = stridx;
1046 stridx += strlen ((syms[src_count])->name) + 1;
1052 /* OK, now we have collected all the data, let's write them out */
1053 if (!BFD_SEND (arch, write_armap,
1054 (arch, elength, map, orl_count, stridx))) {
1064 /* FIXME -- have to byte-swap this */
1067 bsd_write_armap (arch, elength, map, orl_count, stridx)
1069 unsigned int elength;
1074 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1075 unsigned int stringsize = stridx + 4;
1076 unsigned int mapsize = stringsize + ranlibsize;
1078 bfd *current = arch->archive_head;
1079 int last_eltno = 0; /* last element arch seen */
1083 struct stat statbuf;
1085 int padit = mapsize & 1;
1087 if (padit) mapsize ++;
1089 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1091 fstat (arch->iostream, &statbuf); /* FIXME -- descriptor must be open! */
1092 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1093 sprintf (hdr.ar_name, "__.SYMDEF");
1094 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1095 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1096 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1097 for (i = 0; i < sizeof (struct ar_hdr); i++)
1098 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1099 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1101 temp = orl_count /* + 4 */;
1102 bfd_write (&temp, 1, sizeof (temp), arch);
1104 for (count = 0; count < orl_count; count++) {
1106 struct symdef *outp = &outs;
1108 if ((map[count]).pos != last_eltno) {
1109 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1110 firstreal += firstreal % 2;
1111 last_eltno = (map[count]).pos;
1112 current = current->next;
1115 outs.s.string_offset = ((map[count]).namidx) +4;
1116 outs.file_offset = firstreal;
1117 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1120 /* now write the strings themselves */
1122 bfd_write (&temp, 1, sizeof (temp), arch);
1123 for (count = 0; count < orl_count; count++)
1124 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1126 /* The spec sez this should be a newline. But in order to be
1127 bug-compatible for sun's ar we use a null. */
1129 bfd_write("\0",1,1,arch);
1135 /* A coff armap looks like :
1137 struct ar_hdr with name = '/'
1139 offset of file for symbol 0
1140 offset of file for symbol 1
1142 offset of file for symbol n-1
1151 coff_write_armap (arch, elength, map, orl_count, stridx)
1153 unsigned int elength;
1158 unsigned int ranlibsize = (orl_count * 4) + 4;
1159 unsigned int stringsize = stridx;
1160 unsigned int mapsize = stringsize + ranlibsize;
1161 file_ptr archive_member_file_ptr;
1162 bfd *current = arch->archive_head;
1163 int last_eltno = 0; /* last element arch seen */
1166 struct stat statbuf;
1168 int padit = mapsize & 1;
1170 if (padit) mapsize ++;
1172 archive_member_file_ptr =
1173 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1175 fstat (arch->iostream, &statbuf); /* FIXME -- descriptor must be open! */
1176 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1177 hdr.ar_name[0] = '/';
1178 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1179 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1180 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1182 for (i = 0; i < sizeof (struct ar_hdr); i++)
1183 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1185 /* Write the ar header for this item and the number of symbols */
1187 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1188 bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1190 /* Two passes, first write the file offsets for each symbol -
1191 remembering that each offset is on a two byte boundary
1194 for (count = 0; count < orl_count; count++) {
1195 while ((map[count]).pos != last_eltno) {
1196 /* If this is the first time we've seen a ref to this archive
1197 then remember it's size */
1198 archive_member_file_ptr +=
1199 arelt_size (current) + sizeof (struct ar_hdr);
1200 archive_member_file_ptr += archive_member_file_ptr % 2;
1201 current = current->next;
1204 bfd_write (&archive_member_file_ptr,
1206 sizeof (archive_member_file_ptr),
1210 /* now write the strings themselves */
1211 for (count = 0; count < orl_count; count++) {
1212 bfd_write (*((map[count]).name),
1214 strlen (*((map[count]).name))+1, arch);
1217 /* The spec sez this should be a newline. But in order to be
1218 bug-compatible for arc960 we use a null. */
1220 bfd_write("\0",1,1,arch);