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