OSDN Git Service

Revert previous patch.
[pf3gnuchains/pf3gnuchains3x.git] / bfd / coff-rs6000.c
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
7    character set it is.
8    Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, 
9      and John Gilmore.
10    Archive support from Damon A. Permezel.
11    Contributed by IBM Corporation and Cygnus Support.
12
13 This file is part of BFD, the Binary File Descriptor library.
14
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.
19
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.
24
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.  */
28
29 /* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
30 #define RS6000COFF_C 1
31
32 #include "bfd.h"
33 #include "sysdep.h"
34 #include "libbfd.h"
35 #include "coff/internal.h"
36 #include "coff/rs6000.h"
37 #include "libcoff.h"
38
39 /* The main body of code is in coffcode.h.  */
40
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));
58 \f
59 /* We use our own tdata type.  Its first field is the COFF tdata type,
60    so the COFF routines are compatible.  */
61
62 static boolean
63 xcoff_mkobject (abfd)
64      bfd *abfd;
65 {
66   coff_data_type *coff;
67
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)
72     return false;
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;
77   coff->relocbase = 0;
78
79   xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
80
81   /* We set cputype to -1 to indicate that it has not been
82      initialized.  */
83   xcoff_data (abfd)->cputype = -1;
84
85   xcoff_data (abfd)->csects = NULL;
86   xcoff_data (abfd)->debug_indices = NULL;
87
88   return true;
89 }
90
91 /* Copy XCOFF data from one BFD to another.  */
92
93 static boolean
94 xcoff_copy_private_bfd_data (ibfd, obfd)
95      bfd *ibfd;
96      bfd *obfd;
97 {
98   struct xcoff_tdata *ix, *ox;
99   asection *sec;
100
101   if (ibfd->xvec != obfd->xvec)
102     return true;
103   ix = xcoff_data (ibfd);
104   ox = xcoff_data (obfd);
105   ox->full_aouthdr = ix->full_aouthdr;
106   ox->toc = ix->toc;
107   if (ix->sntoc == 0)
108     ox->sntoc = 0;
109   else
110     {
111       sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
112       if (sec == NULL)
113         ox->sntoc = 0;
114       else
115         ox->sntoc = sec->output_section->target_index;
116     }
117   if (ix->snentry == 0)
118     ox->snentry = 0;
119   else
120     {
121       sec = coff_section_from_bfd_index (ibfd, ix->snentry);
122       if (sec == NULL)
123         ox->snentry = 0;
124       else
125         ox->snentry = sec->output_section->target_index;
126     }
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;
133   return true;
134 }
135
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
139    -x option.  */
140
141 static boolean
142 xcoff_is_local_label_name (abfd, name)
143      bfd *abfd ATTRIBUTE_UNUSED;
144      const char *name ATTRIBUTE_UNUSED;
145 {
146   return false;
147 }
148 \f
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.  */
154
155 static reloc_howto_type xcoff_howto_table[] =
156 {
157   /* Standard 32 bit relocation.  */
158   HOWTO (0,                     /* type */                                 
159          0,                     /* rightshift */                           
160          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
161          32,                    /* bitsize */                   
162          false,                 /* pc_relative */                          
163          0,                     /* bitpos */                               
164          complain_overflow_bitfield, /* complain_on_overflow */
165          0,                     /* special_function */                     
166          "R_POS",               /* name */                                 
167          true,                  /* partial_inplace */                      
168          0xffffffff,            /* src_mask */                             
169          0xffffffff,            /* dst_mask */                             
170          false),                /* pcrel_offset */
171
172   /* 32 bit relocation, but store negative value.  */
173   HOWTO (1,                     /* type */                                 
174          0,                     /* rightshift */                           
175          -2,                    /* size (0 = byte, 1 = short, 2 = long) */ 
176          32,                    /* bitsize */                   
177          false,                 /* pc_relative */                          
178          0,                     /* bitpos */                               
179          complain_overflow_bitfield, /* complain_on_overflow */
180          0,                     /* special_function */                     
181          "R_NEG",               /* name */                                 
182          true,                  /* partial_inplace */                      
183          0xffffffff,            /* src_mask */                             
184          0xffffffff,            /* dst_mask */                             
185          false),                /* pcrel_offset */
186
187   /* 32 bit PC relative relocation.  */
188   HOWTO (2,                     /* type */                                 
189          0,                     /* rightshift */                           
190          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
191          32,                    /* bitsize */                   
192          true,                  /* pc_relative */                          
193          0,                     /* bitpos */                               
194          complain_overflow_signed, /* complain_on_overflow */
195          0,                     /* special_function */                     
196          "R_REL",               /* name */                                 
197          true,                  /* partial_inplace */                      
198          0xffffffff,            /* src_mask */                             
199          0xffffffff,            /* dst_mask */                             
200          false),                /* pcrel_offset */
201   
202   /* 16 bit TOC relative relocation.  */
203   HOWTO (3,                     /* type */                                 
204          0,                     /* rightshift */                           
205          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
206          16,                    /* bitsize */                   
207          false,                 /* pc_relative */                          
208          0,                     /* bitpos */                               
209          complain_overflow_bitfield, /* complain_on_overflow */
210          0,                     /* special_function */                     
211          "R_TOC",               /* name */                                 
212          true,                  /* partial_inplace */                      
213          0xffff,                /* src_mask */                             
214          0xffff,                /* dst_mask */                             
215          false),                /* pcrel_offset */
216   
217   /* I don't really know what this is.  */
218   HOWTO (4,                     /* type */                                 
219          1,                     /* rightshift */                           
220          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
221          32,                    /* bitsize */                   
222          false,                 /* pc_relative */                          
223          0,                     /* bitpos */                               
224          complain_overflow_bitfield, /* complain_on_overflow */
225          0,                     /* special_function */                     
226          "R_RTB",               /* name */                                 
227          true,                  /* partial_inplace */                      
228          0xffffffff,            /* src_mask */                             
229          0xffffffff,            /* dst_mask */                             
230          false),                /* pcrel_offset */
231   
232   /* External TOC relative symbol.  */
233   HOWTO (5,                     /* type */                                 
234          0,                     /* rightshift */                           
235          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
236          16,                    /* bitsize */                   
237          false,                 /* pc_relative */                          
238          0,                     /* bitpos */                               
239          complain_overflow_bitfield, /* complain_on_overflow */
240          0,                     /* special_function */                     
241          "R_GL",                /* name */                                 
242          true,                  /* partial_inplace */                      
243          0xffff,                /* src_mask */                             
244          0xffff,                /* dst_mask */                             
245          false),                /* pcrel_offset */
246   
247   /* Local TOC relative symbol.  */
248   HOWTO (6,                     /* type */                                 
249          0,                     /* rightshift */                           
250          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
251          16,                    /* bitsize */                   
252          false,                 /* pc_relative */                          
253          0,                     /* bitpos */                               
254          complain_overflow_bitfield, /* complain_on_overflow */
255          0,                     /* special_function */                     
256          "R_TCL",               /* name */                                 
257          true,                  /* partial_inplace */                      
258          0xffff,                /* src_mask */                             
259          0xffff,                /* dst_mask */                             
260          false),                /* pcrel_offset */
261   
262   EMPTY_HOWTO (7),
263   
264   /* Non modifiable absolute branch.  */
265   HOWTO (8,                     /* type */                                 
266          0,                     /* rightshift */                           
267          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
268          26,                    /* bitsize */                   
269          false,                 /* pc_relative */                          
270          0,                     /* bitpos */                               
271          complain_overflow_bitfield, /* complain_on_overflow */
272          0,                     /* special_function */                     
273          "R_BA",                /* name */                                 
274          true,                  /* partial_inplace */                      
275          0x3fffffc,             /* src_mask */                             
276          0x3fffffc,             /* dst_mask */                             
277          false),                /* pcrel_offset */
278   
279   EMPTY_HOWTO (9),
280
281   /* Non modifiable relative branch.  */
282   HOWTO (0xa,                   /* type */                                 
283          0,                     /* rightshift */                           
284          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
285          26,                    /* bitsize */                   
286          true,                  /* pc_relative */                          
287          0,                     /* bitpos */                               
288          complain_overflow_signed, /* complain_on_overflow */
289          0,                     /* special_function */                     
290          "R_BR",                /* name */                                 
291          true,                  /* partial_inplace */                      
292          0x3fffffc,             /* src_mask */                             
293          0x3fffffc,             /* dst_mask */                             
294          false),                /* pcrel_offset */
295   
296   EMPTY_HOWTO (0xb),
297
298   /* Indirect load.  */
299   HOWTO (0xc,                   /* type */                                 
300          0,                     /* rightshift */                           
301          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
302          16,                    /* bitsize */                   
303          false,                 /* pc_relative */                          
304          0,                     /* bitpos */                               
305          complain_overflow_bitfield, /* complain_on_overflow */
306          0,                     /* special_function */                     
307          "R_RL",                /* name */                                 
308          true,                  /* partial_inplace */                      
309          0xffff,                /* src_mask */                             
310          0xffff,                /* dst_mask */                             
311          false),                /* pcrel_offset */
312   
313   /* Load address.  */
314   HOWTO (0xd,                   /* type */                                 
315          0,                     /* rightshift */                           
316          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
317          16,                    /* bitsize */                   
318          false,                 /* pc_relative */                          
319          0,                     /* bitpos */                               
320          complain_overflow_bitfield, /* complain_on_overflow */
321          0,                     /* special_function */                     
322          "R_RLA",               /* name */                                 
323          true,                  /* partial_inplace */                      
324          0xffff,                /* src_mask */                             
325          0xffff,                /* dst_mask */                             
326          false),                /* pcrel_offset */
327   
328   EMPTY_HOWTO (0xe),
329   
330   /* Non-relocating reference.  */
331   HOWTO (0xf,                   /* type */                                 
332          0,                     /* rightshift */                           
333          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
334          32,                    /* bitsize */                   
335          false,                 /* pc_relative */                          
336          0,                     /* bitpos */                               
337          complain_overflow_bitfield, /* complain_on_overflow */
338          0,                     /* special_function */                     
339          "R_REF",               /* name */                                 
340          false,                 /* partial_inplace */                      
341          0,                     /* src_mask */                             
342          0,                     /* dst_mask */                             
343          false),                /* pcrel_offset */
344   
345   EMPTY_HOWTO (0x10),
346   EMPTY_HOWTO (0x11),
347   
348   /* TOC relative indirect load.  */
349   HOWTO (0x12,                  /* type */                                 
350          0,                     /* rightshift */                           
351          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
352          16,                    /* bitsize */                   
353          false,                 /* pc_relative */                          
354          0,                     /* bitpos */                               
355          complain_overflow_bitfield, /* complain_on_overflow */
356          0,                     /* special_function */                     
357          "R_TRL",               /* name */                                 
358          true,                  /* partial_inplace */                      
359          0xffff,                /* src_mask */                             
360          0xffff,                /* dst_mask */                             
361          false),                /* pcrel_offset */
362   
363   /* TOC relative load address.  */
364   HOWTO (0x13,                  /* type */                                 
365          0,                     /* rightshift */                           
366          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
367          16,                    /* bitsize */                   
368          false,                 /* pc_relative */                          
369          0,                     /* bitpos */                               
370          complain_overflow_bitfield, /* complain_on_overflow */
371          0,                     /* special_function */                     
372          "R_TRLA",              /* name */                                 
373          true,                  /* partial_inplace */                      
374          0xffff,                /* src_mask */                             
375          0xffff,                /* dst_mask */                             
376          false),                /* pcrel_offset */
377   
378   /* Modifiable relative branch.  */
379   HOWTO (0x14,                  /* type */                                 
380          1,                     /* rightshift */                           
381          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
382          32,                    /* bitsize */                   
383          false,                 /* pc_relative */                          
384          0,                     /* bitpos */                               
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 */
392   
393   /* Modifiable absolute branch.  */
394   HOWTO (0x15,                  /* type */                                 
395          1,                     /* rightshift */                           
396          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
397          32,                    /* bitsize */                   
398          false,                 /* pc_relative */                          
399          0,                     /* bitpos */                               
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 */
407   
408   /* Modifiable call absolute indirect.  */
409   HOWTO (0x16,                  /* type */                                 
410          0,                     /* rightshift */                           
411          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
412          16,                    /* bitsize */                   
413          false,                 /* pc_relative */                          
414          0,                     /* bitpos */                               
415          complain_overflow_bitfield, /* complain_on_overflow */
416          0,                     /* special_function */                     
417          "R_CAI",               /* name */                                 
418          true,                  /* partial_inplace */                      
419          0xffff,                /* src_mask */                             
420          0xffff,                /* dst_mask */                             
421          false),                /* pcrel_offset */
422   
423   /* Modifiable call relative.  */
424   HOWTO (0x17,                  /* type */                                 
425          0,                     /* rightshift */                           
426          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
427          16,                    /* bitsize */                   
428          false,                 /* pc_relative */                          
429          0,                     /* bitpos */                               
430          complain_overflow_bitfield, /* complain_on_overflow */
431          0,                     /* special_function */                     
432          "R_CREL",              /* name */                                 
433          true,                  /* partial_inplace */                      
434          0xffff,                /* src_mask */                             
435          0xffff,                /* dst_mask */                             
436          false),                /* pcrel_offset */
437   
438   /* Modifiable branch absolute.  */
439   HOWTO (0x18,                  /* type */                                 
440          0,                     /* rightshift */                           
441          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
442          16,                    /* bitsize */                   
443          false,                 /* pc_relative */                          
444          0,                     /* bitpos */                               
445          complain_overflow_bitfield, /* complain_on_overflow */
446          0,                     /* special_function */                     
447          "R_RBA",               /* name */                                 
448          true,                  /* partial_inplace */                      
449          0xffff,                /* src_mask */                             
450          0xffff,                /* dst_mask */                             
451          false),                /* pcrel_offset */
452   
453   /* Modifiable branch absolute.  */
454   HOWTO (0x19,                  /* type */                                 
455          0,                     /* rightshift */                           
456          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
457          16,                    /* bitsize */                   
458          false,                 /* pc_relative */                          
459          0,                     /* bitpos */                               
460          complain_overflow_bitfield, /* complain_on_overflow */
461          0,                     /* special_function */                     
462          "R_RBAC",              /* name */                                 
463          true,                  /* partial_inplace */                      
464          0xffff,                /* src_mask */                             
465          0xffff,                /* dst_mask */                             
466          false),                /* pcrel_offset */
467   
468   /* Modifiable branch relative.  */
469   HOWTO (0x1a,                  /* type */                                 
470          0,                     /* rightshift */                           
471          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
472          26,                    /* bitsize */                   
473          false,                 /* pc_relative */                          
474          0,                     /* bitpos */                               
475          complain_overflow_signed, /* complain_on_overflow */
476          0,                     /* special_function */                     
477          "R_RBR",               /* name */                                 
478          true,                  /* partial_inplace */                      
479          0xffff,                /* src_mask */                             
480          0xffff,                /* dst_mask */                             
481          false),                /* pcrel_offset */
482   
483   /* Modifiable branch absolute.  */
484   HOWTO (0x1b,                  /* type */                                 
485          0,                     /* rightshift */                           
486          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
487          16,                    /* bitsize */                   
488          false,                 /* pc_relative */                          
489          0,                     /* bitpos */                               
490          complain_overflow_bitfield, /* complain_on_overflow */
491          0,                     /* special_function */                     
492          "R_RBRC",              /* name */                                 
493          true,                  /* partial_inplace */                      
494          0xffff,                /* src_mask */                             
495          0xffff,                /* dst_mask */                             
496          false)                 /* pcrel_offset */
497 };
498
499 static void
500 xcoff_rtype2howto (relent, internal)
501      arelent *relent;
502      struct internal_reloc *internal;
503 {
504   relent->howto = xcoff_howto_table + internal->r_type;
505
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)
511     abort ();
512 #if 0
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))
516     abort ();
517 #endif
518 }
519
520 static reloc_howto_type *
521 xcoff_reloc_type_lookup (abfd, code)
522      bfd *abfd ATTRIBUTE_UNUSED;
523      bfd_reloc_code_real_type code;
524 {
525   switch (code)
526     {
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];
533     case BFD_RELOC_32:
534     case BFD_RELOC_CTOR:
535       return &xcoff_howto_table[0];
536     default:
537       return NULL;
538     }
539 }
540
541 #define SELECT_RELOC(internal, howto)                                   \
542   {                                                                     \
543     internal.r_type = howto->type;                                      \
544     internal.r_size =                                                   \
545       ((howto->complain_on_overflow == complain_overflow_signed         \
546         ? 0x80                                                          \
547         : 0)                                                            \
548        | (howto->bitsize - 1));                                         \
549   }
550 \f
551 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
552
553 #define COFF_LONG_FILENAMES
554
555 #define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
556
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
562
563 #include "coffcode.h"
564 \f
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.
568
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.
574
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.
586
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.  */
595
596 /* XCOFF archives use this as a magic string.  */
597
598 #define XCOFFARMAG "<aiaff>\012"
599 #define SXCOFFARMAG 8
600
601 /* This terminates an XCOFF archive member name.  */
602
603 #define XCOFFARFMAG "`\012"
604 #define SXCOFFARFMAG 2
605
606 /* XCOFF archives start with this (printable) structure.  */
607
608 struct xcoff_ar_file_hdr
609 {
610   /* Magic string.  */
611   char magic[SXCOFFARMAG];
612
613   /* Offset of the member table (decimal ASCII string).  */
614   char memoff[12];
615
616   /* Offset of the global symbol table (decimal ASCII string).  */
617   char symoff[12];
618
619   /* Offset of the first member in the archive (decimal ASCII string).  */
620   char firstmemoff[12];
621
622   /* Offset of the last member in the archive (decimal ASCII string).  */
623   char lastmemoff[12];
624
625   /* Offset of the first member on the free list (decimal ASCII
626      string).  */
627   char freeoff[12];
628 };
629
630 #define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG)
631
632 /* Each XCOFF archive member starts with this (printable) structure.  */
633
634 struct xcoff_ar_hdr
635 {
636   /* File size not including the header (decimal ASCII string).  */
637   char size[12];
638
639   /* File offset of next archive member (decimal ASCII string).  */
640   char nextoff[12];
641
642   /* File offset of previous archive member (decimal ASCII string).  */
643   char prevoff[12];
644
645   /* File mtime (decimal ASCII string).  */
646   char date[12];
647
648   /* File UID (decimal ASCII string).  */
649   char uid[12];
650
651   /* File GID (decimal ASCII string).  */
652   char gid[12];
653
654   /* File mode (octal ASCII string).  */
655   char mode[12];
656
657   /* Length of file name (decimal ASCII string).  */
658   char namlen[4];
659
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.  */
666 };
667
668 #define SIZEOF_AR_HDR (7 * 12 + 4)
669
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)
674
675 /* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
676    archive element.  */
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)
680
681 /* XCOFF archives do not have anything which corresponds to an
682    extended name table.  */
683
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 **))) \
687    bfd_false)
688 #define xcoff_truncate_arname bfd_dont_truncate_arname
689
690 /* We can use the standard get_elt_at_index routine.  */
691
692 #define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
693
694 /* XCOFF archives do not have a timestamp.  */
695
696 #define xcoff_update_armap_timestamp bfd_true
697
698 /* Read in the armap of an XCOFF archive.  */
699
700 static boolean
701 xcoff_slurp_armap (abfd)
702      bfd *abfd;
703 {
704   file_ptr off;
705   struct xcoff_ar_hdr hdr;
706   size_t namlen;
707   bfd_size_type sz;
708   bfd_byte *contents, *cend;
709   unsigned int c, i;
710   carsym *arsym;
711   bfd_byte *p;
712
713   if (xcoff_ardata (abfd) == NULL)
714     {
715       bfd_has_map (abfd) = false;
716       return true;
717     }
718
719   off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
720   if (off == 0)
721     {
722       bfd_has_map (abfd) = false;
723       return true;
724     }
725
726   if (bfd_seek (abfd, off, SEEK_SET) != 0)
727     return false;
728
729   /* The symbol table starts with a normal archive header.  */
730   if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
731     return false;
732
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)
736     return false;
737
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)
742     return false;
743   if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
744     return false;
745
746   /* The symbol table starts with a four byte count.  */
747   c = bfd_h_get_32 (abfd, contents);
748
749   if (c * 4 >= sz)
750     {
751       bfd_set_error (bfd_error_bad_value);
752       return false;
753     }
754
755   bfd_ardata (abfd)->symdefs = ((carsym *)
756                                 bfd_alloc (abfd, c * sizeof (carsym)));
757   if (bfd_ardata (abfd)->symdefs == NULL)
758     return false;
759
760   /* After the count comes a list of four byte file offsets.  */
761   for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
762        i < c;
763        ++i, ++arsym, p += 4)
764     arsym->file_offset = bfd_h_get_32 (abfd, p);
765
766   /* After the file offsets come null terminated symbol names.  */
767   cend = contents + sz;
768   for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
769        i < c;
770        ++i, ++arsym, p += strlen ((char *) p) + 1)
771     {
772       if (p >= cend)
773         {
774           bfd_set_error (bfd_error_bad_value);
775           return false;
776         }
777       arsym->name = (char *) p;
778     }
779
780   bfd_ardata (abfd)->symdef_count = c;
781   bfd_has_map (abfd) = true;
782
783   return true;
784 }
785
786 /* See if this is an XCOFF archive.  */
787
788 static const bfd_target *
789 xcoff_archive_p (abfd)
790      bfd *abfd;
791 {
792   struct xcoff_ar_file_hdr hdr;
793
794   if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd)
795       != SIZEOF_AR_FILE_HDR)
796     {
797       if (bfd_get_error () != bfd_error_system_call)
798         bfd_set_error (bfd_error_wrong_format);
799       return NULL;
800     }
801
802   if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0)
803     {
804       bfd_set_error (bfd_error_wrong_format);
805       return NULL;
806     }
807
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
810      assignment.  */
811   abfd->tdata.aout_ar_data =
812     (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
813
814   if (bfd_ardata (abfd) == (struct artdata *) NULL)
815     return NULL;
816
817   bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
818                                                   (char **) NULL, 10);
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;
823
824   bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR);
825   if (bfd_ardata (abfd)->tdata == NULL)
826     return NULL;
827
828   memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
829
830   if (! xcoff_slurp_armap (abfd))
831     {
832       bfd_release (abfd, bfd_ardata (abfd));
833       abfd->tdata.aout_ar_data = (struct artdata *) NULL;
834       return NULL;
835     }
836
837   return abfd->xvec;
838 }
839
840 /* Read the archive header in an XCOFF archive.  */
841
842 static PTR
843 xcoff_read_ar_hdr (abfd)
844      bfd *abfd;
845 {
846   struct xcoff_ar_hdr hdr;
847   size_t namlen;
848   struct xcoff_ar_hdr *hdrp;
849   struct areltdata *ret;
850
851   if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
852     return NULL;
853
854   namlen = strtol (hdr.namlen, (char **) NULL, 10);
855   hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1);
856   if (hdrp == NULL)
857     return NULL;
858   memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
859   if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen)
860     return NULL;
861   ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
862
863   ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata));
864   if (ret == NULL)
865     return NULL;
866   ret->arch_header = (char *) hdrp;
867   ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
868   ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
869
870   /* Skip over the XCOFFARFMAG at the end of the file name.  */
871   if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0)
872     return NULL;
873
874   return (PTR) ret;
875 }
876
877 /* Open the next element in an XCOFF archive.  */
878
879 static bfd *
880 xcoff_openr_next_archived_file (archive, last_file)
881      bfd *archive;
882      bfd *last_file;
883 {
884   file_ptr filestart;
885
886   if (xcoff_ardata (archive) == NULL)
887     {
888       bfd_set_error (bfd_error_invalid_operation);
889       return NULL;
890     }
891
892   if (last_file == NULL)
893     filestart = bfd_ardata (archive)->first_file_filepos;
894   else
895     filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10);
896
897   if (filestart == 0
898       || filestart == strtol (xcoff_ardata (archive)->memoff,
899                               (char **) NULL, 10)
900       || filestart == strtol (xcoff_ardata (archive)->symoff,
901                               (char **) NULL, 10))
902     {
903       bfd_set_error (bfd_error_no_more_archived_files);
904       return NULL;
905     }
906
907   return _bfd_get_elt_at_filepos (archive, filestart);
908 }
909
910 /* Stat an element in an XCOFF archive.  */
911
912 static int
913 xcoff_generic_stat_arch_elt (abfd, s)
914      bfd *abfd;
915      struct stat *s;
916 {
917   struct xcoff_ar_hdr *hdrp;
918
919   if (abfd->arelt_data == NULL)
920     {
921       bfd_set_error (bfd_error_invalid_operation);
922       return -1;
923     }
924
925   hdrp = arch_xhdr (abfd);
926
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;
932
933   return 0;
934 }
935
936 /* Normalize a file name for inclusion in an archive.  */
937
938 static const char *
939 normalize_filename (abfd)
940      bfd *abfd;
941 {
942   const char *file;
943   const char *filename;
944
945   file = bfd_get_filename (abfd);
946   filename = strrchr (file, '/');
947   if (filename != NULL)
948     filename++;
949   else
950     filename = file;
951   return filename;
952 }
953
954 /* Write out an XCOFF armap.  */
955
956 /*ARGSUSED*/
957 static boolean
958 xcoff_write_armap (abfd, elength, map, orl_count, stridx)
959      bfd *abfd;
960      unsigned int elength ATTRIBUTE_UNUSED;
961      struct orl *map;
962      unsigned int orl_count;
963      int stridx;
964 {
965   struct xcoff_ar_hdr hdr;
966   char *p;
967   unsigned char buf[4];
968   bfd *sub;
969   file_ptr fileoff;
970   unsigned int i;
971
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);
981
982   /* We need spaces, not null bytes, in the header.  */
983   for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
984     if (*p == '\0')
985       *p = ' ';
986
987   if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR
988       || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
989     return false;
990   
991   bfd_h_put_32 (abfd, orl_count, buf);
992   if (bfd_write (buf, 1, 4, abfd) != 4)
993     return false;
994
995   sub = abfd->archive_head;
996   fileoff = SIZEOF_AR_FILE_HDR;
997   i = 0;
998   while (sub != NULL && i < orl_count)
999     {
1000       size_t namlen;
1001
1002       while (((bfd *) (map[i]).pos) == sub)
1003         {
1004           bfd_h_put_32 (abfd, fileoff, buf);
1005           if (bfd_write (buf, 1, 4, abfd) != 4)
1006             return false;
1007           ++i;
1008         }
1009       namlen = strlen (normalize_filename (sub));
1010       namlen = (namlen + 1) &~ 1;
1011       fileoff += (SIZEOF_AR_HDR
1012                   + namlen
1013                   + SXCOFFARFMAG
1014                   + arelt_size (sub));
1015       fileoff = (fileoff + 1) &~ 1;
1016       sub = sub->next;
1017     }
1018
1019   for (i = 0; i < orl_count; i++)
1020     {
1021       const char *name;
1022       size_t namlen;
1023
1024       name = *map[i].name;
1025       namlen = strlen (name);
1026       if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
1027         return false;
1028     }
1029
1030   if ((stridx & 1) != 0)
1031     {
1032       char b;
1033
1034       b = '\0';
1035       if (bfd_write (&b, 1, 1, abfd) != 1)
1036         return false;
1037     }
1038
1039   return true;
1040 }
1041
1042 /* Write out an XCOFF archive.  We always write an entire archive,
1043    rather than fussing with the freelist and so forth.  */
1044
1045 static boolean
1046 xcoff_write_archive_contents (abfd)
1047      bfd *abfd;
1048 {
1049   struct xcoff_ar_file_hdr fhdr;
1050   size_t count;
1051   size_t total_namlen;
1052   file_ptr *offsets;
1053   boolean makemap;
1054   boolean hasobjects;
1055   file_ptr prevoff, nextoff;
1056   bfd *sub;
1057   unsigned int i;
1058   struct xcoff_ar_hdr ahdr;
1059   bfd_size_type size;
1060   char *p;
1061   char decbuf[13];
1062
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);
1067
1068   count = 0;
1069   total_namlen = 0;
1070   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1071     {
1072       ++count;
1073       total_namlen += strlen (normalize_filename (sub)) + 1;
1074     }
1075   offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
1076   if (offsets == NULL)
1077     return false;
1078
1079   if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
1080     return false;
1081
1082   makemap = bfd_has_map (abfd);
1083   hasobjects = false;
1084   prevoff = 0;
1085   nextoff = SIZEOF_AR_FILE_HDR;
1086   for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
1087     {
1088       const char *name;
1089       size_t namlen;
1090       struct xcoff_ar_hdr *ahdrp;
1091       bfd_size_type remaining;
1092
1093       if (makemap && ! hasobjects)
1094         {
1095           if (bfd_check_format (sub, bfd_object))
1096             hasobjects = true;
1097         }
1098
1099       name = normalize_filename (sub);
1100       namlen = strlen (name);
1101
1102       if (sub->arelt_data != NULL)
1103         ahdrp = arch_xhdr (sub);
1104       else
1105         ahdrp = NULL;
1106
1107       if (ahdrp == NULL)
1108         {
1109           struct stat s;
1110
1111           memset (&ahdr, 0, sizeof ahdr);
1112           ahdrp = &ahdr;
1113           if (stat (bfd_get_filename (sub), &s) != 0)
1114             {
1115               bfd_set_error (bfd_error_system_call);
1116               return false;
1117             }
1118
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);
1124
1125           if (sub->arelt_data == NULL)
1126             {
1127               sub->arelt_data = bfd_alloc (sub, sizeof (struct areltdata));
1128               if (sub->arelt_data == NULL)
1129                 return false;
1130             }
1131
1132           arch_eltdata (sub)->parsed_size = s.st_size;
1133         }
1134
1135       sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
1136       sprintf (ahdrp->namlen, "%ld", (long) namlen);
1137
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;
1141
1142       remaining = arelt_size (sub);
1143       size = (SIZEOF_AR_HDR
1144               + namlen
1145               + SXCOFFARFMAG
1146               + remaining);
1147
1148       BFD_ASSERT (nextoff == bfd_tell (abfd));
1149
1150       offsets[i] = nextoff;
1151
1152       prevoff = nextoff;
1153       nextoff += size + (size & 1);
1154
1155       sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
1156
1157       /* We need spaces, not null bytes, in the header.  */
1158       for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
1159         if (*p == '\0')
1160           *p = ' ';
1161
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)
1165               != SXCOFFARFMAG))
1166         return false;
1167
1168       if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
1169         return false;
1170       while (remaining != 0)
1171         {
1172           bfd_size_type amt;
1173           bfd_byte buffer[DEFAULT_BUFFERSIZE];
1174
1175           amt = sizeof buffer;
1176           if (amt > remaining)
1177             amt = remaining;
1178           if (bfd_read (buffer, 1, amt, sub) != amt
1179               || bfd_write (buffer, 1, amt, abfd) != amt)
1180             return false;
1181           remaining -= amt;
1182         }
1183
1184       if ((size & 1) != 0)
1185         {
1186           bfd_byte b;
1187
1188           b = '\0';
1189           if (bfd_write (&b, 1, 1, abfd) != 1)
1190             return false;
1191         }
1192     }
1193
1194   sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
1195
1196   /* Write out the member table.  */
1197
1198   BFD_ASSERT (nextoff == bfd_tell (abfd));
1199   sprintf (fhdr.memoff, "%ld", (long) nextoff);
1200
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);
1209
1210   size = (SIZEOF_AR_HDR
1211           + 12
1212           + count * 12
1213           + total_namlen
1214           + SXCOFFARFMAG);
1215
1216   prevoff = nextoff;
1217   nextoff += size + (size & 1);
1218
1219   if (makemap && hasobjects)
1220     sprintf (ahdr.nextoff, "%ld", (long) nextoff);
1221   else
1222     sprintf (ahdr.nextoff, "%d", 0);
1223
1224   /* We need spaces, not null bytes, in the header.  */
1225   for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
1226     if (*p == '\0')
1227       *p = ' ';
1228
1229   if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
1230       || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
1231           != SXCOFFARFMAG))
1232     return false;
1233
1234   sprintf (decbuf, "%-12ld", (long) count);
1235   if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
1236     return false;
1237   for (i = 0; i < count; i++)
1238     {
1239       sprintf (decbuf, "%-12ld", (long) offsets[i]);
1240       if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
1241         return false;
1242     }
1243   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1244     {
1245       const char *name;
1246       size_t namlen;
1247
1248       name = normalize_filename (sub);
1249       namlen = strlen (name);
1250       if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1)
1251         return false;
1252     }
1253   if ((size & 1) != 0)
1254     {
1255       bfd_byte b;
1256
1257       b = '\0';
1258       if (bfd_write ((PTR) &b, 1, 1, abfd) != 1)
1259         return false;
1260     }
1261
1262   /* Write out the armap, if appropriate.  */
1263
1264   if (! makemap || ! hasobjects)
1265     sprintf (fhdr.symoff, "%d", 0);
1266   else
1267     {
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))
1272         return false;
1273     }
1274
1275   /* Write out the archive file header.  */
1276
1277   /* We need spaces, not null bytes, in the header.  */
1278   for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
1279     if (*p == '\0')
1280       *p = ' ';
1281
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))
1285     return false;
1286
1287   return true;
1288 }
1289 \f
1290 /* We can't use the usual coff_sizeof_headers routine, because AIX
1291    always uses an a.out header.  */
1292
1293 /*ARGSUSED*/
1294 static int
1295 _bfd_xcoff_sizeof_headers (abfd, reloc)
1296      bfd *abfd;
1297      boolean reloc ATTRIBUTE_UNUSED;
1298 {
1299   int size;
1300
1301   size = FILHSZ;
1302   if (xcoff_data (abfd)->full_aouthdr)
1303     size += AOUTSZ;
1304   else
1305     size += SMALL_AOUTSZ;
1306   size += abfd->section_count * SCNHSZ;
1307   return size;
1308 }
1309 \f
1310 #define CORE_FILE_P _bfd_dummy_target
1311
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
1316
1317 #ifdef AIX_CORE
1318 #undef CORE_FILE_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 ();
1323
1324 #undef  coff_core_file_matches_executable_p
1325 #define coff_core_file_matches_executable_p  \
1326                                      rs6000coff_core_file_matches_executable_p
1327
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
1331
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
1335
1336 #undef  coff_get_section_contents
1337 #define coff_get_section_contents       rs6000coff_get_section_contents
1338 #endif /* AIX_CORE */
1339
1340 #ifdef LYNX_CORE
1341
1342 #undef CORE_FILE_P
1343 #define CORE_FILE_P lynx_core_file_p
1344 extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd));
1345
1346 extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
1347                                                             bfd *exec_bfd));
1348 #undef  coff_core_file_matches_executable_p
1349 #define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p
1350
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
1354
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
1358
1359 #endif /* LYNX_CORE */
1360
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
1366
1367 /* The transfer vector that leads the outside world to all of the above. */
1368
1369 const bfd_target
1370 #ifdef TARGET_SYM
1371   TARGET_SYM =
1372 #else
1373   rs6000coff_vec =
1374 #endif
1375 {
1376 #ifdef TARGET_NAME
1377   TARGET_NAME,
1378 #else
1379   "aixcoff-rs6000",             /* name */
1380 #endif
1381   bfd_target_coff_flavour,      
1382   BFD_ENDIAN_BIG,               /* data byte order is big */
1383   BFD_ENDIAN_BIG,               /* header byte order is big */
1384
1385   (HAS_RELOC | EXEC_P |         /* object flags */
1386    HAS_LINENO | HAS_DEBUG | DYNAMIC |
1387    HAS_SYMS | HAS_LOCALS | WP_TEXT),
1388
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 */
1393
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 */
1400
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},
1407
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),
1417
1418   NULL,
1419   
1420   COFF_SWAP_TABLE
1421 };