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.3 1991/04/04 14:56:42 gumby
34 * Revision 1.2 1991/04/03 22:09:43 steve
37 * Revision 1.1.1.1 1991/03/21 21:10:42 gumby
38 * Back from Intel with Steve
40 * Revision 1.1 1991/03/21 21:10:42 gumby
43 * Revision 1.3 1991/03/16 05:55:25 rich
46 * Revision 1.2 1991/03/15 18:15:50 rich
47 * *** empty log message ***
49 * Revision 1.7 1991/03/08 04:18:02 rich
50 * *** empty log message ***
52 * Revision 1.6 1991/03/07 21:55:31 sac
53 * Added primitive file caching, a file open only for input and
54 * less than BFD_INCORE_FILE_SIZE will be malloced and read in
57 * Revision 1.5 1991/03/05 16:31:12 sac
69 /* We keep a cache of archive filepointers to archive elements to
70 speed up searching the archive by filepos. We only add an entry to
71 the cache when we actually read one. We also don't sort the cache;
72 it's short enough to search linearly.
73 Note that the pointers here point to the front of the ar_hdr, not
74 to the front of the contents!
79 struct ar_cache *next;
82 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
83 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
85 #define arch_hdr(bfd) ((struct ar_hdr *) \
86 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
91 _bfd_generic_mkarchive (abfd)
94 abfd->tdata =(void *) zalloc (sizeof (struct artdata));
96 if (abfd->tdata == NULL) {
97 bfd_error = no_memory;
100 bfd_ardata(abfd)->cache = 0;
105 bfd_get_next_mapent (abfd, prev, entry)
110 if (!bfd_has_map (abfd)) {
111 bfd_error = invalid_operation;
112 return BFD_NO_MORE_SYMBOLS;
115 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
116 else if (++prev >= (symindex)(bfd_ardata (abfd)->symdef_count))
117 return BFD_NO_MORE_SYMBOLS;
119 *entry = (bfd_ardata (abfd)->symdefs + prev);
124 /* To be called by backends only */
126 _bfd_create_empty_archive_element_shell (obfd)
131 nbfd = new_bfd_contained_in(obfd);
133 bfd_error = no_memory;
140 bfd_set_archive_head (output_archive, new_head)
141 bfd *output_archive, *new_head;
144 output_archive->archive_head = new_head;
149 look_for_bfd_in_cache (arch_bfd, filepos)
153 struct ar_cache *current;
155 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
156 current = current->next)
157 if (current->ptr == filepos) return current->arelt;
162 /* Kind of stupid to call cons for each one, but we don't do too many */
164 add_bfd_to_cache (arch_bfd, filepos, new_elt)
165 bfd *arch_bfd, *new_elt;
168 struct ar_cache *new_cache = ((struct ar_cache *)
169 zalloc (sizeof (struct ar_cache)));
171 if (new_cache == NULL) {
172 bfd_error = no_memory;
176 new_cache->ptr = filepos;
177 new_cache->arelt = new_elt;
178 new_cache->next = (struct ar_cache *)NULL;
179 if (bfd_ardata (arch_bfd)->cache == NULL)
180 bfd_ardata (arch_bfd)->cache = new_cache;
182 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
184 for (; current->next != NULL; current = current->next);
185 current->next = new_cache;
193 /* The name begins with space. Hence the rest of the name is an index into
197 get_extended_arelt_filename (arch, name)
202 unsigned long index = 0;
204 /* Should extract string so that I can guarantee not to overflow into
205 the next region, but I"m too lazy. */
207 index = strtol (name, NULL, 10);
209 bfd_error = malformed_archive;
213 return bfd_ardata (arch)->extended_names + index;
216 /* This functions reads an arch header and returns an areltdata pointer, or
219 Presumes the file pointer is already in the right place (ie pointing
220 to the ar_hdr in the file). Moves the file pointer; on success it
221 should be pointing to the front of the file contents; on failure it
222 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 ((void *)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 */
257 if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
258 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
259 if (filename == NULL) {
260 bfd_error = malformed_archive;
266 /* We judge the end of the name by looking for a space or a
271 while (namelen < (unsigned)ar_maxnamelen(abfd) &&
272 ( hdr.ar_name[namelen] != 0 &&
273 hdr.ar_name[namelen] != ' ' &&
274 hdr.ar_name[namelen] != ar_padchar(abfd))) {
278 allocsize += namelen + 1;
281 allocptr = zalloc (allocsize);
282 if (allocptr == NULL) {
283 bfd_error = no_memory;
287 ared = (struct areltdata *) allocptr;
289 ared->arch_header = allocptr + sizeof (struct areltdata);
290 memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
291 ared->parsed_size = parsed_size;
293 if (filename != NULL) ared->filename = filename;
295 ared->filename = allocptr + (sizeof (struct areltdata) +
296 sizeof (struct ar_hdr));
298 memcpy (ared->filename, hdr.ar_name, namelen);
299 ared->filename[namelen] = '\0';
306 get_elt_at_filepos (archive, filepos)
310 struct areltdata *new_areldata;
313 n_nfd = look_for_bfd_in_cache (archive, filepos);
314 if (n_nfd) return n_nfd;
316 if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
317 bfd_error = system_call_error;
321 if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
323 n_nfd = _bfd_create_empty_archive_element_shell (archive);
328 n_nfd->origin = bfd_tell (archive);
329 n_nfd->arelt_data = (void *) new_areldata;
330 n_nfd->filename = new_areldata->filename;
332 if (add_bfd_to_cache (archive, filepos, n_nfd))
342 bfd_get_elt_at_index (abfd, index)
348 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
352 /* If you've got an archive, call this to read each subfile. */
354 bfd_openr_next_archived_file (archive, last_file)
355 bfd *archive, *last_file;
358 if ((bfd_get_format (archive) != bfd_archive) ||
359 (archive->direction == write_direction)) {
360 bfd_error = invalid_operation;
365 return BFD_SEND (archive,
366 openr_next_archived_file,
372 bfd *bfd_generic_openr_next_archived_file(archive, last_file)
379 filestart = bfd_ardata (archive)->first_file_filepos;
381 unsigned int size = arelt_size(last_file);
382 filestart = last_file->origin +size + size %2;
387 return get_elt_at_filepos (archive, filestart);
392 bfd_generic_archive_p (abfd)
395 char armag[SARMAG+1];
397 if (bfd_read ((void *)armag, 1, SARMAG, abfd) != SARMAG) {
398 bfd_error = wrong_format;
402 if (strncmp (armag, ARMAG, SARMAG)) return 0;
404 bfd_set_ardata(abfd, (struct artdata *) zalloc (sizeof (struct artdata)));
406 if (bfd_ardata (abfd) == NULL) {
407 bfd_error = no_memory;
411 bfd_ardata (abfd)->first_file_filepos = SARMAG;
413 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
414 free (bfd_ardata (abfd));
419 /* armap could be left ungc'd! FIXME -- potential storage leak */
420 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
421 free (bfd_ardata (abfd));
429 /* Returns false on error, true otherwise */
431 bfd_slurp_bsd_armap (abfd)
434 struct areltdata *mapdata;
436 unsigned int counter = 0;
437 int *raw_armap, *rbase;
438 struct artdata *ardata = bfd_ardata (abfd);
441 if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
442 /* The archive has at least 16 bytes in it */
443 bfd_seek (abfd, -16L, SEEK_CUR);
445 if (strncmp (nextname, "__.SYMDEF ", 16)) {
446 bfd_has_map (abfd) = false;
450 mapdata = snarf_ar_hdr (abfd);
451 if (mapdata == NULL) return false;
453 raw_armap = (int *) zalloc (mapdata->parsed_size);
454 if (raw_armap == NULL) {
455 bfd_error = no_memory;
461 if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
462 mapdata->parsed_size) {
463 bfd_error = malformed_archive;
468 ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
471 ardata->symdefs = (carsym *) rbase;
472 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
474 for (;counter < (unsigned)( ardata->symdef_count); counter++) {
475 struct symdef *sym = ((struct symdef *) rbase) + counter;
476 sym->s.name = sym->s.string_offset + stringbase;
479 ardata->first_file_filepos = bfd_tell (abfd);
480 /* Pad to an even boundary if you have to */
481 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
483 bfd_has_map (abfd) = true;
488 /* Returns false on error, true otherwise */
490 bfd_slurp_coff_armap (abfd)
493 struct areltdata *mapdata;
495 int *raw_armap, *rawptr;
496 struct artdata *ardata = bfd_ardata (abfd);
498 unsigned int stringsize;
501 if (bfd_read ((void *)&nextname, 1, 1, abfd) != 1) {
502 bfd_has_map(abfd) = false;
506 if (nextname != '/') {
507 /* Actually I think this is an error for a COFF archive */
508 bfd_has_map (abfd) = false;
512 bfd_seek (abfd, -1L, SEEK_CUR);
513 mapdata = snarf_ar_hdr (abfd);
514 if (mapdata == NULL) return false;
516 raw_armap = (int *) zalloc (mapdata->parsed_size);
517 if (raw_armap == NULL) {
518 bfd_error = no_memory;
524 if (bfd_read ((void *)raw_armap, 1, mapdata->parsed_size, abfd) !=
525 mapdata->parsed_size) {
526 bfd_error = malformed_archive;
532 /* The coff armap must be read sequentially. So we construct a bsd-style
533 one in core all at once, for simplicity. */
535 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
538 unsigned int nsymz = *raw_armap;
539 unsigned int carsym_size = (nsymz * sizeof (carsym));
540 unsigned int ptrsize = (4 * nsymz);
542 ardata->symdefs = (carsym *) zalloc (carsym_size + stringsize + 1);
543 if (ardata->symdefs == NULL) {
544 bfd_error = no_memory;
547 carsyms = ardata->symdefs;
549 stringbase = ((char *) ardata->symdefs) + carsym_size;
550 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
553 /* OK, build the carsyms */
554 for (i = 0; i < nsymz; i++)
556 rawptr = raw_armap + i + 1;
557 carsyms->file_offset = *rawptr;
558 carsyms->name = stringbase;
559 for (; *(stringbase++););
564 ardata->symdef_count = *raw_armap;
565 ardata->first_file_filepos = bfd_tell (abfd);
566 /* Pad to an even boundary if you have to */
567 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
570 bfd_has_map (abfd) = true;
575 /** Extended name table.
577 Normally archives support only 14-character filenames. Intel has extended
578 the format: longer names are stored in a special element (the first in the
579 archive, or second if there is an armap); the name in the ar_hdr is replaced
580 by <space><index into filename element>. Index is the P.R. of an int (radix:
583 /* Returns false on error, true otherwise */
585 _bfd_slurp_extended_name_table (abfd)
589 struct areltdata *namedata;
591 if (bfd_read ((void *)nextname, 1, 16, abfd) == 16) {
593 bfd_seek (abfd, -16L, SEEK_CUR);
595 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
596 bfd_ardata (abfd)->extended_names = NULL;
600 namedata = snarf_ar_hdr (abfd);
601 if (namedata == NULL) return false;
604 bfd_ardata (abfd)->extended_names = zalloc (namedata->parsed_size);
605 if (bfd_ardata (abfd)->extended_names == NULL) {
606 bfd_error = no_memory;
612 if (bfd_read ((void*)bfd_ardata (abfd)->extended_names, 1,
613 namedata->parsed_size, abfd) != namedata->parsed_size) {
614 bfd_error = malformed_archive;
615 free (bfd_ardata (abfd)->extended_names);
616 bfd_ardata (abfd)->extended_names = NULL;
620 /* Pad to an even boundary if you have to */
621 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
622 bfd_ardata (abfd)->first_file_filepos +=
623 (bfd_ardata (abfd)->first_file_filepos) %2;
631 char *normalize(file)
634 char * filename = strrchr(file, '/');
635 if (filename != (char *)NULL) {
644 /* Follows archive_head and produces an extended name table if necessary.
645 Returns (in tabloc) a pointer to an extended name table, and in tablen
646 the length of the table. If it makes an entry it clobbers the filename
647 so that the element may be written without further massage.
648 Returns true if it ran successfully, false if something went wrong.
649 A successful return may still involve a zero-length tablen!
652 bfd_construct_extended_name_table (abfd, tabloc, tablen)
655 unsigned int *tablen;
657 unsigned int maxname = abfd->xvec->ar_max_namelen;
658 unsigned int total_namelen = 0;
664 /* Figure out how long the table should be */
665 for (current = abfd->archive_head; current != NULL; current = current->next){
666 unsigned int thislen = strlen (normalize(current->filename));
667 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \0 */
670 if (total_namelen == 0) return true;
672 *tabloc = zalloc (total_namelen);
673 if (*tabloc == NULL) {
674 bfd_error = no_memory;
678 *tablen = total_namelen;
681 for (current = abfd->archive_head; current != NULL; current =
683 char *normal =normalize( current->filename);
684 unsigned int thislen = strlen (normal);
685 if (thislen > maxname) {
686 strcpy (strptr, normal);
687 current->filename[0] = ' ';
688 /* We know there will always be enough room (one of the few cases
689 where you may safely use sprintf). */
690 sprintf ((current->filename) + 1, "-%o", (unsigned) (strptr - *tabloc));
692 strptr += thislen + 1;
699 /** A couple of functions for creating ar_hdrs */
701 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
702 The filename must refer to a filename in the filesystem.
703 The filename field of the ar_hdr will NOT be initialized
707 bfd_ar_hdr_from_filesystem (filename)
711 struct areltdata *ared;
716 if (stat (filename, &status) != 0) {
717 bfd_error = system_call_error;
721 ared = (struct areltdata *) zalloc (sizeof (struct ar_hdr) +
722 sizeof (struct areltdata));
724 bfd_error = no_memory;
727 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
729 /* ar headers are space padded, not null padded! */
731 temp1 = temp + sizeof (struct ar_hdr) - 2;
732 for (; temp < temp1; *(temp++) = ' ');
733 strncpy (hdr->ar_fmag, ARFMAG, 2);
735 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
736 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
737 sprintf ((hdr->ar_uid), "%d", status.st_uid);
738 sprintf ((hdr->ar_gid), "%d", status.st_gid);
739 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
740 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
741 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
742 understand how these C losers could design such a ramshackle bunch of
745 temp1 = temp + sizeof (struct ar_hdr) - 2;
746 for (; temp < temp1; temp++) {
747 if (*temp == '\0') *temp = ' ';
749 strncpy (hdr->ar_fmag, ARFMAG, 2);
750 ared->parsed_size = status.st_size;
751 ared->arch_header = (char *) hdr;
757 bfd_special_undocumented_glue (filename)
761 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (filename) -> arch_header;
765 /* Analogous to stat call */
767 bfd_generic_stat_arch_elt (abfd, buf)
774 if (abfd->arelt_data == NULL) {
775 bfd_error = invalid_operation;
779 hdr = arch_hdr (abfd);
781 #define foo(arelt, stelt, size) \
782 buf->stelt = strtol (hdr->arelt, &aloser, size); \
783 if (aloser == hdr->arelt) return -1;
785 foo (ar_date, st_mtime, 10);
786 foo (ar_uid, st_uid, 10);
787 foo (ar_gid, st_gid, 10);
788 foo (ar_mode, st_mode, 8);
789 foo (ar_size, st_size, 10);
794 /* Don't do anything -- it'll be taken care of later */
796 bfd_dont_truncate_arname (ignore_abfd, ignore_filename, ignore_arhdr)
798 char *ignore_filename;
801 /* FIXME -- Actually this is incorrect. If the name is short we
802 should insert into the header; only if it is long should we do
805 Anyway, this interacts unpleasantly with ar's quick-append option,
806 for now just be compatible with the old system */
812 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
817 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
819 char *filename = strrchr (pathname, '/');
820 int maxlen = ar_maxnamelen (abfd);
823 if (filename == NULL)
828 length = strlen (filename);
830 if (length <= maxlen)
831 memcpy (hdr->ar_name, filename, length);
833 /* pathname: meet procrustes */
834 memcpy (hdr->ar_name, filename, maxlen);
838 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
841 /* Store name into ar header. Truncates the name to fit.
842 1> strip pathname to be just the basename.
843 2> if it's short enuf to fit, stuff it in.
844 3> If it doesn't end with .o, truncate it to fit
845 4> truncate it before the .o, append .o, stuff THAT in.
848 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
850 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
855 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
857 char *filename = strrchr (pathname, '/');
858 int maxlen = ar_maxnamelen (abfd);
860 if (filename == NULL)
865 length = strlen (filename);
867 if (length <= maxlen)
868 memcpy (hdr->ar_name, filename, length);
869 else { /* pathname: meet procrustes */
870 memcpy (hdr->ar_name, filename, maxlen);
871 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
872 hdr->ar_name[maxlen - 2] = '.';
873 hdr->ar_name[maxlen - 1] = 'o';
878 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
882 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
884 /* The bfd is open for write and has its format set to bfd_archive */
886 _bfd_write_archive_contents (arch)
891 unsigned int elength = 0;
892 boolean makemap = bfd_has_map (arch);
893 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
897 /* Verify the viability of all entries; if any of them live in the
898 filesystem (as opposed to living in an archive open for input)
899 then construct a fresh ar_hdr for them.
901 for (current = arch->archive_head; current; current = current->next) {
902 if (bfd_write_p (current)) {
903 bfd_error = invalid_operation;
906 if (!current->arelt_data) {
907 current->arelt_data =
908 (void *) bfd_ar_hdr_from_filesystem (current->filename);
909 if (!current->arelt_data) return false;
911 /* Put in the file name */
913 BFD_SEND (arch, _bfd_truncate_arname,(arch,
915 (char *) arch_hdr(current)));
920 if (makemap) { /* don't bother if we won't make a map! */
921 if ((bfd_check_format (current, bfd_object))
922 #if 0 /* FIXME -- these are not set correctly */
923 && ((bfd_get_file_flags (current) & HAS_SYMS))
930 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
933 bfd_seek (arch, 0, SEEK_SET);
934 bfd_write (ARMAG, 1, SARMAG, arch);
936 if (makemap && hasobjects) {
938 if (compute_and_write_armap (arch, elength) != true) {
939 if (etable) free (etable);
947 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
948 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
949 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
950 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
951 for (i = 0; i < sizeof (struct ar_hdr); i++)
952 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
953 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
954 bfd_write (etable, 1, elength, arch);
955 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
956 if (etable) free (etable);
959 for (current = arch->archive_head; current; current = current->next) {
960 char buffer[DEFAULT_BUFFERSIZE];
961 unsigned int remaining = arelt_size (current);
962 struct ar_hdr *hdr = arch_hdr(current);
963 /* write ar header */
965 if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
967 bfd_error = system_call_error;
970 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
973 unsigned int amt = DEFAULT_BUFFERSIZE;
974 if (amt > remaining) {
977 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
978 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
981 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
986 /* Note that the namidx for the first symbol is 0 */
991 compute_and_write_armap (arch, elength)
993 unsigned int elength;
998 int orl_max = 15000; /* fine initial default */
1000 int stridx = 0; /* string index */
1002 /* Dunno if this is the best place for this info... */
1003 if (elength != 0) elength += sizeof (struct ar_hdr);
1004 elength += elength %2 ;
1006 map = (struct orl *) zalloc (orl_max * sizeof (struct orl));
1008 bfd_error = no_memory;
1012 /* Map over each element */
1013 for (current = arch->archive_head;
1014 current != (bfd *)NULL;
1015 current = current->next, elt_no++)
1017 if ((bfd_check_format (current, bfd_object) == true)
1018 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1020 unsigned int storage;
1021 unsigned int symcount;
1022 unsigned int src_count;
1024 storage = get_symtab_upper_bound (current);
1027 syms = (asymbol **) zalloc (storage);
1029 bfd_error = no_memory; /* FIXME -- memory leak */
1032 symcount = bfd_canonicalize_symtab (current, syms);
1035 /* Now map over all the symbols, picking out the ones we want */
1036 for (src_count = 0; src_count <symcount; src_count++) {
1037 flagword flags = (syms[src_count])->flags;
1038 if ((flags & BSF_GLOBAL) ||
1039 (flags & BSF_FORT_COMM)) {
1041 /* This symbol will go into the archive header */
1042 if (orl_count == orl_max)
1045 map = (struct orl *) realloc ((char *) map,
1046 orl_max * sizeof (struct orl));
1049 (map[orl_count]).name = &((syms[src_count])->name);
1050 (map[orl_count]).pos = elt_no;
1051 (map[orl_count]).namidx = stridx;
1053 stridx += strlen ((syms[src_count])->name) + 1;
1060 /* OK, now we have collected all the data, let's write them out */
1061 if (!BFD_SEND (arch, write_armap,
1062 (arch, elength, map, orl_count, stridx))) {
1072 /* FIXME -- have to byte-swap this */
1075 bsd_write_armap (arch, elength, map, orl_count, stridx)
1077 unsigned int elength;
1082 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1083 unsigned int stringsize = stridx + 4;
1084 unsigned int mapsize = stringsize + ranlibsize;
1086 bfd *current = arch->archive_head;
1087 int last_eltno = 0; /* last element arch seen */
1091 struct stat statbuf;
1093 int padit = mapsize & 1;
1095 if (padit) mapsize ++;
1097 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1099 fstat (arch->iostream, &statbuf); /* FIXME -- descriptor must be open! */
1100 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1101 sprintf (hdr.ar_name, "__.SYMDEF");
1102 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1103 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1104 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1105 for (i = 0; i < sizeof (struct ar_hdr); i++)
1106 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1107 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1109 temp = orl_count /* + 4 */;
1110 bfd_write (&temp, 1, sizeof (temp), arch);
1112 for (count = 0; count < orl_count; count++) {
1114 struct symdef *outp = &outs;
1116 if ((map[count]).pos != last_eltno) {
1117 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1118 firstreal += firstreal % 2;
1119 last_eltno = (map[count]).pos;
1120 current = current->next;
1123 outs.s.string_offset = ((map[count]).namidx) +4;
1124 outs.file_offset = firstreal;
1125 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1128 /* now write the strings themselves */
1130 bfd_write (&temp, 1, sizeof (temp), arch);
1131 for (count = 0; count < orl_count; count++)
1132 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1134 /* The spec sez this should be a newline. But in order to be
1135 bug-compatible for sun's ar we use a null. */
1137 bfd_write("\0",1,1,arch);
1143 /* A coff armap looks like :
1145 struct ar_hdr with name = '/'
1147 offset of file for symbol 0
1148 offset of file for symbol 1
1150 offset of file for symbol n-1
1159 coff_write_armap (arch, elength, map, orl_count, stridx)
1161 unsigned int elength;
1166 unsigned int ranlibsize = (orl_count * 4) + 4;
1167 unsigned int stringsize = stridx;
1168 unsigned int mapsize = stringsize + ranlibsize;
1169 file_ptr archive_member_file_ptr;
1170 bfd *current = arch->archive_head;
1171 int last_eltno = 0; /* last element arch seen */
1175 int padit = mapsize & 1;
1177 if (padit) mapsize ++;
1179 archive_member_file_ptr =
1180 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1182 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1183 hdr.ar_name[0] = '/';
1184 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1185 sprintf (hdr.ar_date, "%ld", time (NULL));
1186 /* This, at least, is what Intel coff sets the values to.: */
1187 sprintf ((hdr.ar_uid), "%d", 0);
1188 sprintf ((hdr.ar_gid), "%d", 0);
1189 sprintf ((hdr.ar_mode), "%-7o", 0);
1190 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1192 for (i = 0; i < sizeof (struct ar_hdr); i++)
1193 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1195 /* Write the ar header for this item and the number of symbols */
1197 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1198 bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1200 /* Two passes, first write the file offsets for each symbol -
1201 remembering that each offset is on a two byte boundary
1204 for (count = 0; count < orl_count; count++) {
1205 while ((map[count]).pos != last_eltno) {
1206 /* If this is the first time we've seen a ref to this archive
1207 then remember it's size */
1208 archive_member_file_ptr +=
1209 arelt_size (current) + sizeof (struct ar_hdr);
1210 archive_member_file_ptr += archive_member_file_ptr % 2;
1211 current = current->next;
1214 bfd_write (&archive_member_file_ptr,
1216 sizeof (archive_member_file_ptr),
1220 /* now write the strings themselves */
1221 for (count = 0; count < orl_count; count++) {
1222 bfd_write (*((map[count]).name),
1224 strlen (*((map[count]).name))+1, arch);
1227 /* The spec sez this should be a newline. But in order to be
1228 bug-compatible for arc960 we use a null. */
1230 bfd_write("\0",1,1,arch);