Add AIX 64 shared library support and emulation layer for binutils
[binutils.git] / bfd / coff-rs6000.c
blobeed3ee6805efcc70cd48cba197159374060d46c7
1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2 Copyright 1990-1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 FIXME: Can someone provide a transliteration of this name into ASCII?
5 Using the following chars caused a compiler warning on HIUX (so I replaced
6 them with octal escapes), and isn't useful without an understanding of what
7 character set it is.
8 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
9 and John Gilmore.
10 Archive support from Damon A. Permezel.
11 Contributed by IBM Corporation and Cygnus Support.
13 This file is part of BFD, the Binary File Descriptor library.
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 #include "bfd.h"
30 #include "sysdep.h"
31 #include "bfdlink.h"
32 #include "libbfd.h"
33 #include "coff/internal.h"
34 #include "coff/xcoff.h"
35 #include "coff/rs6000.h"
36 #include "libcoff.h"
37 #include "libxcoff.h"
39 extern boolean _bfd_xcoff_mkobject PARAMS ((bfd *));
40 extern boolean _bfd_xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *));
41 extern boolean _bfd_xcoff_is_local_label_name PARAMS ((bfd *, const char *));
42 extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
43 PARAMS ((bfd *, bfd_reloc_code_real_type));
44 extern boolean _bfd_xcoff_slurp_armap PARAMS ((bfd *));
45 extern const bfd_target *_bfd_xcoff_archive_p PARAMS ((bfd *));
46 extern PTR _bfd_xcoff_read_ar_hdr PARAMS ((bfd *));
47 extern bfd *_bfd_xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
48 extern int _bfd_xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
49 extern boolean _bfd_xcoff_write_armap
50 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
51 extern boolean _bfd_xcoff_write_archive_contents PARAMS ((bfd *));
52 extern int _bfd_xcoff_sizeof_headers PARAMS ((bfd *, boolean));
53 extern void _bfd_xcoff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
54 extern unsigned int _bfd_xcoff_swap_sym_out PARAMS ((bfd *, PTR, PTR));
55 extern void _bfd_xcoff_swap_aux_in PARAMS ((bfd *, PTR, int, int, int, int, PTR));
56 extern unsigned int _bfd_xcoff_swap_aux_out PARAMS ((bfd *, PTR, int, int, int, int, PTR));
58 /* Forward declare _bfd_xcoff_rtype2howto for coffcode.h macro. */
59 void _bfd_xcoff_rtype2howto PARAMS ((arelent *, struct internal_reloc *));
61 /* coffcode.h needs these to be defined. */
62 #define RS6000COFF_C 1
64 #define SELECT_RELOC(internal, howto) \
65 { \
66 internal.r_type = howto->type; \
67 internal.r_size = \
68 ((howto->complain_on_overflow == complain_overflow_signed \
69 ? 0x80 \
70 : 0) \
71 | (howto->bitsize - 1)); \
74 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
75 #define COFF_LONG_FILENAMES
76 #define NO_COFF_SYMBOLS
77 #define RTYPE2HOWTO(cache_ptr, dst) _bfd_xcoff_rtype2howto (cache_ptr, dst)
78 #define coff_mkobject _bfd_xcoff_mkobject
79 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
80 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
81 #define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
82 #ifdef AIX_CORE
83 extern const bfd_target * rs6000coff_core_p PARAMS ((bfd *abfd));
84 extern boolean rs6000coff_core_file_matches_executable_p
85 PARAMS ((bfd *cbfd, bfd *ebfd));
86 extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
87 extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
88 #define CORE_FILE_P rs6000coff_core_p
89 #define coff_core_file_failing_command \
90 rs6000coff_core_file_failing_command
91 #define coff_core_file_failing_signal \
92 rs6000coff_core_file_failing_signal
93 #define coff_core_file_matches_executable_p \
94 rs6000coff_core_file_matches_executable_p
95 #else
96 #define CORE_FILE_P _bfd_dummy_target
97 #define coff_core_file_failing_command \
98 _bfd_nocore_core_file_failing_command
99 #define coff_core_file_failing_signal \
100 _bfd_nocore_core_file_failing_signal
101 #define coff_core_file_matches_executable_p \
102 _bfd_nocore_core_file_matches_executable_p
103 #endif
104 #define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
105 #define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
106 #define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
107 #define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
109 #include "coffcode.h"
111 /* The main body of code is in coffcode.h. */
113 static const char *normalize_filename PARAMS ((bfd *));
114 static boolean xcoff_write_armap_old
115 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
116 static boolean xcoff_write_armap_big
117 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
118 static boolean xcoff_write_archive_contents_old PARAMS ((bfd *));
119 static boolean xcoff_write_archive_contents_big PARAMS ((bfd *));
120 static void xcoff_swap_ldhdr_in
121 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
122 static void xcoff_swap_ldhdr_out
123 PARAMS ((bfd *, const struct internal_ldhdr *, PTR));
124 static void xcoff_swap_ldsym_in
125 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
126 static void xcoff_swap_ldsym_out
127 PARAMS ((bfd *, const struct internal_ldsym *, PTR));
128 static void xcoff_swap_ldrel_in
129 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
130 static void xcoff_swap_ldrel_out
131 PARAMS ((bfd *, const struct internal_ldrel *, PTR));
132 static boolean xcoff_ppc_relocate_section
133 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
134 struct internal_reloc *, struct internal_syment *, asection **));
135 static boolean _bfd_xcoff_put_ldsymbol_name
136 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
137 const char *));
138 static asection *xcoff_create_csect_from_smclas
139 PARAMS ((bfd *, union internal_auxent *, const char *));
140 static boolean xcoff_is_lineno_count_overflow PARAMS ((bfd *, bfd_vma));
141 static boolean xcoff_is_reloc_count_overflow PARAMS ((bfd *, bfd_vma));
142 static bfd_vma xcoff_loader_symbol_offset
143 PARAMS ((bfd *, struct internal_ldhdr *));
144 static bfd_vma xcoff_loader_reloc_offset
145 PARAMS ((bfd *, struct internal_ldhdr *));
146 static boolean xcoff_generate_rtinit
147 PARAMS((bfd *, const char *, const char *, boolean));
148 static boolean do_pad PARAMS((bfd *, unsigned int));
149 static boolean do_copy PARAMS((bfd *, bfd *));
150 static boolean do_shared_object_padding PARAMS ((bfd *, bfd *, ufile_ptr *, int));
152 /* We use our own tdata type. Its first field is the COFF tdata type,
153 so the COFF routines are compatible. */
155 boolean
156 _bfd_xcoff_mkobject (abfd)
157 bfd *abfd;
159 coff_data_type *coff;
160 bfd_size_type amt = sizeof (struct xcoff_tdata);
162 abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
163 if (abfd->tdata.xcoff_obj_data == NULL)
164 return false;
165 coff = coff_data (abfd);
166 coff->symbols = (coff_symbol_type *) NULL;
167 coff->conversion_table = (unsigned int *) NULL;
168 coff->raw_syments = (struct coff_ptr_struct *) NULL;
169 coff->relocbase = 0;
171 xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
173 /* We set cputype to -1 to indicate that it has not been
174 initialized. */
175 xcoff_data (abfd)->cputype = -1;
177 xcoff_data (abfd)->csects = NULL;
178 xcoff_data (abfd)->debug_indices = NULL;
180 /* text section alignment is different than the default */
181 /* xcoff_data (abfd)->text_align_power = 5; */
183 return true;
186 /* Copy XCOFF data from one BFD to another. */
188 boolean
189 _bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
190 bfd *ibfd;
191 bfd *obfd;
193 struct xcoff_tdata *ix, *ox;
194 asection *sec;
196 if (ibfd->xvec != obfd->xvec)
197 return true;
198 ix = xcoff_data (ibfd);
199 ox = xcoff_data (obfd);
200 ox->full_aouthdr = ix->full_aouthdr;
201 ox->toc = ix->toc;
202 if (ix->sntoc == 0)
203 ox->sntoc = 0;
204 else
206 sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
207 if (sec == NULL)
208 ox->sntoc = 0;
209 else
210 ox->sntoc = sec->output_section->target_index;
212 if (ix->snentry == 0)
213 ox->snentry = 0;
214 else
216 sec = coff_section_from_bfd_index (ibfd, ix->snentry);
217 if (sec == NULL)
218 ox->snentry = 0;
219 else
220 ox->snentry = sec->output_section->target_index;
222 ox->text_align_power = ix->text_align_power;
223 ox->data_align_power = ix->data_align_power;
224 ox->modtype = ix->modtype;
225 ox->cputype = ix->cputype;
226 ox->maxdata = ix->maxdata;
227 ox->maxstack = ix->maxstack;
228 return true;
231 /* I don't think XCOFF really has a notion of local labels based on
232 name. This will mean that ld -X doesn't actually strip anything.
233 The AIX native linker does not have a -X option, and it ignores the
234 -x option. */
236 boolean
237 _bfd_xcoff_is_local_label_name (abfd, name)
238 bfd *abfd ATTRIBUTE_UNUSED;
239 const char *name ATTRIBUTE_UNUSED;
241 return false;
244 void
245 _bfd_xcoff_swap_sym_in (abfd, ext1, in1)
246 bfd *abfd;
247 PTR ext1;
248 PTR in1;
250 SYMENT *ext = (SYMENT *)ext1;
251 struct internal_syment * in = (struct internal_syment *)in1;
253 if (ext->e.e_name[0] != 0)
255 memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
257 else
259 in->_n._n_n._n_zeroes = 0;
260 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
263 in->n_value = H_GET_32 (abfd, ext->e_value);
264 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
265 in->n_type = H_GET_16 (abfd, ext->e_type);
266 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
267 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
270 unsigned int
271 _bfd_xcoff_swap_sym_out (abfd, inp, extp)
272 bfd *abfd;
273 PTR inp;
274 PTR extp;
276 struct internal_syment *in = (struct internal_syment *)inp;
277 SYMENT *ext =(SYMENT *)extp;
279 if (in->_n._n_name[0] != 0)
281 memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
283 else
285 H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
286 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
289 H_PUT_32 (abfd, in->n_value, ext->e_value);
290 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
291 H_PUT_16 (abfd, in->n_type, ext->e_type);
292 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
293 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
294 return bfd_coff_symesz (abfd);
297 void
298 _bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
299 bfd *abfd;
300 PTR ext1;
301 int type;
302 int class;
303 int indx;
304 int numaux;
305 PTR in1;
307 AUXENT * ext = (AUXENT *)ext1;
308 union internal_auxent *in = (union internal_auxent *)in1;
310 switch (class)
312 case C_FILE:
313 if (ext->x_file.x_fname[0] == 0)
315 in->x_file.x_n.x_zeroes = 0;
316 in->x_file.x_n.x_offset =
317 H_GET_32 (abfd, ext->x_file.x_n.x_offset);
319 else
321 if (numaux > 1)
323 if (indx == 0)
324 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
325 numaux * sizeof (AUXENT));
327 else
329 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
332 goto end;
334 /* RS/6000 "csect" auxents */
335 case C_EXT:
336 case C_HIDEXT:
337 if (indx + 1 == numaux)
339 in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
340 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
341 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
342 /* We don't have to hack bitfields in x_smtyp because it's
343 defined by shifts-and-ands, which are equivalent on all
344 byte orders. */
345 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
346 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
347 in->x_csect.x_stab = H_GET_32 (abfd, ext->x_csect.x_stab);
348 in->x_csect.x_snstab = H_GET_16 (abfd, ext->x_csect.x_snstab);
349 goto end;
351 break;
353 case C_STAT:
354 case C_LEAFSTAT:
355 case C_HIDDEN:
356 if (type == T_NULL)
358 in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
359 in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
360 in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
361 /* PE defines some extra fields; we zero them out for
362 safety. */
363 in->x_scn.x_checksum = 0;
364 in->x_scn.x_associated = 0;
365 in->x_scn.x_comdat = 0;
367 goto end;
369 break;
372 in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
373 in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
375 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
377 in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
378 H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
379 in->x_sym.x_fcnary.x_fcn.x_endndx.l =
380 H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
382 else
384 in->x_sym.x_fcnary.x_ary.x_dimen[0] =
385 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
386 in->x_sym.x_fcnary.x_ary.x_dimen[1] =
387 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
388 in->x_sym.x_fcnary.x_ary.x_dimen[2] =
389 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
390 in->x_sym.x_fcnary.x_ary.x_dimen[3] =
391 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
394 if (ISFCN (type))
396 in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
398 else
400 in->x_sym.x_misc.x_lnsz.x_lnno =
401 H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
402 in->x_sym.x_misc.x_lnsz.x_size =
403 H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
406 end: ;
407 /* The semicolon is because MSVC doesn't like labels at
408 end of block. */
412 unsigned int _bfd_xcoff_swap_aux_out PARAMS ((bfd *, PTR, int, int, int, int, PTR));
414 unsigned int
415 _bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
416 bfd * abfd;
417 PTR inp;
418 int type;
419 int class;
420 int indx ATTRIBUTE_UNUSED;
421 int numaux ATTRIBUTE_UNUSED;
422 PTR extp;
424 union internal_auxent *in = (union internal_auxent *)inp;
425 AUXENT *ext = (AUXENT *)extp;
427 memset((PTR)ext, 0, bfd_coff_auxesz (abfd));
428 switch (class)
430 case C_FILE:
431 if (in->x_file.x_fname[0] == 0)
433 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
434 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
436 else
438 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
440 goto end;
442 /* RS/6000 "csect" auxents */
443 case C_EXT:
444 case C_HIDEXT:
445 if (indx + 1 == numaux)
447 H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
448 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
449 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
450 /* We don't have to hack bitfields in x_smtyp because it's
451 defined by shifts-and-ands, which are equivalent on all
452 byte orders. */
453 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
454 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
455 H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
456 H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
457 goto end;
459 break;
461 case C_STAT:
462 case C_LEAFSTAT:
463 case C_HIDDEN:
464 if (type == T_NULL)
466 H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
467 H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
468 H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
469 goto end;
471 break;
474 H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
475 H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
477 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
479 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
480 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
481 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
482 ext->x_sym.x_fcnary.x_fcn.x_endndx);
484 else
486 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
487 ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
488 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
489 ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
490 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
491 ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
492 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
493 ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
496 if (ISFCN (type))
497 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
498 else
500 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
501 ext->x_sym.x_misc.x_lnsz.x_lnno);
502 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
503 ext->x_sym.x_misc.x_lnsz.x_size);
506 end:
507 return bfd_coff_auxesz (abfd);
512 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
513 bitsize and whether they are signed or not, along with a
514 conventional type. This table is for the types, which are used for
515 different algorithms for putting in the reloc. Many of these
516 relocs need special_function entries, which I have not written. */
519 reloc_howto_type xcoff_howto_table[] =
521 /* Standard 32 bit relocation. */
522 HOWTO (R_POS, /* type */
523 0, /* rightshift */
524 2, /* size (0 = byte, 1 = short, 2 = long) */
525 32, /* bitsize */
526 false, /* pc_relative */
527 0, /* bitpos */
528 complain_overflow_bitfield, /* complain_on_overflow */
529 0, /* special_function */
530 "R_POS", /* name */
531 true, /* partial_inplace */
532 0xffffffff, /* src_mask */
533 0xffffffff, /* dst_mask */
534 false), /* pcrel_offset */
536 /* 32 bit relocation, but store negative value. */
537 HOWTO (R_NEG, /* type */
538 0, /* rightshift */
539 -2, /* size (0 = byte, 1 = short, 2 = long) */
540 32, /* bitsize */
541 false, /* pc_relative */
542 0, /* bitpos */
543 complain_overflow_bitfield, /* complain_on_overflow */
544 0, /* special_function */
545 "R_NEG", /* name */
546 true, /* partial_inplace */
547 0xffffffff, /* src_mask */
548 0xffffffff, /* dst_mask */
549 false), /* pcrel_offset */
551 /* 32 bit PC relative relocation. */
552 HOWTO (R_REL, /* type */
553 0, /* rightshift */
554 2, /* size (0 = byte, 1 = short, 2 = long) */
555 32, /* bitsize */
556 true, /* pc_relative */
557 0, /* bitpos */
558 complain_overflow_signed, /* complain_on_overflow */
559 0, /* special_function */
560 "R_REL", /* name */
561 true, /* partial_inplace */
562 0xffffffff, /* src_mask */
563 0xffffffff, /* dst_mask */
564 false), /* pcrel_offset */
566 /* 16 bit TOC relative relocation. */
567 HOWTO (R_TOC, /* type */
568 0, /* rightshift */
569 1, /* size (0 = byte, 1 = short, 2 = long) */
570 16, /* bitsize */
571 false, /* pc_relative */
572 0, /* bitpos */
573 complain_overflow_bitfield, /* complain_on_overflow */
574 0, /* special_function */
575 "R_TOC", /* name */
576 true, /* partial_inplace */
577 0xffff, /* src_mask */
578 0xffff, /* dst_mask */
579 false), /* pcrel_offset */
581 /* I don't really know what this is. */
582 HOWTO (R_RTB, /* type */
583 1, /* rightshift */
584 2, /* size (0 = byte, 1 = short, 2 = long) */
585 32, /* bitsize */
586 false, /* pc_relative */
587 0, /* bitpos */
588 complain_overflow_bitfield, /* complain_on_overflow */
589 0, /* special_function */
590 "R_RTB", /* name */
591 true, /* partial_inplace */
592 0xffffffff, /* src_mask */
593 0xffffffff, /* dst_mask */
594 false), /* pcrel_offset */
596 /* External TOC relative symbol. */
597 HOWTO (R_GL, /* type */
598 0, /* rightshift */
599 2, /* size (0 = byte, 1 = short, 2 = long) */
600 16, /* bitsize */
601 false, /* pc_relative */
602 0, /* bitpos */
603 complain_overflow_bitfield, /* complain_on_overflow */
604 0, /* special_function */
605 "R_GL", /* name */
606 true, /* partial_inplace */
607 0xffff, /* src_mask */
608 0xffff, /* dst_mask */
609 false), /* pcrel_offset */
611 /* Local TOC relative symbol. */
612 HOWTO (R_TCL, /* type */
613 0, /* rightshift */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
615 16, /* bitsize */
616 false, /* pc_relative */
617 0, /* bitpos */
618 complain_overflow_bitfield, /* complain_on_overflow */
619 0, /* special_function */
620 "R_TCL", /* name */
621 true, /* partial_inplace */
622 0xffff, /* src_mask */
623 0xffff, /* dst_mask */
624 false), /* pcrel_offset */
626 EMPTY_HOWTO (7),
628 /* Non modifiable absolute branch. */
629 HOWTO (R_BA, /* type */
630 0, /* rightshift */
631 2, /* size (0 = byte, 1 = short, 2 = long) */
632 26, /* bitsize */
633 false, /* pc_relative */
634 0, /* bitpos */
635 complain_overflow_bitfield, /* complain_on_overflow */
636 0, /* special_function */
637 "R_BA", /* name */
638 true, /* partial_inplace */
639 0x3fffffc, /* src_mask */
640 0x3fffffc, /* dst_mask */
641 false), /* pcrel_offset */
643 EMPTY_HOWTO (9),
645 /* Non modifiable relative branch. */
646 HOWTO (R_BR, /* type */
647 0, /* rightshift */
648 2, /* size (0 = byte, 1 = short, 2 = long) */
649 26, /* bitsize */
650 true, /* pc_relative */
651 0, /* bitpos */
652 complain_overflow_signed, /* complain_on_overflow */
653 0, /* special_function */
654 "R_BR", /* name */
655 true, /* partial_inplace */
656 0x3fffffc, /* src_mask */
657 0x3fffffc, /* dst_mask */
658 false), /* pcrel_offset */
660 EMPTY_HOWTO (0xb),
662 /* Indirect load. */
663 HOWTO (R_RL, /* type */
664 0, /* rightshift */
665 2, /* size (0 = byte, 1 = short, 2 = long) */
666 16, /* bitsize */
667 false, /* pc_relative */
668 0, /* bitpos */
669 complain_overflow_bitfield, /* complain_on_overflow */
670 0, /* special_function */
671 "R_RL", /* name */
672 true, /* partial_inplace */
673 0xffff, /* src_mask */
674 0xffff, /* dst_mask */
675 false), /* pcrel_offset */
677 /* Load address. */
678 HOWTO (R_RLA, /* type */
679 0, /* rightshift */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
681 16, /* bitsize */
682 false, /* pc_relative */
683 0, /* bitpos */
684 complain_overflow_bitfield, /* complain_on_overflow */
685 0, /* special_function */
686 "R_RLA", /* name */
687 true, /* partial_inplace */
688 0xffff, /* src_mask */
689 0xffff, /* dst_mask */
690 false), /* pcrel_offset */
692 EMPTY_HOWTO (0xe),
694 /* Non-relocating reference. */
695 HOWTO (R_REF, /* type */
696 0, /* rightshift */
697 2, /* size (0 = byte, 1 = short, 2 = long) */
698 32, /* bitsize */
699 false, /* pc_relative */
700 0, /* bitpos */
701 complain_overflow_bitfield, /* complain_on_overflow */
702 0, /* special_function */
703 "R_REF", /* name */
704 false, /* partial_inplace */
705 0, /* src_mask */
706 0, /* dst_mask */
707 false), /* pcrel_offset */
709 EMPTY_HOWTO (0x10),
710 EMPTY_HOWTO (0x11),
712 /* TOC relative indirect load. */
713 HOWTO (R_TRL, /* type */
714 0, /* rightshift */
715 2, /* size (0 = byte, 1 = short, 2 = long) */
716 16, /* bitsize */
717 false, /* pc_relative */
718 0, /* bitpos */
719 complain_overflow_bitfield, /* complain_on_overflow */
720 0, /* special_function */
721 "R_TRL", /* name */
722 true, /* partial_inplace */
723 0xffff, /* src_mask */
724 0xffff, /* dst_mask */
725 false), /* pcrel_offset */
727 /* TOC relative load address. */
728 HOWTO (R_TRLA, /* type */
729 0, /* rightshift */
730 2, /* size (0 = byte, 1 = short, 2 = long) */
731 16, /* bitsize */
732 false, /* pc_relative */
733 0, /* bitpos */
734 complain_overflow_bitfield, /* complain_on_overflow */
735 0, /* special_function */
736 "R_TRLA", /* name */
737 true, /* partial_inplace */
738 0xffff, /* src_mask */
739 0xffff, /* dst_mask */
740 false), /* pcrel_offset */
742 /* Modifiable relative branch. */
743 HOWTO (R_RRTBI, /* type */
744 1, /* rightshift */
745 2, /* size (0 = byte, 1 = short, 2 = long) */
746 32, /* bitsize */
747 false, /* pc_relative */
748 0, /* bitpos */
749 complain_overflow_bitfield, /* complain_on_overflow */
750 0, /* special_function */
751 "R_RRTBI", /* name */
752 true, /* partial_inplace */
753 0xffffffff, /* src_mask */
754 0xffffffff, /* dst_mask */
755 false), /* pcrel_offset */
757 /* Modifiable absolute branch. */
758 HOWTO (R_RRTBA, /* type */
759 1, /* rightshift */
760 2, /* size (0 = byte, 1 = short, 2 = long) */
761 32, /* bitsize */
762 false, /* pc_relative */
763 0, /* bitpos */
764 complain_overflow_bitfield, /* complain_on_overflow */
765 0, /* special_function */
766 "R_RRTBA", /* name */
767 true, /* partial_inplace */
768 0xffffffff, /* src_mask */
769 0xffffffff, /* dst_mask */
770 false), /* pcrel_offset */
772 /* Modifiable call absolute indirect. */
773 HOWTO (R_CAI, /* type */
774 0, /* rightshift */
775 2, /* size (0 = byte, 1 = short, 2 = long) */
776 16, /* bitsize */
777 false, /* pc_relative */
778 0, /* bitpos */
779 complain_overflow_bitfield, /* complain_on_overflow */
780 0, /* special_function */
781 "R_CAI", /* name */
782 true, /* partial_inplace */
783 0xffff, /* src_mask */
784 0xffff, /* dst_mask */
785 false), /* pcrel_offset */
787 /* Modifiable call relative. */
788 HOWTO (R_CREL, /* type */
789 0, /* rightshift */
790 2, /* size (0 = byte, 1 = short, 2 = long) */
791 16, /* bitsize */
792 false, /* pc_relative */
793 0, /* bitpos */
794 complain_overflow_bitfield, /* complain_on_overflow */
795 0, /* special_function */
796 "R_CREL", /* name */
797 true, /* partial_inplace */
798 0xffff, /* src_mask */
799 0xffff, /* dst_mask */
800 false), /* pcrel_offset */
802 /* Modifiable branch absolute. */
803 HOWTO (R_RBA, /* type */
804 0, /* rightshift */
805 2, /* size (0 = byte, 1 = short, 2 = long) */
806 26, /* bitsize */
807 false, /* pc_relative */
808 0, /* bitpos */
809 complain_overflow_bitfield, /* complain_on_overflow */
810 0, /* special_function */
811 "R_RBA", /* name */
812 true, /* partial_inplace */
813 0xffff, /* src_mask */
814 0xffff, /* dst_mask */
815 false), /* pcrel_offset */
817 /* Modifiable branch absolute. */
818 HOWTO (R_RBAC, /* type */
819 0, /* rightshift */
820 2, /* size (0 = byte, 1 = short, 2 = long) */
821 32, /* bitsize */
822 false, /* pc_relative */
823 0, /* bitpos */
824 complain_overflow_bitfield, /* complain_on_overflow */
825 0, /* special_function */
826 "R_RBAC", /* name */
827 true, /* partial_inplace */
828 0xffff, /* src_mask */
829 0xffff, /* dst_mask */
830 false), /* pcrel_offset */
832 /* Modifiable branch relative. */
833 HOWTO (R_RBR, /* type */
834 0, /* rightshift */
835 2, /* size (0 = byte, 1 = short, 2 = long) */
836 26, /* bitsize */
837 false, /* pc_relative */
838 0, /* bitpos */
839 complain_overflow_signed, /* complain_on_overflow */
840 0, /* special_function */
841 "R_RBR", /* name */
842 true, /* partial_inplace */
843 0xffff, /* src_mask */
844 0xffff, /* dst_mask */
845 false), /* pcrel_offset */
847 /* Modifiable branch absolute. */
848 HOWTO (R_RBRC, /* type */
849 0, /* rightshift */
850 2, /* size (0 = byte, 1 = short, 2 = long) */
851 16, /* bitsize */
852 false, /* pc_relative */
853 0, /* bitpos */
854 complain_overflow_bitfield, /* complain_on_overflow */
855 0, /* special_function */
856 "R_RBRC", /* name */
857 true, /* partial_inplace */
858 0xffff, /* src_mask */
859 0xffff, /* dst_mask */
860 false), /* pcrel_offset */
862 HOWTO (R_POS, /* type */
863 0, /* rightshift */
864 4, /* size (0 = byte, 1 = short, 2 = long) */
865 64, /* bitsize */
866 false, /* pc_relative */
867 0, /* bitpos */
868 complain_overflow_bitfield, /* complain_on_overflow */
869 0, /* special_function */
870 "R_POS", /* name */
871 true, /* partial_inplace */
872 MINUS_ONE, /* src_mask */
873 MINUS_ONE, /* dst_mask */
874 false), /* pcrel_offset */
876 /* 16 bit Non modifiable absolute branch. */
877 HOWTO (R_BA, /* type */
878 0, /* rightshift */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
880 16, /* bitsize */
881 false, /* pc_relative */
882 0, /* bitpos */
883 complain_overflow_bitfield, /* complain_on_overflow */
884 0, /* special_function */
885 "R_BA", /* name */
886 true, /* partial_inplace */
887 0xfffc, /* src_mask */
888 0xfffc, /* dst_mask */
889 false), /* pcrel_offset */
892 void
893 _bfd_xcoff_rtype2howto (relent, internal)
894 arelent *relent;
895 struct internal_reloc *internal;
897 relent->howto = xcoff_howto_table + internal->r_type;
899 /* Check for relocs we don't know of. */
900 if (internal->r_type
901 >= sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]))
902 abort ();
903 if (internal->r_type != relent->howto->type)
904 abort ();
906 /* The r_size field of an XCOFF reloc encodes the bitsize of the
907 relocation, as well as indicating whether it is signed or not.
908 Doublecheck that the relocation information gathered from the
909 type matches this information. The bitsize is not significant
910 for R_REF relocs. */
911 if (relent->howto->dst_mask != 0
912 && (relent->howto->bitsize
913 != ((unsigned int) internal->r_size & 0x3f) + 1))
914 abort ();
915 #if 0
916 if ((internal->r_size & 0x80) != 0
917 ? (relent->howto->complain_on_overflow != complain_overflow_signed)
918 : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
919 abort ();
920 #endif
923 reloc_howto_type *
924 _bfd_xcoff_reloc_type_lookup (abfd, code)
925 bfd *abfd ATTRIBUTE_UNUSED;
926 bfd_reloc_code_real_type code;
928 switch (code)
930 case BFD_RELOC_PPC_B26:
931 return &xcoff_howto_table[0xa];
932 case BFD_RELOC_PPC_BA16:
933 return &xcoff_howto_table[0x1d];
934 case BFD_RELOC_PPC_BA26:
935 return &xcoff_howto_table[8];
936 case BFD_RELOC_PPC_TOC16:
937 return &xcoff_howto_table[3];
938 case BFD_RELOC_32:
939 case BFD_RELOC_CTOR:
940 return &xcoff_howto_table[0];
941 case BFD_RELOC_64:
942 return &xcoff_howto_table[0x1c];
943 default:
944 return NULL;
949 /* XCOFF archive support. The original version of this code was by
950 Damon A. Permezel. It was enhanced to permit cross support, and
951 writing archive files, by Ian Lance Taylor, Cygnus Support.
953 XCOFF uses its own archive format. Everything is hooked together
954 with file offset links, so it is possible to rapidly update an
955 archive in place. Of course, we don't do that. An XCOFF archive
956 has a real file header, not just an ARMAG string. The structure of
957 the file header and of each archive header appear below.
959 An XCOFF archive also has a member table, which is a list of
960 elements in the archive (you can get that by looking through the
961 linked list, but you have to read a lot more of the file). The
962 member table has a normal archive header with an empty name. It is
963 normally (and perhaps must be) the second to last entry in the
964 archive. The member table data is almost printable ASCII. It
965 starts with a 12 character decimal string which is the number of
966 entries in the table. For each entry it has a 12 character decimal
967 string which is the offset in the archive of that member. These
968 entries are followed by a series of null terminated strings which
969 are the member names for each entry.
971 Finally, an XCOFF archive has a global symbol table, which is what
972 we call the armap. The global symbol table has a normal archive
973 header with an empty name. It is normally (and perhaps must be)
974 the last entry in the archive. The contents start with a four byte
975 binary number which is the number of entries. This is followed by
976 a that many four byte binary numbers; each is the file offset of an
977 entry in the archive. These numbers are followed by a series of
978 null terminated strings, which are symbol names.
980 AIX 4.3 introduced a new archive format which can handle larger
981 files and also 32- and 64-bit objects in the same archive. The
982 things said above remain true except that there is now more than
983 one global symbol table. The one is used to index 32-bit objects,
984 the other for 64-bit objects.
986 The new archives (recognizable by the new ARMAG string) has larger
987 field lengths so that we cannot really share any code. Also we have
988 to take care that we are not generating the new form of archives
989 on AIX 4.2 or earlier systems. */
991 /* XCOFF archives use this as a magic string. Note that both strings
992 have the same length. */
994 /* Set the magic for archive. */
996 boolean
997 bfd_xcoff_ar_archive_set_magic (abfd, magic)
998 bfd *abfd ATTRIBUTE_UNUSED;
999 char *magic ATTRIBUTE_UNUSED;
1001 /* Not supported yet. */
1002 return false;
1003 /* bfd_xcoff_archive_set_magic (abfd, magic); */
1006 /* Read in the armap of an XCOFF archive. */
1008 boolean
1009 _bfd_xcoff_slurp_armap (abfd)
1010 bfd *abfd;
1012 file_ptr off;
1013 size_t namlen;
1014 bfd_size_type sz;
1015 bfd_byte *contents, *cend;
1016 bfd_vma c, i;
1017 carsym *arsym;
1018 bfd_byte *p;
1020 if (xcoff_ardata (abfd) == NULL)
1022 bfd_has_map (abfd) = false;
1023 return true;
1026 if (! xcoff_big_format_p (abfd))
1028 /* This is for the old format. */
1029 struct xcoff_ar_hdr hdr;
1031 off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
1032 if (off == 0)
1034 bfd_has_map (abfd) = false;
1035 return true;
1038 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1039 return false;
1041 /* The symbol table starts with a normal archive header. */
1042 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1043 != SIZEOF_AR_HDR)
1044 return false;
1046 /* Skip the name (normally empty). */
1047 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1048 off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1049 if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1050 return false;
1052 sz = strtol (hdr.size, (char **) NULL, 10);
1054 /* Read in the entire symbol table. */
1055 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1056 if (contents == NULL)
1057 return false;
1058 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1059 return false;
1061 /* The symbol table starts with a four byte count. */
1062 c = H_GET_32 (abfd, contents);
1064 if (c * 4 >= sz)
1066 bfd_set_error (bfd_error_bad_value);
1067 return false;
1070 bfd_ardata (abfd)->symdefs =
1071 ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1072 if (bfd_ardata (abfd)->symdefs == NULL)
1073 return false;
1075 /* After the count comes a list of four byte file offsets. */
1076 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
1077 i < c;
1078 ++i, ++arsym, p += 4)
1079 arsym->file_offset = H_GET_32 (abfd, p);
1081 else
1083 /* This is for the new format. */
1084 struct xcoff_ar_hdr_big hdr;
1086 off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
1087 if (off == 0)
1089 bfd_has_map (abfd) = false;
1090 return true;
1093 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1094 return false;
1096 /* The symbol table starts with a normal archive header. */
1097 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1098 != SIZEOF_AR_HDR_BIG)
1099 return false;
1101 /* Skip the name (normally empty). */
1102 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1103 off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1104 if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1105 return false;
1107 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1108 machines) since the field width is 20 and there numbers with more
1109 than 32 bits can be represented. */
1110 sz = strtol (hdr.size, (char **) NULL, 10);
1112 /* Read in the entire symbol table. */
1113 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1114 if (contents == NULL)
1115 return false;
1116 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1117 return false;
1119 /* The symbol table starts with an eight byte count. */
1120 c = H_GET_64 (abfd, contents);
1122 if (c * 8 >= sz)
1124 bfd_set_error (bfd_error_bad_value);
1125 return false;
1128 bfd_ardata (abfd)->symdefs =
1129 ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1130 if (bfd_ardata (abfd)->symdefs == NULL)
1131 return false;
1133 /* After the count comes a list of eight byte file offsets. */
1134 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1135 i < c;
1136 ++i, ++arsym, p += 8)
1137 arsym->file_offset = H_GET_64 (abfd, p);
1140 /* After the file offsets come null terminated symbol names. */
1141 cend = contents + sz;
1142 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1143 i < c;
1144 ++i, ++arsym, p += strlen ((char *) p) + 1)
1146 if (p >= cend)
1148 bfd_set_error (bfd_error_bad_value);
1149 return false;
1151 arsym->name = (char *) p;
1154 bfd_ardata (abfd)->symdef_count = c;
1155 bfd_has_map (abfd) = true;
1157 return true;
1160 /* See if this is an XCOFF archive. */
1162 const bfd_target *
1163 _bfd_xcoff_archive_p (abfd)
1164 bfd *abfd;
1166 char magic[SXCOFFARMAG];
1167 bfd_size_type amt;
1169 if (bfd_bread ((PTR) magic, (bfd_size_type) SXCOFFARMAG, abfd) != SXCOFFARMAG)
1171 if (bfd_get_error () != bfd_error_system_call)
1172 bfd_set_error (bfd_error_wrong_format);
1173 return NULL;
1176 if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
1177 && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1179 bfd_set_error (bfd_error_wrong_format);
1180 return NULL;
1183 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
1184 involves a cast, we can't do it as the left operand of
1185 assignment. */
1186 amt = sizeof (struct artdata);
1187 abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
1188 if (bfd_ardata (abfd) == (struct artdata *) NULL)
1189 return NULL;
1191 bfd_ardata (abfd)->cache = NULL;
1192 bfd_ardata (abfd)->archive_head = NULL;
1193 bfd_ardata (abfd)->symdefs = NULL;
1194 bfd_ardata (abfd)->extended_names = NULL;
1196 /* Now handle the two formats. */
1197 if (magic[1] != 'b')
1199 /* This is the old format. */
1200 struct xcoff_ar_file_hdr hdr;
1202 /* Copy over the magic string. */
1203 memcpy (hdr.magic, magic, SXCOFFARMAG);
1205 /* Now read the rest of the file header. */
1206 if (bfd_bread ((PTR) &hdr.memoff,
1207 (bfd_size_type) SIZEOF_AR_FILE_HDR - SXCOFFARMAG, abfd)
1208 != SIZEOF_AR_FILE_HDR - SXCOFFARMAG)
1210 if (bfd_get_error () != bfd_error_system_call)
1211 bfd_set_error (bfd_error_wrong_format);
1212 return NULL;
1215 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1216 (char **) NULL, 10);
1218 amt = SIZEOF_AR_FILE_HDR;
1219 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1220 if (bfd_ardata (abfd)->tdata == NULL)
1221 return NULL;
1223 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
1225 else
1227 /* This is the new format. */
1228 struct xcoff_ar_file_hdr_big hdr;
1230 /* Copy over the magic string. */
1231 memcpy (hdr.magic, magic, SXCOFFARMAG);
1233 /* Now read the rest of the file header. */
1234 if (bfd_bread ((PTR) &hdr.memoff,
1235 (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG, abfd)
1236 != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG)
1238 if (bfd_get_error () != bfd_error_system_call)
1239 bfd_set_error (bfd_error_wrong_format);
1240 return NULL;
1243 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1244 machines) since the field width is 20 and there numbers with more
1245 than 32 bits can be represented. */
1246 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1247 (char **) NULL, 10);
1249 amt = SIZEOF_AR_FILE_HDR_BIG;
1250 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1251 if (bfd_ardata (abfd)->tdata == NULL)
1252 return NULL;
1254 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1257 if (! _bfd_xcoff_slurp_armap (abfd))
1259 bfd_release (abfd, bfd_ardata (abfd));
1260 abfd->tdata.aout_ar_data = (struct artdata *) NULL;
1261 return NULL;
1264 return abfd->xvec;
1267 /* Read the archive header in an XCOFF archive. */
1270 _bfd_xcoff_read_ar_hdr (abfd)
1271 bfd *abfd;
1273 bfd_size_type namlen;
1274 struct areltdata *ret;
1275 bfd_size_type amt = sizeof (struct areltdata);
1277 ret = (struct areltdata *) bfd_alloc (abfd, amt);
1278 if (ret == NULL)
1279 return NULL;
1281 if (! xcoff_big_format_p (abfd))
1283 struct xcoff_ar_hdr hdr;
1284 struct xcoff_ar_hdr *hdrp;
1286 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1287 != SIZEOF_AR_HDR)
1289 free (ret);
1290 return NULL;
1293 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1294 amt = SIZEOF_AR_HDR + namlen + 1;
1295 hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
1296 if (hdrp == NULL)
1298 free (ret);
1299 return NULL;
1301 memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
1302 if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
1304 free (ret);
1305 return NULL;
1307 ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
1309 ret->arch_header = (char *) hdrp;
1310 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1311 ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
1313 else
1315 struct xcoff_ar_hdr_big hdr;
1316 struct xcoff_ar_hdr_big *hdrp;
1318 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1319 != SIZEOF_AR_HDR_BIG)
1321 free (ret);
1322 return NULL;
1325 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1326 amt = SIZEOF_AR_HDR_BIG + namlen + 1;
1327 hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
1328 if (hdrp == NULL)
1330 free (ret);
1331 return NULL;
1333 memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
1334 if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
1336 free (ret);
1337 return NULL;
1339 ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
1341 ret->arch_header = (char *) hdrp;
1342 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1343 machines) since the field width is 20 and there numbers with more
1344 than 32 bits can be represented. */
1345 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1346 ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
1349 /* Skip over the XCOFFARFMAG at the end of the file name. */
1350 if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
1351 return NULL;
1353 return (PTR) ret;
1356 /* Open the next element in an XCOFF archive. */
1358 bfd *
1359 _bfd_xcoff_openr_next_archived_file (archive, last_file)
1360 bfd *archive;
1361 bfd *last_file;
1363 file_ptr filestart;
1365 if (xcoff_ardata (archive) == NULL)
1367 bfd_set_error (bfd_error_invalid_operation);
1368 return NULL;
1371 if (! xcoff_big_format_p (archive))
1373 if (last_file == NULL)
1374 filestart = bfd_ardata (archive)->first_file_filepos;
1375 else
1376 filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
1377 10);
1379 if (filestart == 0
1380 || filestart == strtol (xcoff_ardata (archive)->memoff,
1381 (char **) NULL, 10)
1382 || filestart == strtol (xcoff_ardata (archive)->symoff,
1383 (char **) NULL, 10))
1385 bfd_set_error (bfd_error_no_more_archived_files);
1386 return NULL;
1389 else
1391 if (last_file == NULL)
1392 filestart = bfd_ardata (archive)->first_file_filepos;
1393 else
1394 /* XXX These actually have to be a calls to strtoll (at least
1395 on 32-bit machines) since the fields's width is 20 and
1396 there numbers with more than 32 bits can be represented. */
1397 filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
1398 10);
1400 /* XXX These actually have to be calls to strtoll (at least on 32-bit
1401 machines) since the fields's width is 20 and there numbers with more
1402 than 32 bits can be represented. */
1403 if (filestart == 0
1404 || filestart == strtol (xcoff_ardata_big (archive)->memoff,
1405 (char **) NULL, 10)
1406 || filestart == strtol (xcoff_ardata_big (archive)->symoff,
1407 (char **) NULL, 10))
1409 bfd_set_error (bfd_error_no_more_archived_files);
1410 return NULL;
1414 return _bfd_get_elt_at_filepos (archive, filestart);
1417 /* Stat an element in an XCOFF archive. */
1420 _bfd_xcoff_generic_stat_arch_elt (abfd, s)
1421 bfd *abfd;
1422 struct stat *s;
1424 if (abfd->arelt_data == NULL)
1426 bfd_set_error (bfd_error_invalid_operation);
1427 return -1;
1430 if (! xcoff_big_format_p (abfd))
1432 struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
1434 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1435 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1436 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1437 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1438 s->st_size = arch_eltdata (abfd)->parsed_size;
1440 else
1442 struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
1444 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1445 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1446 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1447 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1448 s->st_size = arch_eltdata (abfd)->parsed_size;
1451 return 0;
1454 /* Normalize a file name for inclusion in an archive. */
1456 static const char *
1457 normalize_filename (abfd)
1458 bfd *abfd;
1460 const char *file;
1461 const char *filename;
1463 file = bfd_get_filename (abfd);
1464 filename = strrchr (file, '/');
1465 if (filename != NULL)
1466 filename++;
1467 else
1468 filename = file;
1469 return filename;
1472 /* Write out an XCOFF armap. */
1474 /*ARGSUSED*/
1475 static boolean
1476 xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
1477 bfd *abfd;
1478 unsigned int elength ATTRIBUTE_UNUSED;
1479 struct orl *map;
1480 unsigned int orl_count;
1481 int stridx;
1483 struct xcoff_ar_hdr hdr;
1484 char *p;
1485 unsigned char buf[4];
1486 bfd *sub;
1487 file_ptr fileoff;
1488 unsigned int i;
1490 memset (&hdr, 0, sizeof hdr);
1491 sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
1492 sprintf (hdr.nextoff, "%d", 0);
1493 memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
1494 sprintf (hdr.date, "%d", 0);
1495 sprintf (hdr.uid, "%d", 0);
1496 sprintf (hdr.gid, "%d", 0);
1497 sprintf (hdr.mode, "%d", 0);
1498 sprintf (hdr.namlen, "%d", 0);
1500 /* We need spaces, not null bytes, in the header. */
1501 for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
1502 if (*p == '\0')
1503 *p = ' ';
1505 if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1506 != SIZEOF_AR_HDR
1507 || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
1508 != SXCOFFARFMAG))
1509 return false;
1511 H_PUT_32 (abfd, orl_count, buf);
1512 if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1513 return false;
1515 sub = abfd->archive_head;
1516 fileoff = SIZEOF_AR_FILE_HDR;
1517 i = 0;
1518 while (sub != NULL && i < orl_count)
1520 size_t namlen;
1522 while (map[i].u.abfd == sub)
1524 H_PUT_32 (abfd, fileoff, buf);
1525 if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1526 return false;
1527 ++i;
1529 namlen = strlen (normalize_filename (sub));
1530 namlen = (namlen + 1) &~ (size_t) 1;
1531 fileoff += (SIZEOF_AR_HDR
1532 + namlen
1533 + SXCOFFARFMAG
1534 + arelt_size (sub));
1535 fileoff = (fileoff + 1) &~ 1;
1536 sub = sub->next;
1539 for (i = 0; i < orl_count; i++)
1541 const char *name;
1542 size_t namlen;
1544 name = *map[i].name;
1545 namlen = strlen (name);
1546 if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
1547 return false;
1550 if ((stridx & 1) != 0)
1552 char b;
1554 b = '\0';
1555 if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1556 return false;
1559 return true;
1562 static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
1563 #define FMT20 "%-20lld"
1564 #define FMT12 "%-12d"
1565 #define FMT12_OCTAL "%-12o"
1566 #define FMT4 "%-4d"
1567 #define PRINT20(d, v) \
1568 sprintf (buff20, FMT20, (long long)(v)), \
1569 memcpy ((void *) (d), buff20, 20)
1571 #define PRINT12(d, v) \
1572 sprintf (buff20, FMT12, (int)(v)), \
1573 memcpy ((void *) (d), buff20, 12)
1575 #define PRINT12_OCTAL(d, v) \
1576 sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
1577 memcpy ((void *) (d), buff20, 12)
1579 #define PRINT4(d, v) \
1580 sprintf (buff20, FMT4, (int)(v)), \
1581 memcpy ((void *) (d), buff20, 4)
1583 #define READ20(d, v) \
1584 buff20[20] = 0, \
1585 memcpy (buff20, (d), 20), \
1586 (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
1588 static boolean
1589 do_pad (abfd, number)
1590 bfd *abfd;
1591 unsigned int number;
1593 bfd_byte b = 0;
1595 /* Limit pad to <= 4096. */
1596 if (number > 4096)
1597 return false;
1599 while (number--)
1600 if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1601 return false;
1603 return true;
1606 static boolean
1607 do_copy (out_bfd, in_bfd)
1608 bfd *out_bfd;
1609 bfd *in_bfd;
1611 bfd_size_type remaining;
1612 bfd_byte buffer[DEFAULT_BUFFERSIZE];
1614 if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
1615 return false;
1617 remaining = arelt_size (in_bfd);
1619 while (remaining >= DEFAULT_BUFFERSIZE)
1621 if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
1622 || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
1623 return false;
1625 remaining -= DEFAULT_BUFFERSIZE;
1628 if (remaining)
1630 if (bfd_bread (buffer, remaining, in_bfd) != remaining
1631 || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
1632 return false;
1635 return true;
1638 static boolean
1639 do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
1640 bfd *out_bfd;
1641 bfd *in_bfd;
1642 ufile_ptr *offset;
1643 int ar_header_size;
1645 if (bfd_check_format (in_bfd, bfd_object)
1646 && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
1647 && (in_bfd->flags & DYNAMIC) != 0)
1649 bfd_size_type pad = 0;
1650 int text_align_power;
1652 text_align_power = bfd_xcoff_text_align_power (in_bfd);
1653 BFD_ASSERT (2 < text_align_power);
1655 pad = 1 << text_align_power;
1656 pad -= (*offset + ar_header_size) & (pad - 1);
1658 if (! do_pad (out_bfd, pad))
1659 return false;
1661 *offset += pad;
1664 return true;
1667 static boolean
1668 xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
1669 bfd *abfd;
1670 unsigned int elength ATTRIBUTE_UNUSED;
1671 struct orl *map;
1672 unsigned int orl_count;
1673 int stridx;
1675 struct xcoff_ar_file_hdr_big *fhdr;
1676 bfd_vma i, sym_32, sym_64, str_32, str_64;
1677 const bfd_arch_info_type *arch_info = NULL;
1678 bfd *current_bfd;
1679 size_t string_length;
1680 ufile_ptr nextoff, prevoff;
1682 /* First, we look through the symbols and work out which are
1683 from 32-bit objects and which from 64-bit ones. */
1684 sym_32 = sym_64 = str_32 = str_64 = 0;
1686 current_bfd = abfd->archive_head;
1687 if (current_bfd != NULL)
1688 arch_info = bfd_get_arch_info (current_bfd);
1689 i = 0;
1690 while (current_bfd != NULL && i < orl_count)
1692 while (map[i].u.abfd == current_bfd)
1694 string_length = strlen (*map[i].name) + 1;
1696 if (arch_info->bits_per_address == 64)
1698 sym_64++;
1699 str_64 += string_length;
1701 else
1703 sym_32++;
1704 str_32 += string_length;
1706 i++;
1708 current_bfd = current_bfd->next;
1709 if (current_bfd != NULL)
1710 arch_info = bfd_get_arch_info (current_bfd);
1713 /* A quick sanity check... */
1714 BFD_ASSERT (sym_64 + sym_32 == orl_count);
1715 /* Explicit cast to int for compiler. */
1716 BFD_ASSERT ((int)(str_64 + str_32) == stridx);
1718 fhdr = xcoff_ardata_big (abfd);
1720 /* xcoff_write_archive_contents_big passes nextoff in symoff. */
1721 READ20 (fhdr->memoff, prevoff);
1722 READ20 (fhdr->symoff, nextoff);
1724 BFD_ASSERT (nextoff == bfd_tell (abfd));
1726 /* Write out the symbol table.
1727 Layout :
1729 standard big archive header
1730 0x0000 ar_size [0x14]
1731 0x0014 ar_nxtmem [0x14]
1732 0x0028 ar_prvmem [0x14]
1733 0x003C ar_date [0x0C]
1734 0x0048 ar_uid [0x0C]
1735 0x0054 ar_gid [0x0C]
1736 0x0060 ar_mod [0x0C]
1737 0x006C ar_namelen[0x04]
1738 0x0070 ar_fmag [SXCOFFARFMAG]
1740 Symbol table
1741 0x0072 num_syms [0x08], binary
1742 0x0078 offsets [0x08 * num_syms], binary
1743 0x0086 + 0x08 * num_syms names [??]
1744 ?? pad to even bytes.
1747 if (sym_32)
1749 struct xcoff_ar_hdr_big *hdr;
1750 bfd_byte *symbol_table;
1751 bfd_byte *st;
1752 file_ptr fileoff;
1754 bfd_vma symbol_table_size =
1755 SIZEOF_AR_HDR_BIG
1756 + SXCOFFARFMAG
1757 + 8
1758 + 8 * sym_32
1759 + str_32 + (str_32 & 1);
1761 symbol_table = NULL;
1762 symbol_table = (bfd_byte *) bfd_malloc (symbol_table_size);
1763 if (symbol_table == NULL)
1764 return false;
1765 memset (symbol_table, 0, symbol_table_size);
1767 hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1769 PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
1771 if (sym_64)
1772 PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
1773 else
1774 PRINT20 (hdr->nextoff, 0);
1776 PRINT20 (hdr->prevoff, prevoff);
1777 PRINT12 (hdr->date, 0);
1778 PRINT12 (hdr->uid, 0);
1779 PRINT12 (hdr->gid, 0);
1780 PRINT12 (hdr->mode, 0);
1781 PRINT4 (hdr->namlen, 0) ;
1783 st = symbol_table + SIZEOF_AR_HDR_BIG;
1784 memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1785 st += SXCOFFARFMAG;
1787 bfd_h_put_64 (abfd, sym_32, st);
1788 st += 8;
1790 /* loop over the 32 bit offsets */
1791 current_bfd = abfd->archive_head;
1792 if (current_bfd != NULL)
1793 arch_info = bfd_get_arch_info (current_bfd);
1794 fileoff = SIZEOF_AR_FILE_HDR_BIG;
1795 i = 0;
1796 while (current_bfd != NULL && i < orl_count)
1798 while (map[i].u.abfd == current_bfd)
1800 if (arch_info->bits_per_address == 32)
1802 bfd_h_put_64 (abfd, fileoff, st);
1803 st += 8;
1805 i++;
1807 string_length = strlen (normalize_filename (current_bfd));
1808 string_length += string_length & 1;
1809 fileoff += (SIZEOF_AR_HDR_BIG
1810 + string_length
1811 + SXCOFFARFMAG
1812 + arelt_size (current_bfd));
1813 fileoff += fileoff & 1;
1814 current_bfd = current_bfd->next;
1815 if (current_bfd != NULL)
1816 arch_info = bfd_get_arch_info (current_bfd);
1819 /* loop over the 32 bit symbol names */
1820 current_bfd = abfd->archive_head;
1821 if (current_bfd != NULL)
1822 arch_info = bfd_get_arch_info (current_bfd);
1823 i = 0;
1824 while (current_bfd != NULL && i < orl_count)
1826 while (map[i].u.abfd == current_bfd)
1828 if (arch_info->bits_per_address == 32)
1830 string_length = sprintf (st, "%s", *map[i].name);
1831 st += string_length + 1;
1833 i++;
1835 current_bfd = current_bfd->next;
1836 if (current_bfd != NULL)
1837 arch_info = bfd_get_arch_info (current_bfd);
1840 bfd_bwrite (symbol_table, symbol_table_size, abfd);
1842 free (symbol_table);
1843 symbol_table = NULL;
1845 prevoff = nextoff;
1846 nextoff = nextoff + symbol_table_size;
1848 else
1849 PRINT20 (fhdr->symoff, 0);
1851 if (sym_64)
1853 struct xcoff_ar_hdr_big *hdr;
1854 bfd_byte *symbol_table;
1855 bfd_byte *st;
1856 file_ptr fileoff;
1858 bfd_vma symbol_table_size =
1859 SIZEOF_AR_HDR_BIG
1860 + SXCOFFARFMAG
1861 + 8
1862 + 8 * sym_64
1863 + str_64 + (str_64 & 1);
1865 symbol_table = NULL;
1866 symbol_table = (bfd_byte *) bfd_malloc (symbol_table_size);
1867 if (symbol_table == NULL)
1868 return false;
1869 memset (symbol_table, 0, symbol_table_size);
1871 hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1873 PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
1874 PRINT20 (hdr->nextoff, 0);
1875 PRINT20 (hdr->prevoff, prevoff);
1876 PRINT12 (hdr->date, 0);
1877 PRINT12 (hdr->uid, 0);
1878 PRINT12 (hdr->gid, 0);
1879 PRINT12 (hdr->mode, 0);
1880 PRINT4 (hdr->namlen, 0);
1882 st = symbol_table + SIZEOF_AR_HDR_BIG;
1883 memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1884 st += SXCOFFARFMAG;
1886 bfd_h_put_64 (abfd, sym_64, st);
1887 st += 8;
1889 /* loop over the 64 bit offsets */
1890 current_bfd = abfd->archive_head;
1891 if (current_bfd != NULL)
1892 arch_info = bfd_get_arch_info (current_bfd);
1893 fileoff = SIZEOF_AR_FILE_HDR_BIG;
1894 i = 0;
1895 while (current_bfd != NULL && i < orl_count)
1897 while (map[i].u.abfd == current_bfd)
1899 if (arch_info->bits_per_address == 64)
1901 bfd_h_put_64 (abfd, fileoff, st);
1902 st += 8;
1904 i++;
1906 string_length = strlen (normalize_filename (current_bfd));
1907 string_length += string_length & 1;
1908 fileoff += (SIZEOF_AR_HDR_BIG
1909 + string_length
1910 + SXCOFFARFMAG
1911 + arelt_size (current_bfd));
1912 fileoff += fileoff & 1;
1913 current_bfd = current_bfd->next;
1914 if (current_bfd != NULL)
1915 arch_info = bfd_get_arch_info (current_bfd);
1918 /* loop over the 64 bit symbol names */
1919 current_bfd = abfd->archive_head;
1920 if (current_bfd != NULL)
1921 arch_info = bfd_get_arch_info (current_bfd);
1922 i = 0;
1923 while (current_bfd != NULL && i < orl_count)
1925 while (map[i].u.abfd == current_bfd)
1927 if (arch_info->bits_per_address == 64)
1929 string_length = sprintf (st, "%s", *map[i].name);
1930 st += string_length + 1;
1932 i++;
1934 current_bfd = current_bfd->next;
1935 if (current_bfd != NULL)
1936 arch_info = bfd_get_arch_info (current_bfd);
1939 bfd_bwrite (symbol_table, symbol_table_size, abfd);
1941 free (symbol_table);
1942 symbol_table = NULL;
1944 PRINT20 (fhdr->symoff64, nextoff);
1946 else
1947 PRINT20 (fhdr->symoff64, 0);
1949 return true;
1952 boolean
1953 _bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
1954 bfd *abfd;
1955 unsigned int elength ATTRIBUTE_UNUSED;
1956 struct orl *map;
1957 unsigned int orl_count;
1958 int stridx;
1960 if (! xcoff_big_format_p (abfd))
1961 return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
1962 else
1963 return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
1966 /* Write out an XCOFF archive. We always write an entire archive,
1967 rather than fussing with the freelist and so forth. */
1969 static boolean
1970 xcoff_write_archive_contents_old (abfd)
1971 bfd *abfd;
1973 struct xcoff_ar_file_hdr fhdr;
1974 bfd_size_type count;
1975 bfd_size_type total_namlen;
1976 file_ptr *offsets;
1977 boolean makemap;
1978 boolean hasobjects;
1979 ufile_ptr prevoff, nextoff;
1980 bfd *sub;
1981 size_t i;
1982 struct xcoff_ar_hdr ahdr;
1983 bfd_size_type size;
1984 char *p;
1985 char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
1987 memset (&fhdr, 0, sizeof fhdr);
1988 strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
1989 sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
1990 sprintf (fhdr.freeoff, "%d", 0);
1992 count = 0;
1993 total_namlen = 0;
1994 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1996 ++count;
1997 total_namlen += strlen (normalize_filename (sub)) + 1;
1999 offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2000 if (offsets == NULL)
2001 return false;
2003 if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
2004 return false;
2006 makemap = bfd_has_map (abfd);
2007 hasobjects = false;
2008 prevoff = 0;
2009 nextoff = SIZEOF_AR_FILE_HDR;
2010 for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
2012 const char *name;
2013 bfd_size_type namlen;
2014 struct xcoff_ar_hdr *ahdrp;
2015 bfd_size_type remaining;
2017 if (makemap && ! hasobjects)
2019 if (bfd_check_format (sub, bfd_object))
2020 hasobjects = true;
2023 name = normalize_filename (sub);
2024 namlen = strlen (name);
2026 if (sub->arelt_data != NULL)
2027 ahdrp = arch_xhdr (sub);
2028 else
2029 ahdrp = NULL;
2031 if (ahdrp == NULL)
2033 struct stat s;
2035 memset (&ahdr, 0, sizeof ahdr);
2036 ahdrp = &ahdr;
2037 if (stat (bfd_get_filename (sub), &s) != 0)
2039 bfd_set_error (bfd_error_system_call);
2040 return false;
2043 sprintf (ahdrp->size, "%ld", (long) s.st_size);
2044 sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2045 sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2046 sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2047 sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2049 if (sub->arelt_data == NULL)
2051 size = sizeof (struct areltdata);
2052 sub->arelt_data = bfd_alloc (sub, size);
2053 if (sub->arelt_data == NULL)
2054 return false;
2057 arch_eltdata (sub)->parsed_size = s.st_size;
2060 sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2061 sprintf (ahdrp->namlen, "%ld", (long) namlen);
2063 /* If the length of the name is odd, we write out the null byte
2064 after the name as well. */
2065 namlen = (namlen + 1) &~ (bfd_size_type) 1;
2067 remaining = arelt_size (sub);
2068 size = (SIZEOF_AR_HDR
2069 + namlen
2070 + SXCOFFARFMAG
2071 + remaining);
2073 BFD_ASSERT (nextoff == bfd_tell (abfd));
2075 offsets[i] = nextoff;
2077 prevoff = nextoff;
2078 nextoff += size + (size & 1);
2080 sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
2082 /* We need spaces, not null bytes, in the header. */
2083 for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2084 if (*p == '\0')
2085 *p = ' ';
2087 if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2088 != SIZEOF_AR_HDR)
2089 || (bfd_bwrite ((PTR) name, namlen, abfd) != namlen)
2090 || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2091 != SXCOFFARFMAG))
2092 return false;
2094 if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
2095 return false;
2097 if (! do_copy (abfd, sub))
2098 return false;
2100 if (! do_pad (abfd, size & 1))
2101 return false;
2104 sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2106 /* Write out the member table. */
2108 BFD_ASSERT (nextoff == bfd_tell (abfd));
2109 sprintf (fhdr.memoff, "%ld", (long) nextoff);
2111 memset (&ahdr, 0, sizeof ahdr);
2112 sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE +
2113 count * XCOFFARMAG_ELEMENT_SIZE +
2114 total_namlen));
2115 sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2116 sprintf (ahdr.date, "%d", 0);
2117 sprintf (ahdr.uid, "%d", 0);
2118 sprintf (ahdr.gid, "%d", 0);
2119 sprintf (ahdr.mode, "%d", 0);
2120 sprintf (ahdr.namlen, "%d", 0);
2122 size = (SIZEOF_AR_HDR
2123 + XCOFFARMAG_ELEMENT_SIZE
2124 + count * XCOFFARMAG_ELEMENT_SIZE
2125 + total_namlen
2126 + SXCOFFARFMAG);
2128 prevoff = nextoff;
2129 nextoff += size + (size & 1);
2131 if (makemap && hasobjects)
2132 sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2133 else
2134 sprintf (ahdr.nextoff, "%d", 0);
2136 /* We need spaces, not null bytes, in the header. */
2137 for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2138 if (*p == '\0')
2139 *p = ' ';
2141 if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2142 != SIZEOF_AR_HDR)
2143 || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2144 != SXCOFFARFMAG))
2145 return false;
2147 sprintf (decbuf, "%-12ld", (long) count);
2148 if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
2149 != XCOFFARMAG_ELEMENT_SIZE)
2150 return false;
2151 for (i = 0; i < (size_t) count; i++)
2153 sprintf (decbuf, "%-12ld", (long) offsets[i]);
2154 if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
2155 abfd) != XCOFFARMAG_ELEMENT_SIZE)
2156 return false;
2158 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2160 const char *name;
2161 bfd_size_type namlen;
2163 name = normalize_filename (sub);
2164 namlen = strlen (name);
2165 if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
2166 return false;
2169 if (! do_pad (abfd, size & 1))
2170 return false;
2172 /* Write out the armap, if appropriate. */
2173 if (! makemap || ! hasobjects)
2174 sprintf (fhdr.symoff, "%d", 0);
2175 else
2177 BFD_ASSERT (nextoff == bfd_tell (abfd));
2178 sprintf (fhdr.symoff, "%ld", (long) nextoff);
2179 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2180 if (! _bfd_compute_and_write_armap (abfd, 0))
2181 return false;
2184 /* Write out the archive file header. */
2186 /* We need spaces, not null bytes, in the header. */
2187 for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2188 if (*p == '\0')
2189 *p = ' ';
2191 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2192 || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
2193 != SIZEOF_AR_FILE_HDR))
2194 return false;
2196 return true;
2199 static boolean
2200 xcoff_write_archive_contents_big (abfd)
2201 bfd *abfd;
2203 struct xcoff_ar_file_hdr_big fhdr;
2204 bfd_size_type count;
2205 bfd_size_type total_namlen;
2206 file_ptr *offsets;
2207 boolean makemap;
2208 boolean hasobjects;
2209 ufile_ptr prevoff, nextoff;
2210 bfd *current_bfd;
2211 size_t i;
2212 struct xcoff_ar_hdr_big *hdr, ahdr;
2213 bfd_size_type size;
2214 bfd_byte *member_table, *mt;
2215 bfd_vma member_table_size;
2217 memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
2218 memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
2220 if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
2221 return false;
2223 /* Calculate count and total_namlen. */
2224 makemap = bfd_has_map (abfd);
2225 hasobjects = false;
2226 for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
2227 current_bfd != NULL;
2228 current_bfd = current_bfd->next, count++)
2230 total_namlen += strlen (normalize_filename (current_bfd)) + 1;
2232 if (makemap
2233 && ! hasobjects
2234 && bfd_check_format (current_bfd, bfd_object))
2235 hasobjects = true;
2238 offsets = NULL;
2239 if (count)
2241 offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2242 if (offsets == NULL)
2243 return false;
2246 prevoff = 0;
2247 nextoff = SIZEOF_AR_FILE_HDR_BIG;
2248 for (current_bfd = abfd->archive_head, i = 0;
2249 current_bfd != NULL;
2250 current_bfd = current_bfd->next, i++)
2252 const char *name;
2253 bfd_size_type namlen;
2254 struct xcoff_ar_hdr_big *ahdrp;
2255 bfd_size_type remaining;
2257 name = normalize_filename (current_bfd);
2258 namlen = strlen (name);
2260 if (current_bfd->arelt_data != NULL)
2261 ahdrp = arch_xhdr_big (current_bfd);
2262 else
2263 ahdrp = NULL;
2265 if (ahdrp == NULL)
2267 struct stat s;
2269 ahdrp = &ahdr;
2270 /* XXX This should actually be a call to stat64 (at least on
2271 32-bit machines).
2272 XXX This call will fail if the original object is not found. */
2273 if (stat (bfd_get_filename (current_bfd), &s) != 0)
2275 bfd_set_error (bfd_error_system_call);
2276 return false;
2279 PRINT20 (ahdrp->size, s.st_size);
2280 PRINT12 (ahdrp->date, s.st_mtime);
2281 PRINT12 (ahdrp->uid, s.st_uid);
2282 PRINT12 (ahdrp->gid, s.st_gid);
2283 PRINT12_OCTAL (ahdrp->mode, s.st_mode);
2285 if (current_bfd->arelt_data == NULL)
2287 size = sizeof (struct areltdata);
2288 current_bfd->arelt_data = bfd_alloc (current_bfd, size);
2289 if (current_bfd->arelt_data == NULL)
2290 return false;
2293 arch_eltdata (current_bfd)->parsed_size = s.st_size;
2296 PRINT20 (ahdrp->prevoff, prevoff);
2297 PRINT4 (ahdrp->namlen, namlen);
2299 /* If the length of the name is odd, we write out the null byte
2300 after the name as well. */
2301 namlen = (namlen + 1) &~ (bfd_size_type) 1;
2303 remaining = arelt_size (current_bfd);
2304 size = (SIZEOF_AR_HDR_BIG
2305 + namlen
2306 + SXCOFFARFMAG
2307 + remaining);
2309 BFD_ASSERT (nextoff == bfd_tell (abfd));
2311 /* Check for xcoff shared objects.
2312 Their text section needs to be aligned wrt the archive file position.
2313 This requires extra padding before the archive header. */
2314 if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
2315 SIZEOF_AR_HDR_BIG + namlen
2316 + SXCOFFARFMAG))
2317 return false;
2319 offsets[i] = nextoff;
2321 prevoff = nextoff;
2322 nextoff += size + (size & 1);
2324 PRINT20 (ahdrp->nextoff, nextoff);
2326 if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
2327 != SIZEOF_AR_HDR_BIG)
2328 || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
2329 || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
2330 abfd) != SXCOFFARFMAG))
2331 return false;
2333 if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
2334 return false;
2336 if (! do_copy (abfd, current_bfd))
2337 return false;
2339 if (! do_pad (abfd, size & 1))
2340 return false;
2343 if (count)
2345 PRINT20 (fhdr.firstmemoff, offsets[0]);
2346 PRINT20 (fhdr.lastmemoff, prevoff);
2349 /* Write out the member table.
2350 Layout :
2352 standard big archive header
2353 0x0000 ar_size [0x14]
2354 0x0014 ar_nxtmem [0x14]
2355 0x0028 ar_prvmem [0x14]
2356 0x003C ar_date [0x0C]
2357 0x0048 ar_uid [0x0C]
2358 0x0054 ar_gid [0x0C]
2359 0x0060 ar_mod [0x0C]
2360 0x006C ar_namelen[0x04]
2361 0x0070 ar_fmag [0x02]
2363 Member table
2364 0x0072 count [0x14]
2365 0x0086 offsets [0x14 * counts]
2366 0x0086 + 0x14 * counts names [??]
2367 ?? pad to even bytes.
2370 BFD_ASSERT (nextoff == bfd_tell (abfd));
2372 member_table_size = (SIZEOF_AR_HDR_BIG
2373 + SXCOFFARFMAG
2374 + XCOFFARMAGBIG_ELEMENT_SIZE
2375 + count * XCOFFARMAGBIG_ELEMENT_SIZE
2376 + total_namlen);
2378 member_table_size += member_table_size & 1;
2379 member_table = NULL;
2380 member_table = (bfd_byte *) bfd_malloc (member_table_size);
2381 if (member_table == NULL)
2382 return false;
2383 memset (member_table, 0, member_table_size);
2385 hdr = (struct xcoff_ar_hdr_big *) member_table;
2387 PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE +
2388 count * XCOFFARMAGBIG_ELEMENT_SIZE +
2389 total_namlen + (total_namlen & 1)));
2390 if (makemap && hasobjects)
2391 PRINT20 (hdr->nextoff, nextoff + member_table_size);
2392 else
2393 PRINT20 (hdr->nextoff, 0);
2394 PRINT20 (hdr->prevoff, prevoff);
2395 PRINT12 (hdr->date, 0);
2396 PRINT12 (hdr->uid, 0);
2397 PRINT12 (hdr->gid, 0);
2398 PRINT12 (hdr->mode, 0);
2399 PRINT4 (hdr->namlen, 0);
2401 mt = member_table + SIZEOF_AR_HDR_BIG;
2402 memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
2403 mt += SXCOFFARFMAG;
2405 PRINT20 (mt, count);
2406 mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2407 for (i = 0; i < (size_t) count; i++)
2409 PRINT20 (mt, offsets[i]);
2410 mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2413 if (count)
2415 free (offsets);
2416 offsets = NULL;
2419 for (current_bfd = abfd->archive_head; current_bfd != NULL;
2420 current_bfd = current_bfd->next)
2422 const char *name;
2423 size_t namlen;
2425 name = normalize_filename (current_bfd);
2426 namlen = sprintf(mt, "%s", name);
2427 mt += namlen + 1;
2430 if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
2431 return false;
2433 free (member_table);
2434 member_table = NULL;
2436 PRINT20 (fhdr.memoff, nextoff);
2438 prevoff = nextoff;
2439 nextoff += member_table_size;
2441 /* Write out the armap, if appropriate. */
2443 if (! makemap || ! hasobjects)
2444 PRINT20 (fhdr.symoff, 0);
2445 else
2447 BFD_ASSERT (nextoff == bfd_tell (abfd));
2449 /* Save nextoff in fhdr.symoff so the armap routine can use it. */
2450 PRINT20 (fhdr.symoff, nextoff);
2452 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2453 if (! _bfd_compute_and_write_armap (abfd, 0))
2454 return false;
2457 /* Write out the archive file header. */
2459 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2460 || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
2461 abfd) != SIZEOF_AR_FILE_HDR_BIG))
2462 return false;
2464 return true;
2467 boolean
2468 _bfd_xcoff_write_archive_contents (abfd)
2469 bfd *abfd;
2471 if (! xcoff_big_format_p (abfd))
2472 return xcoff_write_archive_contents_old (abfd);
2473 else
2474 return xcoff_write_archive_contents_big (abfd);
2477 /* We can't use the usual coff_sizeof_headers routine, because AIX
2478 always uses an a.out header. */
2481 _bfd_xcoff_sizeof_headers (abfd, reloc)
2482 bfd *abfd;
2483 boolean reloc ATTRIBUTE_UNUSED;
2485 int size;
2487 size = FILHSZ;
2488 if (xcoff_data (abfd)->full_aouthdr)
2489 size += AOUTSZ;
2490 else
2491 size += SMALL_AOUTSZ;
2492 size += abfd->section_count * SCNHSZ;
2493 return size;
2496 /* Routines to swap information in the XCOFF .loader section. If we
2497 ever need to write an XCOFF loader, this stuff will need to be
2498 moved to another file shared by the linker (which XCOFF calls the
2499 ``binder'') and the loader. */
2501 /* Swap in the ldhdr structure. */
2503 static void
2504 xcoff_swap_ldhdr_in (abfd, s, dst)
2505 bfd *abfd;
2506 const PTR s;
2507 struct internal_ldhdr *dst;
2509 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
2511 dst->l_version = bfd_get_32 (abfd, src->l_version);
2512 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
2513 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
2514 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
2515 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
2516 dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
2517 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
2518 dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
2521 /* Swap out the ldhdr structure. */
2523 static void
2524 xcoff_swap_ldhdr_out (abfd, src, d)
2525 bfd *abfd;
2526 const struct internal_ldhdr *src;
2527 PTR d;
2529 struct external_ldhdr *dst = (struct external_ldhdr *) d;
2531 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
2532 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
2533 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
2534 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
2535 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
2536 bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
2537 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
2538 bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
2541 /* Swap in the ldsym structure. */
2543 static void
2544 xcoff_swap_ldsym_in (abfd, s, dst)
2545 bfd *abfd;
2546 const PTR s;
2547 struct internal_ldsym *dst;
2549 const struct external_ldsym *src = (const struct external_ldsym *) s;
2551 if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
2552 memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2553 } else {
2554 dst->_l._l_l._l_zeroes = 0;
2555 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
2557 dst->l_value = bfd_get_32 (abfd, src->l_value);
2558 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
2559 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
2560 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
2561 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
2562 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
2565 /* Swap out the ldsym structure. */
2567 static void
2568 xcoff_swap_ldsym_out (abfd, src, d)
2569 bfd *abfd;
2570 const struct internal_ldsym *src;
2571 PTR d;
2573 struct external_ldsym *dst = (struct external_ldsym *) d;
2575 if (src->_l._l_l._l_zeroes != 0)
2576 memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2577 else
2579 bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
2580 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
2581 dst->_l._l_l._l_offset);
2583 bfd_put_32 (abfd, src->l_value, dst->l_value);
2584 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
2585 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
2586 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
2587 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
2588 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
2591 /* Swap in the ldrel structure. */
2593 static void
2594 xcoff_swap_ldrel_in (abfd, s, dst)
2595 bfd *abfd;
2596 const PTR s;
2597 struct internal_ldrel *dst;
2599 const struct external_ldrel *src = (const struct external_ldrel *) s;
2601 dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
2602 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
2603 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
2604 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
2607 /* Swap out the ldrel structure. */
2609 static void
2610 xcoff_swap_ldrel_out (abfd, src, d)
2611 bfd *abfd;
2612 const struct internal_ldrel *src;
2613 PTR d;
2615 struct external_ldrel *dst = (struct external_ldrel *) d;
2617 bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
2618 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
2619 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
2620 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
2625 /* This is the relocation function for the RS/6000/POWER/PowerPC.
2626 This is currently the only processor which uses XCOFF; I hope that
2627 will never change. */
2629 static boolean
2630 xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
2631 input_section, contents, relocs, syms,
2632 sections)
2633 bfd *output_bfd;
2634 struct bfd_link_info *info;
2635 bfd *input_bfd;
2636 asection *input_section;
2637 bfd_byte *contents;
2638 struct internal_reloc *relocs;
2639 struct internal_syment *syms;
2640 asection **sections;
2642 struct internal_reloc *rel;
2643 struct internal_reloc *relend;
2645 rel = relocs;
2646 relend = rel + input_section->reloc_count;
2648 for (; rel < relend; rel++)
2650 long symndx;
2651 struct xcoff_link_hash_entry *h;
2652 struct internal_syment *sym;
2653 bfd_vma addend;
2654 bfd_vma val;
2655 struct reloc_howto_struct howto;
2656 bfd_reloc_status_type rstat;
2658 /* Relocation type R_REF is a special relocation type which is
2659 merely used to prevent garbage collection from occurring for
2660 the csect including the symbol which it references. */
2661 if (rel->r_type == R_REF)
2662 continue;
2664 symndx = rel->r_symndx;
2666 if (symndx == -1)
2668 h = NULL;
2669 sym = NULL;
2670 addend = 0;
2672 else
2674 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
2675 sym = syms + symndx;
2676 addend = - sym->n_value;
2680 /* We build the howto information on the fly. */
2682 howto.type = rel->r_type;
2683 howto.rightshift = 0;
2684 howto.size = 2;
2685 howto.bitsize = (rel->r_size & 0x1f) + 1;
2686 howto.pc_relative = false;
2687 howto.bitpos = 0;
2688 if ((rel->r_size & 0x80) != 0)
2689 howto.complain_on_overflow = complain_overflow_signed;
2690 else
2691 howto.complain_on_overflow = complain_overflow_bitfield;
2692 howto.special_function = NULL;
2693 howto.name = "internal";
2694 howto.partial_inplace = true;
2695 if (howto.bitsize == 32)
2696 howto.src_mask = howto.dst_mask = 0xffffffff;
2697 else
2699 howto.src_mask = howto.dst_mask = (1 << howto.bitsize) - 1;
2700 if (howto.bitsize == 16)
2701 howto.size = 1;
2703 howto.pcrel_offset = false;
2705 val = 0;
2707 if (h == NULL)
2709 asection *sec;
2711 if (symndx == -1)
2713 sec = bfd_abs_section_ptr;
2714 val = 0;
2716 else
2718 sec = sections[symndx];
2719 /* Hack to make sure we use the right TOC anchor value
2720 if this reloc is against the TOC anchor. */
2722 if (sec->name[3] == '0'
2723 && strcmp (sec->name, ".tc0") == 0)
2725 val = xcoff_data (output_bfd)->toc;
2727 else
2729 val = (sec->output_section->vma
2730 + sec->output_offset
2731 + sym->n_value
2732 - sec->vma);
2736 else
2738 if (h->root.type == bfd_link_hash_defined
2739 || h->root.type == bfd_link_hash_defweak)
2741 asection *sec;
2743 sec = h->root.u.def.section;
2744 val = (h->root.u.def.value
2745 + sec->output_section->vma
2746 + sec->output_offset);
2748 else if (h->root.type == bfd_link_hash_common)
2750 asection *sec;
2752 sec = h->root.u.c.p->section;
2753 val = (sec->output_section->vma
2754 + sec->output_offset);
2756 else if ((h->flags & XCOFF_DEF_DYNAMIC) != 0
2757 || (h->flags & XCOFF_IMPORT) != 0)
2759 /* Every symbol in a shared object is defined somewhere. */
2760 val = 0;
2762 else if (! info->relocateable)
2764 if (! ((*info->callbacks->undefined_symbol)
2765 (info, h->root.root.string, input_bfd, input_section,
2766 rel->r_vaddr - input_section->vma, true)))
2767 return false;
2769 /* Don't try to process the reloc. It can't help, and
2770 it may generate another error. */
2771 continue;
2775 /* I took the relocation type definitions from two documents:
2776 the PowerPC AIX Version 4 Application Binary Interface, First
2777 Edition (April 1992), and the PowerOpen ABI, Big-Endian
2778 32-Bit Hardware Implementation (June 30, 1994). Differences
2779 between the documents are noted below. */
2781 switch (rel->r_type)
2783 case R_RTB:
2784 case R_RRTBI:
2785 case R_RRTBA:
2786 /* These relocs are defined by the PowerPC ABI to be
2787 relative branches which use half of the difference
2788 between the symbol and the program counter. I can't
2789 quite figure out when this is useful. These relocs are
2790 not defined by the PowerOpen ABI. */
2791 default:
2792 (*_bfd_error_handler)
2793 (_("%s: unsupported relocation type 0x%02x"),
2794 bfd_archive_filename (input_bfd), (unsigned int) rel->r_type);
2795 bfd_set_error (bfd_error_bad_value);
2796 return false;
2797 case R_POS:
2798 /* Simple positive relocation. */
2799 break;
2800 case R_NEG:
2801 /* Simple negative relocation. */
2802 val = - val;
2803 break;
2804 case R_REL:
2805 /* Simple PC relative relocation. */
2806 howto.pc_relative = true;
2807 break;
2808 case R_TOC:
2809 /* TOC relative relocation. The value in the instruction in
2810 the input file is the offset from the input file TOC to
2811 the desired location. We want the offset from the final
2812 TOC to the desired location. We have:
2813 isym = iTOC + in
2814 iinsn = in + o
2815 osym = oTOC + on
2816 oinsn = on + o
2817 so we must change insn by on - in.
2819 case R_GL:
2820 /* Global linkage relocation. The value of this relocation
2821 is the address of the entry in the TOC section. */
2822 case R_TCL:
2823 /* Local object TOC address. I can't figure out the
2824 difference between this and case R_GL. */
2825 case R_TRL:
2826 /* TOC relative relocation. A TOC relative load instruction
2827 which may be changed to a load address instruction.
2828 FIXME: We don't currently implement this optimization. */
2829 case R_TRLA:
2830 /* TOC relative relocation. This is a TOC relative load
2831 address instruction which may be changed to a load
2832 instruction. FIXME: I don't know if this is the correct
2833 implementation. */
2834 if (h != NULL && h->smclas != XMC_TD)
2836 if (h->toc_section == NULL)
2838 (*_bfd_error_handler)
2839 (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
2840 bfd_archive_filename (input_bfd), rel->r_vaddr,
2841 h->root.root.string);
2842 bfd_set_error (bfd_error_bad_value);
2843 return false;
2846 BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
2847 val = (h->toc_section->output_section->vma
2848 + h->toc_section->output_offset);
2851 val = ((val - xcoff_data (output_bfd)->toc)
2852 - (sym->n_value - xcoff_data (input_bfd)->toc));
2853 addend = 0;
2854 break;
2855 case R_BA:
2856 /* Absolute branch. We don't want to mess with the lower
2857 two bits of the instruction. */
2858 case R_CAI:
2859 /* The PowerPC ABI defines this as an absolute call which
2860 may be modified to become a relative call. The PowerOpen
2861 ABI does not define this relocation type. */
2862 case R_RBA:
2863 /* Absolute branch which may be modified to become a
2864 relative branch. */
2865 case R_RBAC:
2866 /* The PowerPC ABI defines this as an absolute branch to a
2867 fixed address which may be modified to an absolute branch
2868 to a symbol. The PowerOpen ABI does not define this
2869 relocation type. */
2870 case R_RBRC:
2871 /* The PowerPC ABI defines this as an absolute branch to a
2872 fixed address which may be modified to a relative branch.
2873 The PowerOpen ABI does not define this relocation type. */
2874 howto.src_mask &= ~3;
2875 howto.dst_mask = howto.src_mask;
2876 break;
2877 case R_BR:
2878 /* Relative branch. We don't want to mess with the lower
2879 two bits of the instruction. */
2880 case R_CREL:
2881 /* The PowerPC ABI defines this as a relative call which may
2882 be modified to become an absolute call. The PowerOpen
2883 ABI does not define this relocation type. */
2884 case R_RBR:
2885 /* A relative branch which may be modified to become an
2886 absolute branch. FIXME: We don't implement this,
2887 although we should for symbols of storage mapping class
2888 XMC_XO. */
2889 howto.pc_relative = true;
2890 howto.src_mask &= ~3;
2891 howto.dst_mask = howto.src_mask;
2892 break;
2893 case R_RL:
2894 /* The PowerPC AIX ABI describes this as a load which may be
2895 changed to a load address. The PowerOpen ABI says this
2896 is the same as case R_POS. */
2897 break;
2898 case R_RLA:
2899 /* The PowerPC AIX ABI describes this as a load address
2900 which may be changed to a load. The PowerOpen ABI says
2901 this is the same as R_POS. */
2902 break;
2905 /* If we see an R_BR or R_RBR reloc which is jumping to global
2906 linkage code, and it is followed by an appropriate cror nop
2907 instruction, we replace the cror with lwz r2,20(r1). This
2908 restores the TOC after the glink code. Contrariwise, if the
2909 call is followed by a lwz r2,20(r1), but the call is not
2910 going to global linkage code, we can replace the load with a
2911 cror. */
2912 if ((rel->r_type == R_BR || rel->r_type == R_RBR)
2913 && h != NULL
2914 && h->root.type == bfd_link_hash_defined
2915 && (rel->r_vaddr - input_section->vma + 8
2916 <= input_section->_cooked_size))
2918 bfd_byte *pnext;
2919 unsigned long next;
2921 pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
2922 next = bfd_get_32 (input_bfd, pnext);
2924 /* The _ptrgl function is magic. It is used by the AIX
2925 compiler to call a function through a pointer. */
2926 if (h->smclas == XMC_GL
2927 || strcmp (h->root.root.string, "._ptrgl") == 0)
2929 if (next == 0x4def7b82 /* cror 15,15,15 */
2930 || next == 0x4ffffb82 /* cror 31,31,31 */
2931 || next == 0x60000000) /* ori r0,r0,0 */
2932 bfd_put_32 (input_bfd,
2933 (bfd_vma) 0x80410014, /* lwz r1,20(r1) */
2934 pnext);
2936 else
2938 if (next == 0x80410014) /* lwz r1,20(r1) */
2939 bfd_put_32 (input_bfd,
2940 (bfd_vma) 0x60000000, /* ori r0,r0,0 */
2941 pnext);
2945 /* A PC relative reloc includes the section address. */
2946 if (howto.pc_relative)
2947 addend += input_section->vma;
2949 rstat = _bfd_final_link_relocate (&howto, input_bfd, input_section,
2950 contents,
2951 rel->r_vaddr - input_section->vma,
2952 val, addend);
2954 switch (rstat)
2956 default:
2957 abort ();
2958 case bfd_reloc_ok:
2959 break;
2960 case bfd_reloc_overflow:
2962 const char *name;
2963 char buf[SYMNMLEN + 1];
2964 char howto_name[10];
2966 if (symndx == -1)
2967 name = "*ABS*";
2968 else if (h != NULL)
2969 name = h->root.root.string;
2970 else
2972 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
2974 if (name == NULL)
2975 return false;
2977 sprintf (howto_name, "0x%02x", rel->r_type);
2979 if (! ((*info->callbacks->reloc_overflow)
2980 (info, name, howto_name, (bfd_vma) 0, input_bfd,
2981 input_section, rel->r_vaddr - input_section->vma)))
2982 return false;
2987 return true;
2990 static boolean
2991 _bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
2992 bfd *abfd ATTRIBUTE_UNUSED;
2993 struct xcoff_loader_info *ldinfo;
2994 struct internal_ldsym *ldsym;
2995 const char *name;
2997 size_t len;
2998 len = strlen (name);
3000 if (len <= SYMNMLEN)
3001 strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3002 else
3004 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3006 bfd_size_type newalc;
3007 bfd_byte *newstrings;
3009 newalc = ldinfo->string_alc * 2;
3010 if (newalc == 0)
3011 newalc = 32;
3012 while (ldinfo->string_size + len + 3 > newalc)
3013 newalc *= 2;
3015 newstrings = ((bfd_byte *)
3016 bfd_realloc ((PTR) ldinfo->strings, newalc));
3017 if (newstrings == NULL)
3019 ldinfo->failed = true;
3020 return false;
3022 ldinfo->string_alc = newalc;
3023 ldinfo->strings = newstrings;
3026 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3027 ldinfo->strings + ldinfo->string_size);
3028 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3029 ldsym->_l._l_l._l_zeroes = 0;
3030 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3031 ldinfo->string_size += len + 3;
3034 return true;
3037 static boolean
3038 _bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
3039 struct internal_syment *sym,
3040 const char *name)
3042 if (strlen (name) <= SYMNMLEN)
3044 strncpy (sym->_n._n_name, name, SYMNMLEN);
3046 else
3048 boolean hash;
3049 bfd_size_type indx;
3051 hash = true;
3052 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
3053 hash = false;
3054 indx = _bfd_stringtab_add (strtab, name, hash, false);
3055 if (indx == (bfd_size_type) -1)
3056 return false;
3057 sym->_n._n_n._n_zeroes = 0;
3058 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3060 return true;
3063 static asection *
3064 xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
3065 bfd *abfd;
3066 union internal_auxent *aux;
3067 const char *symbol_name;
3069 asection *return_value = NULL;
3071 /* .sv64 = x_smclas == 17
3072 This is an invalid csect for 32 bit apps. */
3073 static const char *names[19] =
3075 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
3076 ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
3077 ".td", NULL, ".sv3264"
3080 if ((19 >= aux->x_csect.x_smclas) &&
3081 (NULL != names[aux->x_csect.x_smclas]))
3083 return_value = bfd_make_section_anyway
3084 (abfd, names[aux->x_csect.x_smclas]);
3086 else
3088 (*_bfd_error_handler)
3089 (_("%s: symbol `%s' has unrecognized smclas %d"),
3090 bfd_archive_filename (abfd), symbol_name, aux->x_csect.x_smclas);
3091 bfd_set_error (bfd_error_bad_value);
3094 return return_value;
3097 static boolean
3098 xcoff_is_lineno_count_overflow (abfd, value)
3099 bfd *abfd ATTRIBUTE_UNUSED;
3100 bfd_vma value;
3102 if (0xffff <= value)
3103 return true;
3105 return false;
3108 static boolean
3109 xcoff_is_reloc_count_overflow (abfd, value)
3110 bfd *abfd ATTRIBUTE_UNUSED;
3111 bfd_vma value;
3113 if (0xffff <= value)
3114 return true;
3116 return false;
3119 static bfd_vma
3120 xcoff_loader_symbol_offset (abfd, ldhdr)
3121 bfd *abfd;
3122 struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
3124 return bfd_xcoff_ldhdrsz(abfd);
3127 static bfd_vma
3128 xcoff_loader_reloc_offset (abfd, ldhdr)
3129 bfd *abfd;
3130 struct internal_ldhdr *ldhdr;
3132 return bfd_xcoff_ldhdrsz(abfd) +
3133 (ldhdr->l_nsyms * bfd_xcoff_ldsymsz(abfd));
3136 static boolean
3137 xcoff_generate_rtinit (abfd, init, fini, rtld)
3138 bfd *abfd;
3139 const char *init;
3140 const char *fini;
3141 boolean rtld;
3143 bfd_byte filehdr_ext[FILHSZ];
3144 bfd_byte scnhdr_ext[SCNHSZ];
3145 bfd_byte syment_ext[SYMESZ * 10];
3146 bfd_byte reloc_ext[RELSZ * 3];
3147 bfd_byte *data_buffer;
3148 bfd_size_type data_buffer_size;
3149 bfd_byte *string_table = NULL, *st_tmp = NULL;
3150 bfd_size_type string_table_size;
3151 bfd_vma val;
3152 size_t initsz, finisz;
3153 struct internal_filehdr filehdr;
3154 struct internal_scnhdr scnhdr;
3155 struct internal_syment syment;
3156 union internal_auxent auxent;
3157 struct internal_reloc reloc;
3159 char *data_name = ".data";
3160 char *rtinit_name = "__rtinit";
3161 char *rtld_name = "__rtld";
3163 if (! bfd_xcoff_rtinit_size (abfd))
3164 return false;
3166 initsz = (init == NULL ? 0 : 1 + strlen (init));
3167 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3169 /* file header */
3170 memset (filehdr_ext, 0, FILHSZ);
3171 memset (&filehdr, 0, sizeof (struct internal_filehdr));
3172 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
3173 filehdr.f_nscns = 1;
3174 filehdr.f_timdat = 0;
3175 filehdr.f_nsyms = 0; /* at least 6, no more than 10 */
3176 filehdr.f_symptr = 0; /* set below */
3177 filehdr.f_opthdr = 0;
3178 filehdr.f_flags = 0;
3180 /* section header */
3181 memset (scnhdr_ext, 0, SCNHSZ);
3182 memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3183 memcpy (scnhdr.s_name, data_name, strlen (data_name));
3184 scnhdr.s_paddr = 0;
3185 scnhdr.s_vaddr = 0;
3186 scnhdr.s_size = 0; /* set below */
3187 scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3188 scnhdr.s_relptr = 0; /* set below */
3189 scnhdr.s_lnnoptr = 0;
3190 scnhdr.s_nreloc = 0; /* either 1 or 2 */
3191 scnhdr.s_nlnno = 0;
3192 scnhdr.s_flags = STYP_DATA;
3194 /* .data
3195 0x0000 0x00000000 : rtl
3196 0x0004 0x00000010 : offset to init, or 0
3197 0x0008 0x00000028 : offset to fini, or 0
3198 0x000C 0x0000000C : size of descriptor
3199 0x0010 0x00000000 : init, needs a reloc
3200 0x0014 0x00000040 : offset to init name
3201 0x0018 0x00000000 : flags, padded to a word
3202 0x001C 0x00000000 : empty init
3203 0x0020 0x00000000 :
3204 0x0024 0x00000000 :
3205 0x0028 0x00000000 : fini, needs a reloc
3206 0x002C 0x00000??? : offset to fini name
3207 0x0030 0x00000000 : flags, padded to a word
3208 0x0034 0x00000000 : empty fini
3209 0x0038 0x00000000 :
3210 0x003C 0x00000000 :
3211 0x0040 init name
3212 0x0040 + initsz fini name */
3214 data_buffer_size = 0x0040 + initsz + finisz;
3215 data_buffer_size += (data_buffer_size & 7) ? 8 - (data_buffer_size & 7) : 0;
3216 data_buffer = NULL;
3217 data_buffer = (bfd_byte *) bfd_malloc (data_buffer_size);
3218 if (data_buffer == NULL)
3219 return false;
3221 memset (data_buffer, 0, data_buffer_size);
3223 if (initsz)
3225 val = 0x10;
3226 bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
3227 val = 0x40;
3228 bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
3229 memcpy (&data_buffer[val], init, initsz);
3232 if (finisz)
3234 val = 0x28;
3235 bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
3236 val = 0x40 + initsz;
3237 bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
3238 memcpy (&data_buffer[val], fini, finisz);
3241 val = 0x0C;
3242 bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
3244 scnhdr.s_size = data_buffer_size;
3246 /* string table */
3247 string_table_size = 0;
3248 if (initsz > 9)
3249 string_table_size += initsz;
3250 if (finisz > 9)
3251 string_table_size += finisz;
3252 if (string_table_size)
3254 string_table_size += 4;
3255 string_table = (bfd_byte *)bfd_malloc (string_table_size);
3256 memset (string_table, 0, string_table_size);
3257 val = string_table_size;
3258 bfd_h_put_32 (abfd, val, &string_table[0]);
3259 st_tmp = string_table + 4;
3262 /* symbols
3263 0. .data csect
3264 2. __rtinit
3265 4. init function
3266 6. fini function
3267 8. __rtld */
3268 memset (syment_ext, 0, 10 * SYMESZ);
3269 memset (reloc_ext, 0, 3 * RELSZ);
3271 /* .data csect */
3272 memset (&syment, 0, sizeof (struct internal_syment));
3273 memset (&auxent, 0, sizeof (union internal_auxent));
3274 memcpy (syment._n._n_name, data_name, strlen (data_name));
3275 syment.n_scnum = 1;
3276 syment.n_sclass = C_HIDEXT;
3277 syment.n_numaux = 1;
3278 auxent.x_csect.x_scnlen.l = data_buffer_size;
3279 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
3280 auxent.x_csect.x_smclas = XMC_RW;
3281 bfd_coff_swap_sym_out (abfd, &syment,
3282 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3283 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3284 syment.n_numaux,
3285 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3286 filehdr.f_nsyms += 2;
3288 /* __rtinit */
3289 memset (&syment, 0, sizeof (struct internal_syment));
3290 memset (&auxent, 0, sizeof (union internal_auxent));
3291 memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
3292 syment.n_scnum = 1;
3293 syment.n_sclass = C_EXT;
3294 syment.n_numaux = 1;
3295 auxent.x_csect.x_smtyp = XTY_LD;
3296 auxent.x_csect.x_smclas = XMC_RW;
3297 bfd_coff_swap_sym_out (abfd, &syment,
3298 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3299 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3300 syment.n_numaux,
3301 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3302 filehdr.f_nsyms += 2;
3304 /* init */
3305 if (initsz)
3307 memset (&syment, 0, sizeof (struct internal_syment));
3308 memset (&auxent, 0, sizeof (union internal_auxent));
3310 if (initsz > 9)
3312 syment._n._n_n._n_offset = st_tmp - string_table;
3313 memcpy (st_tmp, init, initsz);
3314 st_tmp += initsz;
3316 else
3317 memcpy (syment._n._n_name, init, initsz - 1);
3319 syment.n_sclass = C_EXT;
3320 syment.n_numaux = 1;
3321 bfd_coff_swap_sym_out (abfd, &syment,
3322 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3323 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3324 syment.n_numaux,
3325 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3327 /* reloc */
3328 memset (&reloc, 0, sizeof (struct internal_reloc));
3329 reloc.r_vaddr = 0x0010;
3330 reloc.r_symndx = filehdr.f_nsyms;
3331 reloc.r_type = R_POS;
3332 reloc.r_size = 31;
3333 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
3335 filehdr.f_nsyms += 2;
3336 scnhdr.s_nreloc += 1;
3339 /* fini */
3340 if (finisz)
3342 memset (&syment, 0, sizeof (struct internal_syment));
3343 memset (&auxent, 0, sizeof (union internal_auxent));
3345 if (finisz > 9)
3347 syment._n._n_n._n_offset = st_tmp - string_table;
3348 memcpy (st_tmp, fini, finisz);
3349 st_tmp += finisz;
3351 else
3352 memcpy (syment._n._n_name, fini, finisz - 1);
3354 syment.n_sclass = C_EXT;
3355 syment.n_numaux = 1;
3356 bfd_coff_swap_sym_out (abfd, &syment,
3357 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3358 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3359 syment.n_numaux,
3360 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3362 /* reloc */
3363 memset (&reloc, 0, sizeof (struct internal_reloc));
3364 reloc.r_vaddr = 0x0028;
3365 reloc.r_symndx = filehdr.f_nsyms;
3366 reloc.r_type = R_POS;
3367 reloc.r_size = 31;
3368 bfd_coff_swap_reloc_out (abfd, &reloc,
3369 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3371 filehdr.f_nsyms += 2;
3372 scnhdr.s_nreloc += 1;
3375 if (rtld)
3377 memset (&syment, 0, sizeof (struct internal_syment));
3378 memset (&auxent, 0, sizeof (union internal_auxent));
3379 memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
3380 syment.n_sclass = C_EXT;
3381 syment.n_numaux = 1;
3382 bfd_coff_swap_sym_out (abfd, &syment,
3383 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3384 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3385 syment.n_numaux,
3386 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3388 /* reloc */
3389 memset (&reloc, 0, sizeof (struct internal_reloc));
3390 reloc.r_vaddr = 0x0000;
3391 reloc.r_symndx = filehdr.f_nsyms;
3392 reloc.r_type = R_POS;
3393 reloc.r_size = 31;
3394 bfd_coff_swap_reloc_out (abfd, &reloc,
3395 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3397 filehdr.f_nsyms += 2;
3398 scnhdr.s_nreloc += 1;
3401 scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
3402 filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
3404 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
3405 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
3406 bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
3407 bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
3408 bfd_bwrite (data_buffer, data_buffer_size, abfd);
3409 bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
3410 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
3411 bfd_bwrite (string_table, string_table_size, abfd);
3413 free (data_buffer);
3414 data_buffer = NULL;
3416 return true;
3420 static reloc_howto_type xcoff_dynamic_reloc =
3421 HOWTO (0, /* type */
3422 0, /* rightshift */
3423 2, /* size (0 = byte, 1 = short, 2 = long) */
3424 32, /* bitsize */
3425 false, /* pc_relative */
3426 0, /* bitpos */
3427 complain_overflow_bitfield, /* complain_on_overflow */
3428 0, /* special_function */
3429 "R_POS", /* name */
3430 true, /* partial_inplace */
3431 0xffffffff, /* src_mask */
3432 0xffffffff, /* dst_mask */
3433 false); /* pcrel_offset */
3435 /* glink
3437 The first word of global linkage code must be modified by filling in
3438 the correct TOC offset. */
3440 static unsigned long xcoff_glink_code[9] =
3442 0x81820000, /* lwz r12,0(r2) */
3443 0x90410014, /* stw r2,20(r1) */
3444 0x800c0000, /* lwz r0,0(r12) */
3445 0x804c0004, /* lwz r2,4(r12) */
3446 0x7c0903a6, /* mtctr r0 */
3447 0x4e800420, /* bctr */
3448 0x00000000, /* start of traceback table */
3449 0x000c8000, /* traceback table */
3450 0x00000000, /* traceback table */
3454 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
3456 { /* COFF backend, defined in libcoff.h. */
3457 _bfd_xcoff_swap_aux_in, /* _bfd_coff_swap_aux_in */
3458 _bfd_xcoff_swap_sym_in, /* _bfd_coff_swap_sym_in */
3459 coff_swap_lineno_in, /* _bfd_coff_swap_lineno_in */
3460 _bfd_xcoff_swap_aux_out, /* _bfd_swap_aux_out */
3461 _bfd_xcoff_swap_sym_out, /* _bfd_swap_sym_out */
3462 coff_swap_lineno_out, /* _bfd_swap_lineno_out */
3463 coff_swap_reloc_out, /* _bfd_swap_reloc_out */
3464 coff_swap_filehdr_out, /* _bfd_swap_filehdr_out */
3465 coff_swap_aouthdr_out, /* _bfd_swap_aouthdr_out */
3466 coff_swap_scnhdr_out, /* _bfd_swap_scnhdr_out */
3467 FILHSZ, /* _bfd_filhsz */
3468 AOUTSZ, /* _bfd_aoutsz */
3469 SCNHSZ, /* _bfd_scnhsz */
3470 SYMESZ, /* _bfd_symesz */
3471 AUXESZ, /* _bfd_auxesz */
3472 RELSZ, /* _bfd_relsz */
3473 LINESZ, /* _bfd_linesz */
3474 FILNMLEN, /* _bfd_filnmlen */
3475 true, /* _bfd_coff_long_filenames */
3476 false, /* _bfd_coff_long_section_names */
3477 (3), /* _bfd_coff_default_section_alignment_power */
3478 false, /* _bfd_coff_force_symnames_in_strings */
3479 2, /* _bfd_coff_debug_string_prefix_length */
3480 coff_swap_filehdr_in, /* _bfd_coff_swap_filehdr_in */
3481 coff_swap_aouthdr_in, /* _bfd_swap_aouthdr_in */
3482 coff_swap_scnhdr_in, /* _bfd_swap_scnhdr_in */
3483 coff_swap_reloc_in, /* _bfd_reloc_in */
3484 coff_bad_format_hook, /* _bfd_bad_format_hook */
3485 coff_set_arch_mach_hook, /* _bfd_set_arch_mach_hook */
3486 coff_mkobject_hook, /* _bfd_mkobject_hook */
3487 styp_to_sec_flags, /* _bfd_syp_to_sec_flags */
3488 coff_set_alignment_hook, /* _bfd_set_alignment_hook */
3489 coff_slurp_symbol_table, /* _bfd_coff_slurp_symbol_table */
3490 symname_in_debug_hook, /* _coff_symname_in_debug_hook */
3491 coff_pointerize_aux_hook, /* _bfd_coff_pointerize_aux_hook */
3492 coff_print_aux, /* bfd_coff_print_aux */
3493 dummy_reloc16_extra_cases, /* _bfd_coff_reloc16_extra_cases */
3494 dummy_reloc16_estimate, /* _bfd_coff_reloc16_estimate */
3495 NULL, /* bfd_coff_sym_is_global */
3496 coff_compute_section_file_positions, /* _bfd_coff_compute_section_file_positions */
3497 NULL, /* _bfd_coff_start_final_link */
3498 xcoff_ppc_relocate_section, /* _bfd_coff_relocate_section */
3499 coff_rtype_to_howto, /* _bfd_coff_rtype_to_howto */
3500 NULL, /* _bfd_coff_addust_symndx */
3501 _bfd_generic_link_add_one_symbol, /* _bfd_coff_add_one_symbol */
3502 coff_link_output_has_begun, /* _bfd_coff_link_output_has_begun */
3503 coff_final_link_postscript /* _bfd_coff_final_link_postscript */
3506 0x01DF, /* magic number */
3507 bfd_arch_rs6000, /* architecture */
3508 bfd_mach_rs6k, /* machine */
3510 /* Function pointers to xcoff specific swap routines. */
3511 xcoff_swap_ldhdr_in, /* _xcoff_swap_ldhdr_in */
3512 xcoff_swap_ldhdr_out, /* _xcoff_swap_ldhdr_out */
3513 xcoff_swap_ldsym_in, /* _xcoff_swap_ldsym_in */
3514 xcoff_swap_ldsym_out, /* _xcoff_swap_ldsym_out */
3515 xcoff_swap_ldrel_in, /* _xcoff_swap_ldrel_in */
3516 xcoff_swap_ldrel_out, /* _xcoff_swap_ldrel_out */
3518 /* Sizes. */
3519 LDHDRSZ, /* _xcoff_ldhdrsz */
3520 LDSYMSZ, /* _xcoff_ldsymsz */
3521 LDRELSZ, /* _xcoff_ldrelsz */
3522 12, /* _xcoff_function_descriptor_size */
3523 SMALL_AOUTSZ, /* _xcoff_small_aout_header_size */
3525 /* Versions. */
3526 1, /* _xcoff_ldhdr_version */
3528 _bfd_xcoff_put_symbol_name, /* _xcoff_put_symbol_name */
3529 _bfd_xcoff_put_ldsymbol_name, /* _xcoff_put_ldsymbol_name */
3530 & xcoff_dynamic_reloc, /* dynamic reloc howto */
3531 xcoff_create_csect_from_smclas, /* _xcoff_create_csect_from_smclas */
3533 /* Lineno and reloc count overflow. */
3534 xcoff_is_lineno_count_overflow,
3535 xcoff_is_reloc_count_overflow,
3537 xcoff_loader_symbol_offset,
3538 xcoff_loader_reloc_offset,
3540 /* glink. */
3541 & xcoff_glink_code[0],
3542 (36), /* _xcoff_glink_size */
3544 /* rtinit */
3545 64, /* _xcoff_rtinit_size */
3546 xcoff_generate_rtinit, /* _xcoff_generate_rtinit */
3549 /* The transfer vector that leads the outside world to all of the above. */
3550 const bfd_target rs6000coff_vec =
3552 "aixcoff-rs6000",
3553 bfd_target_xcoff_flavour,
3554 BFD_ENDIAN_BIG, /* data byte order is big */
3555 BFD_ENDIAN_BIG, /* header byte order is big */
3557 (HAS_RELOC | EXEC_P | /* object flags */
3558 HAS_LINENO | HAS_DEBUG | DYNAMIC |
3559 HAS_SYMS | HAS_LOCALS | WP_TEXT),
3561 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
3562 0, /* leading char */
3563 '/', /* ar_pad_char */
3564 15, /* ar_max_namelen??? FIXMEmgo */
3566 /* data */
3567 bfd_getb64, /* bfd_getx64 */
3568 bfd_getb_signed_64, /* bfd_getx_signed_64 */
3569 bfd_putb64, /* bfd_putx64 */
3570 bfd_getb32, /* bfd_getx32 */
3571 bfd_getb_signed_32, /* bfd_getx_signed_32 */
3572 bfd_putb32, /* bfd_putx32 */
3573 bfd_getb16, /* bfd_getx16 */
3574 bfd_getb_signed_16, /* bfd_getx_signed_16 */
3575 bfd_putb16, /* bfd_putx16 */
3577 /* hdrs */
3578 bfd_getb64, /* bfd_h_getx64 */
3579 bfd_getb_signed_64, /* bfd_h_getx_signed_64 */
3580 bfd_putb64, /* bfd_h_putx64 */
3581 bfd_getb32, /* bfd_h_getx32 */
3582 bfd_getb_signed_32, /* bfd_h_getx_signed_32 */
3583 bfd_putb32, /* bfd_h_putx32 */
3584 bfd_getb16, /* bfd_h_getx16 */
3585 bfd_getb_signed_16, /* bfd_h_getx_signed_16 */
3586 bfd_putb16, /* bfd_h_putx16 */
3588 { /* bfd_check_format */
3589 _bfd_dummy_target,
3590 coff_object_p,
3591 _bfd_xcoff_archive_p,
3592 CORE_FILE_P
3595 { /* bfd_set_format */
3596 bfd_false,
3597 coff_mkobject,
3598 _bfd_generic_mkarchive,
3599 bfd_false
3602 {/* bfd_write_contents */
3603 bfd_false,
3604 coff_write_object_contents,
3605 _bfd_xcoff_write_archive_contents,
3606 bfd_false
3609 /* Generic */
3610 bfd_true, /* _close_and_cleanup */
3611 bfd_true, /* _bfd_free_cached_info */
3612 coff_new_section_hook, /* _new_section_hook */
3613 _bfd_generic_get_section_contents, /* _bfd_get_section_contents */
3614 /* _bfd_get_section_contents_in_window */
3615 _bfd_generic_get_section_contents_in_window,
3617 /* Copy */
3618 _bfd_xcoff_copy_private_bfd_data, /* _bfd_copy_private_bfd */
3619 /* _bfd_merge_private_bfd_data */
3620 ((boolean (*) (bfd *, bfd *)) bfd_true),
3621 /* _bfd_copy_pivate_section_data */
3622 ((boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
3623 /* _bfd_copy_private_symbol_data */
3624 ((boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
3625 ((boolean (*) (bfd *, flagword)) bfd_true), /* _bfd_set_private_flags */
3626 ((boolean (*) (bfd *, void * )) bfd_true), /* _bfd_print_private_bfd_data */
3628 /* Core */
3629 coff_core_file_failing_command, /* _core_file_failing_command */
3630 coff_core_file_failing_signal, /* _core_file_failing_signal */
3631 /* _core_file_matches_executable_p */
3632 coff_core_file_matches_executable_p,
3634 /* Archive */
3635 _bfd_xcoff_slurp_armap, /* _slurp_armap */
3636 /* XCOFF archives do not have
3637 anything which corresponds to
3638 an extended name table. */
3639 bfd_false, /* _slurp_extended_name_table */
3640 /* _construct_extended_name_table */
3641 ((boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
3642 bfd_dont_truncate_arname, /* _truncate_arname */
3643 _bfd_xcoff_write_armap, /* _write_armap */
3644 _bfd_xcoff_read_ar_hdr, /* _read_ar_hdr */
3645 _bfd_xcoff_openr_next_archived_file, /* _openr_next_archived_file */
3646 _bfd_generic_get_elt_at_index, /* _get_elt_at_index */
3647 _bfd_xcoff_generic_stat_arch_elt, /* _generic_dtat_arch_elt */
3648 /* XCOFF archives do not have
3649 a timestamp. */
3650 bfd_true, /* _update_armap_timestamp */
3652 /* Symbols */
3653 coff_get_symtab_upper_bound, /* _get_symtab_upper_bound */
3654 coff_get_symtab, /* _get_symtab */
3655 coff_make_empty_symbol, /* _make_empty_symbol */
3656 coff_print_symbol, /* _print_symbol */
3657 coff_get_symbol_info, /* _get_symbol_info */
3658 _bfd_xcoff_is_local_label_name, /* _bfd_is_local_label_name */
3659 coff_get_lineno, /* _get_lineno */
3660 coff_find_nearest_line, /* _find_nearest_line */
3661 coff_bfd_make_debug_symbol, /* _bfd_make_debug_symbol */
3662 _bfd_generic_read_minisymbols, /* _read_minisymbols */
3663 _bfd_generic_minisymbol_to_symbol, /* _minsymbol_to_symbol */
3665 /* Reloc */
3666 coff_get_reloc_upper_bound, /* _get_reloc_upper_bound */
3667 coff_canonicalize_reloc, /* _cononicalize_reloc */
3668 _bfd_xcoff_reloc_type_lookup, /* _bfd_reloc_type_lookup */
3670 /* Write */
3671 coff_set_arch_mach, /* _set_arch_mach */
3672 coff_set_section_contents, /* _set_section_contents */
3674 /* Link */
3675 _bfd_xcoff_sizeof_headers, /* _sizeof_headers */
3676 /* _bfd_get_relocated_section_contents */
3677 bfd_generic_get_relocated_section_contents,
3678 bfd_generic_relax_section, /* _bfd_relax_section */
3679 _bfd_xcoff_bfd_link_hash_table_create, /* _bfd_link_hash_table_create */
3680 _bfd_xcoff_bfd_link_add_symbols, /* _bfd_link_add_symbols */
3681 _bfd_xcoff_bfd_final_link, /* _bfd_filnal_link */
3682 _bfd_generic_link_split_section, /* _bfd_link_split_section */
3683 bfd_generic_gc_sections, /* _bfd_gc_sections */
3684 bfd_generic_merge_sections, /* _bfd_merge_sections */
3686 /* Dynamic */
3687 /* _get_dynamic_symtab_upper_bound */
3688 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3689 _bfd_xcoff_canonicalize_dynamic_symtab, /* _cononicalize_dynamic_symtab */
3690 _bfd_xcoff_get_dynamic_reloc_upper_bound,/* _get_dynamic_reloc_upper_bound */
3691 _bfd_xcoff_canonicalize_dynamic_reloc, /* _cononicalize_dynamic_reloc */
3693 /* Opposite endian version, none exists */
3694 NULL,
3696 /* back end data */
3697 (void *) &bfd_xcoff_backend_data,
3701 * xcoff-powermac target
3702 * Old target.
3703 * Only difference between this target and the rs6000 target is the
3704 * the default architecture and machine type used in coffcode.h
3706 * PowerPC Macs use the same magic numbers as RS/6000
3707 * (because that's how they were bootstrapped originally),
3708 * but they are always PowerPC architecture.
3710 static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
3712 { /* COFF backend, defined in libcoff.h */
3713 _bfd_xcoff_swap_aux_in, /* _bfd_coff_swap_aux_in */
3714 _bfd_xcoff_swap_sym_in, /* _bfd_coff_swap_sym_in */
3715 coff_swap_lineno_in, /* _bfd_coff_swap_lineno_in */
3716 _bfd_xcoff_swap_aux_out, /* _bfd_swap_aux_out */
3717 _bfd_xcoff_swap_sym_out, /* _bfd_swap_sym_out */
3718 coff_swap_lineno_out, /* _bfd_swap_lineno_out */
3719 coff_swap_reloc_out, /* _bfd_swap_reloc_out */
3720 coff_swap_filehdr_out, /* _bfd_swap_filehdr_out */
3721 coff_swap_aouthdr_out, /* _bfd_swap_aouthdr_out */
3722 coff_swap_scnhdr_out, /* _bfd_swap_scnhdr_out */
3723 FILHSZ, /* _bfd_filhsz */
3724 AOUTSZ, /* _bfd_aoutsz */
3725 SCNHSZ, /* _bfd_scnhsz */
3726 SYMESZ, /* _bfd_symesz */
3727 AUXESZ, /* _bfd_auxesz */
3728 RELSZ, /* _bfd_relsz */
3729 LINESZ, /* _bfd_linesz */
3730 FILNMLEN, /* _bfd_filnmlen */
3731 true, /* _bfd_coff_long_filenames */
3732 false, /* _bfd_coff_long_section_names */
3733 (3), /* _bfd_coff_default_section_alignment_power */
3734 false, /* _bfd_coff_force_symnames_in_strings */
3735 2, /* _bfd_coff_debug_string_prefix_length */
3736 coff_swap_filehdr_in, /* _bfd_coff_swap_filehdr_in */
3737 coff_swap_aouthdr_in, /* _bfd_swap_aouthdr_in */
3738 coff_swap_scnhdr_in, /* _bfd_swap_scnhdr_in */
3739 coff_swap_reloc_in, /* _bfd_reloc_in */
3740 coff_bad_format_hook, /* _bfd_bad_format_hook */
3741 coff_set_arch_mach_hook, /* _bfd_set_arch_mach_hook */
3742 coff_mkobject_hook, /* _bfd_mkobject_hook */
3743 styp_to_sec_flags, /* _bfd_syp_to_sec_flags */
3744 coff_set_alignment_hook, /* _bfd_set_alignment_hook */
3745 coff_slurp_symbol_table, /* _bfd_coff_slurp_symbol_table */
3746 symname_in_debug_hook, /* _coff_symname_in_debug_hook */
3747 coff_pointerize_aux_hook, /* _bfd_coff_pointerize_aux_hook */
3748 coff_print_aux, /* bfd_coff_print_aux */
3749 dummy_reloc16_extra_cases, /* _bfd_coff_reloc16_extra_cases */
3750 dummy_reloc16_estimate, /* _bfd_coff_reloc16_estimate */
3751 NULL, /* bfd_coff_sym_is_global */
3752 /* _bfd_coff_compute_section_file_positions */
3753 coff_compute_section_file_positions,
3754 NULL, /* _bfd_coff_start_final_link */
3755 xcoff_ppc_relocate_section, /* _bfd_coff_relocate_section */
3756 coff_rtype_to_howto, /* _bfd_coff_rtype_to_howto */
3757 NULL, /* _bfd_coff_addust_symndx */
3758 _bfd_generic_link_add_one_symbol, /* _bfd_coff_add_one_symbol */
3759 coff_link_output_has_begun, /* _bfd_coff_link_output_has_begun */
3760 coff_final_link_postscript /* _bfd_coff_final_link_postscript */
3763 0x01DF, /* magic number */
3764 bfd_arch_powerpc, /* architecture */
3765 bfd_mach_ppc, /* machine */
3767 /* function pointers to xcoff specific swap routines */
3768 xcoff_swap_ldhdr_in, /* _xcoff_swap_ldhdr_in */
3769 xcoff_swap_ldhdr_out, /* _xcoff_swap_ldhdr_out */
3770 xcoff_swap_ldsym_in, /* _xcoff_swap_ldsym_in */
3771 xcoff_swap_ldsym_out, /* _xcoff_swap_ldsym_out */
3772 xcoff_swap_ldrel_in, /* _xcoff_swap_ldrel_in */
3773 xcoff_swap_ldrel_out, /* _xcoff_swap_ldrel_out */
3775 /* sizes */
3776 LDHDRSZ, /* _xcoff_ldhdrsz */
3777 LDSYMSZ, /* _xcoff_ldsymsz */
3778 LDRELSZ, /* _xcoff_ldrelsz */
3779 12, /* _xcoff_function_descriptor_size */
3780 SMALL_AOUTSZ, /* _xcoff_small_aout_header_size */
3782 /* versions */
3783 1, /* _xcoff_ldhdr_version */
3785 /* xcoff vs xcoff64 putting symbol names */
3786 _bfd_xcoff_put_symbol_name, /* _xcoff_put_symbol_name */
3787 _bfd_xcoff_put_ldsymbol_name, /* _xcoff_put_ldsymbol_name */
3789 &xcoff_dynamic_reloc, /* dynamic reloc howto */
3791 xcoff_create_csect_from_smclas, /* _xcoff_create_csect_from_smclas */
3793 /* lineno and reloc count overflow */
3794 xcoff_is_lineno_count_overflow,
3795 xcoff_is_reloc_count_overflow,
3797 xcoff_loader_symbol_offset,
3798 xcoff_loader_reloc_offset,
3800 /* glink */
3801 &xcoff_glink_code[0],
3802 (36), /* _xcoff_glink_size */
3804 /* rtinit */
3805 0, /* _xcoff_rtinit_size */
3806 xcoff_generate_rtinit, /* _xcoff_generate_rtinit */
3809 /* The transfer vector that leads the outside world to all of the above. */
3810 const bfd_target pmac_xcoff_vec =
3812 "xcoff-powermac",
3813 bfd_target_xcoff_flavour,
3814 BFD_ENDIAN_BIG, /* data byte order is big */
3815 BFD_ENDIAN_BIG, /* header byte order is big */
3817 (HAS_RELOC | EXEC_P | /* object flags */
3818 HAS_LINENO | HAS_DEBUG | DYNAMIC |
3819 HAS_SYMS | HAS_LOCALS | WP_TEXT),
3821 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
3822 0, /* leading char */
3823 '/', /* ar_pad_char */
3824 15, /* ar_max_namelen??? FIXMEmgo */
3826 /* data */
3827 bfd_getb64, /* bfd_getx64 */
3828 bfd_getb_signed_64, /* bfd_getx_signed_64 */
3829 bfd_putb64, /* bfd_putx64 */
3830 bfd_getb32, /* bfd_getx32 */
3831 bfd_getb_signed_32, /* bfd_getx_signed_32 */
3832 bfd_putb32, /* bfd_putx32 */
3833 bfd_getb16, /* bfd_getx16 */
3834 bfd_getb_signed_16, /* bfd_getx_signed_16 */
3835 bfd_putb16, /* bfd_putx16 */
3837 /* hdrs */
3838 bfd_getb64, /* bfd_h_getx64 */
3839 bfd_getb_signed_64, /* bfd_h_getx_signed_64 */
3840 bfd_putb64, /* bfd_h_putx64 */
3841 bfd_getb32, /* bfd_h_getx32 */
3842 bfd_getb_signed_32, /* bfd_h_getx_signed_32 */
3843 bfd_putb32, /* bfd_h_putx32 */
3844 bfd_getb16, /* bfd_h_getx16 */
3845 bfd_getb_signed_16, /* bfd_h_getx_signed_16 */
3846 bfd_putb16, /* bfd_h_putx16 */
3848 { /* bfd_check_format */
3849 _bfd_dummy_target,
3850 coff_object_p,
3851 _bfd_xcoff_archive_p,
3852 CORE_FILE_P
3855 { /* bfd_set_format */
3856 bfd_false,
3857 coff_mkobject,
3858 _bfd_generic_mkarchive,
3859 bfd_false
3862 {/* bfd_write_contents */
3863 bfd_false,
3864 coff_write_object_contents,
3865 _bfd_xcoff_write_archive_contents,
3866 bfd_false
3869 /* Generic */
3870 bfd_true, /* _close_and_cleanup */
3871 bfd_true, /* _bfd_free_cached_info */
3872 coff_new_section_hook, /* _new_section_hook */
3873 _bfd_generic_get_section_contents, /* _bfd_get_section_contents */
3874 /* _bfd_get_section_contents_in_window */
3875 _bfd_generic_get_section_contents_in_window,
3877 /* Copy */
3878 _bfd_xcoff_copy_private_bfd_data, /* _bfd_copy_private_bfd */
3879 /* _bfd_merge_private_bfd_data */
3880 ((boolean (*) (bfd *, bfd *)) bfd_true),
3881 /* _bfd_copy_pivate_section_data */
3882 ((boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
3883 /* _bfd_copy_private_symbol_data */
3884 ((boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
3885 ((boolean (*) (bfd *, flagword)) bfd_true), /* _bfd_set_private_flags */
3886 ((boolean (*) (bfd *, void * )) bfd_true), /* _bfd_print_private_bfd_data */
3888 /* Core */
3889 coff_core_file_failing_command, /* _core_file_failing_command */
3890 coff_core_file_failing_signal, /* _core_file_failing_signal */
3891 /* _core_file_matches_executable_p */
3892 coff_core_file_matches_executable_p,
3894 /* Archive */
3895 _bfd_xcoff_slurp_armap, /* _slurp_armap */
3896 /* XCOFF archives do not have
3897 anything which corresponds to
3898 an extended name table. */
3899 bfd_false, /* _slurp_extended_name_table */
3900 /* _construct_extended_name_table */
3901 ((boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
3902 bfd_dont_truncate_arname, /* _truncate_arname */
3903 _bfd_xcoff_write_armap, /* _write_armap */
3904 _bfd_xcoff_read_ar_hdr, /* _read_ar_hdr */
3905 _bfd_xcoff_openr_next_archived_file, /* _openr_next_archived_file */
3906 _bfd_generic_get_elt_at_index, /* _get_elt_at_index */
3907 _bfd_xcoff_generic_stat_arch_elt, /* _generic_dtat_arch_elt */
3908 /* XCOFF archives do not have
3909 a timestamp. */
3910 bfd_true, /* _update_armap_timestamp */
3912 /* Symbols */
3913 coff_get_symtab_upper_bound, /* _get_symtab_upper_bound */
3914 coff_get_symtab, /* _get_symtab */
3915 coff_make_empty_symbol, /* _make_empty_symbol */
3916 coff_print_symbol, /* _print_symbol */
3917 coff_get_symbol_info, /* _get_symbol_info */
3918 _bfd_xcoff_is_local_label_name, /* _bfd_is_local_label_name */
3919 coff_get_lineno, /* _get_lineno */
3920 coff_find_nearest_line, /* _find_nearest_line */
3921 coff_bfd_make_debug_symbol, /* _bfd_make_debug_symbol */
3922 _bfd_generic_read_minisymbols, /* _read_minisymbols */
3923 _bfd_generic_minisymbol_to_symbol, /* _minsymbol_to_symbol */
3925 /* Reloc */
3926 coff_get_reloc_upper_bound, /* _get_reloc_upper_bound */
3927 coff_canonicalize_reloc, /* _cononicalize_reloc */
3928 _bfd_xcoff_reloc_type_lookup, /* _bfd_reloc_type_lookup */
3930 /* Write */
3931 coff_set_arch_mach, /* _set_arch_mach */
3932 coff_set_section_contents, /* _set_section_contents */
3934 /* Link */
3935 _bfd_xcoff_sizeof_headers, /* _sizeof_headers */
3936 /* _bfd_get_relocated_section_contents */
3937 bfd_generic_get_relocated_section_contents,
3938 bfd_generic_relax_section, /* _bfd_relax_section */
3939 _bfd_xcoff_bfd_link_hash_table_create, /* _bfd_link_hash_table_create */
3940 _bfd_xcoff_bfd_link_add_symbols, /* _bfd_link_add_symbols */
3941 _bfd_xcoff_bfd_final_link, /* _bfd_filnal_link */
3942 _bfd_generic_link_split_section, /* _bfd_link_split_section */
3943 bfd_generic_gc_sections, /* _bfd_gc_sections */
3944 bfd_generic_merge_sections, /* _bfd_merge_sections */
3946 /* Dynamic */
3947 /* _get_dynamic_symtab_upper_bound */
3948 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3949 _bfd_xcoff_canonicalize_dynamic_symtab, /* _cononicalize_dynamic_symtab */
3950 _bfd_xcoff_get_dynamic_reloc_upper_bound,/* _get_dynamic_reloc_upper_bound */
3951 _bfd_xcoff_canonicalize_dynamic_reloc, /* _cononicalize_dynamic_reloc */
3953 /* Opposite endian version, none exists */
3954 NULL,
3956 /* back end data */
3957 (void *) &bfd_pmac_xcoff_backend_data,