1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4 FIXME: Can someone provide a transliteration of this name into ASCII?
5 Using the following chars caused a compiler warning on HIUX (so I replaced
6 them with octal escapes), and isn't useful without an understanding of what
8 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
10 Archive support from Damon A. Permezel.
11 Contributed by IBM Corporation and Cygnus Support.
13 This file is part of BFD, the Binary File Descriptor library.
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
30 #define RS6000COFF_C 1
35 #include "coff/internal.h"
36 #include "coff/rs6000.h"
39 /* The main body of code is in coffcode.h. */
41 static boolean xcoff_mkobject
PARAMS ((bfd
*));
42 static boolean xcoff_copy_private_bfd_data
PARAMS ((bfd
*, bfd
*));
43 static boolean xcoff_is_local_label_name
PARAMS ((bfd
*, const char *));
44 static void xcoff_rtype2howto
45 PARAMS ((arelent
*, struct internal_reloc
*));
46 static reloc_howto_type
*xcoff_reloc_type_lookup
47 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
48 static boolean xcoff_slurp_armap
PARAMS ((bfd
*));
49 static const bfd_target
*xcoff_archive_p
PARAMS ((bfd
*));
50 static PTR xcoff_read_ar_hdr
PARAMS ((bfd
*));
51 static bfd
*xcoff_openr_next_archived_file
PARAMS ((bfd
*, bfd
*));
52 static int xcoff_generic_stat_arch_elt
PARAMS ((bfd
*, struct stat
*));
53 static const char *normalize_filename
PARAMS ((bfd
*));
54 static boolean xcoff_write_armap
55 PARAMS ((bfd
*, unsigned int, struct orl
*, unsigned int, int));
56 static boolean xcoff_write_archive_contents
PARAMS ((bfd
*));
57 static int _bfd_xcoff_sizeof_headers
PARAMS ((bfd
*, boolean
));
59 /* We use our own tdata type. Its first field is the COFF tdata type,
60 so the COFF routines are compatible. */
68 abfd
->tdata
.xcoff_obj_data
=
69 ((struct xcoff_tdata
*)
70 bfd_zalloc (abfd
, sizeof (struct xcoff_tdata
)));
71 if (abfd
->tdata
.xcoff_obj_data
== NULL
)
73 coff
= coff_data (abfd
);
74 coff
->symbols
= (coff_symbol_type
*) NULL
;
75 coff
->conversion_table
= (unsigned int *) NULL
;
76 coff
->raw_syments
= (struct coff_ptr_struct
*) NULL
;
79 xcoff_data (abfd
)->modtype
= ('1' << 8) | 'L';
81 /* We set cputype to -1 to indicate that it has not been
83 xcoff_data (abfd
)->cputype
= -1;
85 xcoff_data (abfd
)->csects
= NULL
;
86 xcoff_data (abfd
)->debug_indices
= NULL
;
91 /* Copy XCOFF data from one BFD to another. */
94 xcoff_copy_private_bfd_data (ibfd
, obfd
)
98 struct xcoff_tdata
*ix
, *ox
;
101 if (ibfd
->xvec
!= obfd
->xvec
)
103 ix
= xcoff_data (ibfd
);
104 ox
= xcoff_data (obfd
);
105 ox
->full_aouthdr
= ix
->full_aouthdr
;
111 sec
= coff_section_from_bfd_index (ibfd
, ix
->sntoc
);
115 ox
->sntoc
= sec
->output_section
->target_index
;
117 if (ix
->snentry
== 0)
121 sec
= coff_section_from_bfd_index (ibfd
, ix
->snentry
);
125 ox
->snentry
= sec
->output_section
->target_index
;
127 ox
->text_align_power
= ix
->text_align_power
;
128 ox
->data_align_power
= ix
->data_align_power
;
129 ox
->modtype
= ix
->modtype
;
130 ox
->cputype
= ix
->cputype
;
131 ox
->maxdata
= ix
->maxdata
;
132 ox
->maxstack
= ix
->maxstack
;
136 /* I don't think XCOFF really has a notion of local labels based on
137 name. This will mean that ld -X doesn't actually strip anything.
138 The AIX native linker does not have a -X option, and it ignores the
142 xcoff_is_local_label_name (abfd
, name
)
143 bfd
*abfd ATTRIBUTE_UNUSED
;
144 const char *name ATTRIBUTE_UNUSED
;
149 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
150 bitsize and whether they are signed or not, along with a
151 conventional type. This table is for the types, which are used for
152 different algorithms for putting in the reloc. Many of these
153 relocs need special_function entries, which I have not written. */
155 static reloc_howto_type xcoff_howto_table
[] =
157 /* Standard 32 bit relocation. */
160 2, /* size (0 = byte, 1 = short, 2 = long) */
162 false, /* pc_relative */
164 complain_overflow_bitfield
, /* complain_on_overflow */
165 0, /* special_function */
167 true, /* partial_inplace */
168 0xffffffff, /* src_mask */
169 0xffffffff, /* dst_mask */
170 false), /* pcrel_offset */
172 /* 32 bit relocation, but store negative value. */
175 -2, /* size (0 = byte, 1 = short, 2 = long) */
177 false, /* pc_relative */
179 complain_overflow_bitfield
, /* complain_on_overflow */
180 0, /* special_function */
182 true, /* partial_inplace */
183 0xffffffff, /* src_mask */
184 0xffffffff, /* dst_mask */
185 false), /* pcrel_offset */
187 /* 32 bit PC relative relocation. */
190 2, /* size (0 = byte, 1 = short, 2 = long) */
192 true, /* pc_relative */
194 complain_overflow_signed
, /* complain_on_overflow */
195 0, /* special_function */
197 true, /* partial_inplace */
198 0xffffffff, /* src_mask */
199 0xffffffff, /* dst_mask */
200 false), /* pcrel_offset */
202 /* 16 bit TOC relative relocation. */
205 1, /* 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 */
217 /* I don't really know what this is. */
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 0xffffffff, /* src_mask */
229 0xffffffff, /* dst_mask */
230 false), /* pcrel_offset */
232 /* External TOC relative symbol. */
235 2, /* size (0 = byte, 1 = short, 2 = long) */
237 false, /* pc_relative */
239 complain_overflow_bitfield
, /* complain_on_overflow */
240 0, /* special_function */
242 true, /* partial_inplace */
243 0xffff, /* src_mask */
244 0xffff, /* dst_mask */
245 false), /* pcrel_offset */
247 /* Local TOC relative symbol. */
250 2, /* size (0 = byte, 1 = short, 2 = long) */
252 false, /* pc_relative */
254 complain_overflow_bitfield
, /* complain_on_overflow */
255 0, /* special_function */
257 true, /* partial_inplace */
258 0xffff, /* src_mask */
259 0xffff, /* dst_mask */
260 false), /* pcrel_offset */
264 /* Non modifiable absolute branch. */
267 2, /* size (0 = byte, 1 = short, 2 = long) */
269 false, /* pc_relative */
271 complain_overflow_bitfield
, /* complain_on_overflow */
272 0, /* special_function */
274 true, /* partial_inplace */
275 0x3fffffc, /* src_mask */
276 0x3fffffc, /* dst_mask */
277 false), /* pcrel_offset */
281 /* Non modifiable relative branch. */
282 HOWTO (0xa, /* type */
284 2, /* size (0 = byte, 1 = short, 2 = long) */
286 true, /* pc_relative */
288 complain_overflow_signed
, /* complain_on_overflow */
289 0, /* special_function */
291 true, /* partial_inplace */
292 0x3fffffc, /* src_mask */
293 0x3fffffc, /* dst_mask */
294 false), /* pcrel_offset */
299 HOWTO (0xc, /* type */
301 2, /* size (0 = byte, 1 = short, 2 = long) */
303 false, /* pc_relative */
305 complain_overflow_bitfield
, /* complain_on_overflow */
306 0, /* special_function */
308 true, /* partial_inplace */
309 0xffff, /* src_mask */
310 0xffff, /* dst_mask */
311 false), /* pcrel_offset */
314 HOWTO (0xd, /* type */
316 2, /* size (0 = byte, 1 = short, 2 = long) */
318 false, /* pc_relative */
320 complain_overflow_bitfield
, /* complain_on_overflow */
321 0, /* special_function */
323 true, /* partial_inplace */
324 0xffff, /* src_mask */
325 0xffff, /* dst_mask */
326 false), /* pcrel_offset */
330 /* Non-relocating reference. */
331 HOWTO (0xf, /* type */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
335 false, /* pc_relative */
337 complain_overflow_bitfield
, /* complain_on_overflow */
338 0, /* special_function */
340 false, /* partial_inplace */
343 false), /* pcrel_offset */
348 /* TOC relative indirect load. */
349 HOWTO (0x12, /* type */
351 2, /* size (0 = byte, 1 = short, 2 = long) */
353 false, /* pc_relative */
355 complain_overflow_bitfield
, /* complain_on_overflow */
356 0, /* special_function */
358 true, /* partial_inplace */
359 0xffff, /* src_mask */
360 0xffff, /* dst_mask */
361 false), /* pcrel_offset */
363 /* TOC relative load address. */
364 HOWTO (0x13, /* type */
366 2, /* size (0 = byte, 1 = short, 2 = long) */
368 false, /* pc_relative */
370 complain_overflow_bitfield
, /* complain_on_overflow */
371 0, /* special_function */
373 true, /* partial_inplace */
374 0xffff, /* src_mask */
375 0xffff, /* dst_mask */
376 false), /* pcrel_offset */
378 /* Modifiable relative branch. */
379 HOWTO (0x14, /* type */
381 2, /* size (0 = byte, 1 = short, 2 = long) */
383 false, /* pc_relative */
385 complain_overflow_bitfield
, /* complain_on_overflow */
386 0, /* special_function */
387 "R_RRTBI", /* name */
388 true, /* partial_inplace */
389 0xffffffff, /* src_mask */
390 0xffffffff, /* dst_mask */
391 false), /* pcrel_offset */
393 /* Modifiable absolute branch. */
394 HOWTO (0x15, /* type */
396 2, /* size (0 = byte, 1 = short, 2 = long) */
398 false, /* pc_relative */
400 complain_overflow_bitfield
, /* complain_on_overflow */
401 0, /* special_function */
402 "R_RRTBA", /* name */
403 true, /* partial_inplace */
404 0xffffffff, /* src_mask */
405 0xffffffff, /* dst_mask */
406 false), /* pcrel_offset */
408 /* Modifiable call absolute indirect. */
409 HOWTO (0x16, /* type */
411 2, /* size (0 = byte, 1 = short, 2 = long) */
413 false, /* pc_relative */
415 complain_overflow_bitfield
, /* complain_on_overflow */
416 0, /* special_function */
418 true, /* partial_inplace */
419 0xffff, /* src_mask */
420 0xffff, /* dst_mask */
421 false), /* pcrel_offset */
423 /* Modifiable call relative. */
424 HOWTO (0x17, /* type */
426 2, /* size (0 = byte, 1 = short, 2 = long) */
428 false, /* pc_relative */
430 complain_overflow_bitfield
, /* complain_on_overflow */
431 0, /* special_function */
433 true, /* partial_inplace */
434 0xffff, /* src_mask */
435 0xffff, /* dst_mask */
436 false), /* pcrel_offset */
438 /* Modifiable branch absolute. */
439 HOWTO (0x18, /* type */
441 2, /* size (0 = byte, 1 = short, 2 = long) */
443 false, /* pc_relative */
445 complain_overflow_bitfield
, /* complain_on_overflow */
446 0, /* special_function */
448 true, /* partial_inplace */
449 0xffff, /* src_mask */
450 0xffff, /* dst_mask */
451 false), /* pcrel_offset */
453 /* Modifiable branch absolute. */
454 HOWTO (0x19, /* type */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
458 false, /* pc_relative */
460 complain_overflow_bitfield
, /* complain_on_overflow */
461 0, /* special_function */
463 true, /* partial_inplace */
464 0xffff, /* src_mask */
465 0xffff, /* dst_mask */
466 false), /* pcrel_offset */
468 /* Modifiable branch relative. */
469 HOWTO (0x1a, /* type */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 false, /* pc_relative */
475 complain_overflow_signed
, /* complain_on_overflow */
476 0, /* special_function */
478 true, /* partial_inplace */
479 0xffff, /* src_mask */
480 0xffff, /* dst_mask */
481 false), /* pcrel_offset */
483 /* Modifiable branch absolute. */
484 HOWTO (0x1b, /* type */
486 2, /* size (0 = byte, 1 = short, 2 = long) */
488 false, /* pc_relative */
490 complain_overflow_bitfield
, /* complain_on_overflow */
491 0, /* special_function */
493 true, /* partial_inplace */
494 0xffff, /* src_mask */
495 0xffff, /* dst_mask */
496 false) /* pcrel_offset */
500 xcoff_rtype2howto (relent
, internal
)
502 struct internal_reloc
*internal
;
504 relent
->howto
= xcoff_howto_table
+ internal
->r_type
;
506 /* The r_size field of an XCOFF reloc encodes the bitsize of the
507 relocation, as well as indicating whether it is signed or not.
508 Doublecheck that the relocation information gathered from the
509 type matches this information. */
510 if (relent
->howto
->bitsize
!= ((unsigned int) internal
->r_size
& 0x1f) + 1)
513 if ((internal
->r_size
& 0x80) != 0
514 ? (relent
->howto
->complain_on_overflow
!= complain_overflow_signed
)
515 : (relent
->howto
->complain_on_overflow
!= complain_overflow_bitfield
))
520 static reloc_howto_type
*
521 xcoff_reloc_type_lookup (abfd
, code
)
522 bfd
*abfd ATTRIBUTE_UNUSED
;
523 bfd_reloc_code_real_type code
;
527 case BFD_RELOC_PPC_B26
:
528 return &xcoff_howto_table
[0xa];
529 case BFD_RELOC_PPC_BA26
:
530 return &xcoff_howto_table
[8];
531 case BFD_RELOC_PPC_TOC16
:
532 return &xcoff_howto_table
[3];
535 return &xcoff_howto_table
[0];
541 #define SELECT_RELOC(internal, howto) \
543 internal.r_type = howto->type; \
545 ((howto->complain_on_overflow == complain_overflow_signed \
548 | (howto->bitsize - 1)); \
551 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
553 #define COFF_LONG_FILENAMES
555 #define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
557 #define coff_mkobject xcoff_mkobject
558 #define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data
559 #define coff_bfd_is_local_label_name xcoff_is_local_label_name
560 #define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup
561 #define coff_relocate_section _bfd_ppc_xcoff_relocate_section
563 #include "coffcode.h"
565 /* XCOFF archive support. The original version of this code was by
566 Damon A. Permezel. It was enhanced to permit cross support, and
567 writing archive files, by Ian Lance Taylor, Cygnus Support.
569 XCOFF uses its own archive format. Everything is hooked together
570 with file offset links, so it is possible to rapidly update an
571 archive in place. Of course, we don't do that. An XCOFF archive
572 has a real file header, not just an ARMAG string. The structure of
573 the file header and of each archive header appear below.
575 An XCOFF archive also has a member table, which is a list of
576 elements in the archive (you can get that by looking through the
577 linked list, but you have to read a lot more of the file). The
578 member table has a normal archive header with an empty name. It is
579 normally (and perhaps must be) the second to last entry in the
580 archive. The member table data is almost printable ASCII. It
581 starts with a 12 character decimal string which is the number of
582 entries in the table. For each entry it has a 12 character decimal
583 string which is the offset in the archive of that member. These
584 entries are followed by a series of null terminated strings which
585 are the member names for each entry.
587 Finally, an XCOFF archive has a global symbol table, which is what
588 we call the armap. The global symbol table has a normal archive
589 header with an empty name. It is normally (and perhaps must be)
590 the last entry in the archive. The contents start with a four byte
591 binary number which is the number of entries. This is followed by
592 a that many four byte binary numbers; each is the file offset of an
593 entry in the archive. These numbers are followed by a series of
594 null terminated strings, which are symbol names. */
596 /* XCOFF archives use this as a magic string. */
598 #define XCOFFARMAG "<aiaff>\012"
599 #define SXCOFFARMAG 8
601 /* This terminates an XCOFF archive member name. */
603 #define XCOFFARFMAG "`\012"
604 #define SXCOFFARFMAG 2
606 /* XCOFF archives start with this (printable) structure. */
608 struct xcoff_ar_file_hdr
611 char magic
[SXCOFFARMAG
];
613 /* Offset of the member table (decimal ASCII string). */
616 /* Offset of the global symbol table (decimal ASCII string). */
619 /* Offset of the first member in the archive (decimal ASCII string). */
620 char firstmemoff
[12];
622 /* Offset of the last member in the archive (decimal ASCII string). */
625 /* Offset of the first member on the free list (decimal ASCII
630 #define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG)
632 /* Each XCOFF archive member starts with this (printable) structure. */
636 /* File size not including the header (decimal ASCII string). */
639 /* File offset of next archive member (decimal ASCII string). */
642 /* File offset of previous archive member (decimal ASCII string). */
645 /* File mtime (decimal ASCII string). */
648 /* File UID (decimal ASCII string). */
651 /* File GID (decimal ASCII string). */
654 /* File mode (octal ASCII string). */
657 /* Length of file name (decimal ASCII string). */
660 /* This structure is followed by the file name. The length of the
661 name is given in the namlen field. If the length of the name is
662 odd, the name is followed by a null byte. The name and optional
663 null byte are followed by XCOFFARFMAG, which is not included in
664 namlen. The contents of the archive member follow; the number of
665 bytes is given in the size field. */
668 #define SIZEOF_AR_HDR (7 * 12 + 4)
670 /* We store a copy of the xcoff_ar_file_hdr in the tdata field of the
671 artdata structure. */
672 #define xcoff_ardata(abfd) \
673 ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata)
675 /* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
677 #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
678 #define arch_xhdr(bfd) \
679 ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header)
681 /* XCOFF archives do not have anything which corresponds to an
682 extended name table. */
684 #define xcoff_slurp_extended_name_table bfd_false
685 #define xcoff_construct_extended_name_table \
686 ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
688 #define xcoff_truncate_arname bfd_dont_truncate_arname
690 /* We can use the standard get_elt_at_index routine. */
692 #define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
694 /* XCOFF archives do not have a timestamp. */
696 #define xcoff_update_armap_timestamp bfd_true
698 /* Read in the armap of an XCOFF archive. */
701 xcoff_slurp_armap (abfd
)
705 struct xcoff_ar_hdr hdr
;
708 bfd_byte
*contents
, *cend
;
713 if (xcoff_ardata (abfd
) == NULL
)
715 bfd_has_map (abfd
) = false;
719 off
= strtol (xcoff_ardata (abfd
)->symoff
, (char **) NULL
, 10);
722 bfd_has_map (abfd
) = false;
726 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0)
729 /* The symbol table starts with a normal archive header. */
730 if (bfd_read ((PTR
) &hdr
, SIZEOF_AR_HDR
, 1, abfd
) != SIZEOF_AR_HDR
)
733 /* Skip the name (normally empty). */
734 namlen
= strtol (hdr
.namlen
, (char **) NULL
, 10);
735 if (bfd_seek (abfd
, ((namlen
+ 1) & ~1) + SXCOFFARFMAG
, SEEK_CUR
) != 0)
738 /* Read in the entire symbol table. */
739 sz
= strtol (hdr
.size
, (char **) NULL
, 10);
740 contents
= (bfd_byte
*) bfd_alloc (abfd
, sz
);
741 if (contents
== NULL
)
743 if (bfd_read ((PTR
) contents
, 1, sz
, abfd
) != sz
)
746 /* The symbol table starts with a four byte count. */
747 c
= bfd_h_get_32 (abfd
, contents
);
751 bfd_set_error (bfd_error_bad_value
);
755 bfd_ardata (abfd
)->symdefs
= ((carsym
*)
756 bfd_alloc (abfd
, c
* sizeof (carsym
)));
757 if (bfd_ardata (abfd
)->symdefs
== NULL
)
760 /* After the count comes a list of four byte file offsets. */
761 for (i
= 0, arsym
= bfd_ardata (abfd
)->symdefs
, p
= contents
+ 4;
763 ++i
, ++arsym
, p
+= 4)
764 arsym
->file_offset
= bfd_h_get_32 (abfd
, p
);
766 /* After the file offsets come null terminated symbol names. */
767 cend
= contents
+ sz
;
768 for (i
= 0, arsym
= bfd_ardata (abfd
)->symdefs
;
770 ++i
, ++arsym
, p
+= strlen ((char *) p
) + 1)
774 bfd_set_error (bfd_error_bad_value
);
777 arsym
->name
= (char *) p
;
780 bfd_ardata (abfd
)->symdef_count
= c
;
781 bfd_has_map (abfd
) = true;
786 /* See if this is an XCOFF archive. */
788 static const bfd_target
*
789 xcoff_archive_p (abfd
)
792 struct xcoff_ar_file_hdr hdr
;
794 if (bfd_read ((PTR
) &hdr
, SIZEOF_AR_FILE_HDR
, 1, abfd
)
795 != SIZEOF_AR_FILE_HDR
)
797 if (bfd_get_error () != bfd_error_system_call
)
798 bfd_set_error (bfd_error_wrong_format
);
802 if (strncmp (hdr
.magic
, XCOFFARMAG
, SXCOFFARMAG
) != 0)
804 bfd_set_error (bfd_error_wrong_format
);
808 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
809 involves a cast, we can't do it as the left operand of
811 abfd
->tdata
.aout_ar_data
=
812 (struct artdata
*) bfd_zalloc (abfd
, sizeof (struct artdata
));
814 if (bfd_ardata (abfd
) == (struct artdata
*) NULL
)
817 bfd_ardata (abfd
)->first_file_filepos
= strtol (hdr
.firstmemoff
,
819 bfd_ardata (abfd
)->cache
= NULL
;
820 bfd_ardata (abfd
)->archive_head
= NULL
;
821 bfd_ardata (abfd
)->symdefs
= NULL
;
822 bfd_ardata (abfd
)->extended_names
= NULL
;
824 bfd_ardata (abfd
)->tdata
= bfd_zalloc (abfd
, SIZEOF_AR_FILE_HDR
);
825 if (bfd_ardata (abfd
)->tdata
== NULL
)
828 memcpy (bfd_ardata (abfd
)->tdata
, &hdr
, SIZEOF_AR_FILE_HDR
);
830 if (! xcoff_slurp_armap (abfd
))
832 bfd_release (abfd
, bfd_ardata (abfd
));
833 abfd
->tdata
.aout_ar_data
= (struct artdata
*) NULL
;
840 /* Read the archive header in an XCOFF archive. */
843 xcoff_read_ar_hdr (abfd
)
846 struct xcoff_ar_hdr hdr
;
848 struct xcoff_ar_hdr
*hdrp
;
849 struct areltdata
*ret
;
851 if (bfd_read ((PTR
) &hdr
, SIZEOF_AR_HDR
, 1, abfd
) != SIZEOF_AR_HDR
)
854 namlen
= strtol (hdr
.namlen
, (char **) NULL
, 10);
855 hdrp
= (struct xcoff_ar_hdr
*) bfd_alloc (abfd
, SIZEOF_AR_HDR
+ namlen
+ 1);
858 memcpy (hdrp
, &hdr
, SIZEOF_AR_HDR
);
859 if (bfd_read ((char *) hdrp
+ SIZEOF_AR_HDR
, 1, namlen
, abfd
) != namlen
)
861 ((char *) hdrp
)[SIZEOF_AR_HDR
+ namlen
] = '\0';
863 ret
= (struct areltdata
*) bfd_alloc (abfd
, sizeof (struct areltdata
));
866 ret
->arch_header
= (char *) hdrp
;
867 ret
->parsed_size
= strtol (hdr
.size
, (char **) NULL
, 10);
868 ret
->filename
= (char *) hdrp
+ SIZEOF_AR_HDR
;
870 /* Skip over the XCOFFARFMAG at the end of the file name. */
871 if (bfd_seek (abfd
, (namlen
& 1) + SXCOFFARFMAG
, SEEK_CUR
) != 0)
877 /* Open the next element in an XCOFF archive. */
880 xcoff_openr_next_archived_file (archive
, last_file
)
886 if (xcoff_ardata (archive
) == NULL
)
888 bfd_set_error (bfd_error_invalid_operation
);
892 if (last_file
== NULL
)
893 filestart
= bfd_ardata (archive
)->first_file_filepos
;
895 filestart
= strtol (arch_xhdr (last_file
)->nextoff
, (char **) NULL
, 10);
898 || filestart
== strtol (xcoff_ardata (archive
)->memoff
,
900 || filestart
== strtol (xcoff_ardata (archive
)->symoff
,
903 bfd_set_error (bfd_error_no_more_archived_files
);
907 return _bfd_get_elt_at_filepos (archive
, filestart
);
910 /* Stat an element in an XCOFF archive. */
913 xcoff_generic_stat_arch_elt (abfd
, s
)
917 struct xcoff_ar_hdr
*hdrp
;
919 if (abfd
->arelt_data
== NULL
)
921 bfd_set_error (bfd_error_invalid_operation
);
925 hdrp
= arch_xhdr (abfd
);
927 s
->st_mtime
= strtol (hdrp
->date
, (char **) NULL
, 10);
928 s
->st_uid
= strtol (hdrp
->uid
, (char **) NULL
, 10);
929 s
->st_gid
= strtol (hdrp
->gid
, (char **) NULL
, 10);
930 s
->st_mode
= strtol (hdrp
->mode
, (char **) NULL
, 8);
931 s
->st_size
= arch_eltdata (abfd
)->parsed_size
;
936 /* Normalize a file name for inclusion in an archive. */
939 normalize_filename (abfd
)
943 const char *filename
;
945 file
= bfd_get_filename (abfd
);
946 filename
= strrchr (file
, '/');
947 if (filename
!= NULL
)
954 /* Write out an XCOFF armap. */
958 xcoff_write_armap (abfd
, elength
, map
, orl_count
, stridx
)
960 unsigned int elength ATTRIBUTE_UNUSED
;
962 unsigned int orl_count
;
965 struct xcoff_ar_hdr hdr
;
967 unsigned char buf
[4];
972 memset (&hdr
, 0, sizeof hdr
);
973 sprintf (hdr
.size
, "%ld", (long) (4 + orl_count
* 4 + stridx
));
974 sprintf (hdr
.nextoff
, "%d", 0);
975 memcpy (hdr
.prevoff
, xcoff_ardata (abfd
)->memoff
, 12);
976 sprintf (hdr
.date
, "%d", 0);
977 sprintf (hdr
.uid
, "%d", 0);
978 sprintf (hdr
.gid
, "%d", 0);
979 sprintf (hdr
.mode
, "%d", 0);
980 sprintf (hdr
.namlen
, "%d", 0);
982 /* We need spaces, not null bytes, in the header. */
983 for (p
= (char *) &hdr
; p
< (char *) &hdr
+ SIZEOF_AR_HDR
; p
++)
987 if (bfd_write ((PTR
) &hdr
, SIZEOF_AR_HDR
, 1, abfd
) != SIZEOF_AR_HDR
988 || bfd_write (XCOFFARFMAG
, 1, SXCOFFARFMAG
, abfd
) != SXCOFFARFMAG
)
991 bfd_h_put_32 (abfd
, orl_count
, buf
);
992 if (bfd_write (buf
, 1, 4, abfd
) != 4)
995 sub
= abfd
->archive_head
;
996 fileoff
= SIZEOF_AR_FILE_HDR
;
998 while (sub
!= NULL
&& i
< orl_count
)
1002 while (((bfd
*) (map
[i
]).pos
) == sub
)
1004 bfd_h_put_32 (abfd
, fileoff
, buf
);
1005 if (bfd_write (buf
, 1, 4, abfd
) != 4)
1009 namlen
= strlen (normalize_filename (sub
));
1010 namlen
= (namlen
+ 1) &~ 1;
1011 fileoff
+= (SIZEOF_AR_HDR
1014 + arelt_size (sub
));
1015 fileoff
= (fileoff
+ 1) &~ 1;
1019 for (i
= 0; i
< orl_count
; i
++)
1024 name
= *map
[i
].name
;
1025 namlen
= strlen (name
);
1026 if (bfd_write (name
, 1, namlen
+ 1, abfd
) != namlen
+ 1)
1030 if ((stridx
& 1) != 0)
1035 if (bfd_write (&b
, 1, 1, abfd
) != 1)
1042 /* Write out an XCOFF archive. We always write an entire archive,
1043 rather than fussing with the freelist and so forth. */
1046 xcoff_write_archive_contents (abfd
)
1049 struct xcoff_ar_file_hdr fhdr
;
1051 size_t total_namlen
;
1055 file_ptr prevoff
, nextoff
;
1058 struct xcoff_ar_hdr ahdr
;
1063 memset (&fhdr
, 0, sizeof fhdr
);
1064 strncpy (fhdr
.magic
, XCOFFARMAG
, SXCOFFARMAG
);
1065 sprintf (fhdr
.firstmemoff
, "%d", SIZEOF_AR_FILE_HDR
);
1066 sprintf (fhdr
.freeoff
, "%d", 0);
1070 for (sub
= abfd
->archive_head
; sub
!= NULL
; sub
= sub
->next
)
1073 total_namlen
+= strlen (normalize_filename (sub
)) + 1;
1075 offsets
= (file_ptr
*) bfd_alloc (abfd
, count
* sizeof (file_ptr
));
1076 if (offsets
== NULL
)
1079 if (bfd_seek (abfd
, SIZEOF_AR_FILE_HDR
, SEEK_SET
) != 0)
1082 makemap
= bfd_has_map (abfd
);
1085 nextoff
= SIZEOF_AR_FILE_HDR
;
1086 for (sub
= abfd
->archive_head
, i
= 0; sub
!= NULL
; sub
= sub
->next
, i
++)
1090 struct xcoff_ar_hdr
*ahdrp
;
1091 bfd_size_type remaining
;
1093 if (makemap
&& ! hasobjects
)
1095 if (bfd_check_format (sub
, bfd_object
))
1099 name
= normalize_filename (sub
);
1100 namlen
= strlen (name
);
1102 if (sub
->arelt_data
!= NULL
)
1103 ahdrp
= arch_xhdr (sub
);
1111 memset (&ahdr
, 0, sizeof ahdr
);
1113 if (stat (bfd_get_filename (sub
), &s
) != 0)
1115 bfd_set_error (bfd_error_system_call
);
1119 sprintf (ahdrp
->size
, "%ld", (long) s
.st_size
);
1120 sprintf (ahdrp
->date
, "%ld", (long) s
.st_mtime
);
1121 sprintf (ahdrp
->uid
, "%ld", (long) s
.st_uid
);
1122 sprintf (ahdrp
->gid
, "%ld", (long) s
.st_gid
);
1123 sprintf (ahdrp
->mode
, "%o", (unsigned int) s
.st_mode
);
1125 if (sub
->arelt_data
== NULL
)
1127 sub
->arelt_data
= bfd_alloc (sub
, sizeof (struct areltdata
));
1128 if (sub
->arelt_data
== NULL
)
1132 arch_eltdata (sub
)->parsed_size
= s
.st_size
;
1135 sprintf (ahdrp
->prevoff
, "%ld", (long) prevoff
);
1136 sprintf (ahdrp
->namlen
, "%ld", (long) namlen
);
1138 /* If the length of the name is odd, we write out the null byte
1139 after the name as well. */
1140 namlen
= (namlen
+ 1) &~ 1;
1142 remaining
= arelt_size (sub
);
1143 size
= (SIZEOF_AR_HDR
1148 BFD_ASSERT (nextoff
== bfd_tell (abfd
));
1150 offsets
[i
] = nextoff
;
1153 nextoff
+= size
+ (size
& 1);
1155 sprintf (ahdrp
->nextoff
, "%ld", (long) nextoff
);
1157 /* We need spaces, not null bytes, in the header. */
1158 for (p
= (char *) ahdrp
; p
< (char *) ahdrp
+ SIZEOF_AR_HDR
; p
++)
1162 if (bfd_write ((PTR
) ahdrp
, 1, SIZEOF_AR_HDR
, abfd
) != SIZEOF_AR_HDR
1163 || bfd_write ((PTR
) name
, 1, namlen
, abfd
) != namlen
1164 || (bfd_write ((PTR
) XCOFFARFMAG
, 1, SXCOFFARFMAG
, abfd
)
1168 if (bfd_seek (sub
, (file_ptr
) 0, SEEK_SET
) != 0)
1170 while (remaining
!= 0)
1173 bfd_byte buffer
[DEFAULT_BUFFERSIZE
];
1175 amt
= sizeof buffer
;
1176 if (amt
> remaining
)
1178 if (bfd_read (buffer
, 1, amt
, sub
) != amt
1179 || bfd_write (buffer
, 1, amt
, abfd
) != amt
)
1184 if ((size
& 1) != 0)
1189 if (bfd_write (&b
, 1, 1, abfd
) != 1)
1194 sprintf (fhdr
.lastmemoff
, "%ld", (long) prevoff
);
1196 /* Write out the member table. */
1198 BFD_ASSERT (nextoff
== bfd_tell (abfd
));
1199 sprintf (fhdr
.memoff
, "%ld", (long) nextoff
);
1201 memset (&ahdr
, 0, sizeof ahdr
);
1202 sprintf (ahdr
.size
, "%ld", (long) (12 + count
* 12 + total_namlen
));
1203 sprintf (ahdr
.prevoff
, "%ld", (long) prevoff
);
1204 sprintf (ahdr
.date
, "%d", 0);
1205 sprintf (ahdr
.uid
, "%d", 0);
1206 sprintf (ahdr
.gid
, "%d", 0);
1207 sprintf (ahdr
.mode
, "%d", 0);
1208 sprintf (ahdr
.namlen
, "%d", 0);
1210 size
= (SIZEOF_AR_HDR
1217 nextoff
+= size
+ (size
& 1);
1219 if (makemap
&& hasobjects
)
1220 sprintf (ahdr
.nextoff
, "%ld", (long) nextoff
);
1222 sprintf (ahdr
.nextoff
, "%d", 0);
1224 /* We need spaces, not null bytes, in the header. */
1225 for (p
= (char *) &ahdr
; p
< (char *) &ahdr
+ SIZEOF_AR_HDR
; p
++)
1229 if (bfd_write ((PTR
) &ahdr
, 1, SIZEOF_AR_HDR
, abfd
) != SIZEOF_AR_HDR
1230 || (bfd_write ((PTR
) XCOFFARFMAG
, 1, SXCOFFARFMAG
, abfd
)
1234 sprintf (decbuf
, "%-12ld", (long) count
);
1235 if (bfd_write ((PTR
) decbuf
, 1, 12, abfd
) != 12)
1237 for (i
= 0; i
< count
; i
++)
1239 sprintf (decbuf
, "%-12ld", (long) offsets
[i
]);
1240 if (bfd_write ((PTR
) decbuf
, 1, 12, abfd
) != 12)
1243 for (sub
= abfd
->archive_head
; sub
!= NULL
; sub
= sub
->next
)
1248 name
= normalize_filename (sub
);
1249 namlen
= strlen (name
);
1250 if (bfd_write ((PTR
) name
, 1, namlen
+ 1, abfd
) != namlen
+ 1)
1253 if ((size
& 1) != 0)
1258 if (bfd_write ((PTR
) &b
, 1, 1, abfd
) != 1)
1262 /* Write out the armap, if appropriate. */
1264 if (! makemap
|| ! hasobjects
)
1265 sprintf (fhdr
.symoff
, "%d", 0);
1268 BFD_ASSERT (nextoff
== bfd_tell (abfd
));
1269 sprintf (fhdr
.symoff
, "%ld", (long) nextoff
);
1270 bfd_ardata (abfd
)->tdata
= (PTR
) &fhdr
;
1271 if (! _bfd_compute_and_write_armap (abfd
, 0))
1275 /* Write out the archive file header. */
1277 /* We need spaces, not null bytes, in the header. */
1278 for (p
= (char *) &fhdr
; p
< (char *) &fhdr
+ SIZEOF_AR_FILE_HDR
; p
++)
1282 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0
1283 || (bfd_write ((PTR
) &fhdr
, SIZEOF_AR_FILE_HDR
, 1, abfd
) !=
1284 SIZEOF_AR_FILE_HDR
))
1290 /* We can't use the usual coff_sizeof_headers routine, because AIX
1291 always uses an a.out header. */
1295 _bfd_xcoff_sizeof_headers (abfd
, reloc
)
1297 boolean reloc ATTRIBUTE_UNUSED
;
1302 if (xcoff_data (abfd
)->full_aouthdr
)
1305 size
+= SMALL_AOUTSZ
;
1306 size
+= abfd
->section_count
* SCNHSZ
;
1310 #define CORE_FILE_P _bfd_dummy_target
1312 #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command
1313 #define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal
1314 #define coff_core_file_matches_executable_p \
1315 _bfd_nocore_core_file_matches_executable_p
1319 #define CORE_FILE_P rs6000coff_core_p
1320 extern const bfd_target
* rs6000coff_core_p ();
1321 extern boolean
rs6000coff_get_section_contents ();
1322 extern boolean
rs6000coff_core_file_matches_executable_p ();
1324 #undef coff_core_file_matches_executable_p
1325 #define coff_core_file_matches_executable_p \
1326 rs6000coff_core_file_matches_executable_p
1328 extern char *rs6000coff_core_file_failing_command
PARAMS ((bfd
*abfd
));
1329 #undef coff_core_file_failing_command
1330 #define coff_core_file_failing_command rs6000coff_core_file_failing_command
1332 extern int rs6000coff_core_file_failing_signal
PARAMS ((bfd
*abfd
));
1333 #undef coff_core_file_failing_signal
1334 #define coff_core_file_failing_signal rs6000coff_core_file_failing_signal
1336 #undef coff_get_section_contents
1337 #define coff_get_section_contents rs6000coff_get_section_contents
1338 #endif /* AIX_CORE */
1343 #define CORE_FILE_P lynx_core_file_p
1344 extern const bfd_target
*lynx_core_file_p
PARAMS ((bfd
*abfd
));
1346 extern boolean lynx_core_file_matches_executable_p
PARAMS ((bfd
*core_bfd
,
1348 #undef coff_core_file_matches_executable_p
1349 #define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p
1351 extern char *lynx_core_file_failing_command
PARAMS ((bfd
*abfd
));
1352 #undef coff_core_file_failing_command
1353 #define coff_core_file_failing_command lynx_core_file_failing_command
1355 extern int lynx_core_file_failing_signal
PARAMS ((bfd
*abfd
));
1356 #undef coff_core_file_failing_signal
1357 #define coff_core_file_failing_signal lynx_core_file_failing_signal
1359 #endif /* LYNX_CORE */
1361 #define _bfd_xcoff_bfd_get_relocated_section_contents \
1362 coff_bfd_get_relocated_section_contents
1363 #define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section
1364 #define _bfd_xcoff_bfd_gc_sections coff_bfd_gc_sections
1365 #define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section
1367 /* The transfer vector that leads the outside world to all of the above. */
1379 "aixcoff-rs6000", /* name */
1381 bfd_target_coff_flavour
,
1382 BFD_ENDIAN_BIG
, /* data byte order is big */
1383 BFD_ENDIAN_BIG
, /* header byte order is big */
1385 (HAS_RELOC
| EXEC_P
| /* object flags */
1386 HAS_LINENO
| HAS_DEBUG
| DYNAMIC
|
1387 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
),
1389 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
1390 0, /* leading char */
1391 '/', /* ar_pad_char */
1392 15, /* ar_max_namelen??? FIXMEmgo */
1394 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1395 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1396 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
1397 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1398 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1399 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
1401 {_bfd_dummy_target
, coff_object_p
, /* bfd_check_format */
1402 xcoff_archive_p
, CORE_FILE_P
},
1403 {bfd_false
, coff_mkobject
, /* bfd_set_format */
1404 _bfd_generic_mkarchive
, bfd_false
},
1405 {bfd_false
, coff_write_object_contents
, /* bfd_write_contents */
1406 xcoff_write_archive_contents
, bfd_false
},
1408 BFD_JUMP_TABLE_GENERIC (coff
),
1409 BFD_JUMP_TABLE_COPY (coff
),
1410 BFD_JUMP_TABLE_CORE (coff
),
1411 BFD_JUMP_TABLE_ARCHIVE (xcoff
),
1412 BFD_JUMP_TABLE_SYMBOLS (coff
),
1413 BFD_JUMP_TABLE_RELOCS (coff
),
1414 BFD_JUMP_TABLE_WRITE (coff
),
1415 BFD_JUMP_TABLE_LINK (_bfd_xcoff
),
1416 BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff
),