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 =(PTR) zalloc (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 *)
143 zalloc (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 = zalloc (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);
302 n_nfd->origin = bfd_tell (archive);
303 n_nfd->arelt_data = (PTR) new_areldata;
304 n_nfd->filename = new_areldata->filename;
306 if (add_bfd_to_cache (archive, filepos, n_nfd))
316 bfd_get_elt_at_index (abfd, index)
322 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
326 /* If you've got an archive, call this to read each subfile. */
328 bfd_openr_next_archived_file (archive, last_file)
329 bfd *archive, *last_file;
332 if ((bfd_get_format (archive) != bfd_archive) ||
333 (archive->direction == write_direction)) {
334 bfd_error = invalid_operation;
339 return BFD_SEND (archive,
340 openr_next_archived_file,
346 bfd *bfd_generic_openr_next_archived_file(archive, last_file)
353 filestart = bfd_ardata (archive)->first_file_filepos;
355 unsigned int size = arelt_size(last_file);
356 filestart = last_file->origin +size + size %2;
361 return get_elt_at_filepos (archive, filestart);
366 bfd_generic_archive_p (abfd)
369 char armag[SARMAG+1];
371 if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
372 bfd_error = wrong_format;
377 if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
379 if (strncmp (armag, ARMAG, SARMAG)) return 0;
382 bfd_set_ardata(abfd, (struct artdata *) zalloc (sizeof (struct artdata)));
384 if (bfd_ardata (abfd) == NULL) {
385 bfd_error = no_memory;
389 bfd_ardata (abfd)->first_file_filepos = SARMAG;
391 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
392 free (bfd_ardata (abfd));
397 /* armap could be left ungc'd! FIXME -- potential storage leak */
398 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
399 free (bfd_ardata (abfd));
407 /* Returns false on error, true otherwise */
409 bfd_slurp_bsd_armap (abfd)
412 struct areltdata *mapdata;
414 unsigned int counter = 0;
415 int *raw_armap, *rbase;
416 struct artdata *ardata = bfd_ardata (abfd);
419 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
420 /* The archive has at least 16 bytes in it */
421 bfd_seek (abfd, -16L, SEEK_CUR);
423 if (strncmp (nextname, "__.SYMDEF ", 16)) {
424 bfd_has_map (abfd) = false;
428 mapdata = snarf_ar_hdr (abfd);
429 if (mapdata == NULL) return false;
431 raw_armap = (int *) zalloc (mapdata->parsed_size);
432 if (raw_armap == NULL) {
433 bfd_error = no_memory;
439 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
440 mapdata->parsed_size) {
441 bfd_error = malformed_archive;
446 ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
449 ardata->symdefs = (carsym *) rbase;
450 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
452 for (;counter < (unsigned)( ardata->symdef_count); counter++) {
453 struct symdef *sym = ((struct symdef *) rbase) + counter;
454 sym->s.name = sym->s.string_offset + stringbase;
457 ardata->first_file_filepos = bfd_tell (abfd);
458 /* Pad to an even boundary if you have to */
459 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
461 bfd_has_map (abfd) = true;
466 /* Returns false on error, true otherwise */
468 bfd_slurp_coff_armap (abfd)
471 struct areltdata *mapdata;
473 int *raw_armap, *rawptr;
474 struct artdata *ardata = bfd_ardata (abfd);
476 unsigned int stringsize;
479 if (bfd_read ((PTR)&nextname, 1, 1, abfd) != 1) {
480 bfd_seek (abfd, -1L, SEEK_CUR);
481 bfd_has_map(abfd) = false;
484 bfd_seek (abfd, -1L, SEEK_CUR);
486 if (nextname != '/') {
487 /* Actually I think this is an error for a COFF archive */
488 bfd_has_map (abfd) = false;
492 mapdata = snarf_ar_hdr (abfd);
493 if (mapdata == NULL) return false;
495 raw_armap = (int *) zalloc (mapdata->parsed_size);
496 if (raw_armap == NULL) {
497 bfd_error = no_memory;
503 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
504 mapdata->parsed_size) {
505 bfd_error = malformed_archive;
511 /* The coff armap must be read sequentially. So we construct a bsd-style
512 one in core all at once, for simplicity. */
514 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
517 unsigned int nsymz = *raw_armap;
518 unsigned int carsym_size = (nsymz * sizeof (carsym));
519 unsigned int ptrsize = (4 * nsymz);
521 ardata->symdefs = (carsym *) zalloc (carsym_size + stringsize + 1);
522 if (ardata->symdefs == NULL) {
523 bfd_error = no_memory;
526 carsyms = ardata->symdefs;
528 stringbase = ((char *) ardata->symdefs) + carsym_size;
529 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
532 /* OK, build the carsyms */
533 for (i = 0; i < nsymz; i++)
535 rawptr = raw_armap + i + 1;
536 carsyms->file_offset = *rawptr;
537 carsyms->name = stringbase;
538 for (; *(stringbase++););
543 ardata->symdef_count = *raw_armap;
544 ardata->first_file_filepos = bfd_tell (abfd);
545 /* Pad to an even boundary if you have to */
546 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
549 bfd_has_map (abfd) = true;
554 /** Extended name table.
556 Normally archives support only 14-character filenames. Intel has extended
557 the format: longer names are stored in a special element (the first in the
558 archive, or second if there is an armap); the name in the ar_hdr is replaced
559 by <space><index into filename element>. Index is the P.R. of an int (radix:
562 /* Returns false on error, true otherwise */
564 _bfd_slurp_extended_name_table (abfd)
568 struct areltdata *namedata;
570 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
572 bfd_seek (abfd, -16L, SEEK_CUR);
574 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
575 bfd_ardata (abfd)->extended_names = NULL;
579 namedata = snarf_ar_hdr (abfd);
580 if (namedata == NULL) return false;
583 bfd_ardata (abfd)->extended_names = zalloc (namedata->parsed_size);
584 if (bfd_ardata (abfd)->extended_names == NULL) {
585 bfd_error = no_memory;
591 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
592 namedata->parsed_size, abfd) != namedata->parsed_size) {
593 bfd_error = malformed_archive;
594 free (bfd_ardata (abfd)->extended_names);
595 bfd_ardata (abfd)->extended_names = NULL;
599 /* It appears that the extended names are newline-padded, not null padded.
602 char *temp = bfd_ardata (abfd)->extended_names;
603 for (; *temp != '\0'; ++temp)
604 if (*temp == '\n') *temp = '\0';
607 /* Pad to an even boundary if you have to */
608 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
609 bfd_ardata (abfd)->first_file_filepos +=
610 (bfd_ardata (abfd)->first_file_filepos) %2;
618 char *normalize(file)
621 char * filename = strrchr(file, '/');
622 if (filename != (char *)NULL) {
631 /* Follows archive_head and produces an extended name table if necessary.
632 Returns (in tabloc) a pointer to an extended name table, and in tablen
633 the length of the table. If it makes an entry it clobbers the filename
634 so that the element may be written without further massage.
635 Returns true if it ran successfully, false if something went wrong.
636 A successful return may still involve a zero-length tablen!
639 bfd_construct_extended_name_table (abfd, tabloc, tablen)
642 unsigned int *tablen;
644 unsigned int maxname = abfd->xvec->ar_max_namelen;
645 unsigned int total_namelen = 0;
651 /* Figure out how long the table should be */
652 for (current = abfd->archive_head; current != NULL; current = current->next){
653 unsigned int thislen = strlen (normalize(current->filename));
654 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
657 if (total_namelen == 0) return true;
659 *tabloc = zalloc (total_namelen);
660 if (*tabloc == NULL) {
661 bfd_error = no_memory;
665 *tablen = total_namelen;
668 for (current = abfd->archive_head; current != NULL; current =
670 char *normal =normalize( current->filename);
671 unsigned int thislen = strlen (normal);
672 if (thislen > maxname) {
673 /* Works for now; may need to be re-engineered if we encounter an oddball
674 archive format and want to generalise this hack. */
675 struct ar_hdr *hdr = arch_hdr(current);
676 strcpy (strptr, normal);
677 strptr[thislen] = '\n';
678 hdr->ar_name[0] = ' ';
679 /* We know there will always be enough room (one of the few cases
680 where you may safely use sprintf). */
681 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
682 /* Kinda Kludgy. We should just use the returned value of sprintf
683 but not all implementations get this right */
685 char *temp = hdr->ar_name +2;
686 for (; temp < hdr->ar_name + maxname; temp++)
687 if (*temp == '\0') *temp = ' ';
689 strptr += thislen + 1;
696 /** A couple of functions for creating ar_hdrs */
698 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
699 The filename must refer to a filename in the filesystem.
700 The filename field of the ar_hdr will NOT be initialized
704 bfd_ar_hdr_from_filesystem (filename)
708 struct areltdata *ared;
713 if (stat (filename, &status) != 0) {
714 bfd_error = system_call_error;
718 ared = (struct areltdata *) zalloc (sizeof (struct ar_hdr) +
719 sizeof (struct areltdata));
721 bfd_error = no_memory;
724 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
726 /* ar headers are space padded, not null padded! */
728 temp1 = temp + sizeof (struct ar_hdr) - 2;
729 for (; temp < temp1; *(temp++) = ' ');
730 strncpy (hdr->ar_fmag, ARFMAG, 2);
732 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
733 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
734 sprintf ((hdr->ar_uid), "%d", status.st_uid);
735 sprintf ((hdr->ar_gid), "%d", status.st_gid);
736 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
737 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
738 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
739 understand how these C losers could design such a ramshackle bunch of
742 temp1 = temp + sizeof (struct ar_hdr) - 2;
743 for (; temp < temp1; temp++) {
744 if (*temp == '\0') *temp = ' ';
746 strncpy (hdr->ar_fmag, ARFMAG, 2);
747 ared->parsed_size = status.st_size;
748 ared->arch_header = (char *) hdr;
754 bfd_special_undocumented_glue (filename)
758 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (filename) -> arch_header;
762 /* Analogous to stat call */
764 bfd_generic_stat_arch_elt (abfd, buf)
771 if (abfd->arelt_data == NULL) {
772 bfd_error = invalid_operation;
776 hdr = arch_hdr (abfd);
778 #define foo(arelt, stelt, size) \
779 buf->stelt = strtol (hdr->arelt, &aloser, size); \
780 if (aloser == hdr->arelt) return -1;
782 foo (ar_date, st_mtime, 10);
783 foo (ar_uid, st_uid, 10);
784 foo (ar_gid, st_gid, 10);
785 foo (ar_mode, st_mode, 8);
786 foo (ar_size, st_size, 10);
792 bfd_dont_truncate_arname (abfd, pathname, arhdr)
797 /* This interacts unpleasantly with ar's quick-append option.
798 Fortunately ic960 users will never use that option. Fixing this
799 is very hard; fortunately I know how to do it and will do so once
800 intel's release is out the door. */
802 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
804 char *filename = strrchr (pathname, '/');
805 int maxlen = ar_maxnamelen (abfd);
807 if (filename == NULL)
812 length = strlen (filename);
814 if (length <= maxlen)
815 memcpy (hdr->ar_name, filename, length);
817 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
823 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
828 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
830 char *filename = strrchr (pathname, '/');
831 int maxlen = ar_maxnamelen (abfd);
834 if (filename == NULL)
839 length = strlen (filename);
841 if (length <= maxlen)
842 memcpy (hdr->ar_name, filename, length);
844 /* pathname: meet procrustes */
845 memcpy (hdr->ar_name, filename, maxlen);
849 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
852 /* Store name into ar header. Truncates the name to fit.
853 1> strip pathname to be just the basename.
854 2> if it's short enuf to fit, stuff it in.
855 3> If it doesn't end with .o, truncate it to fit
856 4> truncate it before the .o, append .o, stuff THAT in.
859 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
861 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
866 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
868 char *filename = strrchr (pathname, '/');
869 int maxlen = ar_maxnamelen (abfd);
871 if (filename == NULL)
876 length = strlen (filename);
878 if (length <= maxlen)
879 memcpy (hdr->ar_name, filename, length);
880 else { /* pathname: meet procrustes */
881 memcpy (hdr->ar_name, filename, maxlen);
882 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
883 hdr->ar_name[maxlen - 2] = '.';
884 hdr->ar_name[maxlen - 1] = 'o';
889 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
893 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
895 /* The bfd is open for write and has its format set to bfd_archive */
897 _bfd_write_archive_contents (arch)
902 unsigned int elength = 0;
903 boolean makemap = bfd_has_map (arch);
904 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
908 /* Verify the viability of all entries; if any of them live in the
909 filesystem (as opposed to living in an archive open for input)
910 then construct a fresh ar_hdr for them.
912 for (current = arch->archive_head; current; current = current->next) {
913 if (bfd_write_p (current)) {
914 bfd_error = invalid_operation;
917 if (!current->arelt_data) {
918 current->arelt_data =
919 (PTR) bfd_ar_hdr_from_filesystem (current->filename);
920 if (!current->arelt_data) return false;
922 /* Put in the file name */
924 BFD_SEND (arch, _bfd_truncate_arname,(arch,
926 (char *) arch_hdr(current)));
931 if (makemap) { /* don't bother if we won't make a map! */
932 if ((bfd_check_format (current, bfd_object))
933 #if 0 /* FIXME -- these are not set correctly */
934 && ((bfd_get_file_flags (current) & HAS_SYMS))
941 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
944 bfd_seek (arch, 0, SEEK_SET);
946 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
948 bfd_write (ARMAG, 1, SARMAG, arch);
951 if (makemap && hasobjects) {
953 if (compute_and_write_armap (arch, elength) != true) {
954 if (etable) free (etable);
962 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
963 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
964 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
965 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
966 for (i = 0; i < sizeof (struct ar_hdr); i++)
967 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
968 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
969 bfd_write (etable, 1, elength, arch);
970 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
971 if (etable) free (etable);
974 for (current = arch->archive_head; current; current = current->next) {
975 char buffer[DEFAULT_BUFFERSIZE];
976 unsigned int remaining = arelt_size (current);
977 struct ar_hdr *hdr = arch_hdr(current);
978 /* write ar header */
980 if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
982 bfd_error = system_call_error;
985 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
988 unsigned int amt = DEFAULT_BUFFERSIZE;
989 if (amt > remaining) {
992 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
993 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
996 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1001 /* Note that the namidx for the first symbol is 0 */
1006 compute_and_write_armap (arch, elength)
1008 unsigned int elength;
1011 file_ptr elt_no = 0;
1013 int orl_max = 15000; /* fine initial default */
1015 int stridx = 0; /* string index */
1017 /* Dunno if this is the best place for this info... */
1018 if (elength != 0) elength += sizeof (struct ar_hdr);
1019 elength += elength %2 ;
1021 map = (struct orl *) zalloc (orl_max * sizeof (struct orl));
1023 bfd_error = no_memory;
1027 /* Map over each element */
1028 for (current = arch->archive_head;
1029 current != (bfd *)NULL;
1030 current = current->next, elt_no++)
1032 if ((bfd_check_format (current, bfd_object) == true)
1033 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1035 unsigned int storage;
1036 unsigned int symcount;
1037 unsigned int src_count;
1039 storage = get_symtab_upper_bound (current);
1042 syms = (asymbol **) zalloc (storage);
1044 bfd_error = no_memory; /* FIXME -- memory leak */
1047 symcount = bfd_canonicalize_symtab (current, syms);
1050 /* Now map over all the symbols, picking out the ones we want */
1051 for (src_count = 0; src_count <symcount; src_count++) {
1052 flagword flags = (syms[src_count])->flags;
1053 if ((flags & BSF_GLOBAL) ||
1054 (flags & BSF_FORT_COMM)) {
1056 /* This symbol will go into the archive header */
1057 if (orl_count == orl_max)
1060 map = (struct orl *) realloc ((char *) map,
1061 orl_max * sizeof (struct orl));
1064 (map[orl_count]).name = &((syms[src_count])->name);
1065 (map[orl_count]).pos = elt_no;
1066 (map[orl_count]).namidx = stridx;
1068 stridx += strlen ((syms[src_count])->name) + 1;
1075 /* OK, now we have collected all the data, let's write them out */
1076 if (!BFD_SEND (arch, write_armap,
1077 (arch, elength, map, orl_count, stridx))) {
1087 /* FIXME -- have to byte-swap this */
1090 bsd_write_armap (arch, elength, map, orl_count, stridx)
1092 unsigned int elength;
1097 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1098 unsigned int stringsize = stridx + 4;
1099 unsigned int mapsize = stringsize + ranlibsize;
1101 bfd *current = arch->archive_head;
1102 int last_eltno = 0; /* last element arch seen */
1106 struct stat statbuf;
1108 int padit = mapsize & 1;
1110 if (padit) mapsize ++;
1112 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1114 fstat (arch->iostream, &statbuf); /* FIXME -- descriptor must be open! */
1115 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1116 sprintf (hdr.ar_name, "__.SYMDEF");
1117 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1118 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1119 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1120 for (i = 0; i < sizeof (struct ar_hdr); i++)
1121 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1122 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1124 temp = orl_count /* + 4 */;
1125 bfd_write (&temp, 1, sizeof (temp), arch);
1127 for (count = 0; count < orl_count; count++) {
1129 struct symdef *outp = &outs;
1131 if ((map[count]).pos != last_eltno) {
1132 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1133 firstreal += firstreal % 2;
1134 last_eltno = (map[count]).pos;
1135 current = current->next;
1138 outs.s.string_offset = ((map[count]).namidx) +4;
1139 outs.file_offset = firstreal;
1140 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1143 /* now write the strings themselves */
1145 bfd_write (&temp, 1, sizeof (temp), arch);
1146 for (count = 0; count < orl_count; count++)
1147 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1149 /* The spec sez this should be a newline. But in order to be
1150 bug-compatible for sun's ar we use a null. */
1152 bfd_write("\0",1,1,arch);
1158 /* A coff armap looks like :
1160 struct ar_hdr with name = '/'
1162 offset of file for symbol 0
1163 offset of file for symbol 1
1165 offset of file for symbol n-1
1174 coff_write_armap (arch, elength, map, orl_count, stridx)
1176 unsigned int elength;
1181 unsigned int ranlibsize = (orl_count * 4) + 4;
1182 unsigned int stringsize = stridx;
1183 unsigned int mapsize = stringsize + ranlibsize;
1184 file_ptr archive_member_file_ptr;
1185 bfd *current = arch->archive_head;
1186 int last_eltno = 0; /* last element arch seen */
1190 int padit = mapsize & 1;
1192 if (padit) mapsize ++;
1194 archive_member_file_ptr =
1195 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1197 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1198 hdr.ar_name[0] = '/';
1199 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1200 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1201 /* This, at least, is what Intel coff sets the values to.: */
1202 sprintf ((hdr.ar_uid), "%d", 0);
1203 sprintf ((hdr.ar_gid), "%d", 0);
1204 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1205 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1207 for (i = 0; i < sizeof (struct ar_hdr); i++)
1208 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1210 /* Write the ar header for this item and the number of symbols */
1212 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1213 bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1215 /* Two passes, first write the file offsets for each symbol -
1216 remembering that each offset is on a two byte boundary
1219 for (count = 0; count < orl_count; count++) {
1220 while ((map[count]).pos != last_eltno) {
1221 /* If this is the first time we've seen a ref to this archive
1222 then remember it's size */
1223 archive_member_file_ptr +=
1224 arelt_size (current) + sizeof (struct ar_hdr);
1225 archive_member_file_ptr += archive_member_file_ptr % 2;
1226 current = current->next;
1229 bfd_write (&archive_member_file_ptr,
1231 sizeof (archive_member_file_ptr),
1235 /* now write the strings themselves */
1236 for (count = 0; count < orl_count; count++) {
1237 bfd_write (*((map[count]).name),
1239 strlen (*((map[count]).name))+1, arch);
1242 /* The spec sez this should be a newline. But in order to be
1243 bug-compatible for arc960 we use a null. */
1245 bfd_write("\0",1,1,arch);