This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / coff-rs6000.c
1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2    Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 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
6    character set it is.
7    Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, 
8      and John Gilmore.
9    Archive support from Damon A. Permezel.
10    Contributed by IBM Corporation and Cygnus Support.
11
12 This file is part of BFD, the Binary File Descriptor library.
13
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.
18
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.
23
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.  */
27
28 /* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
29 #define RS6000COFF_C 1
30
31 #include "bfd.h"
32 #include "sysdep.h"
33 #include "libbfd.h"
34 #include "coff/internal.h"
35 #include "coff/rs6000.h"
36 #include "libcoff.h"
37
38 /* The main body of code is in coffcode.h.  */
39
40 static boolean xcoff_mkobject PARAMS ((bfd *));
41 static boolean xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *));
42 static boolean xcoff_is_local_label_name PARAMS ((bfd *, const char *));
43 static void xcoff_rtype2howto
44   PARAMS ((arelent *, struct internal_reloc *));
45 static reloc_howto_type *xcoff_reloc_type_lookup
46   PARAMS ((bfd *, bfd_reloc_code_real_type));
47 static boolean xcoff_slurp_armap PARAMS ((bfd *));
48 static const bfd_target *xcoff_archive_p PARAMS ((bfd *));
49 static PTR xcoff_read_ar_hdr PARAMS ((bfd *));
50 static bfd *xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
51 static int xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
52 static const char *normalize_filename PARAMS ((bfd *));
53 static boolean xcoff_write_armap
54   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
55 static boolean xcoff_write_archive_contents PARAMS ((bfd *));
56 \f
57 /* We use our own tdata type.  Its first field is the COFF tdata type,
58    so the COFF routines are compatible.  */
59
60 static boolean
61 xcoff_mkobject (abfd)
62      bfd *abfd;
63 {
64   coff_data_type *coff;
65
66   abfd->tdata.xcoff_obj_data =
67     ((struct xcoff_tdata *)
68      bfd_zalloc (abfd, sizeof (struct xcoff_tdata)));
69   if (abfd->tdata.xcoff_obj_data == NULL)
70     return false;
71   coff = coff_data (abfd);
72   coff->symbols = (coff_symbol_type *) NULL;
73   coff->conversion_table = (unsigned int *) NULL;
74   coff->raw_syments = (struct coff_ptr_struct *) NULL;
75   coff->relocbase = 0;
76
77   xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
78
79   /* We set cputype to -1 to indicate that it has not been
80      initialized.  */
81   xcoff_data (abfd)->cputype = -1;
82
83   xcoff_data (abfd)->csects = NULL;
84   xcoff_data (abfd)->debug_indices = NULL;
85
86   return true;
87 }
88
89 /* Copy XCOFF data from one BFD to another.  */
90
91 static boolean
92 xcoff_copy_private_bfd_data (ibfd, obfd)
93      bfd *ibfd;
94      bfd *obfd;
95 {
96   struct xcoff_tdata *ix, *ox;
97   asection *sec;
98
99   if (ibfd->xvec != obfd->xvec)
100     return true;
101   ix = xcoff_data (ibfd);
102   ox = xcoff_data (obfd);
103   ox->full_aouthdr = ix->full_aouthdr;
104   ox->toc = ix->toc;
105   if (ix->sntoc == 0)
106     ox->sntoc = 0;
107   else
108     {
109       sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
110       if (sec == NULL)
111         ox->sntoc = 0;
112       else
113         ox->sntoc = sec->output_section->target_index;
114     }
115   if (ix->snentry == 0)
116     ox->snentry = 0;
117   else
118     {
119       sec = coff_section_from_bfd_index (ibfd, ix->snentry);
120       if (sec == NULL)
121         ox->snentry = 0;
122       else
123         ox->snentry = sec->output_section->target_index;
124     }
125   ox->text_align_power = ix->text_align_power;
126   ox->data_align_power = ix->data_align_power;
127   ox->modtype = ix->modtype;
128   ox->cputype = ix->cputype;
129   ox->maxdata = ix->maxdata;
130   ox->maxstack = ix->maxstack;
131   return true;
132 }
133
134 /* I don't think XCOFF really has a notion of local labels based on
135    name.  This will mean that ld -X doesn't actually strip anything.
136    The AIX native linker does not have a -X option, and it ignores the
137    -x option.  */
138
139 static boolean
140 xcoff_is_local_label_name (abfd, name)
141      bfd *abfd;
142      const char *name;
143 {
144   return false;
145 }
146 \f
147 /* The XCOFF reloc table.  Actually, XCOFF relocations specify the
148    bitsize and whether they are signed or not, along with a
149    conventional type.  This table is for the types, which are used for
150    different algorithms for putting in the reloc.  Many of these
151    relocs need special_function entries, which I have not written.  */
152
153 static reloc_howto_type xcoff_howto_table[] =
154 {
155   /* Standard 32 bit relocation.  */
156   HOWTO (0,                     /* type */                                 
157          0,                     /* rightshift */                           
158          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
159          32,                    /* bitsize */                   
160          false,                 /* pc_relative */                          
161          0,                     /* bitpos */                               
162          complain_overflow_bitfield, /* complain_on_overflow */
163          0,                     /* special_function */                     
164          "R_POS",               /* name */                                 
165          true,                  /* partial_inplace */                      
166          0xffffffff,            /* src_mask */                             
167          0xffffffff,            /* dst_mask */                             
168          false),                /* pcrel_offset */
169
170   /* 32 bit relocation, but store negative value.  */
171   HOWTO (1,                     /* type */                                 
172          0,                     /* rightshift */                           
173          -2,                    /* size (0 = byte, 1 = short, 2 = long) */ 
174          32,                    /* bitsize */                   
175          false,                 /* pc_relative */                          
176          0,                     /* bitpos */                               
177          complain_overflow_bitfield, /* complain_on_overflow */
178          0,                     /* special_function */                     
179          "R_NEG",               /* name */                                 
180          true,                  /* partial_inplace */                      
181          0xffffffff,            /* src_mask */                             
182          0xffffffff,            /* dst_mask */                             
183          false),                /* pcrel_offset */
184
185   /* 32 bit PC relative relocation.  */
186   HOWTO (2,                     /* type */                                 
187          0,                     /* rightshift */                           
188          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
189          32,                    /* bitsize */                   
190          true,                  /* pc_relative */                          
191          0,                     /* bitpos */                               
192          complain_overflow_signed, /* complain_on_overflow */
193          0,                     /* special_function */                     
194          "R_REL",               /* name */                                 
195          true,                  /* partial_inplace */                      
196          0xffffffff,            /* src_mask */                             
197          0xffffffff,            /* dst_mask */                             
198          false),                /* pcrel_offset */
199   
200   /* 16 bit TOC relative relocation.  */
201   HOWTO (3,                     /* type */                                 
202          0,                     /* rightshift */                           
203          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
204          16,                    /* bitsize */                   
205          false,                 /* pc_relative */                          
206          0,                     /* bitpos */                               
207          complain_overflow_bitfield, /* complain_on_overflow */
208          0,                     /* special_function */                     
209          "R_TOC",               /* name */                                 
210          true,                  /* partial_inplace */                      
211          0xffff,                /* src_mask */                             
212          0xffff,                /* dst_mask */                             
213          false),                /* pcrel_offset */
214   
215   /* I don't really know what this is.  */
216   HOWTO (4,                     /* type */                                 
217          1,                     /* rightshift */                           
218          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
219          32,                    /* bitsize */                   
220          false,                 /* pc_relative */                          
221          0,                     /* bitpos */                               
222          complain_overflow_bitfield, /* complain_on_overflow */
223          0,                     /* special_function */                     
224          "R_RTB",               /* name */                                 
225          true,                  /* partial_inplace */                      
226          0xffffffff,            /* src_mask */                             
227          0xffffffff,            /* dst_mask */                             
228          false),                /* pcrel_offset */
229   
230   /* External TOC relative symbol.  */
231   HOWTO (5,                     /* type */                                 
232          0,                     /* rightshift */                           
233          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
234          16,                    /* bitsize */                   
235          false,                 /* pc_relative */                          
236          0,                     /* bitpos */                               
237          complain_overflow_bitfield, /* complain_on_overflow */
238          0,                     /* special_function */                     
239          "R_GL",                /* name */                                 
240          true,                  /* partial_inplace */                      
241          0xffff,                /* src_mask */                             
242          0xffff,                /* dst_mask */                             
243          false),                /* pcrel_offset */
244   
245   /* Local TOC relative symbol.  */
246   HOWTO (6,                     /* type */                                 
247          0,                     /* rightshift */                           
248          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
249          16,                    /* bitsize */                   
250          false,                 /* pc_relative */                          
251          0,                     /* bitpos */                               
252          complain_overflow_bitfield, /* complain_on_overflow */
253          0,                     /* special_function */                     
254          "R_TCL",               /* name */                                 
255          true,                  /* partial_inplace */                      
256          0xffff,                /* src_mask */                             
257          0xffff,                /* dst_mask */                             
258          false),                /* pcrel_offset */
259   
260   { 7 },
261   
262   /* Non modifiable absolute branch.  */
263   HOWTO (8,                     /* type */                                 
264          0,                     /* rightshift */                           
265          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
266          26,                    /* bitsize */                   
267          false,                 /* pc_relative */                          
268          0,                     /* bitpos */                               
269          complain_overflow_bitfield, /* complain_on_overflow */
270          0,                     /* special_function */                     
271          "R_BA",                /* name */                                 
272          true,                  /* partial_inplace */                      
273          0x3fffffc,             /* src_mask */                             
274          0x3fffffc,             /* dst_mask */                             
275          false),                /* pcrel_offset */
276   
277   { 9 },
278
279   /* Non modifiable relative branch.  */
280   HOWTO (0xa,                   /* type */                                 
281          0,                     /* rightshift */                           
282          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
283          26,                    /* bitsize */                   
284          true,                  /* pc_relative */                          
285          0,                     /* bitpos */                               
286          complain_overflow_signed, /* complain_on_overflow */
287          0,                     /* special_function */                     
288          "R_BR",                /* name */                                 
289          true,                  /* partial_inplace */                      
290          0x3fffffc,             /* src_mask */                             
291          0x3fffffc,             /* dst_mask */                             
292          false),                /* pcrel_offset */
293   
294   { 0xb },
295
296   /* Indirect load.  */
297   HOWTO (0xc,                   /* type */                                 
298          0,                     /* rightshift */                           
299          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
300          16,                    /* bitsize */                   
301          false,                 /* pc_relative */                          
302          0,                     /* bitpos */                               
303          complain_overflow_bitfield, /* complain_on_overflow */
304          0,                     /* special_function */                     
305          "R_RL",                /* name */                                 
306          true,                  /* partial_inplace */                      
307          0xffff,                /* src_mask */                             
308          0xffff,                /* dst_mask */                             
309          false),                /* pcrel_offset */
310   
311   /* Load address.  */
312   HOWTO (0xd,                   /* type */                                 
313          0,                     /* rightshift */                           
314          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
315          16,                    /* bitsize */                   
316          false,                 /* pc_relative */                          
317          0,                     /* bitpos */                               
318          complain_overflow_bitfield, /* complain_on_overflow */
319          0,                     /* special_function */                     
320          "R_RLA",               /* name */                                 
321          true,                  /* partial_inplace */                      
322          0xffff,                /* src_mask */                             
323          0xffff,                /* dst_mask */                             
324          false),                /* pcrel_offset */
325   
326   { 0xe },
327   
328   /* Non-relocating reference.  */
329   HOWTO (0xf,                   /* type */                                 
330          0,                     /* rightshift */                           
331          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
332          32,                    /* bitsize */                   
333          false,                 /* pc_relative */                          
334          0,                     /* bitpos */                               
335          complain_overflow_bitfield, /* complain_on_overflow */
336          0,                     /* special_function */                     
337          "R_REF",               /* name */                                 
338          false,                 /* partial_inplace */                      
339          0,                     /* src_mask */                             
340          0,                     /* dst_mask */                             
341          false),                /* pcrel_offset */
342   
343   { 0x10 },
344   { 0x11 },
345   
346   /* TOC relative indirect load.  */
347   HOWTO (0x12,                  /* type */                                 
348          0,                     /* rightshift */                           
349          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
350          16,                    /* bitsize */                   
351          false,                 /* pc_relative */                          
352          0,                     /* bitpos */                               
353          complain_overflow_bitfield, /* complain_on_overflow */
354          0,                     /* special_function */                     
355          "R_TRL",               /* name */                                 
356          true,                  /* partial_inplace */                      
357          0xffff,                /* src_mask */                             
358          0xffff,                /* dst_mask */                             
359          false),                /* pcrel_offset */
360   
361   /* TOC relative load address.  */
362   HOWTO (0x13,                  /* type */                                 
363          0,                     /* rightshift */                           
364          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
365          16,                    /* bitsize */                   
366          false,                 /* pc_relative */                          
367          0,                     /* bitpos */                               
368          complain_overflow_bitfield, /* complain_on_overflow */
369          0,                     /* special_function */                     
370          "R_TRLA",              /* name */                                 
371          true,                  /* partial_inplace */                      
372          0xffff,                /* src_mask */                             
373          0xffff,                /* dst_mask */                             
374          false),                /* pcrel_offset */
375   
376   /* Modifiable relative branch.  */
377   HOWTO (0x14,                  /* type */                                 
378          1,                     /* rightshift */                           
379          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
380          32,                    /* bitsize */                   
381          false,                 /* pc_relative */                          
382          0,                     /* bitpos */                               
383          complain_overflow_bitfield, /* complain_on_overflow */
384          0,                     /* special_function */                     
385          "R_RRTBI",             /* name */                                 
386          true,                  /* partial_inplace */                      
387          0xffffffff,            /* src_mask */                             
388          0xffffffff,            /* dst_mask */                             
389          false),                /* pcrel_offset */
390   
391   /* Modifiable absolute branch.  */
392   HOWTO (0x15,                  /* type */                                 
393          1,                     /* rightshift */                           
394          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
395          32,                    /* bitsize */                   
396          false,                 /* pc_relative */                          
397          0,                     /* bitpos */                               
398          complain_overflow_bitfield, /* complain_on_overflow */
399          0,                     /* special_function */                     
400          "R_RRTBA",             /* name */                                 
401          true,                  /* partial_inplace */                      
402          0xffffffff,            /* src_mask */                             
403          0xffffffff,            /* dst_mask */                             
404          false),                /* pcrel_offset */
405   
406   /* Modifiable call absolute indirect.  */
407   HOWTO (0x16,                  /* type */                                 
408          0,                     /* rightshift */                           
409          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
410          16,                    /* bitsize */                   
411          false,                 /* pc_relative */                          
412          0,                     /* bitpos */                               
413          complain_overflow_bitfield, /* complain_on_overflow */
414          0,                     /* special_function */                     
415          "R_CAI",               /* name */                                 
416          true,                  /* partial_inplace */                      
417          0xffff,                /* src_mask */                             
418          0xffff,                /* dst_mask */                             
419          false),                /* pcrel_offset */
420   
421   /* Modifiable call relative.  */
422   HOWTO (0x17,                  /* type */                                 
423          0,                     /* rightshift */                           
424          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
425          16,                    /* bitsize */                   
426          false,                 /* pc_relative */                          
427          0,                     /* bitpos */                               
428          complain_overflow_bitfield, /* complain_on_overflow */
429          0,                     /* special_function */                     
430          "R_CREL",              /* name */                                 
431          true,                  /* partial_inplace */                      
432          0xffff,                /* src_mask */                             
433          0xffff,                /* dst_mask */                             
434          false),                /* pcrel_offset */
435   
436   /* Modifiable branch absolute.  */
437   HOWTO (0x18,                  /* type */                                 
438          0,                     /* rightshift */                           
439          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
440          16,                    /* bitsize */                   
441          false,                 /* pc_relative */                          
442          0,                     /* bitpos */                               
443          complain_overflow_bitfield, /* complain_on_overflow */
444          0,                     /* special_function */                     
445          "R_RBA",               /* name */                                 
446          true,                  /* partial_inplace */                      
447          0xffff,                /* src_mask */                             
448          0xffff,                /* dst_mask */                             
449          false),                /* pcrel_offset */
450   
451   /* Modifiable branch absolute.  */
452   HOWTO (0x19,                  /* type */                                 
453          0,                     /* rightshift */                           
454          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
455          16,                    /* bitsize */                   
456          false,                 /* pc_relative */                          
457          0,                     /* bitpos */                               
458          complain_overflow_bitfield, /* complain_on_overflow */
459          0,                     /* special_function */                     
460          "R_RBAC",              /* name */                                 
461          true,                  /* partial_inplace */                      
462          0xffff,                /* src_mask */                             
463          0xffff,                /* dst_mask */                             
464          false),                /* pcrel_offset */
465   
466   /* Modifiable branch relative.  */
467   HOWTO (0x1a,                  /* type */                                 
468          0,                     /* rightshift */                           
469          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
470          26,                    /* bitsize */                   
471          false,                 /* pc_relative */                          
472          0,                     /* bitpos */                               
473          complain_overflow_signed, /* complain_on_overflow */
474          0,                     /* special_function */                     
475          "R_RBR",               /* name */                                 
476          true,                  /* partial_inplace */                      
477          0xffff,                /* src_mask */                             
478          0xffff,                /* dst_mask */                             
479          false),                /* pcrel_offset */
480   
481   /* Modifiable branch absolute.  */
482   HOWTO (0x1b,                  /* type */                                 
483          0,                     /* rightshift */                           
484          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
485          16,                    /* bitsize */                   
486          false,                 /* pc_relative */                          
487          0,                     /* bitpos */                               
488          complain_overflow_bitfield, /* complain_on_overflow */
489          0,                     /* special_function */                     
490          "R_RBRC",              /* name */                                 
491          true,                  /* partial_inplace */                      
492          0xffff,                /* src_mask */                             
493          0xffff,                /* dst_mask */                             
494          false)                 /* pcrel_offset */
495 };
496
497 static void
498 xcoff_rtype2howto (relent, internal)
499      arelent *relent;
500      struct internal_reloc *internal;
501 {
502   relent->howto = xcoff_howto_table + internal->r_type;
503
504   /* The r_size field of an XCOFF reloc encodes the bitsize of the
505      relocation, as well as indicating whether it is signed or not.
506      Doublecheck that the relocation information gathered from the
507      type matches this information.  */
508   if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1)
509     abort ();
510 #if 0
511   if ((internal->r_size & 0x80) != 0
512       ? (relent->howto->complain_on_overflow != complain_overflow_signed)
513       : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
514     abort ();
515 #endif
516 }
517
518 static reloc_howto_type *
519 xcoff_reloc_type_lookup (abfd, code)
520      bfd *abfd;
521      bfd_reloc_code_real_type code;
522 {
523   switch (code)
524     {
525     case BFD_RELOC_PPC_B26:
526       return &xcoff_howto_table[0xa];
527     case BFD_RELOC_PPC_BA26:
528       return &xcoff_howto_table[8];
529     case BFD_RELOC_PPC_TOC16:
530       return &xcoff_howto_table[3];
531     case BFD_RELOC_32:
532     case BFD_RELOC_CTOR:
533       return &xcoff_howto_table[0];
534     default:
535       return NULL;
536     }
537 }
538
539 #define SELECT_RELOC(internal, howto)                                   \
540   {                                                                     \
541     internal.r_type = howto->type;                                      \
542     internal.r_size =                                                   \
543       ((howto->complain_on_overflow == complain_overflow_signed         \
544         ? 0x80                                                          \
545         : 0)                                                            \
546        | (howto->bitsize - 1));                                         \
547   }
548 \f
549 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
550
551 #define COFF_LONG_FILENAMES
552
553 #define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
554
555 #define coff_mkobject xcoff_mkobject
556 #define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data
557 #define coff_bfd_is_local_label_name xcoff_is_local_label_name
558 #define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup
559 #define coff_relocate_section _bfd_ppc_xcoff_relocate_section
560
561 #include "coffcode.h"
562 \f
563 /* XCOFF archive support.  The original version of this code was by
564    Damon A. Permezel.  It was enhanced to permit cross support, and
565    writing archive files, by Ian Lance Taylor, Cygnus Support.
566
567    XCOFF uses its own archive format.  Everything is hooked together
568    with file offset links, so it is possible to rapidly update an
569    archive in place.  Of course, we don't do that.  An XCOFF archive
570    has a real file header, not just an ARMAG string.  The structure of
571    the file header and of each archive header appear below.
572
573    An XCOFF archive also has a member table, which is a list of
574    elements in the archive (you can get that by looking through the
575    linked list, but you have to read a lot more of the file).  The
576    member table has a normal archive header with an empty name.  It is
577    normally (and perhaps must be) the second to last entry in the
578    archive.  The member table data is almost printable ASCII.  It
579    starts with a 12 character decimal string which is the number of
580    entries in the table.  For each entry it has a 12 character decimal
581    string which is the offset in the archive of that member.  These
582    entries are followed by a series of null terminated strings which
583    are the member names for each entry.
584
585    Finally, an XCOFF archive has a global symbol table, which is what
586    we call the armap.  The global symbol table has a normal archive
587    header with an empty name.  It is normally (and perhaps must be)
588    the last entry in the archive.  The contents start with a four byte
589    binary number which is the number of entries.  This is followed by
590    a that many four byte binary numbers; each is the file offset of an
591    entry in the archive.  These numbers are followed by a series of
592    null terminated strings, which are symbol names.  */
593
594 /* XCOFF archives use this as a magic string.  */
595
596 #define XCOFFARMAG "<aiaff>\012"
597 #define SXCOFFARMAG 8
598
599 /* This terminates an XCOFF archive member name.  */
600
601 #define XCOFFARFMAG "`\012"
602 #define SXCOFFARFMAG 2
603
604 /* XCOFF archives start with this (printable) structure.  */
605
606 struct xcoff_ar_file_hdr
607 {
608   /* Magic string.  */
609   char magic[SXCOFFARMAG];
610
611   /* Offset of the member table (decimal ASCII string).  */
612   char memoff[12];
613
614   /* Offset of the global symbol table (decimal ASCII string).  */
615   char symoff[12];
616
617   /* Offset of the first member in the archive (decimal ASCII string).  */
618   char firstmemoff[12];
619
620   /* Offset of the last member in the archive (decimal ASCII string).  */
621   char lastmemoff[12];
622
623   /* Offset of the first member on the free list (decimal ASCII
624      string).  */
625   char freeoff[12];
626 };
627
628 #define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG)
629
630 /* Each XCOFF archive member starts with this (printable) structure.  */
631
632 struct xcoff_ar_hdr
633 {
634   /* File size not including the header (decimal ASCII string).  */
635   char size[12];
636
637   /* File offset of next archive member (decimal ASCII string).  */
638   char nextoff[12];
639
640   /* File offset of previous archive member (decimal ASCII string).  */
641   char prevoff[12];
642
643   /* File mtime (decimal ASCII string).  */
644   char date[12];
645
646   /* File UID (decimal ASCII string).  */
647   char uid[12];
648
649   /* File GID (decimal ASCII string).  */
650   char gid[12];
651
652   /* File mode (octal ASCII string).  */
653   char mode[12];
654
655   /* Length of file name (decimal ASCII string).  */
656   char namlen[4];
657
658   /* This structure is followed by the file name.  The length of the
659      name is given in the namlen field.  If the length of the name is
660      odd, the name is followed by a null byte.  The name and optional
661      null byte are followed by XCOFFARFMAG, which is not included in
662      namlen.  The contents of the archive member follow; the number of
663      bytes is given in the size field.  */
664 };
665
666 #define SIZEOF_AR_HDR (7 * 12 + 4)
667
668 /* We store a copy of the xcoff_ar_file_hdr in the tdata field of the
669    artdata structure.  */
670 #define xcoff_ardata(abfd) \
671   ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata)
672
673 /* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
674    archive element.  */
675 #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
676 #define arch_xhdr(bfd) \
677   ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header)
678
679 /* XCOFF archives do not have anything which corresponds to an
680    extended name table.  */
681
682 #define xcoff_slurp_extended_name_table bfd_false
683 #define xcoff_construct_extended_name_table \
684   ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
685    bfd_false)
686 #define xcoff_truncate_arname bfd_dont_truncate_arname
687
688 /* We can use the standard get_elt_at_index routine.  */
689
690 #define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
691
692 /* XCOFF archives do not have a timestamp.  */
693
694 #define xcoff_update_armap_timestamp bfd_true
695
696 /* Read in the armap of an XCOFF archive.  */
697
698 static boolean
699 xcoff_slurp_armap (abfd)
700      bfd *abfd;
701 {
702   file_ptr off;
703   struct xcoff_ar_hdr hdr;
704   size_t namlen;
705   bfd_size_type sz;
706   bfd_byte *contents, *cend;
707   unsigned int c, i;
708   carsym *arsym;
709   bfd_byte *p;
710
711   if (xcoff_ardata (abfd) == NULL)
712     {
713       bfd_has_map (abfd) = false;
714       return true;
715     }
716
717   off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
718   if (off == 0)
719     {
720       bfd_has_map (abfd) = false;
721       return true;
722     }
723
724   if (bfd_seek (abfd, off, SEEK_SET) != 0)
725     return false;
726
727   /* The symbol table starts with a normal archive header.  */
728   if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
729     return false;
730
731   /* Skip the name (normally empty).  */
732   namlen = strtol (hdr.namlen, (char **) NULL, 10);
733   if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0)
734     return false;
735
736   /* Read in the entire symbol table.  */
737   sz = strtol (hdr.size, (char **) NULL, 10);
738   contents = (bfd_byte *) bfd_alloc (abfd, sz);
739   if (contents == NULL)
740     return false;
741   if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
742     return false;
743
744   /* The symbol table starts with a four byte count.  */
745   c = bfd_h_get_32 (abfd, contents);
746
747   if (c * 4 >= sz)
748     {
749       bfd_set_error (bfd_error_bad_value);
750       return false;
751     }
752
753   bfd_ardata (abfd)->symdefs = ((carsym *)
754                                 bfd_alloc (abfd, c * sizeof (carsym)));
755   if (bfd_ardata (abfd)->symdefs == NULL)
756     return false;
757
758   /* After the count comes a list of four byte file offsets.  */
759   for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
760        i < c;
761        ++i, ++arsym, p += 4)
762     arsym->file_offset = bfd_h_get_32 (abfd, p);
763
764   /* After the file offsets come null terminated symbol names.  */
765   cend = contents + sz;
766   for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
767        i < c;
768        ++i, ++arsym, p += strlen ((char *) p) + 1)
769     {
770       if (p >= cend)
771         {
772           bfd_set_error (bfd_error_bad_value);
773           return false;
774         }
775       arsym->name = (char *) p;
776     }
777
778   bfd_ardata (abfd)->symdef_count = c;
779   bfd_has_map (abfd) = true;
780
781   return true;
782 }
783
784 /* See if this is an XCOFF archive.  */
785
786 static const bfd_target *
787 xcoff_archive_p (abfd)
788      bfd *abfd;
789 {
790   struct xcoff_ar_file_hdr hdr;
791
792   if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd)
793       != SIZEOF_AR_FILE_HDR)
794     {
795       if (bfd_get_error () != bfd_error_system_call)
796         bfd_set_error (bfd_error_wrong_format);
797       return NULL;
798     }
799
800   if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0)
801     {
802       bfd_set_error (bfd_error_wrong_format);
803       return NULL;
804     }
805
806   /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
807      involves a cast, we can't do it as the left operand of
808      assignment.  */
809   abfd->tdata.aout_ar_data =
810     (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
811
812   if (bfd_ardata (abfd) == (struct artdata *) NULL)
813     return NULL;
814
815   bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
816                                                   (char **) NULL, 10);
817   bfd_ardata (abfd)->cache = NULL;
818   bfd_ardata (abfd)->archive_head = NULL;
819   bfd_ardata (abfd)->symdefs = NULL;
820   bfd_ardata (abfd)->extended_names = NULL;
821
822   bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR);
823   if (bfd_ardata (abfd)->tdata == NULL)
824     return NULL;
825
826   memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
827
828   if (! xcoff_slurp_armap (abfd))
829     {
830       bfd_release (abfd, bfd_ardata (abfd));
831       abfd->tdata.aout_ar_data = (struct artdata *) NULL;
832       return NULL;
833     }
834
835   return abfd->xvec;
836 }
837
838 /* Read the archive header in an XCOFF archive.  */
839
840 static PTR
841 xcoff_read_ar_hdr (abfd)
842      bfd *abfd;
843 {
844   struct xcoff_ar_hdr hdr;
845   size_t namlen;
846   struct xcoff_ar_hdr *hdrp;
847   struct areltdata *ret;
848
849   if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
850     return NULL;
851
852   namlen = strtol (hdr.namlen, (char **) NULL, 10);
853   hdrp = bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1);
854   if (hdrp == NULL)
855     return NULL;
856   memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
857   if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen)
858     return NULL;
859   ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
860
861   ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata));
862   if (ret == NULL)
863     return NULL;
864   ret->arch_header = (char *) hdrp;
865   ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
866   ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
867
868   /* Skip over the XCOFFARFMAG at the end of the file name.  */
869   if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0)
870     return NULL;
871
872   return (PTR) ret;
873 }
874
875 /* Open the next element in an XCOFF archive.  */
876
877 static bfd *
878 xcoff_openr_next_archived_file (archive, last_file)
879      bfd *archive;
880      bfd *last_file;
881 {
882   file_ptr filestart;
883
884   if (xcoff_ardata (archive) == NULL)
885     {
886       bfd_set_error (bfd_error_invalid_operation);
887       return NULL;
888     }
889
890   if (last_file == NULL)
891     filestart = bfd_ardata (archive)->first_file_filepos;
892   else
893     filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10);
894
895   if (filestart == 0
896       || filestart == strtol (xcoff_ardata (archive)->memoff,
897                               (char **) NULL, 10)
898       || filestart == strtol (xcoff_ardata (archive)->symoff,
899                               (char **) NULL, 10))
900     {
901       bfd_set_error (bfd_error_no_more_archived_files);
902       return NULL;
903     }
904
905   return _bfd_get_elt_at_filepos (archive, filestart);
906 }
907
908 /* Stat an element in an XCOFF archive.  */
909
910 static int
911 xcoff_generic_stat_arch_elt (abfd, s)
912      bfd *abfd;
913      struct stat *s;
914 {
915   struct xcoff_ar_hdr *hdrp;
916
917   if (abfd->arelt_data == NULL)
918     {
919       bfd_set_error (bfd_error_invalid_operation);
920       return -1;
921     }
922
923   hdrp = arch_xhdr (abfd);
924
925   s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
926   s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
927   s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
928   s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
929   s->st_size = arch_eltdata (abfd)->parsed_size;
930
931   return 0;
932 }
933
934 /* Normalize a file name for inclusion in an archive.  */
935
936 static const char *
937 normalize_filename (abfd)
938      bfd *abfd;
939 {
940   const char *file;
941   const char *filename;
942
943   file = bfd_get_filename (abfd);
944   filename = strrchr (file, '/');
945   if (filename != NULL)
946     filename++;
947   else
948     filename = file;
949   return filename;
950 }
951
952 /* Write out an XCOFF armap.  */
953
954 /*ARGSUSED*/
955 static boolean
956 xcoff_write_armap (abfd, elength, map, orl_count, stridx)
957      bfd *abfd;
958      unsigned int elength;
959      struct orl *map;
960      unsigned int orl_count;
961      int stridx;
962 {
963   struct xcoff_ar_hdr hdr;
964   char *p;
965   unsigned char buf[4];
966   bfd *sub;
967   file_ptr fileoff;
968   unsigned int i;
969
970   memset (&hdr, 0, sizeof hdr);
971   sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
972   sprintf (hdr.nextoff, "%d", 0);
973   memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12);
974   sprintf (hdr.date, "%d", 0);
975   sprintf (hdr.uid, "%d", 0);
976   sprintf (hdr.gid, "%d", 0);
977   sprintf (hdr.mode, "%d", 0);
978   sprintf (hdr.namlen, "%d", 0);
979
980   /* We need spaces, not null bytes, in the header.  */
981   for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
982     if (*p == '\0')
983       *p = ' ';
984
985   if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR
986       || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
987     return false;
988   
989   bfd_h_put_32 (abfd, orl_count, buf);
990   if (bfd_write (buf, 1, 4, abfd) != 4)
991     return false;
992
993   sub = abfd->archive_head;
994   fileoff = SIZEOF_AR_FILE_HDR;
995   i = 0;
996   while (sub != NULL && i < orl_count)
997     {
998       size_t namlen;
999
1000       while (((bfd *) (map[i]).pos) == sub)
1001         {
1002           bfd_h_put_32 (abfd, fileoff, buf);
1003           if (bfd_write (buf, 1, 4, abfd) != 4)
1004             return false;
1005           ++i;
1006         }
1007       namlen = strlen (normalize_filename (sub));
1008       namlen = (namlen + 1) &~ 1;
1009       fileoff += (SIZEOF_AR_HDR
1010                   + namlen
1011                   + SXCOFFARFMAG
1012                   + arelt_size (sub));
1013       fileoff = (fileoff + 1) &~ 1;
1014       sub = sub->next;
1015     }
1016
1017   for (i = 0; i < orl_count; i++)
1018     {
1019       const char *name;
1020       size_t namlen;
1021
1022       name = *map[i].name;
1023       namlen = strlen (name);
1024       if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
1025         return false;
1026     }
1027
1028   if ((stridx & 1) != 0)
1029     {
1030       char b;
1031
1032       b = '\0';
1033       if (bfd_write (&b, 1, 1, abfd) != 1)
1034         return false;
1035     }
1036
1037   return true;
1038 }
1039
1040 /* Write out an XCOFF archive.  We always write an entire archive,
1041    rather than fussing with the freelist and so forth.  */
1042
1043 static boolean
1044 xcoff_write_archive_contents (abfd)
1045      bfd *abfd;
1046 {
1047   struct xcoff_ar_file_hdr fhdr;
1048   size_t count;
1049   size_t total_namlen;
1050   file_ptr *offsets;
1051   boolean makemap;
1052   boolean hasobjects;
1053   file_ptr prevoff, nextoff;
1054   bfd *sub;
1055   unsigned int i;
1056   struct xcoff_ar_hdr ahdr;
1057   bfd_size_type size;
1058   char *p;
1059   char decbuf[13];
1060
1061   memset (&fhdr, 0, sizeof fhdr);
1062   strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
1063   sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
1064   sprintf (fhdr.freeoff, "%d", 0);
1065
1066   count = 0;
1067   total_namlen = 0;
1068   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1069     {
1070       ++count;
1071       total_namlen += strlen (normalize_filename (sub)) + 1;
1072     }
1073   offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
1074   if (offsets == NULL)
1075     return false;
1076
1077   if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
1078     return false;
1079
1080   makemap = bfd_has_map (abfd);
1081   hasobjects = false;
1082   prevoff = 0;
1083   nextoff = SIZEOF_AR_FILE_HDR;
1084   for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
1085     {
1086       const char *name;
1087       size_t namlen;
1088       struct xcoff_ar_hdr *ahdrp;
1089       bfd_size_type remaining;
1090
1091       if (makemap && ! hasobjects)
1092         {
1093           if (bfd_check_format (sub, bfd_object))
1094             hasobjects = true;
1095         }
1096
1097       name = normalize_filename (sub);
1098       namlen = strlen (name);
1099
1100       if (sub->arelt_data != NULL)
1101         ahdrp = arch_xhdr (sub);
1102       else
1103         ahdrp = NULL;
1104
1105       if (ahdrp == NULL)
1106         {
1107           struct stat s;
1108
1109           memset (&ahdr, 0, sizeof ahdr);
1110           ahdrp = &ahdr;
1111           if (stat (bfd_get_filename (sub), &s) != 0)
1112             {
1113               bfd_set_error (bfd_error_system_call);
1114               return false;
1115             }
1116
1117           sprintf (ahdrp->size, "%ld", (long) s.st_size);
1118           sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
1119           sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
1120           sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
1121           sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
1122
1123           if (sub->arelt_data == NULL)
1124             {
1125               sub->arelt_data = ((struct areltdata *)
1126                                  bfd_alloc (sub, sizeof (struct areltdata)));
1127               if (sub->arelt_data == NULL)
1128                 return false;
1129             }
1130
1131           arch_eltdata (sub)->parsed_size = s.st_size;
1132         }
1133
1134       sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
1135       sprintf (ahdrp->namlen, "%ld", (long) namlen);
1136
1137       /* If the length of the name is odd, we write out the null byte
1138          after the name as well.  */
1139       namlen = (namlen + 1) &~ 1;
1140
1141       remaining = arelt_size (sub);
1142       size = (SIZEOF_AR_HDR
1143               + namlen
1144               + SXCOFFARFMAG
1145               + remaining);
1146
1147       BFD_ASSERT (nextoff == bfd_tell (abfd));
1148
1149       offsets[i] = nextoff;
1150
1151       prevoff = nextoff;
1152       nextoff += size + (size & 1);
1153
1154       sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
1155
1156       /* We need spaces, not null bytes, in the header.  */
1157       for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
1158         if (*p == '\0')
1159           *p = ' ';
1160
1161       if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
1162           || bfd_write ((PTR) name, 1, namlen, abfd) != namlen
1163           || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
1164               != SXCOFFARFMAG))
1165         return false;
1166
1167       if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
1168         return false;
1169       while (remaining != 0)
1170         {
1171           bfd_size_type amt;
1172           bfd_byte buffer[DEFAULT_BUFFERSIZE];
1173
1174           amt = sizeof buffer;
1175           if (amt > remaining)
1176             amt = remaining;
1177           if (bfd_read (buffer, 1, amt, sub) != amt
1178               || bfd_write (buffer, 1, amt, abfd) != amt)
1179             return false;
1180           remaining -= amt;
1181         }
1182
1183       if ((size & 1) != 0)
1184         {
1185           bfd_byte b;
1186
1187           b = '\0';
1188           if (bfd_write (&b, 1, 1, abfd) != 1)
1189             return false;
1190         }
1191     }
1192
1193   sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
1194
1195   /* Write out the member table.  */
1196
1197   BFD_ASSERT (nextoff == bfd_tell (abfd));
1198   sprintf (fhdr.memoff, "%ld", (long) nextoff);
1199
1200   memset (&ahdr, 0, sizeof ahdr);
1201   sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen));
1202   sprintf (ahdr.prevoff, "%ld", (long) prevoff);
1203   sprintf (ahdr.date, "%d", 0);
1204   sprintf (ahdr.uid, "%d", 0);
1205   sprintf (ahdr.gid, "%d", 0);
1206   sprintf (ahdr.mode, "%d", 0);
1207   sprintf (ahdr.namlen, "%d", 0);
1208
1209   size = (SIZEOF_AR_HDR
1210           + 12
1211           + count * 12
1212           + total_namlen
1213           + SXCOFFARFMAG);
1214
1215   prevoff = nextoff;
1216   nextoff += size + (size & 1);
1217
1218   if (makemap && hasobjects)
1219     sprintf (ahdr.nextoff, "%ld", (long) nextoff);
1220   else
1221     sprintf (ahdr.nextoff, "%d", 0);
1222
1223   /* We need spaces, not null bytes, in the header.  */
1224   for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
1225     if (*p == '\0')
1226       *p = ' ';
1227
1228   if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
1229       || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
1230           != SXCOFFARFMAG))
1231     return false;
1232
1233   sprintf (decbuf, "%-12ld", (long) count);
1234   if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
1235     return false;
1236   for (i = 0; i < count; i++)
1237     {
1238       sprintf (decbuf, "%-12ld", (long) offsets[i]);
1239       if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
1240         return false;
1241     }
1242   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1243     {
1244       const char *name;
1245       size_t namlen;
1246
1247       name = normalize_filename (sub);
1248       namlen = strlen (name);
1249       if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1)
1250         return false;
1251     }
1252   if ((size & 1) != 0)
1253     {
1254       bfd_byte b;
1255
1256       b = '\0';
1257       if (bfd_write ((PTR) &b, 1, 1, abfd) != 1)
1258         return false;
1259     }
1260
1261   /* Write out the armap, if appropriate.  */
1262
1263   if (! makemap || ! hasobjects)
1264     sprintf (fhdr.symoff, "%d", 0);
1265   else
1266     {
1267       BFD_ASSERT (nextoff == bfd_tell (abfd));
1268       sprintf (fhdr.symoff, "%ld", (long) nextoff);
1269       bfd_ardata (abfd)->tdata = (PTR) &fhdr;
1270       if (! _bfd_compute_and_write_armap (abfd, 0))
1271         return false;
1272     }
1273
1274   /* Write out the archive file header.  */
1275
1276   /* We need spaces, not null bytes, in the header.  */
1277   for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
1278     if (*p == '\0')
1279       *p = ' ';
1280
1281   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1282       || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR, 1, abfd) !=
1283           SIZEOF_AR_FILE_HDR))
1284     return false;
1285
1286   return true;
1287 }
1288 \f
1289 /* We can't use the usual coff_sizeof_headers routine, because AIX
1290    always uses an a.out header.  */
1291
1292 /*ARGSUSED*/
1293 static int
1294 _bfd_xcoff_sizeof_headers (abfd, reloc)
1295      bfd *abfd;
1296      boolean reloc;
1297 {
1298   int size;
1299
1300   size = FILHSZ;
1301   if (xcoff_data (abfd)->full_aouthdr)
1302     size += AOUTSZ;
1303   else
1304     size += SMALL_AOUTSZ;
1305   size += abfd->section_count * SCNHSZ;
1306   return size;
1307 }
1308 \f
1309 #define CORE_FILE_P _bfd_dummy_target
1310
1311 #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command
1312 #define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal
1313 #define coff_core_file_matches_executable_p \
1314   _bfd_nocore_core_file_matches_executable_p
1315
1316 #ifdef AIX_CORE
1317 #undef CORE_FILE_P
1318 #define CORE_FILE_P rs6000coff_core_p
1319 extern const bfd_target * rs6000coff_core_p ();
1320 extern boolean rs6000coff_get_section_contents ();
1321 extern boolean rs6000coff_core_file_matches_executable_p ();
1322
1323 #undef  coff_core_file_matches_executable_p
1324 #define coff_core_file_matches_executable_p  \
1325                                      rs6000coff_core_file_matches_executable_p
1326
1327 extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
1328 #undef coff_core_file_failing_command
1329 #define coff_core_file_failing_command rs6000coff_core_file_failing_command
1330
1331 extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
1332 #undef coff_core_file_failing_signal
1333 #define coff_core_file_failing_signal rs6000coff_core_file_failing_signal
1334
1335 #undef  coff_get_section_contents
1336 #define coff_get_section_contents       rs6000coff_get_section_contents
1337 #endif /* AIX_CORE */
1338
1339 #ifdef LYNX_CORE
1340
1341 #undef CORE_FILE_P
1342 #define CORE_FILE_P lynx_core_file_p
1343 extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd));
1344
1345 extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
1346                                                             bfd *exec_bfd));
1347 #undef  coff_core_file_matches_executable_p
1348 #define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p
1349
1350 extern char *lynx_core_file_failing_command PARAMS ((bfd *abfd));
1351 #undef coff_core_file_failing_command
1352 #define coff_core_file_failing_command lynx_core_file_failing_command
1353
1354 extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd));
1355 #undef coff_core_file_failing_signal
1356 #define coff_core_file_failing_signal lynx_core_file_failing_signal
1357
1358 #endif /* LYNX_CORE */
1359
1360 #define _bfd_xcoff_bfd_get_relocated_section_contents \
1361   coff_bfd_get_relocated_section_contents
1362 #define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section
1363 #define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section
1364
1365 /* The transfer vector that leads the outside world to all of the above. */
1366
1367 const bfd_target
1368 #ifdef TARGET_SYM
1369   TARGET_SYM =
1370 #else
1371   rs6000coff_vec =
1372 #endif
1373 {
1374 #ifdef TARGET_NAME
1375   TARGET_NAME,
1376 #else
1377   "aixcoff-rs6000",             /* name */
1378 #endif
1379   bfd_target_coff_flavour,      
1380   BFD_ENDIAN_BIG,               /* data byte order is big */
1381   BFD_ENDIAN_BIG,               /* header byte order is big */
1382
1383   (HAS_RELOC | EXEC_P |         /* object flags */
1384    HAS_LINENO | HAS_DEBUG | DYNAMIC |
1385    HAS_SYMS | HAS_LOCALS | WP_TEXT),
1386
1387   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1388   0,                            /* leading char */
1389   '/',                          /* ar_pad_char */
1390   15,                           /* ar_max_namelen??? FIXMEmgo */
1391
1392   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1393      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1394      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1395   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1396      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1397      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1398
1399   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
1400      xcoff_archive_p, CORE_FILE_P},
1401   {bfd_false, coff_mkobject,            /* bfd_set_format */
1402      _bfd_generic_mkarchive, bfd_false},
1403   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
1404      xcoff_write_archive_contents, bfd_false},
1405
1406      BFD_JUMP_TABLE_GENERIC (coff),
1407      BFD_JUMP_TABLE_COPY (coff),
1408      BFD_JUMP_TABLE_CORE (coff),
1409      BFD_JUMP_TABLE_ARCHIVE (xcoff),
1410      BFD_JUMP_TABLE_SYMBOLS (coff),
1411      BFD_JUMP_TABLE_RELOCS (coff),
1412      BFD_JUMP_TABLE_WRITE (coff),
1413      BFD_JUMP_TABLE_LINK (_bfd_xcoff),
1414      BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
1415
1416   COFF_SWAP_TABLE,
1417 };