2 /*** archive.c -- an attempt at combining the machine-independent parts of
5 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
7 This file is part of BFD, the Binary File Diddler.
9 BFD is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 1, or (at your option)
14 BFD is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with BFD; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 o - all archive elements start on an even boundary, newline padded;
26 o - all arch headers are char *;
27 o - all arch headers are the same size (across architectures).
39 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
42 /* We keep a cache of archive filepointers to archive elements to
43 speed up searching the archive by filepos. We only add an entry to
44 the cache when we actually read one. We also don't sort the cache;
45 it's short enough to search linearly.
46 Note that the pointers here point to the front of the ar_hdr, not
47 to the front of the contents!
52 struct ar_cache *next;
55 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
56 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
58 #define arch_hdr(bfd) ((struct ar_hdr *) \
59 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
62 _bfd_generic_mkarchive (abfd)
65 set_tdata (abfd, bfd_zalloc(abfd, sizeof (struct artdata)));
67 if (bfd_ardata (abfd) == NULL) {
68 bfd_error = no_memory;
71 bfd_ardata(abfd)->cache = 0;
76 bfd_get_next_mapent (abfd, prev, entry)
81 if (!bfd_has_map (abfd)) {
82 bfd_error = invalid_operation;
83 return BFD_NO_MORE_SYMBOLS;
86 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
87 else if (++prev >= bfd_ardata (abfd)->symdef_count)
88 return BFD_NO_MORE_SYMBOLS;
90 *entry = (bfd_ardata (abfd)->symdefs + prev);
95 /* To be called by backends only */
97 _bfd_create_empty_archive_element_shell (obfd)
102 nbfd = new_bfd_contained_in(obfd);
104 bfd_error = no_memory;
111 bfd_set_archive_head (output_archive, new_head)
112 bfd *output_archive, *new_head;
115 output_archive->archive_head = new_head;
120 look_for_bfd_in_cache (arch_bfd, filepos)
124 struct ar_cache *current;
126 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
127 current = current->next)
128 if (current->ptr == filepos) return current->arelt;
133 /* Kind of stupid to call cons for each one, but we don't do too many */
135 add_bfd_to_cache (arch_bfd, filepos, new_elt)
136 bfd *arch_bfd, *new_elt;
139 struct ar_cache *new_cache = (struct ar_cache *)
140 bfd_zalloc(arch_bfd, sizeof (struct ar_cache));
142 if (new_cache == NULL) {
143 bfd_error = no_memory;
147 new_cache->ptr = filepos;
148 new_cache->arelt = new_elt;
149 new_cache->next = (struct ar_cache *)NULL;
150 if (bfd_ardata (arch_bfd)->cache == NULL)
151 bfd_ardata (arch_bfd)->cache = new_cache;
153 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
155 for (; current->next != NULL; current = current->next);
156 current->next = new_cache;
164 /* The name begins with space. Hence the rest of the name is an index into
168 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.
207 char *hdrp = (char *) &hdr;
208 unsigned int parsed_size;
209 struct areltdata *ared;
210 char *filename = NULL;
211 unsigned int namelen = 0;
212 unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
215 if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
216 != sizeof (struct ar_hdr)) {
217 bfd_error = no_more_archived_files;
220 if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
221 bfd_error = malformed_archive;
226 parsed_size = strtol (hdr.ar_size, NULL, 10);
228 bfd_error = malformed_archive;
232 /* extract the filename from the archive */
233 if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
234 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
235 if (filename == NULL) {
236 bfd_error = malformed_archive;
242 /* We judge the end of the name by looking for a space or a
247 while (namelen < (unsigned)ar_maxnamelen(abfd) &&
248 ( hdr.ar_name[namelen] != 0 &&
249 hdr.ar_name[namelen] != ' ' &&
250 hdr.ar_name[namelen] != ar_padchar(abfd))) {
254 allocsize += namelen + 1;
257 allocptr = bfd_zalloc(abfd, allocsize);
258 if (allocptr == NULL) {
259 bfd_error = no_memory;
263 ared = (struct areltdata *) allocptr;
265 ared->arch_header = allocptr + sizeof (struct areltdata);
266 memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
267 ared->parsed_size = parsed_size;
269 if (filename != NULL) ared->filename = filename;
271 ared->filename = allocptr + (sizeof (struct areltdata) +
272 sizeof (struct ar_hdr));
274 memcpy (ared->filename, hdr.ar_name, namelen);
275 ared->filename[namelen] = '\0';
282 get_elt_at_filepos (archive, filepos)
286 struct areltdata *new_areldata;
289 n_nfd = look_for_bfd_in_cache (archive, filepos);
290 if (n_nfd) return n_nfd;
292 if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
293 bfd_error = system_call_error;
297 if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
299 n_nfd = _bfd_create_empty_archive_element_shell (archive);
301 bfd_release (archive, (PTR)new_areldata);
304 n_nfd->origin = bfd_tell (archive);
305 n_nfd->arelt_data = (PTR) new_areldata;
306 n_nfd->filename = new_areldata->filename;
308 if (add_bfd_to_cache (archive, filepos, n_nfd))
312 bfd_release (archive, (PTR)n_nfd);
313 bfd_release (archive, (PTR)new_areldata);
318 bfd_get_elt_at_index (abfd, index)
324 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
328 /* If you've got an archive, call this to read each subfile. */
330 bfd_openr_next_archived_file (archive, last_file)
331 bfd *archive, *last_file;
334 if ((bfd_get_format (archive) != bfd_archive) ||
335 (archive->direction == write_direction)) {
336 bfd_error = invalid_operation;
341 return BFD_SEND (archive,
342 openr_next_archived_file,
348 bfd *bfd_generic_openr_next_archived_file(archive, last_file)
355 filestart = bfd_ardata (archive)->first_file_filepos;
357 unsigned int size = arelt_size(last_file);
358 /* Pad to an even boundary... */
359 filestart = last_file->origin + size + size%2;
362 return get_elt_at_filepos (archive, filestart);
367 bfd_generic_archive_p (abfd)
370 char armag[SARMAG+1];
372 if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
373 bfd_error = wrong_format;
378 if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
380 if (strncmp (armag, ARMAG, SARMAG)) return 0;
383 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
384 involves a cast, we can't do it as the left operand of assignment. */
385 set_tdata (abfd, bfd_zalloc(abfd,sizeof (struct artdata)));
387 if (bfd_ardata (abfd) == NULL) {
388 bfd_error = no_memory;
392 bfd_ardata (abfd)->first_file_filepos = SARMAG;
394 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
395 bfd_release(abfd, bfd_ardata (abfd));
400 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
401 bfd_release(abfd, bfd_ardata (abfd));
409 /* Returns false on error, true otherwise */
411 bfd_slurp_bsd_armap (abfd)
414 struct areltdata *mapdata;
416 unsigned int counter = 0;
417 int *raw_armap, *rbase;
418 struct artdata *ardata = bfd_ardata (abfd);
421 /* FIXME, if the read fails, this routine quietly returns "true"!!
422 It should probably do that if the read gives 0 bytes (empty archive),
423 but fail for any other size... */
424 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
425 /* The archive has at least 16 bytes in it */
426 bfd_seek (abfd, -16L, SEEK_CUR);
428 /* This should be using RANLIBMAG, but at least it can be grepped for
430 if (strncmp (nextname, "__.SYMDEF ", 16)) {
431 bfd_has_map (abfd) = false;
435 mapdata = snarf_ar_hdr (abfd);
436 if (mapdata == NULL) return false;
438 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
439 if (raw_armap == NULL) {
440 bfd_error = no_memory;
442 bfd_release (abfd, (PTR)mapdata);
446 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
447 mapdata->parsed_size) {
448 bfd_error = malformed_archive;
449 bfd_release (abfd, (PTR)raw_armap);
453 ardata->symdef_count = *raw_armap / sizeof (struct symdef);
456 ardata->symdefs = (carsym *) rbase;
457 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
459 for (;counter < ardata->symdef_count; counter++) {
460 struct symdef *sym = ((struct symdef *) rbase) + counter;
461 sym->s.name = sym->s.string_offset + stringbase;
464 ardata->first_file_filepos = bfd_tell (abfd);
465 /* Pad to an even boundary if you have to */
466 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
467 /* FIXME, we should provide some way to free raw_ardata when
468 we are done using the strings from it. For now, it seems
469 to be allocated on an obstack anyway... */
470 bfd_has_map (abfd) = true;
475 /* Returns false on error, true otherwise */
477 bfd_slurp_coff_armap (abfd)
480 struct areltdata *mapdata;
482 int *raw_armap, *rawptr;
483 struct artdata *ardata = bfd_ardata (abfd);
485 unsigned int stringsize;
489 result = bfd_read ((PTR)&nextname, 1, 1, abfd);
490 bfd_seek (abfd, -1L, SEEK_CUR);
492 if (result != 1 || nextname != '/') {
493 /* Actually I think this is an error for a COFF archive */
494 bfd_has_map (abfd) = false;
498 mapdata = snarf_ar_hdr (abfd);
499 if (mapdata == NULL) return false;
501 raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
502 if (raw_armap == NULL) {
503 bfd_error = no_memory;
505 bfd_release (abfd, (PTR)mapdata);
509 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
510 mapdata->parsed_size) {
511 bfd_error = malformed_archive;
513 bfd_release (abfd, (PTR)raw_armap);
517 /* The coff armap must be read sequentially. So we construct a bsd-style
518 one in core all at once, for simplicity. */
520 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
523 unsigned int nsymz = *raw_armap;
524 unsigned int carsym_size = (nsymz * sizeof (carsym));
525 unsigned int ptrsize = (4 * nsymz);
527 ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
528 if (ardata->symdefs == NULL) {
529 bfd_error = no_memory;
532 carsyms = ardata->symdefs;
534 stringbase = ((char *) ardata->symdefs) + carsym_size;
535 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
538 /* OK, build the carsyms */
539 for (i = 0; i < nsymz; i++)
541 rawptr = raw_armap + i + 1;
542 carsyms->file_offset = *rawptr;
543 carsyms->name = stringbase;
544 for (; *(stringbase++););
549 ardata->symdef_count = *raw_armap;
550 ardata->first_file_filepos = bfd_tell (abfd);
551 /* Pad to an even boundary if you have to */
552 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
553 bfd_release (abfd, (PTR)raw_armap);
554 bfd_release (abfd, (PTR)mapdata);
555 bfd_has_map (abfd) = true;
559 /** Extended name table.
561 Normally archives support only 14-character filenames. Intel has extended
562 the format: longer names are stored in a special element (the first in the
563 archive, or second if there is an armap); the name in the ar_hdr is replaced
564 by <space><index into filename element>. Index is the P.R. of an int (radix:
567 /* Returns false on error, true otherwise */
569 _bfd_slurp_extended_name_table (abfd)
573 struct areltdata *namedata;
575 /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
576 we probably don't want to return true. */
577 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
579 bfd_seek (abfd, -16L, SEEK_CUR);
581 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
582 bfd_ardata (abfd)->extended_names = NULL;
586 namedata = snarf_ar_hdr (abfd);
587 if (namedata == NULL) return false;
589 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
590 if (bfd_ardata (abfd)->extended_names == NULL) {
591 bfd_error = no_memory;
593 bfd_release (abfd, (PTR)namedata);
597 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
598 namedata->parsed_size, abfd) != namedata->parsed_size) {
599 bfd_error = malformed_archive;
600 bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
601 bfd_ardata (abfd)->extended_names = NULL;
605 /* It appears that the extended names are newline-padded, not null padded.
608 char *temp = bfd_ardata (abfd)->extended_names;
609 for (; *temp != '\0'; ++temp)
610 if (*temp == '\n') *temp = '\0';
613 /* Pad to an even boundary if you have to */
614 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
615 bfd_ardata (abfd)->first_file_filepos +=
616 (bfd_ardata (abfd)->first_file_filepos) %2;
618 /* FIXME, we can't release namedata here because it was allocated
619 below extended_names on the obstack... */
620 /* bfd_release (abfd, namedata); */
626 char *normalize(file)
629 char * filename = strrchr(file, '/');
630 if (filename != (char *)NULL) {
639 /* Follows archive_head and produces an extended name table if necessary.
640 Returns (in tabloc) a pointer to an extended name table, and in tablen
641 the length of the table. If it makes an entry it clobbers the filename
642 so that the element may be written without further massage.
643 Returns true if it ran successfully, false if something went wrong.
644 A successful return may still involve a zero-length tablen!
647 bfd_construct_extended_name_table (abfd, tabloc, tablen)
650 unsigned int *tablen;
652 unsigned int maxname = abfd->xvec->ar_max_namelen;
653 unsigned int total_namelen = 0;
659 /* Figure out how long the table should be */
660 for (current = abfd->archive_head; current != NULL; current = current->next){
661 unsigned int thislen = strlen (normalize(current->filename));
662 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
665 if (total_namelen == 0) return true;
667 *tabloc = bfd_zalloc (abfd,total_namelen);
668 if (*tabloc == NULL) {
669 bfd_error = no_memory;
673 *tablen = total_namelen;
676 for (current = abfd->archive_head; current != NULL; current =
678 char *normal =normalize( current->filename);
679 unsigned int thislen = strlen (normal);
680 if (thislen > maxname) {
681 /* Works for now; may need to be re-engineered if we encounter an oddball
682 archive format and want to generalise this hack. */
683 struct ar_hdr *hdr = arch_hdr(current);
684 strcpy (strptr, normal);
685 strptr[thislen] = '\n';
686 hdr->ar_name[0] = ' ';
687 /* We know there will always be enough room (one of the few cases
688 where you may safely use sprintf). */
689 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
690 /* Kinda Kludgy. We should just use the returned value of sprintf
691 but not all implementations get this right */
693 char *temp = hdr->ar_name +2;
694 for (; temp < hdr->ar_name + maxname; temp++)
695 if (*temp == '\0') *temp = ' ';
697 strptr += thislen + 1;
704 /** A couple of functions for creating ar_hdrs */
706 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
707 The filename must refer to a filename in the filesystem.
708 The filename field of the ar_hdr will NOT be initialized
712 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
714 CONST char *filename)
717 struct areltdata *ared;
722 if (stat (filename, &status) != 0) {
723 bfd_error = system_call_error;
727 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
728 sizeof (struct areltdata));
730 bfd_error = no_memory;
733 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
735 /* ar headers are space padded, not null padded! */
737 temp1 = temp + sizeof (struct ar_hdr) - 2;
738 for (; temp < temp1; *(temp++) = ' ');
739 strncpy (hdr->ar_fmag, ARFMAG, 2);
741 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
742 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
743 sprintf ((hdr->ar_uid), "%d", status.st_uid);
744 sprintf ((hdr->ar_gid), "%d", status.st_gid);
745 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
746 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
747 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
748 understand how these C losers could design such a ramshackle bunch of
751 temp1 = temp + sizeof (struct ar_hdr) - 2;
752 for (; temp < temp1; temp++) {
753 if (*temp == '\0') *temp = ' ';
755 strncpy (hdr->ar_fmag, ARFMAG, 2);
756 ared->parsed_size = status.st_size;
757 ared->arch_header = (char *) hdr;
763 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
768 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
772 /* Analogous to stat call */
774 bfd_generic_stat_arch_elt (abfd, buf)
781 if (abfd->arelt_data == NULL) {
782 bfd_error = invalid_operation;
786 hdr = arch_hdr (abfd);
788 #define foo(arelt, stelt, size) \
789 buf->stelt = strtol (hdr->arelt, &aloser, size); \
790 if (aloser == hdr->arelt) return -1;
792 foo (ar_date, st_mtime, 10);
793 foo (ar_uid, st_uid, 10);
794 foo (ar_gid, st_gid, 10);
795 foo (ar_mode, st_mode, 8);
796 foo (ar_size, st_size, 10);
802 bfd_dont_truncate_arname (abfd, pathname, arhdr)
804 CONST char *pathname;
807 /* FIXME: This interacts unpleasantly with ar's quick-append option.
808 Fortunately ic960 users will never use that option. Fixing this
809 is very hard; fortunately I know how to do it and will do so once
810 intel's release is out the door. */
812 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
814 CONST char *filename = strrchr (pathname, '/');
815 int maxlen = ar_maxnamelen (abfd);
817 if (filename == NULL)
822 length = strlen (filename);
824 if (length <= maxlen)
825 memcpy (hdr->ar_name, filename, length);
827 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
833 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
835 CONST char *pathname;
838 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
840 CONST char *filename = strrchr (pathname, '/');
841 int maxlen = ar_maxnamelen (abfd);
844 if (filename == NULL)
849 length = strlen (filename);
851 if (length <= maxlen)
852 memcpy (hdr->ar_name, filename, length);
854 /* pathname: meet procrustes */
855 memcpy (hdr->ar_name, filename, maxlen);
859 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
862 /* Store name into ar header. Truncates the name to fit.
863 1> strip pathname to be just the basename.
864 2> if it's short enuf to fit, stuff it in.
865 3> If it doesn't end with .o, truncate it to fit
866 4> truncate it before the .o, append .o, stuff THAT in.
869 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
871 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
873 CONST char *pathname;
876 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
878 CONST char *filename = strrchr (pathname, '/');
879 int maxlen = ar_maxnamelen (abfd);
881 if (filename == NULL)
886 length = strlen (filename);
888 if (length <= maxlen)
889 memcpy (hdr->ar_name, filename, length);
890 else { /* pathname: meet procrustes */
891 memcpy (hdr->ar_name, filename, maxlen);
892 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
893 hdr->ar_name[maxlen - 2] = '.';
894 hdr->ar_name[maxlen - 1] = 'o';
899 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
903 PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
905 /* The bfd is open for write and has its format set to bfd_archive */
907 _bfd_write_archive_contents (arch)
912 unsigned int elength = 0;
913 boolean makemap = bfd_has_map (arch);
914 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
917 /* Verify the viability of all entries; if any of them live in the
918 filesystem (as opposed to living in an archive open for input)
919 then construct a fresh ar_hdr for them.
921 for (current = arch->archive_head; current; current = current->next) {
922 if (bfd_write_p (current)) {
923 bfd_error = invalid_operation;
926 if (!current->arelt_data) {
927 current->arelt_data =
928 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
929 if (!current->arelt_data) return false;
931 /* Put in the file name */
933 BFD_SEND (arch, _bfd_truncate_arname,(arch,
935 (char *) arch_hdr(current)));
940 if (makemap) { /* don't bother if we won't make a map! */
941 if ((bfd_check_format (current, bfd_object))
942 #if 0 /* FIXME -- these are not set correctly */
943 && ((bfd_get_file_flags (current) & HAS_SYMS))
950 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
953 bfd_seek (arch, 0, SEEK_SET);
955 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
957 bfd_write (ARMAG, 1, SARMAG, arch);
960 if (makemap && hasobjects) {
962 if (compute_and_write_armap (arch, elength) != true) {
970 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
971 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
972 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
973 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
974 for (i = 0; i < sizeof (struct ar_hdr); i++)
975 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
976 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
977 bfd_write (etable, 1, elength, arch);
978 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
982 for (current = arch->archive_head; current; current = current->next) {
983 char buffer[DEFAULT_BUFFERSIZE];
984 unsigned int remaining = arelt_size (current);
985 struct ar_hdr *hdr = arch_hdr(current);
986 /* write ar header */
988 if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
990 bfd_error = system_call_error;
993 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
996 unsigned int amt = DEFAULT_BUFFERSIZE;
997 if (amt > remaining) {
1000 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
1001 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
1004 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1009 /* Note that the namidx for the first symbol is 0 */
1012 compute_and_write_armap (arch, elength)
1014 unsigned int elength;
1017 file_ptr elt_no = 0;
1019 int orl_max = 15000; /* fine initial default */
1021 int stridx = 0; /* string index */
1023 /* Dunno if this is the best place for this info... */
1024 if (elength != 0) elength += sizeof (struct ar_hdr);
1025 elength += elength %2 ;
1027 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1029 bfd_error = no_memory;
1033 /* Map over each element */
1034 for (current = arch->archive_head;
1035 current != (bfd *)NULL;
1036 current = current->next, elt_no++)
1038 if ((bfd_check_format (current, bfd_object) == true)
1039 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1041 unsigned int storage;
1042 unsigned int symcount;
1043 unsigned int src_count;
1045 storage = get_symtab_upper_bound (current);
1048 syms = (asymbol **) bfd_zalloc (arch,storage);
1050 bfd_error = no_memory; /* FIXME -- memory leak */
1053 symcount = bfd_canonicalize_symtab (current, syms);
1056 /* Now map over all the symbols, picking out the ones we want */
1057 for (src_count = 0; src_count <symcount; src_count++) {
1058 flagword flags = (syms[src_count])->flags;
1059 if ((flags & BSF_GLOBAL) ||
1060 (flags & BSF_FORT_COMM)) {
1062 /* This symbol will go into the archive header */
1063 if (orl_count == orl_max)
1066 map = (struct orl *) bfd_realloc (arch, (char *) map,
1067 orl_max * sizeof (struct orl));
1070 (map[orl_count]).name = (char **) &((syms[src_count])->name);
1071 (map[orl_count]).pos = elt_no;
1072 (map[orl_count]).namidx = stridx;
1074 stridx += strlen ((syms[src_count])->name) + 1;
1081 /* OK, now we have collected all the data, let's write them out */
1082 if (!BFD_SEND (arch, write_armap,
1083 (arch, elength, map, orl_count, stridx))) {
1093 /* FIXME -- have to byte-swap this */
1096 bsd_write_armap (arch, elength, map, orl_count, stridx)
1098 unsigned int elength;
1103 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1104 unsigned int stringsize = stridx + 4;
1105 unsigned int mapsize = stringsize + ranlibsize;
1107 bfd *current = arch->archive_head;
1108 int last_eltno = 0; /* last element arch seen */
1112 struct stat statbuf;
1114 int padit = mapsize & 1;
1116 if (padit) mapsize ++;
1118 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1120 stat (arch->filename, &statbuf);
1121 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1122 sprintf (hdr.ar_name, RANLIBMAG);
1123 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1124 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1125 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1126 for (i = 0; i < sizeof (struct ar_hdr); i++)
1127 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1128 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1130 /* FIXME, this needs to be byte-swapped! */
1131 temp = orl_count /* + 4 */;
1132 bfd_write (&temp, 1, sizeof (temp), arch);
1134 for (count = 0; count < orl_count; count++) {
1136 struct symdef *outp = &outs;
1138 if ((map[count]).pos != last_eltno) {
1139 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1140 firstreal += firstreal % 2;
1141 last_eltno = (map[count]).pos;
1142 current = current->next;
1145 outs.s.string_offset = ((map[count]).namidx) +4;
1146 outs.file_offset = firstreal;
1147 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1150 /* now write the strings themselves */
1151 /* FIXME, this needs to be byte-swapped! */
1153 bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
1154 for (count = 0; count < orl_count; count++)
1155 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1157 /* The spec sez this should be a newline. But in order to be
1158 bug-compatible for sun's ar we use a null. */
1160 bfd_write("\0",1,1,arch);
1166 /* A coff armap looks like :
1168 struct ar_hdr with name = '/'
1170 offset of file for symbol 0
1171 offset of file for symbol 1
1173 offset of file for symbol n-1
1182 coff_write_armap (arch, elength, map, orl_count, stridx)
1184 unsigned int elength;
1189 unsigned int ranlibsize = (orl_count * 4) + 4;
1190 unsigned int stringsize = stridx;
1191 unsigned int mapsize = stringsize + ranlibsize;
1192 file_ptr archive_member_file_ptr;
1193 bfd *current = arch->archive_head;
1194 int last_eltno = 0; /* last element arch seen */
1198 int padit = mapsize & 1;
1200 if (padit) mapsize ++;
1202 archive_member_file_ptr =
1203 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1205 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1206 hdr.ar_name[0] = '/';
1207 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1208 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1209 /* This, at least, is what Intel coff sets the values to.: */
1210 sprintf ((hdr.ar_uid), "%d", 0);
1211 sprintf ((hdr.ar_gid), "%d", 0);
1212 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1213 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1215 for (i = 0; i < sizeof (struct ar_hdr); i++)
1216 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1218 /* Write the ar header for this item and the number of symbols */
1220 bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
1221 /* FIXME, this needs to be byte-swapped */
1222 bfd_write ((PTR)&orl_count, 1, sizeof (orl_count), arch);
1224 /* Two passes, first write the file offsets for each symbol -
1225 remembering that each offset is on a two byte boundary
1228 for (count = 0; count < orl_count; count++) {
1229 while ((map[count]).pos != last_eltno) {
1230 /* If this is the first time we've seen a ref to this archive
1231 then remember it's size */
1232 archive_member_file_ptr +=
1233 arelt_size (current) + sizeof (struct ar_hdr);
1234 archive_member_file_ptr += archive_member_file_ptr % 2;
1235 current = current->next;
1238 /* FIXME, this needs to be byte-swapped */
1239 bfd_write ((PTR)&archive_member_file_ptr,
1241 sizeof (archive_member_file_ptr),
1245 /* now write the strings themselves */
1246 for (count = 0; count < orl_count; count++) {
1247 bfd_write ((PTR)*((map[count]).name),
1249 strlen (*((map[count]).name))+1, arch);
1252 /* The spec sez this should be a newline. But in order to be
1253 bug-compatible for arc960 we use a null. */
1255 bfd_write("\0",1,1,arch);