1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3 FIXME: Can someone provide a transliteration of this name into ASCII?
4 Using the following chars caused a compiler warning on HIUX (so I replaced
5 them with octal escapes), and isn't useful without an understanding of what
7 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
9 Archive support from Damon A. Permezel.
10 Contributed by IBM Corporation and Cygnus Support.
12 This file is part of BFD, the Binary File Descriptor library.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
29 #define RS6000COFF_C 1
35 #include "coff/internal.h"
36 #include "coff/rs6000.h"
39 static boolean xcoff_slurp_armap PARAMS ((bfd *));
40 static const bfd_target *xcoff_archive_p PARAMS ((bfd *));
41 static PTR xcoff_read_ar_hdr PARAMS ((bfd *));
42 static bfd *xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
43 static int xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
44 static const char *normalize_filename PARAMS ((bfd *));
45 static boolean xcoff_write_armap
46 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
47 static boolean xcoff_write_archive_contents PARAMS ((bfd *));
49 /* The main body of code is in coffcode.h. */
51 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
53 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
54 bitsize and whether they are signed or not, along with a
55 conventional type. This table is for the types, which are used for
56 different algorithms for putting in the reloc. Many of these
57 relocs need special_function entries, which I have not written. */
59 static reloc_howto_type rs6000coff_howto_table[] =
61 /* Standard 32 bit relocation. */
64 2, /* size (0 = byte, 1 = short, 2 = long) */
66 false, /* pc_relative */
68 complain_overflow_bitfield, /* complain_on_overflow */
69 0, /* special_function */
71 true, /* partial_inplace */
72 0xffffffff, /* src_mask */
73 0xffffffff, /* dst_mask */
74 false), /* pcrel_offset */
76 /* 32 bit relocation, but store negative value. */
79 -2, /* size (0 = byte, 1 = short, 2 = long) */
81 false, /* pc_relative */
83 complain_overflow_bitfield, /* complain_on_overflow */
84 0, /* special_function */
86 true, /* partial_inplace */
87 0xffffffff, /* src_mask */
88 0xffffffff, /* dst_mask */
89 false), /* pcrel_offset */
91 /* 32 bit PC relative relocation. */
94 2, /* size (0 = byte, 1 = short, 2 = long) */
96 true, /* pc_relative */
98 complain_overflow_signed, /* complain_on_overflow */
99 0, /* special_function */
101 true, /* partial_inplace */
102 0xffffffff, /* src_mask */
103 0xffffffff, /* dst_mask */
104 false), /* pcrel_offset */
106 /* 16 bit TOC relative relocation. */
109 1, /* size (0 = byte, 1 = short, 2 = long) */
111 false, /* pc_relative */
113 complain_overflow_signed, /* complain_on_overflow */
114 0, /* special_function */
116 true, /* partial_inplace */
117 0xffff, /* src_mask */
118 0xffff, /* dst_mask */
119 false), /* pcrel_offset */
121 /* I don't really know what this is. */
124 2, /* size (0 = byte, 1 = short, 2 = long) */
126 false, /* pc_relative */
128 complain_overflow_bitfield, /* complain_on_overflow */
129 0, /* special_function */
131 true, /* partial_inplace */
132 0xffffffff, /* src_mask */
133 0xffffffff, /* dst_mask */
134 false), /* pcrel_offset */
136 /* External TOC relative symbol. */
139 2, /* size (0 = byte, 1 = short, 2 = long) */
141 false, /* pc_relative */
143 complain_overflow_bitfield, /* complain_on_overflow */
144 0, /* special_function */
146 true, /* partial_inplace */
147 0xffff, /* src_mask */
148 0xffff, /* dst_mask */
149 false), /* pcrel_offset */
151 /* Local TOC relative symbol. */
154 2, /* size (0 = byte, 1 = short, 2 = long) */
156 false, /* pc_relative */
158 complain_overflow_bitfield, /* complain_on_overflow */
159 0, /* special_function */
161 true, /* partial_inplace */
162 0xffff, /* src_mask */
163 0xffff, /* dst_mask */
164 false), /* pcrel_offset */
168 /* Non modifiable absolute branch. */
171 2, /* size (0 = byte, 1 = short, 2 = long) */
173 false, /* pc_relative */
175 complain_overflow_bitfield, /* complain_on_overflow */
176 0, /* special_function */
178 true, /* partial_inplace */
179 0x3fffffc, /* src_mask */
180 0x3fffffc, /* dst_mask */
181 false), /* pcrel_offset */
185 /* Non modifiable relative branch. */
186 HOWTO (0xa, /* type */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
190 true, /* pc_relative */
192 complain_overflow_signed, /* complain_on_overflow */
193 0, /* special_function */
195 true, /* partial_inplace */
196 0x3fffffc, /* src_mask */
197 0x3fffffc, /* dst_mask */
198 false), /* pcrel_offset */
203 HOWTO (0xc, /* type */
205 2, /* size (0 = byte, 1 = short, 2 = long) */
207 false, /* pc_relative */
209 complain_overflow_bitfield, /* complain_on_overflow */
210 0, /* special_function */
212 true, /* partial_inplace */
213 0xffff, /* src_mask */
214 0xffff, /* dst_mask */
215 false), /* pcrel_offset */
218 HOWTO (0xd, /* type */
220 2, /* size (0 = byte, 1 = short, 2 = long) */
222 false, /* pc_relative */
224 complain_overflow_bitfield, /* complain_on_overflow */
225 0, /* special_function */
227 true, /* partial_inplace */
228 0xffff, /* src_mask */
229 0xffff, /* dst_mask */
230 false), /* pcrel_offset */
234 /* Non-relocating reference. */
235 HOWTO (0xf, /* type */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
239 false, /* pc_relative */
241 complain_overflow_bitfield, /* complain_on_overflow */
242 0, /* special_function */
244 false, /* partial_inplace */
247 false), /* pcrel_offset */
252 /* TOC relative indirect load. */
253 HOWTO (0x12, /* type */
255 2, /* size (0 = byte, 1 = short, 2 = long) */
257 false, /* pc_relative */
259 complain_overflow_bitfield, /* complain_on_overflow */
260 0, /* special_function */
262 true, /* partial_inplace */
263 0xffff, /* src_mask */
264 0xffff, /* dst_mask */
265 false), /* pcrel_offset */
267 /* TOC relative load address. */
268 HOWTO (0x13, /* type */
270 2, /* size (0 = byte, 1 = short, 2 = long) */
272 false, /* pc_relative */
274 complain_overflow_bitfield, /* complain_on_overflow */
275 0, /* special_function */
277 true, /* partial_inplace */
278 0xffff, /* src_mask */
279 0xffff, /* dst_mask */
280 false), /* pcrel_offset */
282 /* Modifiable relative branch. */
283 HOWTO (0x14, /* type */
285 2, /* size (0 = byte, 1 = short, 2 = long) */
287 false, /* pc_relative */
289 complain_overflow_bitfield, /* complain_on_overflow */
290 0, /* special_function */
291 "R_RRTBI", /* name */
292 true, /* partial_inplace */
293 0xffffffff, /* src_mask */
294 0xffffffff, /* dst_mask */
295 false), /* pcrel_offset */
297 /* Modifiable absolute branch. */
298 HOWTO (0x15, /* type */
300 2, /* size (0 = byte, 1 = short, 2 = long) */
302 false, /* pc_relative */
304 complain_overflow_bitfield, /* complain_on_overflow */
305 0, /* special_function */
306 "R_RRTBA", /* name */
307 true, /* partial_inplace */
308 0xffffffff, /* src_mask */
309 0xffffffff, /* dst_mask */
310 false), /* pcrel_offset */
312 /* Modifiable call absolute indirect. */
313 HOWTO (0x16, /* type */
315 2, /* size (0 = byte, 1 = short, 2 = long) */
317 false, /* pc_relative */
319 complain_overflow_bitfield, /* complain_on_overflow */
320 0, /* special_function */
322 true, /* partial_inplace */
323 0xffff, /* src_mask */
324 0xffff, /* dst_mask */
325 false), /* pcrel_offset */
327 /* Modifiable call relative. */
328 HOWTO (0x17, /* type */
330 2, /* size (0 = byte, 1 = short, 2 = long) */
332 false, /* pc_relative */
334 complain_overflow_bitfield, /* complain_on_overflow */
335 0, /* special_function */
337 true, /* partial_inplace */
338 0xffff, /* src_mask */
339 0xffff, /* dst_mask */
340 false), /* pcrel_offset */
342 /* Modifiable branch absolute. */
343 HOWTO (0x18, /* type */
345 2, /* size (0 = byte, 1 = short, 2 = long) */
347 false, /* pc_relative */
349 complain_overflow_bitfield, /* complain_on_overflow */
350 0, /* special_function */
352 true, /* partial_inplace */
353 0xffff, /* src_mask */
354 0xffff, /* dst_mask */
355 false), /* pcrel_offset */
357 /* Modifiable branch absolute. */
358 HOWTO (0x19, /* type */
360 2, /* size (0 = byte, 1 = short, 2 = long) */
362 false, /* pc_relative */
364 complain_overflow_bitfield, /* complain_on_overflow */
365 0, /* special_function */
367 true, /* partial_inplace */
368 0xffff, /* src_mask */
369 0xffff, /* dst_mask */
370 false), /* pcrel_offset */
372 /* Modifiable branch relative. */
373 HOWTO (0x1a, /* type */
375 2, /* size (0 = byte, 1 = short, 2 = long) */
377 false, /* pc_relative */
379 complain_overflow_signed, /* complain_on_overflow */
380 0, /* special_function */
382 true, /* partial_inplace */
383 0xffff, /* src_mask */
384 0xffff, /* dst_mask */
385 false), /* pcrel_offset */
387 /* Modifiable branch absolute. */
388 HOWTO (0x1b, /* type */
390 2, /* size (0 = byte, 1 = short, 2 = long) */
392 false, /* pc_relative */
394 complain_overflow_bitfield, /* complain_on_overflow */
395 0, /* special_function */
397 true, /* partial_inplace */
398 0xffff, /* src_mask */
399 0xffff, /* dst_mask */
400 false) /* pcrel_offset */
403 #define RTYPE2HOWTO(cache_ptr, dst) rs6000coff_rtype2howto (cache_ptr, dst)
405 static void rs6000coff_rtype2howto PARAMS ((arelent *,
406 struct internal_reloc *));
409 rs6000coff_rtype2howto (relent, internal)
411 struct internal_reloc *internal;
413 relent->howto = rs6000coff_howto_table + internal->r_type;
415 /* The r_size field of an XCOFF reloc encodes the bitsize of the
416 relocation, as well as indicating whether it is signed or not.
417 Doublecheck that the relocation information gathered from the
418 type matches this information. */
419 if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1)
422 if ((internal->r_size & 0x80) != 0
423 ? (relent->howto->complain_on_overflow != complain_overflow_signed)
424 : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
429 #define coff_bfd_reloc_type_lookup rs6000coff_reloc_type_lookup
431 static reloc_howto_type *rs6000coff_reloc_type_lookup
432 PARAMS ((bfd *, bfd_reloc_code_real_type));
434 static reloc_howto_type *
435 rs6000coff_reloc_type_lookup (abfd, code)
437 bfd_reloc_code_real_type code;
441 case BFD_RELOC_PPC_B26:
442 return &rs6000coff_howto_table[0xa];
443 case BFD_RELOC_PPC_BA26:
444 return &rs6000coff_howto_table[8];
445 case BFD_RELOC_PPC_TOC16:
446 return &rs6000coff_howto_table[3];
448 return &rs6000coff_howto_table[0];
454 #define SELECT_RELOC(internal, howto) \
456 internal.r_type = howto->type; \
458 ((howto->complain_on_overflow == complain_overflow_signed \
461 | (howto->bitsize - 1)); \
464 #define COFF_LONG_FILENAMES
466 #include "coffcode.h"
468 /* XCOFF archive support. The original version of this code was by
469 Damon A. Permezel. It was enhanced to permit cross support, and
470 writing archive files, by Ian Lance Taylor, Cygnus Support.
472 XCOFF uses its own archive format. Everything is hooked together
473 with file offset links, so it is possible to rapidly update an
474 archive in place. Of course, we don't do that. An XCOFF archive
475 has a real file header, not just an ARMAG string. The structure of
476 the file header and of each archive header appear below.
478 An XCOFF archive also has a member table, which is a list of
479 elements in the archive (you can get that by looking through the
480 linked list, but you have to read a lot more of the file). The
481 member table has a normal archive header with an empty name. It is
482 normally (and perhaps must be) the second to last entry in the
483 archive. The member table data is almost printable ASCII. It
484 starts with a 12 character decimal string which is the number of
485 entries in the table. For each entry it has a 12 character decimal
486 string which is the offset in the archive of that member. These
487 entries are followed by a series of null terminated strings which
488 are the member names for each entry.
490 Finally, an XCOFF archive has a global symbol table, which is what
491 we call the armap. The global symbol table has a normal archive
492 header with an empty name. It is normally (and perhaps must be)
493 the last entry in the archive. The contents start with a four byte
494 binary number which is the number of entries. This is followed by
495 a that many four byte binary numbers; each is the file offset of an
496 entry in the archive. These numbers are followed by a series of
497 null terminated strings, which are symbol names. */
499 /* XCOFF archives use this as a magic string. */
501 #define XCOFFARMAG "<aiaff>\012"
502 #define SXCOFFARMAG 8
504 /* This terminates an XCOFF archive member name. */
506 #define XCOFFARFMAG "`\012"
507 #define SXCOFFARFMAG 2
509 /* XCOFF archives start with this (printable) structure. */
511 struct xcoff_ar_file_hdr
514 char magic[SXCOFFARMAG];
516 /* Offset of the member table (decimal ASCII string). */
519 /* Offset of the global symbol table (decimal ASCII string). */
522 /* Offset of the first member in the archive (decimal ASCII string). */
523 char firstmemoff[12];
525 /* Offset of the last member in the archive (decimal ASCII string). */
528 /* Offset of the first member on the free list (decimal ASCII
533 #define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG)
535 /* Each XCOFF archive member starts with this (printable) structure. */
539 /* File size not including the header (decimal ASCII string). */
542 /* File offset of next archive member (decimal ASCII string). */
545 /* File offset of previous archive member (decimal ASCII string). */
548 /* File mtime (decimal ASCII string). */
551 /* File UID (decimal ASCII string). */
554 /* File GID (decimal ASCII string). */
557 /* File mode (octal ASCII string). */
560 /* Length of file name (decimal ASCII string). */
563 /* This structure is followed by the file name. The length of the
564 name is given in the namlen field. If the length of the name is
565 odd, the name is followed by a null byte. The name and optional
566 null byte are followed by XCOFFARFMAG, which is not included in
567 namlen. The contents of the archive member follow; the number of
568 bytes is given in the size field. */
571 #define SIZEOF_AR_HDR (7 * 12 + 4)
573 /* We store a copy of the xcoff_ar_file_hdr in the tdata field of the
574 artdata structure. */
575 #define xcoff_ardata(abfd) \
576 ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata)
578 /* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
580 #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
581 #define arch_xhdr(bfd) \
582 ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header)
584 /* XCOFF archives do not have anything which corresponds to an
585 extended name table. */
587 #define xcoff_slurp_extended_name_table bfd_false
588 #define xcoff_construct_extended_name_table \
589 ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
591 #define xcoff_truncate_arname bfd_dont_truncate_arname
593 /* XCOFF archives do not have a timestamp. */
595 #define xcoff_update_armap_timestamp bfd_true
597 /* Read in the armap of an XCOFF archive. */
600 xcoff_slurp_armap (abfd)
604 struct xcoff_ar_hdr hdr;
607 bfd_byte *contents, *cend;
612 if (xcoff_ardata (abfd) == NULL)
614 bfd_has_map (abfd) = false;
618 off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
621 bfd_has_map (abfd) = false;
625 if (bfd_seek (abfd, off, SEEK_SET) != 0)
628 /* The symbol table starts with a normal archive header. */
629 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
632 /* Skip the name (normally empty). */
633 namlen = strtol (hdr.namlen, (char **) NULL, 10);
634 if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0)
637 /* Read in the entire symbol table. */
638 sz = strtol (hdr.size, (char **) NULL, 10);
639 contents = (bfd_byte *) bfd_alloc (abfd, sz);
640 if (contents == NULL)
642 bfd_set_error (bfd_error_no_memory);
645 if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
648 /* The symbol table starts with a four byte count. */
649 c = bfd_h_get_32 (abfd, contents);
653 bfd_set_error (bfd_error_bad_value);
657 bfd_ardata (abfd)->symdefs = ((carsym *)
658 bfd_alloc (abfd, c * sizeof (carsym)));
659 if (bfd_ardata (abfd)->symdefs == NULL)
661 bfd_set_error (bfd_error_no_memory);
665 /* After the count comes a list of four byte file offsets. */
666 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
668 ++i, ++arsym, p += 4)
669 arsym->file_offset = bfd_h_get_32 (abfd, p);
671 /* After the file offsets come null terminated symbol names. */
672 cend = contents + sz;
673 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
675 ++i, ++arsym, p += strlen ((char *) p) + 1)
679 bfd_set_error (bfd_error_bad_value);
682 arsym->name = (char *) p;
685 bfd_ardata (abfd)->symdef_count = c;
686 bfd_has_map (abfd) = true;
691 /* See if this is an XCOFF archive. */
693 static const bfd_target *
694 xcoff_archive_p (abfd)
697 struct xcoff_ar_file_hdr hdr;
699 if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd)
700 != SIZEOF_AR_FILE_HDR)
702 if (bfd_get_error () != bfd_error_system_call)
703 bfd_set_error (bfd_error_wrong_format);
707 if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0)
709 bfd_set_error (bfd_error_wrong_format);
713 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
714 involves a cast, we can't do it as the left operand of
716 abfd->tdata.aout_ar_data =
717 (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
719 if (bfd_ardata (abfd) == (struct artdata *) NULL)
721 bfd_set_error (bfd_error_no_memory);
725 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
727 bfd_ardata (abfd)->cache = NULL;
728 bfd_ardata (abfd)->archive_head = NULL;
729 bfd_ardata (abfd)->symdefs = NULL;
730 bfd_ardata (abfd)->extended_names = NULL;
732 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR);
733 if (bfd_ardata (abfd)->tdata == NULL)
735 bfd_set_error (bfd_error_no_memory);
739 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
741 if (! xcoff_slurp_armap (abfd))
743 bfd_release (abfd, bfd_ardata (abfd));
744 abfd->tdata.aout_ar_data = (struct artdata *) NULL;
751 /* Read the archive header in an XCOFF archive. */
754 xcoff_read_ar_hdr (abfd)
757 struct xcoff_ar_hdr hdr;
759 struct xcoff_ar_hdr *hdrp;
760 struct areltdata *ret;
762 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
765 namlen = strtol (hdr.namlen, (char **) NULL, 10);
766 hdrp = bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1);
769 bfd_set_error (bfd_error_no_memory);
772 memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
773 if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen)
775 ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
777 ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata));
780 bfd_set_error (bfd_error_no_memory);
783 ret->arch_header = (char *) hdrp;
784 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
785 ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
787 /* Skip over the XCOFFARFMAG at the end of the file name. */
788 if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0)
794 /* Open the next element in an XCOFF archive. */
797 xcoff_openr_next_archived_file (archive, last_file)
803 if (xcoff_ardata (archive) == NULL)
805 bfd_set_error (bfd_error_invalid_operation);
809 if (last_file == NULL)
810 filestart = bfd_ardata (archive)->first_file_filepos;
812 filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10);
815 || filestart == strtol (xcoff_ardata (archive)->memoff,
817 || filestart == strtol (xcoff_ardata (archive)->symoff,
820 bfd_set_error (bfd_error_no_more_archived_files);
824 return _bfd_get_elt_at_filepos (archive, filestart);
827 /* Stat an element in an XCOFF archive. */
830 xcoff_generic_stat_arch_elt (abfd, s)
834 struct xcoff_ar_hdr *hdrp;
836 if (abfd->arelt_data == NULL)
838 bfd_set_error (bfd_error_invalid_operation);
842 hdrp = arch_xhdr (abfd);
844 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
845 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
846 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
847 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
848 s->st_size = arch_eltdata (abfd)->parsed_size;
853 /* Normalize a file name for inclusion in an archive. */
856 normalize_filename (abfd)
860 const char *filename;
862 file = bfd_get_filename (abfd);
863 filename = strrchr (file, '/');
864 if (filename != NULL)
871 /* Write out an XCOFF armap. */
875 xcoff_write_armap (abfd, elength, map, orl_count, stridx)
877 unsigned int elength;
879 unsigned int orl_count;
882 struct xcoff_ar_hdr hdr;
889 memset (&hdr, 0, sizeof hdr);
890 sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
891 sprintf (hdr.nextoff, "%d", 0);
892 memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12);
893 sprintf (hdr.date, "%d", 0);
894 sprintf (hdr.uid, "%d", 0);
895 sprintf (hdr.gid, "%d", 0);
896 sprintf (hdr.mode, "%d", 0);
897 sprintf (hdr.namlen, "%d", 0);
899 /* We need spaces, not null bytes, in the header. */
900 for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
904 if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR
905 || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
908 bfd_h_put_32 (abfd, orl_count, buf);
909 if (bfd_write (buf, 1, 4, abfd) != 4)
912 sub = abfd->archive_head;
913 fileoff = SIZEOF_AR_FILE_HDR;
915 while (sub != NULL && i < orl_count)
919 while (((bfd *) (map[i]).pos) == sub)
921 bfd_h_put_32 (abfd, fileoff, buf);
922 if (bfd_write (buf, 1, 4, abfd) != 4)
926 namlen = strlen (normalize_filename (sub));
927 namlen = (namlen + 1) &~ 1;
928 fileoff += (SIZEOF_AR_HDR
932 fileoff = (fileoff + 1) &~ 1;
936 for (i = 0; i < orl_count; i++)
942 namlen = strlen (name);
943 if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
947 if ((stridx & 1) != 0)
952 if (bfd_write (&b, 1, 1, abfd) != 1)
959 /* Write out an XCOFF archive. We always write an entire archive,
960 rather than fussing with the freelist and so forth. */
963 xcoff_write_archive_contents (abfd)
966 struct xcoff_ar_file_hdr fhdr;
972 file_ptr prevoff, nextoff;
975 struct xcoff_ar_hdr ahdr;
980 memset (&fhdr, 0, sizeof fhdr);
981 strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
982 sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
983 sprintf (fhdr.freeoff, "%d", 0);
987 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
990 total_namlen += strlen (normalize_filename (sub)) + 1;
992 offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
995 bfd_set_error (bfd_error_no_memory);
999 if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
1002 makemap = bfd_has_map (abfd);
1005 nextoff = SIZEOF_AR_FILE_HDR;
1006 for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
1010 struct xcoff_ar_hdr *ahdrp;
1011 bfd_size_type remaining;
1013 if (makemap && ! hasobjects)
1015 if (bfd_check_format (sub, bfd_object))
1019 name = normalize_filename (sub);
1020 namlen = strlen (name);
1022 if (sub->arelt_data != NULL)
1023 ahdrp = arch_xhdr (sub);
1031 memset (&ahdr, 0, sizeof ahdr);
1033 if (stat (bfd_get_filename (sub), &s) != 0)
1035 bfd_set_error (bfd_error_system_call);
1039 sprintf (ahdrp->size, "%ld", (long) s.st_size);
1040 sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
1041 sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
1042 sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
1043 sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
1045 if (sub->arelt_data == NULL)
1047 sub->arelt_data = ((struct areltdata *)
1048 bfd_alloc (sub, sizeof (struct areltdata)));
1049 if (sub->arelt_data == NULL)
1051 bfd_set_error (bfd_error_no_memory);
1056 arch_eltdata (sub)->parsed_size = s.st_size;
1059 sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
1060 sprintf (ahdrp->namlen, "%ld", (long) namlen);
1062 /* If the length of the name is odd, we write out the null byte
1063 after the name as well. */
1064 namlen = (namlen + 1) &~ 1;
1066 remaining = arelt_size (sub);
1067 size = (SIZEOF_AR_HDR
1072 BFD_ASSERT (nextoff == bfd_tell (abfd));
1074 offsets[i] = nextoff;
1077 nextoff += size + (size & 1);
1079 sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
1081 /* We need spaces, not null bytes, in the header. */
1082 for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
1086 if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
1087 || bfd_write ((PTR) name, 1, namlen, abfd) != namlen
1088 || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
1092 if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
1094 while (remaining != 0)
1097 bfd_byte buffer[DEFAULT_BUFFERSIZE];
1099 amt = sizeof buffer;
1100 if (amt > remaining)
1102 if (bfd_read (buffer, 1, amt, sub) != amt
1103 || bfd_write (buffer, 1, amt, abfd) != amt)
1108 if ((size & 1) != 0)
1113 if (bfd_write (&b, 1, 1, abfd) != 1)
1118 sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
1120 /* Write out the member table. */
1122 BFD_ASSERT (nextoff == bfd_tell (abfd));
1123 sprintf (fhdr.memoff, "%ld", (long) nextoff);
1125 memset (&ahdr, 0, sizeof ahdr);
1126 sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen));
1127 sprintf (ahdr.prevoff, "%ld", (long) prevoff);
1128 sprintf (ahdr.date, "%d", 0);
1129 sprintf (ahdr.uid, "%d", 0);
1130 sprintf (ahdr.gid, "%d", 0);
1131 sprintf (ahdr.mode, "%d", 0);
1132 sprintf (ahdr.namlen, "%d", 0);
1134 size = (SIZEOF_AR_HDR
1141 nextoff += size + (size & 1);
1143 if (makemap && hasobjects)
1144 sprintf (ahdr.nextoff, "%ld", (long) nextoff);
1146 sprintf (ahdr.nextoff, "%d", 0);
1148 /* We need spaces, not null bytes, in the header. */
1149 for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
1153 if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
1154 || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
1158 sprintf (decbuf, "%-12ld", (long) count);
1159 if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
1161 for (i = 0; i < count; i++)
1163 sprintf (decbuf, "%-12ld", (long) offsets[i]);
1164 if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
1167 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1172 name = normalize_filename (sub);
1173 namlen = strlen (name);
1174 if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1)
1177 if ((size & 1) != 0)
1182 if (bfd_write ((PTR) &b, 1, 1, abfd) != 1)
1186 /* Write out the armap, if appropriate. */
1188 if (! makemap || ! hasobjects)
1189 sprintf (fhdr.symoff, "%d", 0);
1192 BFD_ASSERT (nextoff == bfd_tell (abfd));
1193 sprintf (fhdr.symoff, "%ld", (long) nextoff);
1194 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
1195 if (! _bfd_compute_and_write_armap (abfd, 0))
1199 /* Write out the archive file header. */
1201 /* We need spaces, not null bytes, in the header. */
1202 for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
1206 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1207 || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR, 1, abfd) !=
1208 SIZEOF_AR_FILE_HDR))
1214 #define CORE_FILE_P _bfd_dummy_target
1216 #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command
1217 #define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal
1218 #define coff_core_file_matches_executable_p \
1219 _bfd_nocore_core_file_matches_executable_p
1223 #define CORE_FILE_P rs6000coff_core_p
1224 extern const bfd_target * rs6000coff_core_p ();
1225 extern boolean rs6000coff_get_section_contents ();
1226 extern boolean rs6000coff_core_file_matches_executable_p ();
1228 #undef coff_core_file_matches_executable_p
1229 #define coff_core_file_matches_executable_p \
1230 rs6000coff_core_file_matches_executable_p
1232 extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
1233 #undef coff_core_file_failing_command
1234 #define coff_core_file_failing_command rs6000coff_core_file_failing_command
1236 extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
1237 #undef coff_core_file_failing_signal
1238 #define coff_core_file_failing_signal rs6000coff_core_file_failing_signal
1240 #undef coff_get_section_contents
1241 #define coff_get_section_contents rs6000coff_get_section_contents
1242 #endif /* AIX_CORE */
1247 #define CORE_FILE_P lynx_core_file_p
1248 extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd));
1250 extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
1252 #undef coff_core_file_matches_executable_p
1253 #define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p
1255 extern char *lynx_core_file_failing_command PARAMS ((bfd *abfd));
1256 #undef coff_core_file_failing_command
1257 #define coff_core_file_failing_command lynx_core_file_failing_command
1259 extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd));
1260 #undef coff_core_file_failing_signal
1261 #define coff_core_file_failing_signal lynx_core_file_failing_signal
1263 #endif /* LYNX_CORE */
1265 /* The transfer vector that leads the outside world to all of the above. */
1267 const bfd_target rs6000coff_vec =
1269 "aixcoff-rs6000", /* name */
1270 bfd_target_coff_flavour,
1271 true, /* data byte order is big */
1272 true, /* header byte order is big */
1274 (HAS_RELOC | EXEC_P | /* object flags */
1275 HAS_LINENO | HAS_DEBUG |
1276 HAS_SYMS | HAS_LOCALS | WP_TEXT),
1278 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1279 0, /* leading char */
1280 '/', /* ar_pad_char */
1281 15, /* ar_max_namelen??? FIXMEmgo */
1283 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1284 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1285 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1286 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1287 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1288 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1290 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1291 xcoff_archive_p, CORE_FILE_P},
1292 {bfd_false, coff_mkobject, /* bfd_set_format */
1293 _bfd_generic_mkarchive, bfd_false},
1294 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
1295 xcoff_write_archive_contents, bfd_false},
1297 BFD_JUMP_TABLE_GENERIC (coff),
1298 BFD_JUMP_TABLE_COPY (coff),
1299 BFD_JUMP_TABLE_CORE (coff),
1300 BFD_JUMP_TABLE_ARCHIVE (xcoff),
1301 BFD_JUMP_TABLE_SYMBOLS (coff),
1302 BFD_JUMP_TABLE_RELOCS (coff),
1303 BFD_JUMP_TABLE_WRITE (coff),
1304 BFD_JUMP_TABLE_LINK (coff),
1305 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),