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