Extensive minor changes to avoid various gcc warnings. Also:
[external/binutils.git] / bfd / coff-rs6000.c
1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2    Copyright 1990, 1991, 1992, 1993, 1994 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 /* This port currently only handles reading object files, except when
29    compiled on an RS/6000 host.  -- no archive support, no core files.
30    In all cases, it does not support writing.
31
32    FIXMEmgo comments are left from Metin Ozisik's original port.  */
33
34 /* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
35 #define RS6000COFF_C 1
36
37 #include "bfd.h"
38 #include "sysdep.h"
39 #include "libbfd.h"
40 #include "obstack.h"
41 #include "coff/internal.h"
42 #include "coff/rs6000.h"
43 #include "libcoff.h"
44
45 /* The main body of code is in coffcode.h.  */
46
47 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
48
49 /* The XCOFF reloc table.  Actually, XCOFF relocations specify the
50    bitsize and whether they are signed or not, along with a
51    conventional type.  This table is for the types, which are used for
52    different algorithms for putting in the reloc.  Many of these
53    relocs need special_function entries, which I have not written.  */
54
55 static reloc_howto_type rs6000coff_howto_table[] =
56 {
57   /* Standard 32 bit relocation.  */
58   HOWTO (0,                     /* type */                                 
59          0,                     /* rightshift */                           
60          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
61          32,                    /* bitsize */                   
62          false,                 /* pc_relative */                          
63          0,                     /* bitpos */                               
64          complain_overflow_bitfield, /* complain_on_overflow */
65          0,                     /* special_function */                     
66          "R_POS",               /* name */                                 
67          true,                  /* partial_inplace */                      
68          0xffffffff,            /* src_mask */                             
69          0xffffffff,            /* dst_mask */                             
70          false),                /* pcrel_offset */
71
72   /* 32 bit relocation, but store negative value.  */
73   HOWTO (1,                     /* type */                                 
74          0,                     /* rightshift */                           
75          -2,                    /* size (0 = byte, 1 = short, 2 = long) */ 
76          32,                    /* bitsize */                   
77          false,                 /* pc_relative */                          
78          0,                     /* bitpos */                               
79          complain_overflow_bitfield, /* complain_on_overflow */
80          0,                     /* special_function */                     
81          "R_NEG",               /* name */                                 
82          true,                  /* partial_inplace */                      
83          0xffffffff,            /* src_mask */                             
84          0xffffffff,            /* dst_mask */                             
85          false),                /* pcrel_offset */
86
87   /* 32 bit PC relative relocation.  */
88   HOWTO (2,                     /* type */                                 
89          0,                     /* rightshift */                           
90          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
91          32,                    /* bitsize */                   
92          true,                  /* pc_relative */                          
93          0,                     /* bitpos */                               
94          complain_overflow_signed, /* complain_on_overflow */
95          0,                     /* special_function */                     
96          "R_REL",               /* name */                                 
97          true,                  /* partial_inplace */                      
98          0xffffffff,            /* src_mask */                             
99          0xffffffff,            /* dst_mask */                             
100          false),                /* pcrel_offset */
101   
102   /* 16 bit TOC relative relocation.  */
103   HOWTO (3,                     /* type */                                 
104          0,                     /* rightshift */                           
105          1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
106          16,                    /* bitsize */                   
107          false,                 /* pc_relative */                          
108          0,                     /* bitpos */                               
109          complain_overflow_signed, /* complain_on_overflow */
110          0,                     /* special_function */                     
111          "R_TOC",               /* name */                                 
112          true,                  /* partial_inplace */                      
113          0xffff,                /* src_mask */                             
114          0xffff,                /* dst_mask */                             
115          false),                /* pcrel_offset */
116   
117   /* I don't really know what this is.  */
118   HOWTO (4,                     /* type */                                 
119          1,                     /* rightshift */                           
120          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
121          32,                    /* bitsize */                   
122          false,                 /* pc_relative */                          
123          0,                     /* bitpos */                               
124          complain_overflow_bitfield, /* complain_on_overflow */
125          0,                     /* special_function */                     
126          "R_RTB",               /* name */                                 
127          true,                  /* partial_inplace */                      
128          0xffffffff,            /* src_mask */                             
129          0xffffffff,            /* dst_mask */                             
130          false),                /* pcrel_offset */
131   
132   /* External TOC relative symbol.  */
133   HOWTO (5,                     /* type */                                 
134          0,                     /* rightshift */                           
135          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
136          16,                    /* bitsize */                   
137          false,                 /* pc_relative */                          
138          0,                     /* bitpos */                               
139          complain_overflow_bitfield, /* complain_on_overflow */
140          0,                     /* special_function */                     
141          "R_GL",                /* name */                                 
142          true,                  /* partial_inplace */                      
143          0xffff,                /* src_mask */                             
144          0xffff,                /* dst_mask */                             
145          false),                /* pcrel_offset */
146   
147   /* Local TOC relative symbol.  */
148   HOWTO (6,                     /* type */                                 
149          0,                     /* rightshift */                           
150          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
151          16,                    /* bitsize */                   
152          false,                 /* pc_relative */                          
153          0,                     /* bitpos */                               
154          complain_overflow_bitfield, /* complain_on_overflow */
155          0,                     /* special_function */                     
156          "R_TCL",               /* name */                                 
157          true,                  /* partial_inplace */                      
158          0xffff,                /* src_mask */                             
159          0xffff,                /* dst_mask */                             
160          false),                /* pcrel_offset */
161   
162   { 7 },
163   
164   /* Non modifiable absolute branch.  */
165   HOWTO (8,                     /* type */                                 
166          0,                     /* rightshift */                           
167          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
168          26,                    /* bitsize */                   
169          false,                 /* pc_relative */                          
170          0,                     /* bitpos */                               
171          complain_overflow_bitfield, /* complain_on_overflow */
172          0,                     /* special_function */                     
173          "R_BA",                /* name */                                 
174          true,                  /* partial_inplace */                      
175          0x3fffffc,             /* src_mask */                             
176          0x3fffffc,             /* dst_mask */                             
177          false),                /* pcrel_offset */
178   
179   { 9 },
180
181   /* Non modifiable relative branch.  */
182   HOWTO (0xa,                   /* type */                                 
183          0,                     /* rightshift */                           
184          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
185          26,                    /* bitsize */                   
186          true,                  /* pc_relative */                          
187          0,                     /* bitpos */                               
188          complain_overflow_signed, /* complain_on_overflow */
189          0,                     /* special_function */                     
190          "R_BR",                /* name */                                 
191          true,                  /* partial_inplace */                      
192          0x3fffffc,             /* src_mask */                             
193          0x3fffffc,             /* dst_mask */                             
194          false),                /* pcrel_offset */
195   
196   { 0xb },
197
198   /* Indirect load.  */
199   HOWTO (0xc,                   /* type */                                 
200          0,                     /* rightshift */                           
201          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
202          16,                    /* bitsize */                   
203          false,                 /* pc_relative */                          
204          0,                     /* bitpos */                               
205          complain_overflow_bitfield, /* complain_on_overflow */
206          0,                     /* special_function */                     
207          "R_RL",                /* name */                                 
208          true,                  /* partial_inplace */                      
209          0xffff,                /* src_mask */                             
210          0xffff,                /* dst_mask */                             
211          false),                /* pcrel_offset */
212   
213   /* Load address.  */
214   HOWTO (0xd,                   /* type */                                 
215          0,                     /* rightshift */                           
216          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
217          16,                    /* bitsize */                   
218          false,                 /* pc_relative */                          
219          0,                     /* bitpos */                               
220          complain_overflow_bitfield, /* complain_on_overflow */
221          0,                     /* special_function */                     
222          "R_RLA",               /* name */                                 
223          true,                  /* partial_inplace */                      
224          0xffff,                /* src_mask */                             
225          0xffff,                /* dst_mask */                             
226          false),                /* pcrel_offset */
227   
228   { 0xe },
229   
230   /* Non-relocating reference.  */
231   HOWTO (0xf,                   /* type */                                 
232          0,                     /* rightshift */                           
233          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
234          32,                    /* bitsize */                   
235          false,                 /* pc_relative */                          
236          0,                     /* bitpos */                               
237          complain_overflow_bitfield, /* complain_on_overflow */
238          0,                     /* special_function */                     
239          "R_REF",               /* name */                                 
240          false,                 /* partial_inplace */                      
241          0,                     /* src_mask */                             
242          0,                     /* dst_mask */                             
243          false),                /* pcrel_offset */
244   
245   { 0x10 },
246   { 0x11 },
247   
248   /* TOC relative indirect load.  */
249   HOWTO (0x12,                  /* type */                                 
250          0,                     /* rightshift */                           
251          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
252          16,                    /* bitsize */                   
253          false,                 /* pc_relative */                          
254          0,                     /* bitpos */                               
255          complain_overflow_bitfield, /* complain_on_overflow */
256          0,                     /* special_function */                     
257          "R_TRL",               /* name */                                 
258          true,                  /* partial_inplace */                      
259          0xffff,                /* src_mask */                             
260          0xffff,                /* dst_mask */                             
261          false),                /* pcrel_offset */
262   
263   /* TOC relative load address.  */
264   HOWTO (0x13,                  /* type */                                 
265          0,                     /* rightshift */                           
266          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
267          16,                    /* bitsize */                   
268          false,                 /* pc_relative */                          
269          0,                     /* bitpos */                               
270          complain_overflow_bitfield, /* complain_on_overflow */
271          0,                     /* special_function */                     
272          "R_TRLA",              /* name */                                 
273          true,                  /* partial_inplace */                      
274          0xffff,                /* src_mask */                             
275          0xffff,                /* dst_mask */                             
276          false),                /* pcrel_offset */
277   
278   /* Modifiable relative branch.  */
279   HOWTO (0x14,                  /* type */                                 
280          1,                     /* rightshift */                           
281          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
282          32,                    /* bitsize */                   
283          false,                 /* pc_relative */                          
284          0,                     /* bitpos */                               
285          complain_overflow_bitfield, /* complain_on_overflow */
286          0,                     /* special_function */                     
287          "R_RRTBI",             /* name */                                 
288          true,                  /* partial_inplace */                      
289          0xffffffff,            /* src_mask */                             
290          0xffffffff,            /* dst_mask */                             
291          false),                /* pcrel_offset */
292   
293   /* Modifiable absolute branch.  */
294   HOWTO (0x15,                  /* type */                                 
295          1,                     /* rightshift */                           
296          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
297          32,                    /* bitsize */                   
298          false,                 /* pc_relative */                          
299          0,                     /* bitpos */                               
300          complain_overflow_bitfield, /* complain_on_overflow */
301          0,                     /* special_function */                     
302          "R_RRTBA",             /* name */                                 
303          true,                  /* partial_inplace */                      
304          0xffffffff,            /* src_mask */                             
305          0xffffffff,            /* dst_mask */                             
306          false),                /* pcrel_offset */
307   
308   /* Modifiable call absolute indirect.  */
309   HOWTO (0x16,                  /* type */                                 
310          0,                     /* rightshift */                           
311          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
312          16,                    /* bitsize */                   
313          false,                 /* pc_relative */                          
314          0,                     /* bitpos */                               
315          complain_overflow_bitfield, /* complain_on_overflow */
316          0,                     /* special_function */                     
317          "R_CAI",               /* name */                                 
318          true,                  /* partial_inplace */                      
319          0xffff,                /* src_mask */                             
320          0xffff,                /* dst_mask */                             
321          false),                /* pcrel_offset */
322   
323   /* Modifiable call relative.  */
324   HOWTO (0x17,                  /* 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_REL",               /* name */                                 
333          true,                  /* partial_inplace */                      
334          0xffff,                /* src_mask */                             
335          0xffff,                /* dst_mask */                             
336          false),                /* pcrel_offset */
337   
338   /* Modifiable branch absolute.  */
339   HOWTO (0x18,                  /* 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_RBA",               /* name */                                 
348          true,                  /* partial_inplace */                      
349          0xffff,                /* src_mask */                             
350          0xffff,                /* dst_mask */                             
351          false),                /* pcrel_offset */
352   
353   /* Modifiable branch absolute.  */
354   HOWTO (0x19,                  /* type */                                 
355          0,                     /* rightshift */                           
356          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
357          16,                    /* bitsize */                   
358          false,                 /* pc_relative */                          
359          0,                     /* bitpos */                               
360          complain_overflow_bitfield, /* complain_on_overflow */
361          0,                     /* special_function */                     
362          "R_RBAC",              /* name */                                 
363          true,                  /* partial_inplace */                      
364          0xffff,                /* src_mask */                             
365          0xffff,                /* dst_mask */                             
366          false),                /* pcrel_offset */
367   
368   /* Modifiable branch relative.  */
369   HOWTO (0x1a,                  /* type */                                 
370          0,                     /* rightshift */                           
371          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
372          26,                    /* bitsize */                   
373          false,                 /* pc_relative */                          
374          0,                     /* bitpos */                               
375          complain_overflow_signed, /* complain_on_overflow */
376          0,                     /* special_function */                     
377          "R_REL",               /* name */                                 
378          true,                  /* partial_inplace */                      
379          0xffff,                /* src_mask */                             
380          0xffff,                /* dst_mask */                             
381          false),                /* pcrel_offset */
382   
383   /* Modifiable branch absolute.  */
384   HOWTO (0x1b,                  /* 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_REL",               /* name */                                 
393          true,                  /* partial_inplace */                      
394          0xffff,                /* src_mask */                             
395          0xffff,                /* dst_mask */                             
396          false)                 /* pcrel_offset */
397 };
398
399 #define RTYPE2HOWTO(cache_ptr, dst) rs6000coff_rtype2howto (cache_ptr, dst)
400
401 static void rs6000coff_rtype2howto PARAMS ((arelent *,
402                                             struct internal_reloc *));
403
404 static void
405 rs6000coff_rtype2howto (relent, internal)
406      arelent *relent;
407      struct internal_reloc *internal;
408 {
409   relent->howto = rs6000coff_howto_table + internal->r_type;
410
411   /* The r_size field of an XCOFF reloc encodes the bitsize of the
412      relocation, as well as indicating whether it is signed or not.
413      Doublecheck that the relocation information gathered from the
414      type matches this information.  */
415   if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1)
416     abort ();
417 #if 0
418   if ((internal->r_size & 0x80) != 0
419       ? (relent->howto->complain_on_overflow != complain_overflow_signed)
420       : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
421     abort ();
422 #endif
423 }
424
425 #define coff_bfd_reloc_type_lookup rs6000coff_reloc_type_lookup
426
427 static reloc_howto_type *rs6000coff_reloc_type_lookup
428   PARAMS ((bfd *, bfd_reloc_code_real_type));
429
430 static reloc_howto_type *
431 rs6000coff_reloc_type_lookup (abfd, code)
432      bfd *abfd;
433      bfd_reloc_code_real_type code;
434 {
435   switch (code)
436     {
437     case BFD_RELOC_PPC_B26:
438       return &rs6000coff_howto_table[0xa];
439     case BFD_RELOC_PPC_BA26:
440       return &rs6000coff_howto_table[8];
441     case BFD_RELOC_PPC_TOC16:
442       return &rs6000coff_howto_table[3];
443     case BFD_RELOC_32:
444       return &rs6000coff_howto_table[0];
445     default:
446       return NULL;
447     }
448 }
449
450 #define SELECT_RELOC(internal, howto)                                   \
451   {                                                                     \
452     internal.r_type = howto->type;                                      \
453     internal.r_size =                                                   \
454       ((howto->complain_on_overflow == complain_overflow_signed         \
455         ? 0x80                                                          \
456         : 0)                                                            \
457        | (howto->bitsize - 1));                                         \
458   }
459
460 #define COFF_LONG_FILENAMES
461
462 #include "coffcode.h"
463
464 #define coff_archive_p          bfd_generic_archive_p
465 #define coff_mkarchive          _bfd_generic_mkarchive
466
467 #ifdef HOST_AIX
468
469 /* ------------------------------------------------------------------------ */
470 /*      Support for archive file stuff..                                    */
471 /*      Stolen from Damon A. Permezel's `bfd' portation.                    */
472 /* ------------------------------------------------------------------------ */
473
474 #define rs6000coff_slurp_armap bfd_slurp_coff_armap
475 #define rs6000coff_slurp_extended_name_table _bfd_slurp_extended_name_table
476 #define rs6000coff_construct_extended_name_table \
477   _bfd_archive_coff_construct_extended_name_table
478 #define rs6000coff_truncate_arname bfd_dont_truncate_arname
479 #define rs6000coff_update_armap_timestamp bfd_true
480
481 #undef  coff_mkarchive
482 #define coff_mkarchive                  rs6000coff_mkarchive
483
484 #undef  coff_archive_p
485 #define coff_archive_p                  rs6000coff_archive_p
486
487 #include "/usr/include/ar.h"            /* <ar.h> doesn't do it.        */
488
489
490 #define arch_hdr(bfd)           \
491         ((struct ar_hdr *)      \
492          (((struct areltdata *)((bfd)->arelt_data))->arch_header))
493
494
495 static boolean
496 rs6000coff_mkarchive (abfd)
497      bfd *abfd;
498 {
499         bfd_set_error (bfd_error_invalid_operation);    /* write not supported  */
500         return false;
501 }
502
503
504 /* This functions reads an arch header and returns an areltdata pointer, or
505    NULL on error.
506
507    Presumes the file pointer is already in the right place (ie pointing
508    to the ar_hdr in the file).   Moves the file pointer; on success it
509    should be pointing to the front of the file contents; on failure it
510    could have been moved arbitrarily.
511 */
512
513 struct areltdata *
514 rs6000coff_snarf_ar_hdr (abfd)
515      bfd *abfd;
516 {
517         struct {
518                 struct ar_hdr hdr;
519                 char namebuf[256];
520         } h;
521         int size;
522         struct areltdata *ared;
523         char *allocptr;
524
525         size = sizeof (h.hdr);
526         if (bfd_read(&h.hdr, 1, size, abfd) != size) {
527                 if (bfd_get_error () != bfd_error_system_call)
528                   bfd_set_error (bfd_error_no_more_archived_files);
529                 return NULL;
530         }
531         size  = atoi(h.hdr.ar_namlen);  /* ar_name[] length     */
532         size += size & 1;
533
534         if (bfd_read(&h.hdr._ar_name.ar_name[2], 1, size, abfd) != size) {
535                 if (bfd_get_error () != bfd_error_system_call)
536                   bfd_set_error (bfd_error_no_more_archived_files);
537                 return NULL;
538         }
539
540         if (strncmp(h.hdr._ar_name.ar_fmag + size, AIAFMAG, 2)) {
541                 bfd_set_error (bfd_error_malformed_archive);
542                 return NULL;
543         }
544
545         h.hdr._ar_name.ar_name[size] = 0;       /* terminate filename   */
546
547         /*
548          * if the filename is NULL, we're (probably) at the end.
549          */
550         if (size == 0) {
551                 bfd_set_error (bfd_error_no_more_archived_files);
552                 return NULL;
553         }
554
555         size += sizeof (h.hdr);
556         allocptr = bfd_zalloc(abfd, sizeof (*ared) + size);
557
558         if (allocptr == NULL) {
559                 bfd_set_error (bfd_error_no_memory);
560                 return NULL;
561         }
562
563         ared = (struct areltdata *) allocptr;
564
565         ared->arch_header = (void *) (allocptr + sizeof (struct areltdata));
566         memcpy ((char *) ared->arch_header, &h.hdr, size);
567         ared->parsed_size = atoi(h.hdr.ar_size);
568         ared->filename    = ((AR_HDR*) ared->arch_header)->_ar_name.ar_name;
569
570         return ared;
571 }
572
573 /* Stolen directly from archive.c, except it calls rs6000coff_snarf_ar_hdr.
574    Why wasn't this part of the transfer vector?  */
575
576 bfd *
577 rs6000coff_get_elt_at_filepos (archive, filepos)
578      bfd *archive;
579      file_ptr filepos;
580 {
581   struct areltdata *new_areldata;
582   bfd *n_nfd;
583
584   n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
585   if (n_nfd) return n_nfd;
586
587   if (0 != bfd_seek (archive, filepos, SEEK_SET))
588     return NULL;
589
590   if ((new_areldata = rs6000coff_snarf_ar_hdr (archive)) == NULL) return NULL;
591   
592   n_nfd = _bfd_create_empty_archive_element_shell (archive);
593   if (n_nfd == NULL) {
594     bfd_release (archive, (PTR)new_areldata);
595     return NULL;
596   }
597   n_nfd->origin = bfd_tell (archive);
598   n_nfd->arelt_data = (PTR) new_areldata;
599   n_nfd->filename = new_areldata->filename;
600
601   if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
602     return n_nfd;
603
604   /* huh? */
605   bfd_release (archive, (PTR)n_nfd);
606   bfd_release (archive, (PTR)new_areldata);
607   return NULL;
608 }
609
610 /*
611  * xcoff_openr_next_archived_file -     xcoff has nxt/prv seek addrs.
612  */
613 static bfd *
614 rs6000coff_openr_next_archived_file(archive, last_file)
615   bfd *archive, *last_file; 
616 {
617         file_ptr filestart;
618
619         if (!last_file)
620                 filestart = bfd_ardata(archive)->first_file_filepos;
621         else
622                 filestart = atol(arch_hdr(last_file)->ar_nxtmem);
623
624         return rs6000coff_get_elt_at_filepos (archive, filestart);
625 }
626
627
628 static const bfd_target *
629 rs6000coff_archive_p (abfd)
630      bfd *abfd;
631 {
632         struct fl_hdr hdr;
633         register struct artdata *art;
634
635         if (bfd_read (&hdr, sizeof (hdr), 1, abfd) != sizeof (hdr)) {
636                 if (bfd_get_error () != bfd_error_system_call)
637                   bfd_set_error (bfd_error_wrong_format);
638                 return 0;
639         }
640
641         if (strncmp(hdr.fl_magic, AIAMAG, SAIAMAG)) {
642                 bfd_set_error (bfd_error_wrong_format);
643                 return 0;
644         }
645
646         /*
647          * bfd_ardata() accesses the bfd->tdata field.
648          */
649         abfd->tdata.aout_ar_data =
650           (void *) bfd_zalloc(abfd, sizeof (*art) + sizeof (hdr));
651         if ((art = bfd_ardata (abfd)) == NULL) {
652                 bfd_set_error (bfd_error_no_memory);
653                 return 0;
654         }
655
656         art->first_file_filepos = atoi(hdr.fl_fstmoff);
657         *(struct fl_hdr *) (1 + art) = hdr;
658
659         /* Someday...
660          * slurp in the member table, which I think is the armap equivalent.
661         xcoff_slurp_armap(abfd);
662          */
663   
664         return abfd->xvec;
665 }
666
667
668 static int
669 rs6000coff_generic_stat_arch_elt(abfd, buf)
670   bfd *abfd;
671   struct stat *buf;
672 {
673         struct ar_hdr *hdr;
674         char *aloser;
675   
676         if (abfd->arelt_data == NULL) {
677                 bfd_set_error (bfd_error_invalid_operation);
678                 return -1;
679         }
680     
681         hdr = arch_hdr (abfd);
682
683 #define foo(arelt, stelt, size)  \
684         buf->stelt = strtol (hdr->arelt, &aloser, size); \
685                 if (aloser == hdr->arelt) return -1;
686   
687         foo (ar_date, st_mtime, 10);
688         foo (ar_uid, st_uid, 10);
689         foo (ar_gid, st_gid, 10);
690         foo (ar_mode, st_mode, 8);
691         foo (ar_size, st_size, 10);
692 #undef foo
693
694         return 0;
695 }
696
697 static boolean
698 rs6000coff_write_armap (arch, elength, map, orl_count, stridx)
699   bfd *arch;
700   unsigned int elength;
701   struct orl *map; 
702   unsigned int orl_count;
703   int stridx;
704 {
705         bfd_set_error (bfd_error_invalid_operation);
706         return false;
707 }
708 #endif  /* HOST_AIX */
709
710 \f
711 #define CORE_FILE_P _bfd_dummy_target
712
713 #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command
714 #define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal
715 #define coff_core_file_matches_executable_p \
716   _bfd_nocore_core_file_matches_executable_p
717
718 #ifdef AIX_CORE
719 #undef CORE_FILE_P
720 #define CORE_FILE_P rs6000coff_core_p
721 extern const bfd_target * rs6000coff_core_p ();
722 extern boolean rs6000coff_get_section_contents ();
723 extern boolean rs6000coff_core_file_matches_executable_p ();
724
725 #undef  coff_core_file_matches_executable_p
726 #define coff_core_file_matches_executable_p  \
727                                      rs6000coff_core_file_matches_executable_p
728
729 #undef  coff_get_section_contents
730 #define coff_get_section_contents       rs6000coff_get_section_contents
731 #endif /* AIX_CORE */
732
733 #ifdef LYNX_CORE
734
735 #undef CORE_FILE_P
736 #define CORE_FILE_P lynx_core_file_p
737 extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd));
738
739 extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
740                                                             bfd *exec_bfd));
741 #undef  coff_core_file_matches_executable_p
742 #define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p
743
744 extern char *lynx_core_file_failing_command PARAMS ((bfd *abfd));
745 #undef coff_core_file_failing_command
746 #define coff_core_file_failing_command lynx_core_file_failing_command
747
748 extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd));
749 #undef coff_core_file_failing_signal
750 #define coff_core_file_failing_signal lynx_core_file_failing_signal
751
752 #endif /* LYNX_CORE */
753
754 /* The transfer vector that leads the outside world to all of the above. */
755
756 const bfd_target rs6000coff_vec =
757 {
758   "aixcoff-rs6000",             /* name */
759   bfd_target_coff_flavour,      
760   true,                         /* data byte order is big */
761   true,                         /* header byte order is big */
762
763   (HAS_RELOC | EXEC_P |         /* object flags */
764    HAS_LINENO | HAS_DEBUG |
765    HAS_SYMS | HAS_LOCALS | WP_TEXT),
766
767   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
768   0,                            /* leading char */
769   '/',                          /* ar_pad_char */
770   15,                           /* ar_max_namelen??? FIXMEmgo */
771   3,                            /* default alignment power */
772
773   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
774      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
775      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
776   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
777      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
778      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
779
780   {_bfd_dummy_target, coff_object_p,    /* bfd_check_format */
781      coff_archive_p, CORE_FILE_P},
782   {bfd_false, coff_mkobject, coff_mkarchive, /* bfd_set_format */
783      bfd_false},
784   {bfd_false, coff_write_object_contents,       /* bfd_write_contents */
785      _bfd_write_archive_contents, bfd_false},
786
787      BFD_JUMP_TABLE_GENERIC (coff),
788      BFD_JUMP_TABLE_COPY (coff),
789      BFD_JUMP_TABLE_CORE (coff),
790 #ifdef HOST_AIX
791      BFD_JUMP_TABLE_ARCHIVE (rs6000coff),
792 #else
793      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
794 #endif
795      BFD_JUMP_TABLE_SYMBOLS (coff),
796      BFD_JUMP_TABLE_RELOCS (coff),
797      BFD_JUMP_TABLE_WRITE (coff),
798      BFD_JUMP_TABLE_LINK (coff),
799      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
800
801   COFF_SWAP_TABLE,
802 };