OSDN Git Service

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