1 /* BFD back-end for archive files (libraries).
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 @setfilename archive-info
27 An archive (or library) is just another BFD. It has a symbol
28 table, although there's not much a user program will do with it.
30 The big difference between an archive BFD and an ordinary BFD
31 is that the archive doesn't have sections. Instead it has a
32 chain of BFDs that are considered its contents. These BFDs can
33 be manipulated like any other. The BFDs contained in an
34 archive opened for reading will all be opened for reading. You
35 may put either input or output BFDs into an archive opened for
36 output; they will be handled correctly when the archive is closed.
38 Use <<bfd_openr_next_archived_file>> to step through
39 the contents of an archive opened for input. You don't
40 have to read the entire archive if you don't want
41 to! Read it until you find what you want.
43 Archive contents of output BFDs are chained through the
44 <<next>> pointer in a BFD. The first one is findable through
45 the <<archive_head>> slot of the archive. Set it with
46 <<bfd_set_archive_head>> (q.v.). A given BFD may be in only one
47 open output archive at a time.
49 As expected, the BFD archive code is more general than the
50 archive code of any given environment. BFD archives may
51 contain files of different formats (e.g., a.out and coff) and
52 even different architectures. You may even place archives
53 recursively into archives!
55 This can cause unexpected confusion, since some archive
56 formats are more expressive than others. For instance, Intel
57 COFF archives can preserve long filenames; SunOS a.out archives
58 cannot. If you move a file from the first to the second
59 format and back again, the filename may be truncated.
60 Likewise, different a.out environments have different
61 conventions as to how they truncate filenames, whether they
62 preserve directory names in filenames, etc. When
63 interoperating with native tools, be sure your files are
66 Beware: most of these formats do not react well to the
67 presence of spaces in filenames. We do the best we can, but
68 can't always handle this case due to restrictions in the format of
69 archives. Many Unix utilities are braindead in regards to
70 spaces and such in filenames anyway, so this shouldn't be much
73 Archives are supported in BFD in <<archive.c>>.
78 o - all archive elements start on an even boundary, newline padded;
79 o - all arch headers are char *;
80 o - all arch headers are the same size (across architectures).
83 /* Some formats provide a way to cram a long filename into the short
84 (16 chars) space provided by a BSD archive. The trick is: make a
85 special "file" in the front of the archive, sort of like the SYMDEF
86 entry. If the filename is too long to fit, put it in the extended
87 name table, and use its index as the filename. To prevent
88 confusion prepend the index with a space. This means you can't
89 have filenames that start with a space, but then again, many Unix
90 utilities can't handle that anyway.
92 This scheme unfortunately requires that you stand on your head in
93 order to write an archive since you need to put a magic file at the
94 front, and need to touch every entry to do so. C'est la vie.
96 We support two variants of this idea:
97 The SVR4 format (extended name table is named "//"),
98 and an extended pseudo-BSD variant (extended name table is named
99 "ARFILENAMES/"). The origin of the latter format is uncertain.
101 BSD 4.4 uses a third scheme: It writes a long filename
102 directly after the header. This allows 'ar q' to work.
103 We currently can read BSD 4.4 archives, but not write them.
106 /* Summary of archive member names:
108 Symbol table (must be first):
109 "__.SYMDEF " - Symbol table, Berkeley style, produced by ranlib.
110 "/ " - Symbol table, system 5 style.
112 Long name table (must be before regular file members):
113 "// " - Long name table, System 5 R4 style.
114 "ARFILENAMES/ " - Long name table, non-standard extended BSD (not BSD 4.4).
116 Regular file members with short names:
117 "filename.o/ " - Regular file, System 5 style (embedded spaces ok).
118 "filename.o " - Regular file, Berkeley style (no embedded spaces).
120 Regular files with long names (or embedded spaces, for BSD variants):
121 "/18 " - SVR4 style, name at offset 18 in name table.
122 "#1/23 " - Long name (or embedded paces) 23 characters long,
123 BSD 4.4 style, full name follows header.
124 Implemented for reading, not writing.
125 " 18 " - Long name 18 characters long, extended pseudo-BSD.
132 #include "aout/ranlib.h"
134 #include <string.h> /* For memchr, strrchr and friends */
142 #define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
145 /* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file
146 is included, then obstack.h, which thinks if offsetof is defined, it
147 doesn't need to include stddef.h. */
148 /* Define offsetof for those systems which lack it */
150 #if !defined (offsetof)
151 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
154 /* We keep a cache of archive filepointers to archive elements to
155 speed up searching the archive by filepos. We only add an entry to
156 the cache when we actually read one. We also don't sort the cache;
157 it's generally short enough to search linearly.
158 Note that the pointers here point to the front of the ar_hdr, not
159 to the front of the contents!
164 struct ar_cache *next;
167 #define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
168 #define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
170 #define arch_eltdata(bfd) ((struct areltdata *)((bfd)->arelt_data))
171 #define arch_hdr(bfd) ((struct ar_hdr *)arch_eltdata(bfd)->arch_header)
173 /* Forward declarations of functions */
176 compute_and_write_armap PARAMS ((bfd *arch, unsigned int elength));
179 bsd_update_armap_timestamp PARAMS ((bfd *arch));
184 _bfd_generic_mkarchive (abfd)
187 abfd->tdata.aout_ar_data = (struct artdata *)bfd_zalloc(abfd,
188 sizeof (struct artdata));
190 if (bfd_ardata (abfd) == NULL) {
191 bfd_error = no_memory;
194 bfd_ardata(abfd)->cache = 0;
203 symindex bfd_get_next_mapent(bfd *abfd, symindex previous, carsym **sym);
206 Step through archive @var{abfd}'s symbol table (if it
207 has one). Successively update @var{sym} with the next symbol's
208 information, returning that symbol's (internal) index into the
211 Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get
212 the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already
215 A <<carsym>> is a canonical archive symbol. The only
216 user-visible element is its name, a null-terminated string.
220 DEFUN(bfd_get_next_mapent,(abfd, prev, entry),
225 if (!bfd_has_map (abfd)) {
226 bfd_error = invalid_operation;
227 return BFD_NO_MORE_SYMBOLS;
230 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
231 else if (++prev >= bfd_ardata (abfd)->symdef_count)
232 return BFD_NO_MORE_SYMBOLS;
234 *entry = (bfd_ardata (abfd)->symdefs + prev);
238 /* To be called by backends only */
241 _bfd_create_empty_archive_element_shell (obfd)
246 nbfd = new_bfd_contained_in(obfd);
249 bfd_error = no_memory;
260 boolean bfd_set_archive_head(bfd *output, bfd *new_head);
263 Set the head of the chain of
264 BFDs contained in the archive @var{output} to @var{new_head}.
268 DEFUN(bfd_set_archive_head,(output_archive, new_head),
269 bfd *output_archive AND
273 output_archive->archive_head = new_head;
278 look_for_bfd_in_cache (arch_bfd, filepos)
282 struct ar_cache *current;
284 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
285 current = current->next)
286 if (current->ptr == filepos) return current->arelt;
291 /* Kind of stupid to call cons for each one, but we don't do too many */
293 add_bfd_to_cache (arch_bfd, filepos, new_elt)
294 bfd *arch_bfd, *new_elt;
297 struct ar_cache *new_cache = (struct ar_cache *)
298 bfd_zalloc(arch_bfd, sizeof (struct ar_cache));
300 if (new_cache == NULL) {
301 bfd_error = no_memory;
305 new_cache->ptr = filepos;
306 new_cache->arelt = new_elt;
307 new_cache->next = (struct ar_cache *)NULL;
308 if (bfd_ardata (arch_bfd)->cache == NULL)
309 bfd_ardata (arch_bfd)->cache = new_cache;
311 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
313 while (current->next != NULL)
314 current = current->next;
315 current->next = new_cache;
323 /* The name begins with space. Hence the rest of the name is an index into
326 get_extended_arelt_filename (arch, name)
330 unsigned long index = 0;
332 /* Should extract string so that I can guarantee not to overflow into
333 the next region, but I'm too lazy. */
335 /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */
336 index = strtol (name+1, NULL, 10);
338 bfd_error = malformed_archive;
342 return bfd_ardata (arch)->extended_names + index;
345 /* This functions reads an arch header and returns an areltdata pointer, or
348 Presumes the file pointer is already in the right place (ie pointing
349 to the ar_hdr in the file). Moves the file pointer; on success it
350 should be pointing to the front of the file contents; on failure it
351 could have been moved arbitrarily.
363 char *hdrp = (char *) &hdr;
364 unsigned int parsed_size;
365 struct areltdata *ared;
366 char *filename = NULL;
367 unsigned int namelen = 0;
368 unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
371 if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
372 != sizeof (struct ar_hdr)) {
373 bfd_error = no_more_archived_files;
376 if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
377 bfd_error = malformed_archive;
382 parsed_size = strtol (hdr.ar_size, NULL, 10);
384 bfd_error = malformed_archive;
388 /* extract the filename from the archive - there are two ways to
389 specify an extendend name table, either the first char of the
390 name is a space, or it's a slash. */
391 if ((hdr.ar_name[0] == '/'
392 || (hdr.ar_name[0] == ' '
393 && memchr (hdr.ar_name, '/', ar_maxnamelen(abfd)) == NULL))
394 && bfd_ardata (abfd)->extended_names != NULL) {
395 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
396 if (filename == NULL) {
397 bfd_error = malformed_archive;
401 /* BSD4.4-style long filename.
402 Only implemented for reading, so far! */
403 else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1'
404 && hdr.ar_name[2] == '/' && isdigit(hdr.ar_name[3]))
406 /* BSD-4.4 extended name */
407 namelen = atoi (&hdr.ar_name[3]);
408 allocsize += namelen + 1;
409 parsed_size -= namelen;
411 allocptr = bfd_zalloc(abfd, allocsize);
412 if (allocptr == NULL) {
413 bfd_error = no_memory;
417 + (sizeof (struct areltdata) + sizeof (struct ar_hdr));
418 if (bfd_read (filename, 1, namelen, abfd) != namelen) {
419 bfd_error = no_more_archived_files;
422 filename[namelen] = '\0';
426 /* We judge the end of the name by looking for '/' or ' '.
427 Note: The SYSV format (terminated by '/') allows embedded
428 spaces, so only look for ' ' if we don't find '/'. */
431 while (hdr.ar_name[namelen] != '\0' &&
432 hdr.ar_name[namelen] != '/') {
434 if (namelen == (unsigned)ar_maxnamelen(abfd)) {
436 while (hdr.ar_name[namelen] != ' '
437 && namelen < (unsigned)ar_maxnamelen(abfd)) {
444 allocsize += namelen + 1;
448 allocptr = bfd_zalloc(abfd, allocsize);
449 if (allocptr == NULL) {
450 bfd_error = no_memory;
455 ared = (struct areltdata *) allocptr;
457 ared->arch_header = allocptr + sizeof (struct areltdata);
458 memcpy ((char *) ared->arch_header, (char *) &hdr, sizeof (struct ar_hdr));
459 ared->parsed_size = parsed_size;
461 if (filename != NULL) ared->filename = filename;
463 ared->filename = allocptr + (sizeof (struct areltdata) +
464 sizeof (struct ar_hdr));
466 memcpy (ared->filename, hdr.ar_name, namelen);
467 ared->filename[namelen] = '\0';
473 /* This is an internal function; it's mainly used when indexing
474 through the archive symbol table, but also used to get the next
475 element, since it handles the bookkeeping so nicely for us.
479 get_elt_at_filepos (archive, filepos)
483 struct areltdata *new_areldata;
486 n_nfd = look_for_bfd_in_cache (archive, filepos);
490 if (0 > bfd_seek (archive, filepos, SEEK_SET))
492 bfd_error = system_call_error;
496 if ((new_areldata = snarf_ar_hdr (archive)) == NULL)
499 n_nfd = _bfd_create_empty_archive_element_shell (archive);
502 bfd_release (archive, (PTR)new_areldata);
506 n_nfd->origin = bfd_tell (archive);
507 n_nfd->arelt_data = (PTR) new_areldata;
508 n_nfd->filename = new_areldata->filename;
510 if (add_bfd_to_cache (archive, filepos, n_nfd))
514 bfd_release (archive, (PTR)n_nfd);
515 bfd_release (archive, (PTR)new_areldata);
524 bfd *bfd_get_elt_at_index(bfd *archive, int index);
527 Return the BFD which is referenced by the symbol in @var{archive}
528 indexed by @var{index}. @var{index} should have been returned by
529 <<bfd_get_next_mapent>> (q.v.).
533 DEFUN(bfd_get_elt_at_index,(abfd, index),
539 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
545 bfd_openr_next_archived_file
548 bfd *bfd_openr_next_archived_file(bfd *archive, bfd *previous);
551 Provided a BFD, @var{archive}, containing an archive and NULL, open
552 an input BFD on the first contained element and returns that.
553 Subsequent calls should pass
554 the archive and the previous return value to return a created
555 BFD to the next contained element. NULL is returned when there
561 bfd_openr_next_archived_file (archive, last_file)
565 if ((bfd_get_format (archive) != bfd_archive) ||
566 (archive->direction == write_direction))
568 bfd_error = invalid_operation;
572 return BFD_SEND (archive,
573 openr_next_archived_file,
579 bfd_generic_openr_next_archived_file (archive, last_file)
586 filestart = bfd_ardata (archive)->first_file_filepos;
588 unsigned int size = arelt_size(last_file);
589 /* Pad to an even boundary...
590 Note that last_file->origin can be odd in the case of
591 BSD-4.4-style element with a long odd size. */
592 filestart = last_file->origin + size;
593 filestart += filestart % 2;
596 return get_elt_at_filepos (archive, filestart);
601 bfd_generic_archive_p (abfd)
604 char armag[SARMAG+1];
606 if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
607 bfd_error = wrong_format;
612 if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
614 if (strncmp (armag, ARMAG, SARMAG) &&
615 strncmp (armag, ARMAGB, SARMAG)) return 0;
620 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
621 involves a cast, we can't do it as the left operand of assignment. */
622 abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc(abfd,sizeof (struct artdata));
624 if (bfd_ardata (abfd) == NULL) {
625 bfd_error = no_memory;
629 bfd_ardata (abfd)->first_file_filepos = SARMAG;
631 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
632 bfd_release(abfd, bfd_ardata (abfd));
633 abfd->tdata.aout_ar_data = NULL;
637 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
638 bfd_release(abfd, bfd_ardata (abfd));
639 abfd->tdata.aout_ar_data = NULL;
646 /* Returns false on error, true otherwise */
648 DEFUN (do_slurp_bsd_armap, (abfd),
651 struct areltdata *mapdata;
652 unsigned int counter = 0;
653 int *raw_armap, *rbase;
654 struct artdata *ardata = bfd_ardata (abfd);
656 unsigned int parsed_size;
658 mapdata = snarf_ar_hdr (abfd);
659 if (mapdata == NULL) return false;
660 parsed_size = mapdata->parsed_size;
661 bfd_release (abfd, (PTR)mapdata); /* Don't need it any more. */
663 raw_armap = (int *) bfd_zalloc(abfd, parsed_size);
664 if (raw_armap == NULL) {
665 bfd_error = no_memory;
669 if (bfd_read ((PTR)raw_armap, 1, parsed_size, abfd) != parsed_size) {
670 bfd_error = malformed_archive;
672 bfd_release (abfd, (PTR)raw_armap);
676 ardata->symdef_count = (bfd_h_get_32 (abfd, (bfd_byte *) raw_armap)
677 / sizeof (struct symdef));
679 if (ardata->symdef_count * sizeof (struct symdef)
680 > parsed_size - sizeof (*raw_armap)) {
681 /* Probably we're using the wrong byte ordering. */
682 bfd_error = wrong_format;
688 ardata->symdefs = (carsym *) rbase;
689 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
691 for (;counter < ardata->symdef_count; counter++) {
692 struct symdef *sym = ((struct symdef *) rbase) + counter;
693 sym->s.name = (bfd_h_get_32 (abfd, (bfd_byte *) (&sym->s.string_offset))
695 sym->file_offset = bfd_h_get_32 (abfd,
696 (bfd_byte *) (&(sym->file_offset)));
699 ardata->first_file_filepos = bfd_tell (abfd);
700 /* Pad to an even boundary if you have to */
701 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
702 /* FIXME, we should provide some way to free raw_ardata when
703 we are done using the strings from it. For now, it seems
704 to be allocated on an obstack anyway... */
705 bfd_has_map (abfd) = true;
709 /* Returns false on error, true otherwise */
711 DEFUN (do_slurp_coff_armap, (abfd),
714 struct areltdata *mapdata;
715 int *raw_armap, *rawptr;
716 struct artdata *ardata = bfd_ardata (abfd);
718 unsigned int stringsize;
719 unsigned int parsed_size;
721 unsigned int nsymz; /* Number of symbols in armap. */
723 bfd_vma (*swap) PARAMS ((bfd_byte*));
724 char int_buf[sizeof(long)];
725 unsigned int carsym_size, ptrsize, i;
727 mapdata = snarf_ar_hdr (abfd);
728 if (mapdata == NULL) return false;
729 parsed_size = mapdata->parsed_size;
730 bfd_release (abfd, (PTR)mapdata); /* Don't need it any more. */
732 if (bfd_read ((PTR)int_buf, 1, 4, abfd) != 4) {
733 bfd_error = malformed_archive;
736 /* It seems that all numeric information in a coff archive is always
737 in big endian format, nomatter the host or target. */
739 nsymz = bfd_getb32((PTR)int_buf);
740 stringsize = parsed_size - (4 * nsymz) - 4;
743 /* ... except that some archive formats are broken, and it may be our
744 fault - the i960 little endian coff sometimes has big and sometimes
745 little, because our tools changed. Here's a horrible hack to clean
748 if (stringsize > 0xfffff) {
749 /* This looks dangerous, let's do it the other way around */
750 nsymz = bfd_getl32((PTR)int_buf);
751 stringsize = parsed_size - (4 * nsymz) - 4;
756 /* The coff armap must be read sequentially. So we construct a bsd-style
757 one in core all at once, for simplicity. */
759 carsym_size = (nsymz * sizeof (carsym));
760 ptrsize = (4 * nsymz);
762 ardata->symdefs = (carsym *) bfd_zalloc(abfd, carsym_size + stringsize + 1);
763 if (ardata->symdefs == NULL) {
764 bfd_error = no_memory;
767 carsyms = ardata->symdefs;
768 stringbase = ((char *) ardata->symdefs) + carsym_size;
770 /* Allocate and read in the raw offsets. */
771 raw_armap = (int *) bfd_alloc(abfd, ptrsize);
772 if (raw_armap == NULL) {
773 bfd_error = no_memory;
774 goto release_symdefs;
776 if (bfd_read ((PTR)raw_armap, 1, ptrsize, abfd) != ptrsize
777 || bfd_read ((PTR)stringbase, 1, stringsize, abfd) != stringsize) {
778 bfd_error = malformed_archive;
779 goto release_raw_armap;
782 /* OK, build the carsyms */
783 for (i = 0; i < nsymz; i++) {
784 rawptr = raw_armap + i;
785 carsyms->file_offset = swap((PTR)rawptr);
786 carsyms->name = stringbase;
787 stringbase += strlen (stringbase) + 1;
792 ardata->symdef_count = nsymz;
793 ardata->first_file_filepos = bfd_tell (abfd);
794 /* Pad to an even boundary if you have to */
795 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
797 bfd_has_map (abfd) = true;
798 bfd_release (abfd, (PTR)raw_armap);
802 bfd_release (abfd, (PTR)raw_armap);
804 bfd_release (abfd, (PTR)(ardata)->symdefs);
808 /* This routine can handle either coff-style or bsd-style armaps.
809 Returns false on error, true otherwise */
812 bfd_slurp_armap (abfd)
816 int i = bfd_read ((PTR)nextname, 1, 16, abfd);
823 bfd_seek (abfd, (file_ptr) -16, SEEK_CUR);
825 if (!strncmp (nextname, "__.SYMDEF ", 16))
826 return do_slurp_bsd_armap (abfd);
827 else if (!strncmp (nextname, "/ ", 16))
828 return do_slurp_coff_armap (abfd);
830 bfd_has_map (abfd) = false;
834 /* Returns false on error, true otherwise */
835 /* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the
836 header is in a slightly different order and the map name is '/'.
837 This flavour is used by hp300hpux. */
839 bfd_slurp_bsd_armap_f2 (abfd)
842 struct areltdata *mapdata;
844 unsigned int counter = 0;
845 int *raw_armap, *rbase;
846 struct artdata *ardata = bfd_ardata (abfd);
848 unsigned int stringsize;
849 int i = bfd_read ((PTR)nextname, 1, 16, abfd);
856 /* The archive has at least 16 bytes in it */
857 bfd_seek (abfd, -16L, SEEK_CUR);
859 if (!strncmp (nextname, "__.SYMDEF ", 16))
860 return do_slurp_bsd_armap (abfd);
862 if (strncmp (nextname, "/ ", 16))
864 bfd_has_map (abfd) = false;
868 mapdata = snarf_ar_hdr (abfd);
869 if (mapdata == NULL) return false;
871 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
872 if (raw_armap == NULL)
874 bfd_error = no_memory;
876 bfd_release (abfd, (PTR)mapdata);
880 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
881 mapdata->parsed_size)
883 bfd_error = malformed_archive;
885 bfd_release (abfd, (PTR)raw_armap);
889 ardata->symdef_count = bfd_h_get_16(abfd, (PTR)raw_armap);
891 if (ardata->symdef_count * sizeof (struct symdef)
892 > mapdata->parsed_size - sizeof (*raw_armap))
894 /* Probably we're using the wrong byte ordering. */
895 bfd_error = wrong_format;
901 stringsize = bfd_h_get_32(abfd, (PTR)(((char*)raw_armap)+2));
902 /* skip sym count and string sz */
903 rbase = (int*)(((char*)raw_armap) + 6);
904 stringbase = (char *) rbase;
905 ardata->symdefs = (carsym *)(((char*) rbase) + stringsize);
907 for (;counter < ardata->symdef_count; counter++)
909 struct symdef *sym = ((struct symdef *) ardata->symdefs) + counter;
910 sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
911 sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
914 ardata->first_file_filepos = bfd_tell (abfd);
915 /* Pad to an even boundary if you have to */
916 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
917 /* FIXME, we should provide some way to free raw_ardata when
918 we are done using the strings from it. For now, it seems
919 to be allocated on an obstack anyway... */
920 bfd_has_map (abfd) = true;
924 /** Extended name table.
926 Normally archives support only 14-character filenames.
928 Intel has extended the format: longer names are stored in a special
929 element (the first in the archive, or second if there is an armap);
930 the name in the ar_hdr is replaced by <space><index into filename
931 element>. Index is the P.R. of an int (decimal). Data General have
932 extended the format by using the prefix // for the special element */
934 /* Returns false on error, true otherwise */
936 _bfd_slurp_extended_name_table (abfd)
940 struct areltdata *namedata;
942 /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
943 we probably don't want to return true. */
944 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
946 bfd_seek (abfd, (file_ptr) -16, SEEK_CUR);
948 if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
949 strncmp (nextname, "// ", 16) != 0)
951 bfd_ardata (abfd)->extended_names = NULL;
955 namedata = snarf_ar_hdr (abfd);
956 if (namedata == NULL) return false;
958 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
959 if (bfd_ardata (abfd)->extended_names == NULL) {
960 bfd_error = no_memory;
962 bfd_release (abfd, (PTR)namedata);
966 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
967 namedata->parsed_size, abfd) != namedata->parsed_size) {
968 bfd_error = malformed_archive;
969 bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
970 bfd_ardata (abfd)->extended_names = NULL;
974 /* Since the archive is supposed to be printable if it contains
975 text, the entries in the list are newline-padded, not null
976 padded. In SVR4-style archives, the names also have a
977 trailing '/'. We'll fix both problems here.. */
979 char *temp = bfd_ardata (abfd)->extended_names;
980 char *limit = temp + namedata->parsed_size;
981 for (; temp < limit; ++temp)
983 temp[temp[-1] == '/' ? -1 : 0] = '\0';
986 /* Pad to an even boundary if you have to */
987 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
988 bfd_ardata (abfd)->first_file_filepos +=
989 (bfd_ardata (abfd)->first_file_filepos) %2;
991 /* FIXME, we can't release namedata here because it was allocated
992 below extended_names on the obstack... */
993 /* bfd_release (abfd, namedata); */
1000 /* Return a copy of the stuff in the filename between any :]> and a
1003 DEFUN(normalize,(file),
1010 first = file + strlen(file)-1;
1013 while (first != file)
1017 if (*first == ':' || *first == ']' ||*first == '>')
1026 copy = bfd_xmalloc(last - first + 1);
1027 memcpy(copy, first, last-first);
1028 copy[last-first] = 0;
1035 DEFUN (normalize, (file),
1038 CONST char * filename = strrchr(file, '/');
1040 if (filename != (char *)NULL) {
1049 /* Follows archive_head and produces an extended name table if necessary.
1050 Returns (in tabloc) a pointer to an extended name table, and in tablen
1051 the length of the table. If it makes an entry it clobbers the filename
1052 so that the element may be written without further massage.
1053 Returns true if it ran successfully, false if something went wrong.
1054 A successful return may still involve a zero-length tablen!
1057 DEFUN (bfd_construct_extended_name_table, (abfd, tabloc, tablen),
1060 unsigned int *tablen)
1062 unsigned int maxname = abfd->xvec->ar_max_namelen;
1063 unsigned int total_namelen = 0;
1069 /* Figure out how long the table should be */
1070 for (current = abfd->archive_head; current != NULL; current = current->next){
1071 unsigned int thislen = strlen (normalize(current->filename));
1072 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
1075 if (total_namelen == 0) return true;
1077 *tabloc = bfd_zalloc (abfd,total_namelen);
1078 if (*tabloc == NULL) {
1079 bfd_error = no_memory;
1083 *tablen = total_namelen;
1086 for (current = abfd->archive_head; current != NULL; current =
1088 CONST char *normal =normalize( current->filename);
1089 unsigned int thislen = strlen (normal);
1090 if (thislen > maxname) {
1091 /* Works for now; may need to be re-engineered if we encounter an oddball
1092 archive format and want to generalise this hack. */
1093 struct ar_hdr *hdr = arch_hdr(current);
1094 strcpy (strptr, normal);
1095 strptr[thislen] = '\n';
1096 hdr->ar_name[0] = ' ';
1097 /* We know there will always be enough room (one of the few cases
1098 where you may safely use sprintf). */
1099 sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc));
1100 /* Kinda Kludgy. We should just use the returned value of sprintf
1101 but not all implementations get this right */
1103 char *temp = hdr->ar_name +2;
1104 for (; temp < hdr->ar_name + maxname; temp++)
1105 if (*temp == '\0') *temp = ' ';
1107 strptr += thislen + 1;
1114 /** A couple of functions for creating ar_hdrs */
1116 /* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
1117 The filename must refer to a filename in the filesystem.
1118 The filename field of the ar_hdr will NOT be initialized
1122 DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
1124 CONST char *filename)
1127 struct areltdata *ared;
1132 if (stat (filename, &status) != 0) {
1133 bfd_error = system_call_error;
1137 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
1138 sizeof (struct areltdata));
1140 bfd_error = no_memory;
1143 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
1145 /* ar headers are space padded, not null padded! */
1146 memset (hdr, ' ', sizeof (struct ar_hdr));
1148 strncpy (hdr->ar_fmag, ARFMAG, 2);
1150 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
1151 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
1152 sprintf ((hdr->ar_uid), "%d", status.st_uid);
1153 sprintf ((hdr->ar_gid), "%d", status.st_gid);
1154 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
1155 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
1156 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
1157 understand how these C losers could design such a ramshackle bunch of
1159 temp = (char *) hdr;
1160 temp1 = temp + sizeof (struct ar_hdr) - 2;
1161 for (; temp < temp1; temp++) {
1162 if (*temp == '\0') *temp = ' ';
1164 strncpy (hdr->ar_fmag, ARFMAG, 2);
1165 ared->parsed_size = status.st_size;
1166 ared->arch_header = (char *) hdr;
1171 /* This is magic required by the "ar" program. Since it's
1172 undocumented, it's undocumented. You may think that it would
1173 take a strong stomach to write this, and it does, but it takes
1174 even a stronger stomach to try to code around such a thing!
1178 DEFUN(bfd_special_undocumented_glue, (abfd, filename),
1182 struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename);
1185 return (struct ar_hdr *) ar_elt->arch_header;
1189 /* Analogous to stat call */
1191 bfd_generic_stat_arch_elt (abfd, buf)
1198 if (abfd->arelt_data == NULL) {
1199 bfd_error = invalid_operation;
1203 hdr = arch_hdr (abfd);
1205 #define foo(arelt, stelt, size) \
1206 buf->stelt = strtol (hdr->arelt, &aloser, size); \
1207 if (aloser == hdr->arelt) return -1;
1209 foo (ar_date, st_mtime, 10);
1210 foo (ar_uid, st_uid, 10);
1211 foo (ar_gid, st_gid, 10);
1212 foo (ar_mode, st_mode, 8);
1214 buf->st_size = arch_eltdata (abfd)->parsed_size;
1220 bfd_dont_truncate_arname (abfd, pathname, arhdr)
1222 CONST char *pathname;
1225 /* FIXME: This interacts unpleasantly with ar's quick-append option.
1226 Fortunately ic960 users will never use that option. Fixing this
1227 is very hard; fortunately I know how to do it and will do so once
1228 intel's release is out the door. */
1230 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1232 CONST char *filename = normalize(pathname);
1233 int maxlen = ar_maxnamelen (abfd);
1235 length = strlen (filename);
1237 if (length <= maxlen)
1238 memcpy (hdr->ar_name, filename, length);
1240 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
1246 bfd_bsd_truncate_arname (abfd, pathname, arhdr)
1248 CONST char *pathname;
1251 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1253 CONST char *filename = strrchr (pathname, '/');
1254 int maxlen = ar_maxnamelen (abfd);
1257 if (filename == NULL)
1258 filename = pathname;
1262 length = strlen (filename);
1264 if (length <= maxlen)
1265 memcpy (hdr->ar_name, filename, length);
1267 /* pathname: meet procrustes */
1268 memcpy (hdr->ar_name, filename, maxlen);
1272 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
1275 /* Store name into ar header. Truncates the name to fit.
1276 1> strip pathname to be just the basename.
1277 2> if it's short enuf to fit, stuff it in.
1278 3> If it doesn't end with .o, truncate it to fit
1279 4> truncate it before the .o, append .o, stuff THAT in.
1282 /* This is what gnu ar does. It's better but incompatible with the bsd ar. */
1284 bfd_gnu_truncate_arname (abfd, pathname, arhdr)
1286 CONST char *pathname;
1289 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
1291 CONST char *filename = strrchr (pathname, '/');
1292 int maxlen = ar_maxnamelen (abfd);
1294 if (filename == NULL)
1295 filename = pathname;
1299 length = strlen (filename);
1301 if (length <= maxlen)
1302 memcpy (hdr->ar_name, filename, length);
1303 else { /* pathname: meet procrustes */
1304 memcpy (hdr->ar_name, filename, maxlen);
1305 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
1306 hdr->ar_name[maxlen - 2] = '.';
1307 hdr->ar_name[maxlen - 1] = 'o';
1312 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
1316 /* The BFD is open for write and has its format set to bfd_archive */
1318 _bfd_write_archive_contents (arch)
1322 char *etable = NULL;
1323 unsigned int elength = 0;
1324 boolean makemap = bfd_has_map (arch);
1325 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
1329 /* Verify the viability of all entries; if any of them live in the
1330 filesystem (as opposed to living in an archive open for input)
1331 then construct a fresh ar_hdr for them.
1333 for (current = arch->archive_head; current; current = current->next) {
1334 if (bfd_write_p (current)) {
1335 bfd_error = invalid_operation;
1338 if (!current->arelt_data) {
1339 current->arelt_data =
1340 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
1341 if (!current->arelt_data) return false;
1343 /* Put in the file name */
1345 BFD_SEND (arch, _bfd_truncate_arname,(arch,
1347 (char *) arch_hdr(current)));
1352 if (makemap) { /* don't bother if we won't make a map! */
1353 if ((bfd_check_format (current, bfd_object))
1354 #if 0 /* FIXME -- these are not set correctly */
1355 && ((bfd_get_file_flags (current) & HAS_SYMS))
1362 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
1365 bfd_seek (arch, (file_ptr) 0, SEEK_SET);
1367 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
1369 bfd_write (ARMAG, 1, SARMAG, arch);
1372 if (makemap && hasobjects) {
1374 if (compute_and_write_armap (arch, elength) != true) {
1382 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1383 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
1384 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
1385 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1386 for (i = 0; i < sizeof (struct ar_hdr); i++)
1387 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1388 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1389 bfd_write (etable, 1, elength, arch);
1390 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
1394 for (current = arch->archive_head; current; current = current->next) {
1395 char buffer[DEFAULT_BUFFERSIZE];
1396 unsigned int remaining = arelt_size (current);
1397 struct ar_hdr *hdr = arch_hdr(current);
1398 /* write ar header */
1400 if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
1402 bfd_error = system_call_error;
1405 if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) goto syserr;
1408 unsigned int amt = DEFAULT_BUFFERSIZE;
1409 if (amt > remaining) {
1413 if (bfd_read (buffer, amt, 1, current) != amt) {
1414 if (errno) goto syserr;
1415 /* Looks like a truncated archive. */
1416 bfd_error = malformed_archive;
1419 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
1422 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1425 /* Verify the timestamp in the archive file. If it would
1426 not be accepted by the linker, rewrite it until it would be.
1427 If anything odd happens, break out and just return.
1428 (The Berkeley linker checks the timestamp and refuses to read the
1429 table-of-contents if it is >60 seconds less than the file's
1430 modified-time. That painful hack requires this painful hack. */
1434 /* FIXME! This kludge is to avoid adding a member to the xvec,
1435 while generating a small patch for Adobe. FIXME! The
1436 update_armap_timestamp function call should be in the xvec,
1439 if (bfd_update_armap_timestamp (arch) == true) break;
1442 Instead, we check whether in a BSD archive, and call directly. */
1444 if (arch->xvec->write_armap != bsd_write_armap)
1446 if (bsd_update_armap_timestamp(arch) == true) /* FIXME!!! Vector it */
1450 "Warning: writing archive was slow: rewriting timestamp\n");
1451 } while (++tries < 6 );
1456 /* Note that the namidx for the first symbol is 0 */
1459 compute_and_write_armap (arch, elength)
1461 unsigned int elength;
1464 file_ptr elt_no = 0;
1466 int orl_max = 15000; /* fine initial default */
1468 int stridx = 0; /* string index */
1470 /* Dunno if this is the best place for this info... */
1471 if (elength != 0) elength += sizeof (struct ar_hdr);
1472 elength += elength %2 ;
1474 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
1476 bfd_error = no_memory;
1480 /* Drop all the files called __.SYMDEF, we're going to make our
1482 while (arch->archive_head &&
1483 strcmp(arch->archive_head->filename,"__.SYMDEF") == 0)
1485 arch->archive_head = arch->archive_head->next;
1487 /* Map over each element */
1488 for (current = arch->archive_head;
1489 current != (bfd *)NULL;
1490 current = current->next, elt_no++)
1492 if ((bfd_check_format (current, bfd_object) == true)
1493 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1495 unsigned int storage;
1496 unsigned int symcount;
1497 unsigned int src_count;
1499 storage = get_symtab_upper_bound (current);
1502 syms = (asymbol **) bfd_zalloc (arch,storage);
1504 bfd_error = no_memory; /* FIXME -- memory leak */
1507 symcount = bfd_canonicalize_symtab (current, syms);
1510 /* Now map over all the symbols, picking out the ones we want */
1511 for (src_count = 0; src_count <symcount; src_count++) {
1513 (syms[src_count])->flags;
1515 syms[src_count]->section;
1517 if ((flags & BSF_GLOBAL ||
1519 flags & BSF_INDIRECT ||
1520 bfd_is_com_section (sec))
1521 && (sec != &bfd_und_section)) {
1523 /* This symbol will go into the archive header */
1524 if (orl_count == orl_max)
1527 map = (struct orl *) bfd_realloc (arch, (char *) map,
1528 orl_max * sizeof (struct orl));
1531 (map[orl_count]).name = (char **) &((syms[src_count])->name);
1532 (map[orl_count]).pos = (file_ptr) current;
1533 (map[orl_count]).namidx = stridx;
1535 stridx += strlen ((syms[src_count])->name) + 1;
1542 /* OK, now we have collected all the data, let's write them out */
1543 if (!BFD_SEND (arch, write_armap,
1544 (arch, elength, map, orl_count, stridx))) {
1554 bsd_write_armap (arch, elength, map, orl_count, stridx)
1556 unsigned int elength;
1558 unsigned int orl_count;
1561 int padit = stridx & 1;
1562 unsigned int ranlibsize = orl_count * sizeof (struct ranlib);
1563 unsigned int stringsize = stridx + padit;
1564 /* Include 8 bytes to store ranlibsize and stringsize in output. */
1565 unsigned int mapsize = ranlibsize + stringsize + 8;
1567 bfd *current = arch->archive_head;
1568 bfd *last_elt = current; /* last element arch seen */
1572 struct stat statbuf;
1575 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1577 stat (arch->filename, &statbuf);
1578 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1579 sprintf (hdr.ar_name, RANLIBMAG);
1580 /* Remember the timestamp, to keep it holy. But fudge it a little. */
1581 bfd_ardata(arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
1582 bfd_ardata(arch)->armap_datepos = SARMAG +
1583 offsetof(struct ar_hdr, ar_date[0]);
1584 sprintf (hdr.ar_date, "%ld", bfd_ardata(arch)->armap_timestamp);
1585 sprintf (hdr.ar_uid, "%d", getuid());
1586 sprintf (hdr.ar_gid, "%d", getgid());
1587 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1588 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1589 for (i = 0; i < sizeof (struct ar_hdr); i++)
1590 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1591 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
1592 bfd_h_put_32(arch, (bfd_vma) ranlibsize, (PTR)&temp);
1593 bfd_write (&temp, 1, sizeof (temp), arch);
1595 for (count = 0; count < orl_count; count++) {
1597 struct symdef *outp = &outs;
1599 if (((bfd *)(map[count]).pos) != last_elt) {
1601 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1602 firstreal += firstreal % 2;
1603 current = current->next;
1604 } while (current != (bfd *)(map[count]).pos);
1605 } /* if new archive element */
1608 bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
1609 bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
1610 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1613 /* now write the strings themselves */
1614 bfd_h_put_32(arch, stringsize, (PTR)&temp);
1615 bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
1616 for (count = 0; count < orl_count; count++)
1617 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1619 /* The spec sez this should be a newline. But in order to be
1620 bug-compatible for sun's ar we use a null. */
1622 bfd_write("",1,1,arch);
1628 /* At the end of archive file handling, update the timestamp in the
1629 file, so the linker will accept it.
1631 Return true if the timestamp was OK, or an unusual problem happened.
1632 Return false if we updated the timestamp. */
1635 bsd_update_armap_timestamp (arch)
1638 struct stat archstat;
1642 /* Flush writes, get last-write timestamp from file, and compare it
1643 to the timestamp IN the file. */
1645 if (bfd_stat (arch, &archstat) == -1) {
1646 perror ("Reading archive file mod timestamp");
1647 return true; /* Can't read mod time for some reason */
1649 if (archstat.st_mtime <= bfd_ardata(arch)->armap_timestamp)
1650 return true; /* OK by the linker's rules */
1652 /* Update the timestamp. */
1653 bfd_ardata(arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;
1655 /* Prepare an ASCII version suitable for writing. */
1656 memset (hdr.ar_date, 0, sizeof (hdr.ar_date));
1657 sprintf (hdr.ar_date, "%ld", bfd_ardata(arch)->armap_timestamp);
1658 for (i = 0; i < sizeof (hdr.ar_date); i++)
1659 if (hdr.ar_date[i] == '\0')
1660 (hdr.ar_date)[i] = ' ';
1662 /* Write it into the file. */
1663 bfd_seek (arch, bfd_ardata(arch)->armap_datepos, SEEK_SET);
1664 if (bfd_write (hdr.ar_date, sizeof(hdr.ar_date), 1, arch)
1665 != sizeof(hdr.ar_date)) {
1666 perror ("Writing updated armap timestamp");
1667 return true; /* Some error while writing */
1670 return false; /* We updated the timestamp successfully. */
1674 /* A coff armap looks like :
1676 struct ar_hdr with name = '/'
1678 offset of file for symbol 0
1679 offset of file for symbol 1
1681 offset of file for symbol n-1
1690 coff_write_armap (arch, elength, map, symbol_count, stridx)
1692 unsigned int elength;
1694 unsigned int symbol_count;
1697 /* The size of the ranlib is the number of exported symbols in the
1698 archive * the number of bytes in a int, + an int for the count */
1700 unsigned int ranlibsize = (symbol_count * 4) + 4;
1701 unsigned int stringsize = stridx;
1702 unsigned int mapsize = stringsize + ranlibsize;
1703 file_ptr archive_member_file_ptr;
1704 bfd *current = arch->archive_head;
1708 int padit = mapsize & 1;
1710 if (padit) mapsize ++;
1712 /* work out where the first object file will go in the archive */
1713 archive_member_file_ptr = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1715 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1716 hdr.ar_name[0] = '/';
1717 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1718 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
1719 /* This, at least, is what Intel coff sets the values to.: */
1720 sprintf ((hdr.ar_uid), "%d", 0);
1721 sprintf ((hdr.ar_gid), "%d", 0);
1722 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
1723 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1725 for (i = 0; i < sizeof (struct ar_hdr); i++)
1726 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1728 /* Write the ar header for this item and the number of symbols */
1731 bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
1733 bfd_write_bigendian_4byte_int(arch, symbol_count);
1735 /* Two passes, first write the file offsets for each symbol -
1736 remembering that each offset is on a two byte boundary. */
1738 /* Write out the file offset for the file associated with each
1739 symbol, and remember to keep the offsets padded out. */
1741 current = arch->archive_head;
1743 while (current != (bfd *)NULL && count < symbol_count) {
1744 /* For each symbol which is used defined in this object, write out
1745 the object file's address in the archive */
1747 while (((bfd *)(map[count]).pos) == current) {
1748 bfd_write_bigendian_4byte_int(arch, archive_member_file_ptr);
1751 /* Add size of this archive entry */
1752 archive_member_file_ptr += arelt_size (current) + sizeof (struct
1754 /* remember aboout the even alignment */
1755 archive_member_file_ptr += archive_member_file_ptr % 2;
1756 current = current->next;
1761 /* now write the strings themselves */
1762 for (count = 0; count < symbol_count; count++) {
1763 bfd_write ((PTR)*((map[count]).name),
1765 strlen (*((map[count]).name))+1, arch);
1768 /* The spec sez this should be a newline. But in order to be
1769 bug-compatible for arc960 we use a null. */
1771 bfd_write("",1,1,arch);