ld/
[binutils.git] / bfd / coff-rs6000.c
blob975bc6755a5bc05569fd9c4ccecede83456b0502
1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2 Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 bfd_boolean _bfd_xcoff_mkobject
40 PARAMS ((bfd *));
41 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
42 PARAMS ((bfd *, bfd *));
43 extern bfd_boolean _bfd_xcoff_is_local_label_name
44 PARAMS ((bfd *, const char *));
45 extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
46 PARAMS ((bfd *, bfd_reloc_code_real_type));
47 extern bfd_boolean _bfd_xcoff_slurp_armap
48 PARAMS ((bfd *));
49 extern const bfd_target *_bfd_xcoff_archive_p
50 PARAMS ((bfd *));
51 extern PTR _bfd_xcoff_read_ar_hdr
52 PARAMS ((bfd *));
53 extern bfd *_bfd_xcoff_openr_next_archived_file
54 PARAMS ((bfd *, bfd *));
55 extern int _bfd_xcoff_stat_arch_elt
56 PARAMS ((bfd *, struct stat *));
57 extern bfd_boolean _bfd_xcoff_write_armap
58 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
59 extern bfd_boolean _bfd_xcoff_write_archive_contents
60 PARAMS ((bfd *));
61 extern int _bfd_xcoff_sizeof_headers
62 PARAMS ((bfd *, struct bfd_link_info *));
63 extern void _bfd_xcoff_swap_sym_in
64 PARAMS ((bfd *, PTR, PTR));
65 extern unsigned int _bfd_xcoff_swap_sym_out
66 PARAMS ((bfd *, PTR, PTR));
67 extern void _bfd_xcoff_swap_aux_in
68 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
69 extern unsigned int _bfd_xcoff_swap_aux_out
70 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
71 static void xcoff_swap_reloc_in
72 PARAMS ((bfd *, PTR, PTR));
73 static unsigned int xcoff_swap_reloc_out
74 PARAMS ((bfd *, PTR, PTR));
76 /* Forward declare xcoff_rtype2howto for coffcode.h macro. */
77 void xcoff_rtype2howto
78 PARAMS ((arelent *, struct internal_reloc *));
80 /* coffcode.h needs these to be defined. */
81 #define RS6000COFF_C 1
83 #define SELECT_RELOC(internal, howto) \
84 { \
85 internal.r_type = howto->type; \
86 internal.r_size = \
87 ((howto->complain_on_overflow == complain_overflow_signed \
88 ? 0x80 \
89 : 0) \
90 | (howto->bitsize - 1)); \
93 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
94 #define COFF_LONG_FILENAMES
95 #define NO_COFF_SYMBOLS
96 #define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
97 #define coff_mkobject _bfd_xcoff_mkobject
98 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
99 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
100 #define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
101 #define coff_bfd_reloc_name_lookup _bfd_xcoff_reloc_name_lookup
102 #ifdef AIX_CORE
103 extern const bfd_target * rs6000coff_core_p
104 PARAMS ((bfd *abfd));
105 extern bfd_boolean rs6000coff_core_file_matches_executable_p
106 PARAMS ((bfd *cbfd, bfd *ebfd));
107 extern char *rs6000coff_core_file_failing_command
108 PARAMS ((bfd *abfd));
109 extern int rs6000coff_core_file_failing_signal
110 PARAMS ((bfd *abfd));
111 #define CORE_FILE_P rs6000coff_core_p
112 #define coff_core_file_failing_command \
113 rs6000coff_core_file_failing_command
114 #define coff_core_file_failing_signal \
115 rs6000coff_core_file_failing_signal
116 #define coff_core_file_matches_executable_p \
117 rs6000coff_core_file_matches_executable_p
118 #else
119 #define CORE_FILE_P _bfd_dummy_target
120 #define coff_core_file_failing_command \
121 _bfd_nocore_core_file_failing_command
122 #define coff_core_file_failing_signal \
123 _bfd_nocore_core_file_failing_signal
124 #define coff_core_file_matches_executable_p \
125 _bfd_nocore_core_file_matches_executable_p
126 #endif
127 #define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
128 #define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
129 #define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
130 #define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
131 #define coff_swap_reloc_in xcoff_swap_reloc_in
132 #define coff_swap_reloc_out xcoff_swap_reloc_out
133 #define NO_COFF_RELOCS
135 #include "coffcode.h"
137 /* The main body of code is in coffcode.h. */
139 static const char *normalize_filename
140 PARAMS ((bfd *));
141 static bfd_boolean xcoff_write_armap_old
142 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
143 static bfd_boolean xcoff_write_armap_big
144 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
145 static bfd_boolean xcoff_write_archive_contents_old
146 PARAMS ((bfd *));
147 static bfd_boolean xcoff_write_archive_contents_big
148 PARAMS ((bfd *));
149 static void xcoff_swap_ldhdr_in
150 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
151 static void xcoff_swap_ldhdr_out
152 PARAMS ((bfd *, const struct internal_ldhdr *, PTR));
153 static void xcoff_swap_ldsym_in
154 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
155 static void xcoff_swap_ldsym_out
156 PARAMS ((bfd *, const struct internal_ldsym *, PTR));
157 static void xcoff_swap_ldrel_in
158 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
159 static void xcoff_swap_ldrel_out
160 PARAMS ((bfd *, const struct internal_ldrel *, PTR));
161 static bfd_boolean xcoff_ppc_relocate_section
162 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
163 struct internal_reloc *, struct internal_syment *, asection **));
164 static bfd_boolean _bfd_xcoff_put_ldsymbol_name
165 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
166 const char *));
167 static asection *xcoff_create_csect_from_smclas
168 PARAMS ((bfd *, union internal_auxent *, const char *));
169 static bfd_boolean xcoff_is_lineno_count_overflow
170 PARAMS ((bfd *, bfd_vma));
171 static bfd_boolean xcoff_is_reloc_count_overflow
172 PARAMS ((bfd *, bfd_vma));
173 static bfd_vma xcoff_loader_symbol_offset
174 PARAMS ((bfd *, struct internal_ldhdr *));
175 static bfd_vma xcoff_loader_reloc_offset
176 PARAMS ((bfd *, struct internal_ldhdr *));
177 static bfd_boolean xcoff_generate_rtinit
178 PARAMS ((bfd *, const char *, const char *, bfd_boolean));
179 static bfd_boolean do_pad
180 PARAMS ((bfd *, unsigned int));
181 static bfd_boolean do_copy
182 PARAMS ((bfd *, bfd *));
183 static bfd_boolean do_shared_object_padding
184 PARAMS ((bfd *, bfd *, file_ptr *, int));
186 /* Relocation functions */
187 static bfd_boolean xcoff_reloc_type_br
188 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
190 static bfd_boolean xcoff_complain_overflow_dont_func
191 PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
192 static bfd_boolean xcoff_complain_overflow_bitfield_func
193 PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
194 static bfd_boolean xcoff_complain_overflow_signed_func
195 PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
196 static bfd_boolean xcoff_complain_overflow_unsigned_func
197 PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
199 bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
200 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
202 xcoff_reloc_type_pos, /* R_POS (0x00) */
203 xcoff_reloc_type_neg, /* R_NEG (0x01) */
204 xcoff_reloc_type_rel, /* R_REL (0x02) */
205 xcoff_reloc_type_toc, /* R_TOC (0x03) */
206 xcoff_reloc_type_fail, /* R_RTB (0x04) */
207 xcoff_reloc_type_toc, /* R_GL (0x05) */
208 xcoff_reloc_type_toc, /* R_TCL (0x06) */
209 xcoff_reloc_type_fail, /* (0x07) */
210 xcoff_reloc_type_ba, /* R_BA (0x08) */
211 xcoff_reloc_type_fail, /* (0x09) */
212 xcoff_reloc_type_br, /* R_BR (0x0a) */
213 xcoff_reloc_type_fail, /* (0x0b) */
214 xcoff_reloc_type_pos, /* R_RL (0x0c) */
215 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
216 xcoff_reloc_type_fail, /* (0x0e) */
217 xcoff_reloc_type_noop, /* R_REF (0x0f) */
218 xcoff_reloc_type_fail, /* (0x10) */
219 xcoff_reloc_type_fail, /* (0x11) */
220 xcoff_reloc_type_toc, /* R_TRL (0x12) */
221 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
222 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
223 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
224 xcoff_reloc_type_ba, /* R_CAI (0x16) */
225 xcoff_reloc_type_crel, /* R_CREL (0x17) */
226 xcoff_reloc_type_ba, /* R_RBA (0x18) */
227 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
228 xcoff_reloc_type_br, /* R_RBR (0x1a) */
229 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
232 bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
233 PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS)) =
235 xcoff_complain_overflow_dont_func,
236 xcoff_complain_overflow_bitfield_func,
237 xcoff_complain_overflow_signed_func,
238 xcoff_complain_overflow_unsigned_func,
241 /* We use our own tdata type. Its first field is the COFF tdata type,
242 so the COFF routines are compatible. */
244 bfd_boolean
245 _bfd_xcoff_mkobject (abfd)
246 bfd *abfd;
248 coff_data_type *coff;
249 bfd_size_type amt = sizeof (struct xcoff_tdata);
251 abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
252 if (abfd->tdata.xcoff_obj_data == NULL)
253 return FALSE;
254 coff = coff_data (abfd);
255 coff->symbols = (coff_symbol_type *) NULL;
256 coff->conversion_table = (unsigned int *) NULL;
257 coff->raw_syments = (struct coff_ptr_struct *) NULL;
258 coff->relocbase = 0;
260 xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
262 /* We set cputype to -1 to indicate that it has not been
263 initialized. */
264 xcoff_data (abfd)->cputype = -1;
266 xcoff_data (abfd)->csects = NULL;
267 xcoff_data (abfd)->debug_indices = NULL;
269 /* text section alignment is different than the default */
270 bfd_xcoff_text_align_power (abfd) = 2;
272 return TRUE;
275 /* Copy XCOFF data from one BFD to another. */
277 bfd_boolean
278 _bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
279 bfd *ibfd;
280 bfd *obfd;
282 struct xcoff_tdata *ix, *ox;
283 asection *sec;
285 if (ibfd->xvec != obfd->xvec)
286 return TRUE;
287 ix = xcoff_data (ibfd);
288 ox = xcoff_data (obfd);
289 ox->full_aouthdr = ix->full_aouthdr;
290 ox->toc = ix->toc;
291 if (ix->sntoc == 0)
292 ox->sntoc = 0;
293 else
295 sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
296 if (sec == NULL)
297 ox->sntoc = 0;
298 else
299 ox->sntoc = sec->output_section->target_index;
301 if (ix->snentry == 0)
302 ox->snentry = 0;
303 else
305 sec = coff_section_from_bfd_index (ibfd, ix->snentry);
306 if (sec == NULL)
307 ox->snentry = 0;
308 else
309 ox->snentry = sec->output_section->target_index;
311 bfd_xcoff_text_align_power (obfd) = bfd_xcoff_text_align_power (ibfd);
312 bfd_xcoff_data_align_power (obfd) = bfd_xcoff_data_align_power (ibfd);
313 ox->modtype = ix->modtype;
314 ox->cputype = ix->cputype;
315 ox->maxdata = ix->maxdata;
316 ox->maxstack = ix->maxstack;
317 return TRUE;
320 /* I don't think XCOFF really has a notion of local labels based on
321 name. This will mean that ld -X doesn't actually strip anything.
322 The AIX native linker does not have a -X option, and it ignores the
323 -x option. */
325 bfd_boolean
326 _bfd_xcoff_is_local_label_name (abfd, name)
327 bfd *abfd ATTRIBUTE_UNUSED;
328 const char *name ATTRIBUTE_UNUSED;
330 return FALSE;
333 void
334 _bfd_xcoff_swap_sym_in (abfd, ext1, in1)
335 bfd *abfd;
336 PTR ext1;
337 PTR in1;
339 SYMENT *ext = (SYMENT *)ext1;
340 struct internal_syment * in = (struct internal_syment *)in1;
342 if (ext->e.e_name[0] != 0)
344 memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
346 else
348 in->_n._n_n._n_zeroes = 0;
349 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
352 in->n_value = H_GET_32 (abfd, ext->e_value);
353 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
354 in->n_type = H_GET_16 (abfd, ext->e_type);
355 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
356 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
359 unsigned int
360 _bfd_xcoff_swap_sym_out (abfd, inp, extp)
361 bfd *abfd;
362 PTR inp;
363 PTR extp;
365 struct internal_syment *in = (struct internal_syment *)inp;
366 SYMENT *ext =(SYMENT *)extp;
368 if (in->_n._n_name[0] != 0)
370 memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
372 else
374 H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
375 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
378 H_PUT_32 (abfd, in->n_value, ext->e_value);
379 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
380 H_PUT_16 (abfd, in->n_type, ext->e_type);
381 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
382 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
383 return bfd_coff_symesz (abfd);
386 void
387 _bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
388 bfd *abfd;
389 PTR ext1;
390 int type;
391 int class;
392 int indx;
393 int numaux;
394 PTR in1;
396 AUXENT * ext = (AUXENT *)ext1;
397 union internal_auxent *in = (union internal_auxent *)in1;
399 switch (class)
401 case C_FILE:
402 if (ext->x_file.x_fname[0] == 0)
404 in->x_file.x_n.x_zeroes = 0;
405 in->x_file.x_n.x_offset =
406 H_GET_32 (abfd, ext->x_file.x_n.x_offset);
408 else
410 if (numaux > 1)
412 if (indx == 0)
413 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
414 numaux * sizeof (AUXENT));
416 else
418 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
421 goto end;
423 /* RS/6000 "csect" auxents */
424 case C_EXT:
425 case C_HIDEXT:
426 if (indx + 1 == numaux)
428 in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
429 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
430 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
431 /* We don't have to hack bitfields in x_smtyp because it's
432 defined by shifts-and-ands, which are equivalent on all
433 byte orders. */
434 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
435 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
436 in->x_csect.x_stab = H_GET_32 (abfd, ext->x_csect.x_stab);
437 in->x_csect.x_snstab = H_GET_16 (abfd, ext->x_csect.x_snstab);
438 goto end;
440 break;
442 case C_STAT:
443 case C_LEAFSTAT:
444 case C_HIDDEN:
445 if (type == T_NULL)
447 in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
448 in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
449 in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
450 /* PE defines some extra fields; we zero them out for
451 safety. */
452 in->x_scn.x_checksum = 0;
453 in->x_scn.x_associated = 0;
454 in->x_scn.x_comdat = 0;
456 goto end;
458 break;
461 in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
462 in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
464 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
466 in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
467 H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
468 in->x_sym.x_fcnary.x_fcn.x_endndx.l =
469 H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
471 else
473 in->x_sym.x_fcnary.x_ary.x_dimen[0] =
474 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
475 in->x_sym.x_fcnary.x_ary.x_dimen[1] =
476 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
477 in->x_sym.x_fcnary.x_ary.x_dimen[2] =
478 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
479 in->x_sym.x_fcnary.x_ary.x_dimen[3] =
480 H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
483 if (ISFCN (type))
485 in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
487 else
489 in->x_sym.x_misc.x_lnsz.x_lnno =
490 H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
491 in->x_sym.x_misc.x_lnsz.x_size =
492 H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
495 end: ;
496 /* The semicolon is because MSVC doesn't like labels at
497 end of block. */
501 unsigned int _bfd_xcoff_swap_aux_out
502 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
504 unsigned int
505 _bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
506 bfd * abfd;
507 PTR inp;
508 int type;
509 int class;
510 int indx ATTRIBUTE_UNUSED;
511 int numaux ATTRIBUTE_UNUSED;
512 PTR extp;
514 union internal_auxent *in = (union internal_auxent *)inp;
515 AUXENT *ext = (AUXENT *)extp;
517 memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
518 switch (class)
520 case C_FILE:
521 if (in->x_file.x_fname[0] == 0)
523 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
524 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
526 else
528 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
530 goto end;
532 /* RS/6000 "csect" auxents */
533 case C_EXT:
534 case C_HIDEXT:
535 if (indx + 1 == numaux)
537 H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
538 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
539 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
540 /* We don't have to hack bitfields in x_smtyp because it's
541 defined by shifts-and-ands, which are equivalent on all
542 byte orders. */
543 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
544 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
545 H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
546 H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
547 goto end;
549 break;
551 case C_STAT:
552 case C_LEAFSTAT:
553 case C_HIDDEN:
554 if (type == T_NULL)
556 H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
557 H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
558 H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
559 goto end;
561 break;
564 H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
565 H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
567 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
569 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
570 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
571 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
572 ext->x_sym.x_fcnary.x_fcn.x_endndx);
574 else
576 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
577 ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
578 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
579 ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
580 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
581 ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
582 H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
583 ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
586 if (ISFCN (type))
587 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
588 else
590 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
591 ext->x_sym.x_misc.x_lnsz.x_lnno);
592 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
593 ext->x_sym.x_misc.x_lnsz.x_size);
596 end:
597 return bfd_coff_auxesz (abfd);
602 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
603 bitsize and whether they are signed or not, along with a
604 conventional type. This table is for the types, which are used for
605 different algorithms for putting in the reloc. Many of these
606 relocs need special_function entries, which I have not written. */
609 reloc_howto_type xcoff_howto_table[] =
611 /* Standard 32 bit relocation. */
612 HOWTO (R_POS, /* type */
613 0, /* rightshift */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
615 32, /* bitsize */
616 FALSE, /* pc_relative */
617 0, /* bitpos */
618 complain_overflow_bitfield, /* complain_on_overflow */
619 0, /* special_function */
620 "R_POS", /* name */
621 TRUE, /* partial_inplace */
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
624 FALSE), /* pcrel_offset */
626 /* 32 bit relocation, but store negative value. */
627 HOWTO (R_NEG, /* type */
628 0, /* rightshift */
629 -2, /* size (0 = byte, 1 = short, 2 = long) */
630 32, /* bitsize */
631 FALSE, /* pc_relative */
632 0, /* bitpos */
633 complain_overflow_bitfield, /* complain_on_overflow */
634 0, /* special_function */
635 "R_NEG", /* name */
636 TRUE, /* partial_inplace */
637 0xffffffff, /* src_mask */
638 0xffffffff, /* dst_mask */
639 FALSE), /* pcrel_offset */
641 /* 32 bit PC relative relocation. */
642 HOWTO (R_REL, /* type */
643 0, /* rightshift */
644 2, /* size (0 = byte, 1 = short, 2 = long) */
645 32, /* bitsize */
646 TRUE, /* pc_relative */
647 0, /* bitpos */
648 complain_overflow_signed, /* complain_on_overflow */
649 0, /* special_function */
650 "R_REL", /* name */
651 TRUE, /* partial_inplace */
652 0xffffffff, /* src_mask */
653 0xffffffff, /* dst_mask */
654 FALSE), /* pcrel_offset */
656 /* 16 bit TOC relative relocation. */
657 HOWTO (R_TOC, /* type */
658 0, /* rightshift */
659 1, /* size (0 = byte, 1 = short, 2 = long) */
660 16, /* bitsize */
661 FALSE, /* pc_relative */
662 0, /* bitpos */
663 complain_overflow_bitfield, /* complain_on_overflow */
664 0, /* special_function */
665 "R_TOC", /* name */
666 TRUE, /* partial_inplace */
667 0xffff, /* src_mask */
668 0xffff, /* dst_mask */
669 FALSE), /* pcrel_offset */
671 /* I don't really know what this is. */
672 HOWTO (R_RTB, /* type */
673 1, /* rightshift */
674 2, /* size (0 = byte, 1 = short, 2 = long) */
675 32, /* bitsize */
676 FALSE, /* pc_relative */
677 0, /* bitpos */
678 complain_overflow_bitfield, /* complain_on_overflow */
679 0, /* special_function */
680 "R_RTB", /* name */
681 TRUE, /* partial_inplace */
682 0xffffffff, /* src_mask */
683 0xffffffff, /* dst_mask */
684 FALSE), /* pcrel_offset */
686 /* External TOC relative symbol. */
687 HOWTO (R_GL, /* type */
688 0, /* rightshift */
689 1, /* size (0 = byte, 1 = short, 2 = long) */
690 16, /* bitsize */
691 FALSE, /* pc_relative */
692 0, /* bitpos */
693 complain_overflow_bitfield, /* complain_on_overflow */
694 0, /* special_function */
695 "R_GL", /* name */
696 TRUE, /* partial_inplace */
697 0xffff, /* src_mask */
698 0xffff, /* dst_mask */
699 FALSE), /* pcrel_offset */
701 /* Local TOC relative symbol. */
702 HOWTO (R_TCL, /* type */
703 0, /* rightshift */
704 1, /* size (0 = byte, 1 = short, 2 = long) */
705 16, /* bitsize */
706 FALSE, /* pc_relative */
707 0, /* bitpos */
708 complain_overflow_bitfield, /* complain_on_overflow */
709 0, /* special_function */
710 "R_TCL", /* name */
711 TRUE, /* partial_inplace */
712 0xffff, /* src_mask */
713 0xffff, /* dst_mask */
714 FALSE), /* pcrel_offset */
716 EMPTY_HOWTO (7),
718 /* Non modifiable absolute branch. */
719 HOWTO (R_BA, /* type */
720 0, /* rightshift */
721 2, /* size (0 = byte, 1 = short, 2 = long) */
722 26, /* bitsize */
723 FALSE, /* pc_relative */
724 0, /* bitpos */
725 complain_overflow_bitfield, /* complain_on_overflow */
726 0, /* special_function */
727 "R_BA_26", /* name */
728 TRUE, /* partial_inplace */
729 0x03fffffc, /* src_mask */
730 0x03fffffc, /* dst_mask */
731 FALSE), /* pcrel_offset */
733 EMPTY_HOWTO (9),
735 /* Non modifiable relative branch. */
736 HOWTO (R_BR, /* type */
737 0, /* rightshift */
738 2, /* size (0 = byte, 1 = short, 2 = long) */
739 26, /* bitsize */
740 TRUE, /* pc_relative */
741 0, /* bitpos */
742 complain_overflow_signed, /* complain_on_overflow */
743 0, /* special_function */
744 "R_BR", /* name */
745 TRUE, /* partial_inplace */
746 0x03fffffc, /* src_mask */
747 0x03fffffc, /* dst_mask */
748 FALSE), /* pcrel_offset */
750 EMPTY_HOWTO (0xb),
752 /* Indirect load. */
753 HOWTO (R_RL, /* type */
754 0, /* rightshift */
755 1, /* size (0 = byte, 1 = short, 2 = long) */
756 16, /* bitsize */
757 FALSE, /* pc_relative */
758 0, /* bitpos */
759 complain_overflow_bitfield, /* complain_on_overflow */
760 0, /* special_function */
761 "R_RL", /* name */
762 TRUE, /* partial_inplace */
763 0xffff, /* src_mask */
764 0xffff, /* dst_mask */
765 FALSE), /* pcrel_offset */
767 /* Load address. */
768 HOWTO (R_RLA, /* type */
769 0, /* rightshift */
770 1, /* size (0 = byte, 1 = short, 2 = long) */
771 16, /* bitsize */
772 FALSE, /* pc_relative */
773 0, /* bitpos */
774 complain_overflow_bitfield, /* complain_on_overflow */
775 0, /* special_function */
776 "R_RLA", /* name */
777 TRUE, /* partial_inplace */
778 0xffff, /* src_mask */
779 0xffff, /* dst_mask */
780 FALSE), /* pcrel_offset */
782 EMPTY_HOWTO (0xe),
784 /* Non-relocating reference. */
785 HOWTO (R_REF, /* type */
786 0, /* rightshift */
787 2, /* size (0 = byte, 1 = short, 2 = long) */
788 32, /* bitsize */
789 FALSE, /* pc_relative */
790 0, /* bitpos */
791 complain_overflow_dont, /* complain_on_overflow */
792 0, /* special_function */
793 "R_REF", /* name */
794 FALSE, /* partial_inplace */
795 0, /* src_mask */
796 0, /* dst_mask */
797 FALSE), /* pcrel_offset */
799 EMPTY_HOWTO (0x10),
800 EMPTY_HOWTO (0x11),
802 /* TOC relative indirect load. */
803 HOWTO (R_TRL, /* type */
804 0, /* rightshift */
805 1, /* size (0 = byte, 1 = short, 2 = long) */
806 16, /* bitsize */
807 FALSE, /* pc_relative */
808 0, /* bitpos */
809 complain_overflow_bitfield, /* complain_on_overflow */
810 0, /* special_function */
811 "R_TRL", /* name */
812 TRUE, /* partial_inplace */
813 0xffff, /* src_mask */
814 0xffff, /* dst_mask */
815 FALSE), /* pcrel_offset */
817 /* TOC relative load address. */
818 HOWTO (R_TRLA, /* type */
819 0, /* rightshift */
820 1, /* size (0 = byte, 1 = short, 2 = long) */
821 16, /* bitsize */
822 FALSE, /* pc_relative */
823 0, /* bitpos */
824 complain_overflow_bitfield, /* complain_on_overflow */
825 0, /* special_function */
826 "R_TRLA", /* name */
827 TRUE, /* partial_inplace */
828 0xffff, /* src_mask */
829 0xffff, /* dst_mask */
830 FALSE), /* pcrel_offset */
832 /* Modifiable relative branch. */
833 HOWTO (R_RRTBI, /* type */
834 1, /* rightshift */
835 2, /* size (0 = byte, 1 = short, 2 = long) */
836 32, /* bitsize */
837 FALSE, /* pc_relative */
838 0, /* bitpos */
839 complain_overflow_bitfield, /* complain_on_overflow */
840 0, /* special_function */
841 "R_RRTBI", /* name */
842 TRUE, /* partial_inplace */
843 0xffffffff, /* src_mask */
844 0xffffffff, /* dst_mask */
845 FALSE), /* pcrel_offset */
847 /* Modifiable absolute branch. */
848 HOWTO (R_RRTBA, /* type */
849 1, /* rightshift */
850 2, /* size (0 = byte, 1 = short, 2 = long) */
851 32, /* bitsize */
852 FALSE, /* pc_relative */
853 0, /* bitpos */
854 complain_overflow_bitfield, /* complain_on_overflow */
855 0, /* special_function */
856 "R_RRTBA", /* name */
857 TRUE, /* partial_inplace */
858 0xffffffff, /* src_mask */
859 0xffffffff, /* dst_mask */
860 FALSE), /* pcrel_offset */
862 /* Modifiable call absolute indirect. */
863 HOWTO (R_CAI, /* type */
864 0, /* rightshift */
865 1, /* size (0 = byte, 1 = short, 2 = long) */
866 16, /* bitsize */
867 FALSE, /* pc_relative */
868 0, /* bitpos */
869 complain_overflow_bitfield, /* complain_on_overflow */
870 0, /* special_function */
871 "R_CAI", /* name */
872 TRUE, /* partial_inplace */
873 0xffff, /* src_mask */
874 0xffff, /* dst_mask */
875 FALSE), /* pcrel_offset */
877 /* Modifiable call relative. */
878 HOWTO (R_CREL, /* type */
879 0, /* rightshift */
880 1, /* size (0 = byte, 1 = short, 2 = long) */
881 16, /* bitsize */
882 FALSE, /* pc_relative */
883 0, /* bitpos */
884 complain_overflow_bitfield, /* complain_on_overflow */
885 0, /* special_function */
886 "R_CREL", /* name */
887 TRUE, /* partial_inplace */
888 0xffff, /* src_mask */
889 0xffff, /* dst_mask */
890 FALSE), /* pcrel_offset */
892 /* Modifiable branch absolute. */
893 HOWTO (R_RBA, /* type */
894 0, /* rightshift */
895 2, /* size (0 = byte, 1 = short, 2 = long) */
896 26, /* bitsize */
897 FALSE, /* pc_relative */
898 0, /* bitpos */
899 complain_overflow_bitfield, /* complain_on_overflow */
900 0, /* special_function */
901 "R_RBA", /* name */
902 TRUE, /* partial_inplace */
903 0x03fffffc, /* src_mask */
904 0x03fffffc, /* dst_mask */
905 FALSE), /* pcrel_offset */
907 /* Modifiable branch absolute. */
908 HOWTO (R_RBAC, /* type */
909 0, /* rightshift */
910 2, /* size (0 = byte, 1 = short, 2 = long) */
911 32, /* bitsize */
912 FALSE, /* pc_relative */
913 0, /* bitpos */
914 complain_overflow_bitfield, /* complain_on_overflow */
915 0, /* special_function */
916 "R_RBAC", /* name */
917 TRUE, /* partial_inplace */
918 0xffffffff, /* src_mask */
919 0xffffffff, /* dst_mask */
920 FALSE), /* pcrel_offset */
922 /* Modifiable branch relative. */
923 HOWTO (R_RBR, /* type */
924 0, /* rightshift */
925 2, /* size (0 = byte, 1 = short, 2 = long) */
926 26, /* bitsize */
927 FALSE, /* pc_relative */
928 0, /* bitpos */
929 complain_overflow_signed, /* complain_on_overflow */
930 0, /* special_function */
931 "R_RBR_26", /* name */
932 TRUE, /* partial_inplace */
933 0x03fffffc, /* src_mask */
934 0x03fffffc, /* dst_mask */
935 FALSE), /* pcrel_offset */
937 /* Modifiable branch absolute. */
938 HOWTO (R_RBRC, /* type */
939 0, /* rightshift */
940 1, /* size (0 = byte, 1 = short, 2 = long) */
941 16, /* bitsize */
942 FALSE, /* pc_relative */
943 0, /* bitpos */
944 complain_overflow_bitfield, /* complain_on_overflow */
945 0, /* special_function */
946 "R_RBRC", /* name */
947 TRUE, /* partial_inplace */
948 0xffff, /* src_mask */
949 0xffff, /* dst_mask */
950 FALSE), /* pcrel_offset */
952 /* 16 bit Non modifiable absolute branch. */
953 HOWTO (R_BA, /* type */
954 0, /* rightshift */
955 1, /* size (0 = byte, 1 = short, 2 = long) */
956 16, /* bitsize */
957 FALSE, /* pc_relative */
958 0, /* bitpos */
959 complain_overflow_bitfield, /* complain_on_overflow */
960 0, /* special_function */
961 "R_BA_16", /* name */
962 TRUE, /* partial_inplace */
963 0xfffc, /* src_mask */
964 0xfffc, /* dst_mask */
965 FALSE), /* pcrel_offset */
967 /* Modifiable branch relative. */
968 HOWTO (R_RBR, /* type */
969 0, /* rightshift */
970 1, /* size (0 = byte, 1 = short, 2 = long) */
971 16, /* bitsize */
972 FALSE, /* pc_relative */
973 0, /* bitpos */
974 complain_overflow_signed, /* complain_on_overflow */
975 0, /* special_function */
976 "R_RBR_16", /* name */
977 TRUE, /* partial_inplace */
978 0xffff, /* src_mask */
979 0xffff, /* dst_mask */
980 FALSE), /* pcrel_offset */
982 /* Modifiable branch relative. */
983 HOWTO (R_RBA, /* type */
984 0, /* rightshift */
985 1, /* size (0 = byte, 1 = short, 2 = long) */
986 16, /* bitsize */
987 FALSE, /* pc_relative */
988 0, /* bitpos */
989 complain_overflow_signed, /* complain_on_overflow */
990 0, /* special_function */
991 "R_RBA_16", /* name */
992 TRUE, /* partial_inplace */
993 0xffff, /* src_mask */
994 0xffff, /* dst_mask */
995 FALSE), /* pcrel_offset */
999 void
1000 xcoff_rtype2howto (relent, internal)
1001 arelent *relent;
1002 struct internal_reloc *internal;
1004 if (internal->r_type > R_RBRC)
1005 abort ();
1007 /* Default howto layout works most of the time */
1008 relent->howto = &xcoff_howto_table[internal->r_type];
1010 /* Special case some 16 bit reloc */
1011 if (15 == (internal->r_size & 0x1f))
1013 if (R_BA == internal->r_type)
1014 relent->howto = &xcoff_howto_table[0x1c];
1015 else if (R_RBR == internal->r_type)
1016 relent->howto = &xcoff_howto_table[0x1d];
1017 else if (R_RBA == internal->r_type)
1018 relent->howto = &xcoff_howto_table[0x1e];
1021 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1022 relocation, as well as indicating whether it is signed or not.
1023 Doublecheck that the relocation information gathered from the
1024 type matches this information. The bitsize is not significant
1025 for R_REF relocs. */
1026 if (relent->howto->dst_mask != 0
1027 && (relent->howto->bitsize
1028 != ((unsigned int) internal->r_size & 0x1f) + 1))
1029 abort ();
1032 reloc_howto_type *
1033 _bfd_xcoff_reloc_type_lookup (abfd, code)
1034 bfd *abfd ATTRIBUTE_UNUSED;
1035 bfd_reloc_code_real_type code;
1037 switch (code)
1039 case BFD_RELOC_PPC_B26:
1040 return &xcoff_howto_table[0xa];
1041 case BFD_RELOC_PPC_BA16:
1042 return &xcoff_howto_table[0x1c];
1043 case BFD_RELOC_PPC_BA26:
1044 return &xcoff_howto_table[8];
1045 case BFD_RELOC_PPC_TOC16:
1046 return &xcoff_howto_table[3];
1047 case BFD_RELOC_32:
1048 case BFD_RELOC_CTOR:
1049 return &xcoff_howto_table[0];
1050 default:
1051 return NULL;
1055 static reloc_howto_type *
1056 _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1057 const char *r_name)
1059 unsigned int i;
1061 for (i = 0;
1062 i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]);
1063 i++)
1064 if (xcoff_howto_table[i].name != NULL
1065 && strcasecmp (xcoff_howto_table[i].name, r_name) == 0)
1066 return &xcoff_howto_table[i];
1068 return NULL;
1071 /* XCOFF archive support. The original version of this code was by
1072 Damon A. Permezel. It was enhanced to permit cross support, and
1073 writing archive files, by Ian Lance Taylor, Cygnus Support.
1075 XCOFF uses its own archive format. Everything is hooked together
1076 with file offset links, so it is possible to rapidly update an
1077 archive in place. Of course, we don't do that. An XCOFF archive
1078 has a real file header, not just an ARMAG string. The structure of
1079 the file header and of each archive header appear below.
1081 An XCOFF archive also has a member table, which is a list of
1082 elements in the archive (you can get that by looking through the
1083 linked list, but you have to read a lot more of the file). The
1084 member table has a normal archive header with an empty name. It is
1085 normally (and perhaps must be) the second to last entry in the
1086 archive. The member table data is almost printable ASCII. It
1087 starts with a 12 character decimal string which is the number of
1088 entries in the table. For each entry it has a 12 character decimal
1089 string which is the offset in the archive of that member. These
1090 entries are followed by a series of null terminated strings which
1091 are the member names for each entry.
1093 Finally, an XCOFF archive has a global symbol table, which is what
1094 we call the armap. The global symbol table has a normal archive
1095 header with an empty name. It is normally (and perhaps must be)
1096 the last entry in the archive. The contents start with a four byte
1097 binary number which is the number of entries. This is followed by
1098 a that many four byte binary numbers; each is the file offset of an
1099 entry in the archive. These numbers are followed by a series of
1100 null terminated strings, which are symbol names.
1102 AIX 4.3 introduced a new archive format which can handle larger
1103 files and also 32- and 64-bit objects in the same archive. The
1104 things said above remain true except that there is now more than
1105 one global symbol table. The one is used to index 32-bit objects,
1106 the other for 64-bit objects.
1108 The new archives (recognizable by the new ARMAG string) has larger
1109 field lengths so that we cannot really share any code. Also we have
1110 to take care that we are not generating the new form of archives
1111 on AIX 4.2 or earlier systems. */
1113 /* XCOFF archives use this as a magic string. Note that both strings
1114 have the same length. */
1116 /* Set the magic for archive. */
1118 bfd_boolean
1119 bfd_xcoff_ar_archive_set_magic (abfd, magic)
1120 bfd *abfd ATTRIBUTE_UNUSED;
1121 char *magic ATTRIBUTE_UNUSED;
1123 /* Not supported yet. */
1124 return FALSE;
1125 /* bfd_xcoff_archive_set_magic (abfd, magic); */
1128 /* Read in the armap of an XCOFF archive. */
1130 bfd_boolean
1131 _bfd_xcoff_slurp_armap (abfd)
1132 bfd *abfd;
1134 file_ptr off;
1135 size_t namlen;
1136 bfd_size_type sz;
1137 bfd_byte *contents, *cend;
1138 bfd_vma c, i;
1139 carsym *arsym;
1140 bfd_byte *p;
1142 if (xcoff_ardata (abfd) == NULL)
1144 bfd_has_map (abfd) = FALSE;
1145 return TRUE;
1148 if (! xcoff_big_format_p (abfd))
1150 /* This is for the old format. */
1151 struct xcoff_ar_hdr hdr;
1153 off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
1154 if (off == 0)
1156 bfd_has_map (abfd) = FALSE;
1157 return TRUE;
1160 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1161 return FALSE;
1163 /* The symbol table starts with a normal archive header. */
1164 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1165 != SIZEOF_AR_HDR)
1166 return FALSE;
1168 /* Skip the name (normally empty). */
1169 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1170 off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1171 if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1172 return FALSE;
1174 sz = strtol (hdr.size, (char **) NULL, 10);
1176 /* Read in the entire symbol table. */
1177 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1178 if (contents == NULL)
1179 return FALSE;
1180 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1181 return FALSE;
1183 /* The symbol table starts with a four byte count. */
1184 c = H_GET_32 (abfd, contents);
1186 if (c * 4 >= sz)
1188 bfd_set_error (bfd_error_bad_value);
1189 return FALSE;
1192 bfd_ardata (abfd)->symdefs =
1193 ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1194 if (bfd_ardata (abfd)->symdefs == NULL)
1195 return FALSE;
1197 /* After the count comes a list of four byte file offsets. */
1198 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
1199 i < c;
1200 ++i, ++arsym, p += 4)
1201 arsym->file_offset = H_GET_32 (abfd, p);
1203 else
1205 /* This is for the new format. */
1206 struct xcoff_ar_hdr_big hdr;
1208 off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
1209 if (off == 0)
1211 bfd_has_map (abfd) = FALSE;
1212 return TRUE;
1215 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1216 return FALSE;
1218 /* The symbol table starts with a normal archive header. */
1219 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1220 != SIZEOF_AR_HDR_BIG)
1221 return FALSE;
1223 /* Skip the name (normally empty). */
1224 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1225 off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1226 if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1227 return FALSE;
1229 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1230 machines) since the field width is 20 and there numbers with more
1231 than 32 bits can be represented. */
1232 sz = strtol (hdr.size, (char **) NULL, 10);
1234 /* Read in the entire symbol table. */
1235 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1236 if (contents == NULL)
1237 return FALSE;
1238 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1239 return FALSE;
1241 /* The symbol table starts with an eight byte count. */
1242 c = H_GET_64 (abfd, contents);
1244 if (c * 8 >= sz)
1246 bfd_set_error (bfd_error_bad_value);
1247 return FALSE;
1250 bfd_ardata (abfd)->symdefs =
1251 ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1252 if (bfd_ardata (abfd)->symdefs == NULL)
1253 return FALSE;
1255 /* After the count comes a list of eight byte file offsets. */
1256 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1257 i < c;
1258 ++i, ++arsym, p += 8)
1259 arsym->file_offset = H_GET_64 (abfd, p);
1262 /* After the file offsets come null terminated symbol names. */
1263 cend = contents + sz;
1264 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1265 i < c;
1266 ++i, ++arsym, p += strlen ((char *) p) + 1)
1268 if (p >= cend)
1270 bfd_set_error (bfd_error_bad_value);
1271 return FALSE;
1273 arsym->name = (char *) p;
1276 bfd_ardata (abfd)->symdef_count = c;
1277 bfd_has_map (abfd) = TRUE;
1279 return TRUE;
1282 /* See if this is an XCOFF archive. */
1284 const bfd_target *
1285 _bfd_xcoff_archive_p (abfd)
1286 bfd *abfd;
1288 struct artdata *tdata_hold;
1289 char magic[SXCOFFARMAG];
1290 bfd_size_type amt = SXCOFFARMAG;
1292 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
1294 if (bfd_get_error () != bfd_error_system_call)
1295 bfd_set_error (bfd_error_wrong_format);
1296 return NULL;
1299 if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
1300 && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1302 bfd_set_error (bfd_error_wrong_format);
1303 return NULL;
1306 tdata_hold = bfd_ardata (abfd);
1308 amt = sizeof (struct artdata);
1309 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
1310 if (bfd_ardata (abfd) == (struct artdata *) NULL)
1311 goto error_ret_restore;
1313 /* Cleared by bfd_zalloc above.
1314 bfd_ardata (abfd)->cache = NULL;
1315 bfd_ardata (abfd)->archive_head = NULL;
1316 bfd_ardata (abfd)->symdefs = NULL;
1317 bfd_ardata (abfd)->extended_names = NULL;
1318 bfd_ardata (abfd)->extended_names_size = 0; */
1320 /* Now handle the two formats. */
1321 if (magic[1] != 'b')
1323 /* This is the old format. */
1324 struct xcoff_ar_file_hdr hdr;
1326 /* Copy over the magic string. */
1327 memcpy (hdr.magic, magic, SXCOFFARMAG);
1329 /* Now read the rest of the file header. */
1330 amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
1331 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1333 if (bfd_get_error () != bfd_error_system_call)
1334 bfd_set_error (bfd_error_wrong_format);
1335 goto error_ret;
1338 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1339 (char **) NULL, 10);
1341 amt = SIZEOF_AR_FILE_HDR;
1342 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1343 if (bfd_ardata (abfd)->tdata == NULL)
1344 goto error_ret;
1346 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
1348 else
1350 /* This is the new format. */
1351 struct xcoff_ar_file_hdr_big hdr;
1353 /* Copy over the magic string. */
1354 memcpy (hdr.magic, magic, SXCOFFARMAG);
1356 /* Now read the rest of the file header. */
1357 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1358 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1360 if (bfd_get_error () != bfd_error_system_call)
1361 bfd_set_error (bfd_error_wrong_format);
1362 goto error_ret;
1365 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
1366 (const char **) 0,
1367 10);
1369 amt = SIZEOF_AR_FILE_HDR_BIG;
1370 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1371 if (bfd_ardata (abfd)->tdata == NULL)
1372 goto error_ret;
1374 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1377 if (! _bfd_xcoff_slurp_armap (abfd))
1379 error_ret:
1380 bfd_release (abfd, bfd_ardata (abfd));
1381 error_ret_restore:
1382 bfd_ardata (abfd) = tdata_hold;
1383 return NULL;
1386 return abfd->xvec;
1389 /* Read the archive header in an XCOFF archive. */
1392 _bfd_xcoff_read_ar_hdr (abfd)
1393 bfd *abfd;
1395 bfd_size_type namlen;
1396 struct areltdata *ret;
1397 bfd_size_type amt = sizeof (struct areltdata);
1399 ret = (struct areltdata *) bfd_alloc (abfd, amt);
1400 if (ret == NULL)
1401 return NULL;
1403 if (! xcoff_big_format_p (abfd))
1405 struct xcoff_ar_hdr hdr;
1406 struct xcoff_ar_hdr *hdrp;
1408 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1409 != SIZEOF_AR_HDR)
1411 free (ret);
1412 return NULL;
1415 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1416 amt = SIZEOF_AR_HDR + namlen + 1;
1417 hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
1418 if (hdrp == NULL)
1420 free (ret);
1421 return NULL;
1423 memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
1424 if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
1426 free (ret);
1427 return NULL;
1429 ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
1431 ret->arch_header = (char *) hdrp;
1432 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1433 ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
1435 else
1437 struct xcoff_ar_hdr_big hdr;
1438 struct xcoff_ar_hdr_big *hdrp;
1440 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1441 != SIZEOF_AR_HDR_BIG)
1443 free (ret);
1444 return NULL;
1447 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1448 amt = SIZEOF_AR_HDR_BIG + namlen + 1;
1449 hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
1450 if (hdrp == NULL)
1452 free (ret);
1453 return NULL;
1455 memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
1456 if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
1458 free (ret);
1459 return NULL;
1461 ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
1463 ret->arch_header = (char *) hdrp;
1464 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1465 machines) since the field width is 20 and there numbers with more
1466 than 32 bits can be represented. */
1467 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1468 ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
1471 /* Skip over the XCOFFARFMAG at the end of the file name. */
1472 if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
1473 return NULL;
1475 return (PTR) ret;
1478 /* Open the next element in an XCOFF archive. */
1480 bfd *
1481 _bfd_xcoff_openr_next_archived_file (archive, last_file)
1482 bfd *archive;
1483 bfd *last_file;
1485 file_ptr filestart;
1487 if (xcoff_ardata (archive) == NULL)
1489 bfd_set_error (bfd_error_invalid_operation);
1490 return NULL;
1493 if (! xcoff_big_format_p (archive))
1495 if (last_file == NULL)
1496 filestart = bfd_ardata (archive)->first_file_filepos;
1497 else
1498 filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
1499 10);
1501 if (filestart == 0
1502 || filestart == strtol (xcoff_ardata (archive)->memoff,
1503 (char **) NULL, 10)
1504 || filestart == strtol (xcoff_ardata (archive)->symoff,
1505 (char **) NULL, 10))
1507 bfd_set_error (bfd_error_no_more_archived_files);
1508 return NULL;
1511 else
1513 if (last_file == NULL)
1514 filestart = bfd_ardata (archive)->first_file_filepos;
1515 else
1516 /* XXX These actually have to be a calls to strtoll (at least
1517 on 32-bit machines) since the fields's width is 20 and
1518 there numbers with more than 32 bits can be represented. */
1519 filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
1520 10);
1522 /* XXX These actually have to be calls to strtoll (at least on 32-bit
1523 machines) since the fields's width is 20 and there numbers with more
1524 than 32 bits can be represented. */
1525 if (filestart == 0
1526 || filestart == strtol (xcoff_ardata_big (archive)->memoff,
1527 (char **) NULL, 10)
1528 || filestart == strtol (xcoff_ardata_big (archive)->symoff,
1529 (char **) NULL, 10))
1531 bfd_set_error (bfd_error_no_more_archived_files);
1532 return NULL;
1536 return _bfd_get_elt_at_filepos (archive, filestart);
1539 /* Stat an element in an XCOFF archive. */
1542 _bfd_xcoff_stat_arch_elt (abfd, s)
1543 bfd *abfd;
1544 struct stat *s;
1546 if (abfd->arelt_data == NULL)
1548 bfd_set_error (bfd_error_invalid_operation);
1549 return -1;
1552 if (! xcoff_big_format_p (abfd->my_archive))
1554 struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
1556 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1557 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1558 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1559 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1560 s->st_size = arch_eltdata (abfd)->parsed_size;
1562 else
1564 struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
1566 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1567 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1568 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1569 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1570 s->st_size = arch_eltdata (abfd)->parsed_size;
1573 return 0;
1576 /* Normalize a file name for inclusion in an archive. */
1578 static const char *
1579 normalize_filename (abfd)
1580 bfd *abfd;
1582 const char *file;
1583 const char *filename;
1585 file = bfd_get_filename (abfd);
1586 filename = strrchr (file, '/');
1587 if (filename != NULL)
1588 filename++;
1589 else
1590 filename = file;
1591 return filename;
1594 /* Write out an XCOFF armap. */
1596 static bfd_boolean
1597 xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
1598 bfd *abfd;
1599 unsigned int elength ATTRIBUTE_UNUSED;
1600 struct orl *map;
1601 unsigned int orl_count;
1602 int stridx;
1604 struct xcoff_ar_hdr hdr;
1605 char *p;
1606 unsigned char buf[4];
1607 bfd *sub;
1608 file_ptr fileoff;
1609 unsigned int i;
1611 memset (&hdr, 0, sizeof hdr);
1612 sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
1613 sprintf (hdr.nextoff, "%d", 0);
1614 memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
1615 sprintf (hdr.date, "%d", 0);
1616 sprintf (hdr.uid, "%d", 0);
1617 sprintf (hdr.gid, "%d", 0);
1618 sprintf (hdr.mode, "%d", 0);
1619 sprintf (hdr.namlen, "%d", 0);
1621 /* We need spaces, not null bytes, in the header. */
1622 for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
1623 if (*p == '\0')
1624 *p = ' ';
1626 if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1627 != SIZEOF_AR_HDR
1628 || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
1629 != SXCOFFARFMAG))
1630 return FALSE;
1632 H_PUT_32 (abfd, orl_count, buf);
1633 if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1634 return FALSE;
1636 sub = abfd->archive_head;
1637 fileoff = SIZEOF_AR_FILE_HDR;
1638 i = 0;
1639 while (sub != NULL && i < orl_count)
1641 size_t namlen;
1643 while (map[i].u.abfd == sub)
1645 H_PUT_32 (abfd, fileoff, buf);
1646 if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1647 return FALSE;
1648 ++i;
1650 namlen = strlen (normalize_filename (sub));
1651 namlen = (namlen + 1) &~ (size_t) 1;
1652 fileoff += (SIZEOF_AR_HDR
1653 + namlen
1654 + SXCOFFARFMAG
1655 + arelt_size (sub));
1656 fileoff = (fileoff + 1) &~ 1;
1657 sub = sub->next;
1660 for (i = 0; i < orl_count; i++)
1662 const char *name;
1663 size_t namlen;
1665 name = *map[i].name;
1666 namlen = strlen (name);
1667 if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
1668 return FALSE;
1671 if ((stridx & 1) != 0)
1673 char b;
1675 b = '\0';
1676 if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1677 return FALSE;
1680 return TRUE;
1683 static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
1684 #define FMT20 "%-20lld"
1685 #define FMT12 "%-12d"
1686 #define FMT12_OCTAL "%-12o"
1687 #define FMT4 "%-4d"
1688 #define PRINT20(d, v) \
1689 sprintf (buff20, FMT20, (long long)(v)), \
1690 memcpy ((void *) (d), buff20, 20)
1692 #define PRINT12(d, v) \
1693 sprintf (buff20, FMT12, (int)(v)), \
1694 memcpy ((void *) (d), buff20, 12)
1696 #define PRINT12_OCTAL(d, v) \
1697 sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
1698 memcpy ((void *) (d), buff20, 12)
1700 #define PRINT4(d, v) \
1701 sprintf (buff20, FMT4, (int)(v)), \
1702 memcpy ((void *) (d), buff20, 4)
1704 #define READ20(d, v) \
1705 buff20[20] = 0, \
1706 memcpy (buff20, (d), 20), \
1707 (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
1709 static bfd_boolean
1710 do_pad (abfd, number)
1711 bfd *abfd;
1712 unsigned int number;
1714 bfd_byte b = 0;
1716 /* Limit pad to <= 4096. */
1717 if (number > 4096)
1718 return FALSE;
1720 while (number--)
1721 if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1722 return FALSE;
1724 return TRUE;
1727 static bfd_boolean
1728 do_copy (out_bfd, in_bfd)
1729 bfd *out_bfd;
1730 bfd *in_bfd;
1732 bfd_size_type remaining;
1733 bfd_byte buffer[DEFAULT_BUFFERSIZE];
1735 if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
1736 return FALSE;
1738 remaining = arelt_size (in_bfd);
1740 while (remaining >= DEFAULT_BUFFERSIZE)
1742 if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
1743 || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
1744 return FALSE;
1746 remaining -= DEFAULT_BUFFERSIZE;
1749 if (remaining)
1751 if (bfd_bread (buffer, remaining, in_bfd) != remaining
1752 || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
1753 return FALSE;
1756 return TRUE;
1759 static bfd_boolean
1760 do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
1761 bfd *out_bfd;
1762 bfd *in_bfd;
1763 file_ptr *offset;
1764 int ar_header_size;
1766 if (bfd_check_format (in_bfd, bfd_object)
1767 && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
1768 && (in_bfd->flags & DYNAMIC) != 0)
1770 bfd_size_type pad = 0;
1771 int text_align_power;
1773 text_align_power = bfd_xcoff_text_align_power (in_bfd);
1775 pad = 1 << text_align_power;
1776 pad -= (*offset + ar_header_size) & (pad - 1);
1778 if (! do_pad (out_bfd, pad))
1779 return FALSE;
1781 *offset += pad;
1784 return TRUE;
1787 static bfd_boolean
1788 xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
1789 bfd *abfd;
1790 unsigned int elength ATTRIBUTE_UNUSED;
1791 struct orl *map;
1792 unsigned int orl_count;
1793 int stridx;
1795 struct xcoff_ar_file_hdr_big *fhdr;
1796 bfd_vma i, sym_32, sym_64, str_32, str_64;
1797 const bfd_arch_info_type *arch_info = NULL;
1798 bfd *current_bfd;
1799 size_t string_length;
1800 file_ptr nextoff, prevoff;
1802 /* First, we look through the symbols and work out which are
1803 from 32-bit objects and which from 64-bit ones. */
1804 sym_32 = sym_64 = str_32 = str_64 = 0;
1806 current_bfd = abfd->archive_head;
1807 if (current_bfd != NULL)
1808 arch_info = bfd_get_arch_info (current_bfd);
1809 i = 0;
1810 while (current_bfd != NULL && i < orl_count)
1812 while (map[i].u.abfd == current_bfd)
1814 string_length = strlen (*map[i].name) + 1;
1816 if (arch_info->bits_per_address == 64)
1818 sym_64++;
1819 str_64 += string_length;
1821 else
1823 sym_32++;
1824 str_32 += string_length;
1826 i++;
1828 current_bfd = current_bfd->next;
1829 if (current_bfd != NULL)
1830 arch_info = bfd_get_arch_info (current_bfd);
1833 /* A quick sanity check... */
1834 BFD_ASSERT (sym_64 + sym_32 == orl_count);
1835 /* Explicit cast to int for compiler. */
1836 BFD_ASSERT ((int)(str_64 + str_32) == stridx);
1838 fhdr = xcoff_ardata_big (abfd);
1840 /* xcoff_write_archive_contents_big passes nextoff in symoff. */
1841 READ20 (fhdr->memoff, prevoff);
1842 READ20 (fhdr->symoff, nextoff);
1844 BFD_ASSERT (nextoff == bfd_tell (abfd));
1846 /* Write out the symbol table.
1847 Layout :
1849 standard big archive header
1850 0x0000 ar_size [0x14]
1851 0x0014 ar_nxtmem [0x14]
1852 0x0028 ar_prvmem [0x14]
1853 0x003C ar_date [0x0C]
1854 0x0048 ar_uid [0x0C]
1855 0x0054 ar_gid [0x0C]
1856 0x0060 ar_mod [0x0C]
1857 0x006C ar_namelen[0x04]
1858 0x0070 ar_fmag [SXCOFFARFMAG]
1860 Symbol table
1861 0x0072 num_syms [0x08], binary
1862 0x0078 offsets [0x08 * num_syms], binary
1863 0x0086 + 0x08 * num_syms names [??]
1864 ?? pad to even bytes.
1867 if (sym_32)
1869 struct xcoff_ar_hdr_big *hdr;
1870 char *symbol_table;
1871 char *st;
1872 file_ptr fileoff;
1874 bfd_vma symbol_table_size =
1875 SIZEOF_AR_HDR_BIG
1876 + SXCOFFARFMAG
1878 + 8 * sym_32
1879 + str_32 + (str_32 & 1);
1881 symbol_table = bfd_zmalloc (symbol_table_size);
1882 if (symbol_table == NULL)
1883 return FALSE;
1885 hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1887 PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
1889 if (sym_64)
1890 PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
1891 else
1892 PRINT20 (hdr->nextoff, 0);
1894 PRINT20 (hdr->prevoff, prevoff);
1895 PRINT12 (hdr->date, 0);
1896 PRINT12 (hdr->uid, 0);
1897 PRINT12 (hdr->gid, 0);
1898 PRINT12 (hdr->mode, 0);
1899 PRINT4 (hdr->namlen, 0) ;
1901 st = symbol_table + SIZEOF_AR_HDR_BIG;
1902 memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1903 st += SXCOFFARFMAG;
1905 bfd_h_put_64 (abfd, sym_32, st);
1906 st += 8;
1908 /* loop over the 32 bit offsets */
1909 current_bfd = abfd->archive_head;
1910 if (current_bfd != NULL)
1911 arch_info = bfd_get_arch_info (current_bfd);
1912 fileoff = SIZEOF_AR_FILE_HDR_BIG;
1913 i = 0;
1914 while (current_bfd != NULL && i < orl_count)
1916 while (map[i].u.abfd == current_bfd)
1918 if (arch_info->bits_per_address == 32)
1920 bfd_h_put_64 (abfd, fileoff, st);
1921 st += 8;
1923 i++;
1925 string_length = strlen (normalize_filename (current_bfd));
1926 string_length += string_length & 1;
1927 fileoff += (SIZEOF_AR_HDR_BIG
1928 + string_length
1929 + SXCOFFARFMAG
1930 + arelt_size (current_bfd));
1931 fileoff += fileoff & 1;
1932 current_bfd = current_bfd->next;
1933 if (current_bfd != NULL)
1934 arch_info = bfd_get_arch_info (current_bfd);
1937 /* loop over the 32 bit symbol names */
1938 current_bfd = abfd->archive_head;
1939 if (current_bfd != NULL)
1940 arch_info = bfd_get_arch_info (current_bfd);
1941 i = 0;
1942 while (current_bfd != NULL && i < orl_count)
1944 while (map[i].u.abfd == current_bfd)
1946 if (arch_info->bits_per_address == 32)
1948 string_length = sprintf (st, "%s", *map[i].name);
1949 st += string_length + 1;
1951 i++;
1953 current_bfd = current_bfd->next;
1954 if (current_bfd != NULL)
1955 arch_info = bfd_get_arch_info (current_bfd);
1958 bfd_bwrite (symbol_table, symbol_table_size, abfd);
1960 free (symbol_table);
1962 prevoff = nextoff;
1963 nextoff = nextoff + symbol_table_size;
1965 else
1966 PRINT20 (fhdr->symoff, 0);
1968 if (sym_64)
1970 struct xcoff_ar_hdr_big *hdr;
1971 char *symbol_table;
1972 char *st;
1973 file_ptr fileoff;
1975 bfd_vma symbol_table_size =
1976 SIZEOF_AR_HDR_BIG
1977 + SXCOFFARFMAG
1979 + 8 * sym_64
1980 + str_64 + (str_64 & 1);
1982 symbol_table = bfd_zmalloc (symbol_table_size);
1983 if (symbol_table == NULL)
1984 return FALSE;
1986 hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1988 PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
1989 PRINT20 (hdr->nextoff, 0);
1990 PRINT20 (hdr->prevoff, prevoff);
1991 PRINT12 (hdr->date, 0);
1992 PRINT12 (hdr->uid, 0);
1993 PRINT12 (hdr->gid, 0);
1994 PRINT12 (hdr->mode, 0);
1995 PRINT4 (hdr->namlen, 0);
1997 st = symbol_table + SIZEOF_AR_HDR_BIG;
1998 memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1999 st += SXCOFFARFMAG;
2001 bfd_h_put_64 (abfd, sym_64, st);
2002 st += 8;
2004 /* loop over the 64 bit offsets */
2005 current_bfd = abfd->archive_head;
2006 if (current_bfd != NULL)
2007 arch_info = bfd_get_arch_info (current_bfd);
2008 fileoff = SIZEOF_AR_FILE_HDR_BIG;
2009 i = 0;
2010 while (current_bfd != NULL && i < orl_count)
2012 while (map[i].u.abfd == current_bfd)
2014 if (arch_info->bits_per_address == 64)
2016 bfd_h_put_64 (abfd, fileoff, st);
2017 st += 8;
2019 i++;
2021 string_length = strlen (normalize_filename (current_bfd));
2022 string_length += string_length & 1;
2023 fileoff += (SIZEOF_AR_HDR_BIG
2024 + string_length
2025 + SXCOFFARFMAG
2026 + arelt_size (current_bfd));
2027 fileoff += fileoff & 1;
2028 current_bfd = current_bfd->next;
2029 if (current_bfd != NULL)
2030 arch_info = bfd_get_arch_info (current_bfd);
2033 /* loop over the 64 bit symbol names */
2034 current_bfd = abfd->archive_head;
2035 if (current_bfd != NULL)
2036 arch_info = bfd_get_arch_info (current_bfd);
2037 i = 0;
2038 while (current_bfd != NULL && i < orl_count)
2040 while (map[i].u.abfd == current_bfd)
2042 if (arch_info->bits_per_address == 64)
2044 string_length = sprintf (st, "%s", *map[i].name);
2045 st += string_length + 1;
2047 i++;
2049 current_bfd = current_bfd->next;
2050 if (current_bfd != NULL)
2051 arch_info = bfd_get_arch_info (current_bfd);
2054 bfd_bwrite (symbol_table, symbol_table_size, abfd);
2056 free (symbol_table);
2058 PRINT20 (fhdr->symoff64, nextoff);
2060 else
2061 PRINT20 (fhdr->symoff64, 0);
2063 return TRUE;
2066 bfd_boolean
2067 _bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
2068 bfd *abfd;
2069 unsigned int elength ATTRIBUTE_UNUSED;
2070 struct orl *map;
2071 unsigned int orl_count;
2072 int stridx;
2074 if (! xcoff_big_format_p (abfd))
2075 return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
2076 else
2077 return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
2080 /* Write out an XCOFF archive. We always write an entire archive,
2081 rather than fussing with the freelist and so forth. */
2083 static bfd_boolean
2084 xcoff_write_archive_contents_old (abfd)
2085 bfd *abfd;
2087 struct xcoff_ar_file_hdr fhdr;
2088 bfd_size_type count;
2089 bfd_size_type total_namlen;
2090 file_ptr *offsets;
2091 bfd_boolean makemap;
2092 bfd_boolean hasobjects;
2093 file_ptr prevoff, nextoff;
2094 bfd *sub;
2095 size_t i;
2096 struct xcoff_ar_hdr ahdr;
2097 bfd_size_type size;
2098 char *p;
2099 char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
2101 memset (&fhdr, 0, sizeof fhdr);
2102 (void) strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
2103 sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
2104 sprintf (fhdr.freeoff, "%d", 0);
2106 count = 0;
2107 total_namlen = 0;
2108 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2110 ++count;
2111 total_namlen += strlen (normalize_filename (sub)) + 1;
2113 offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2114 if (offsets == NULL)
2115 return FALSE;
2117 if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
2118 return FALSE;
2120 makemap = bfd_has_map (abfd);
2121 hasobjects = FALSE;
2122 prevoff = 0;
2123 nextoff = SIZEOF_AR_FILE_HDR;
2124 for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
2126 const char *name;
2127 bfd_size_type namlen;
2128 struct xcoff_ar_hdr *ahdrp;
2129 bfd_size_type remaining;
2131 if (makemap && ! hasobjects)
2133 if (bfd_check_format (sub, bfd_object))
2134 hasobjects = TRUE;
2137 name = normalize_filename (sub);
2138 namlen = strlen (name);
2140 if (sub->arelt_data != NULL)
2141 ahdrp = arch_xhdr (sub);
2142 else
2143 ahdrp = NULL;
2145 if (ahdrp == NULL)
2147 struct stat s;
2149 memset (&ahdr, 0, sizeof ahdr);
2150 ahdrp = &ahdr;
2151 if (stat (bfd_get_filename (sub), &s) != 0)
2153 bfd_set_error (bfd_error_system_call);
2154 return FALSE;
2157 sprintf (ahdrp->size, "%ld", (long) s.st_size);
2158 sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2159 sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2160 sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2161 sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2163 if (sub->arelt_data == NULL)
2165 size = sizeof (struct areltdata);
2166 sub->arelt_data = bfd_alloc (sub, size);
2167 if (sub->arelt_data == NULL)
2168 return FALSE;
2171 arch_eltdata (sub)->parsed_size = s.st_size;
2174 sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2175 sprintf (ahdrp->namlen, "%ld", (long) namlen);
2177 /* If the length of the name is odd, we write out the null byte
2178 after the name as well. */
2179 namlen = (namlen + 1) &~ (bfd_size_type) 1;
2181 remaining = arelt_size (sub);
2182 size = (SIZEOF_AR_HDR
2183 + namlen
2184 + SXCOFFARFMAG
2185 + remaining);
2187 BFD_ASSERT (nextoff == bfd_tell (abfd));
2189 offsets[i] = nextoff;
2191 prevoff = nextoff;
2192 nextoff += size + (size & 1);
2194 sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
2196 /* We need spaces, not null bytes, in the header. */
2197 for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2198 if (*p == '\0')
2199 *p = ' ';
2201 if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2202 != SIZEOF_AR_HDR)
2203 || bfd_bwrite ((PTR) name, namlen, abfd) != namlen
2204 || bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
2205 abfd) != SXCOFFARFMAG)
2206 return FALSE;
2208 if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
2209 return FALSE;
2211 if (! do_copy (abfd, sub))
2212 return FALSE;
2214 if (! do_pad (abfd, size & 1))
2215 return FALSE;
2218 sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2220 /* Write out the member table. */
2222 BFD_ASSERT (nextoff == bfd_tell (abfd));
2223 sprintf (fhdr.memoff, "%ld", (long) nextoff);
2225 memset (&ahdr, 0, sizeof ahdr);
2226 sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
2227 + count * XCOFFARMAG_ELEMENT_SIZE
2228 + total_namlen));
2229 sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2230 sprintf (ahdr.date, "%d", 0);
2231 sprintf (ahdr.uid, "%d", 0);
2232 sprintf (ahdr.gid, "%d", 0);
2233 sprintf (ahdr.mode, "%d", 0);
2234 sprintf (ahdr.namlen, "%d", 0);
2236 size = (SIZEOF_AR_HDR
2237 + XCOFFARMAG_ELEMENT_SIZE
2238 + count * XCOFFARMAG_ELEMENT_SIZE
2239 + total_namlen
2240 + SXCOFFARFMAG);
2242 prevoff = nextoff;
2243 nextoff += size + (size & 1);
2245 if (makemap && hasobjects)
2246 sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2247 else
2248 sprintf (ahdr.nextoff, "%d", 0);
2250 /* We need spaces, not null bytes, in the header. */
2251 for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2252 if (*p == '\0')
2253 *p = ' ';
2255 if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2256 != SIZEOF_AR_HDR)
2257 || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2258 != SXCOFFARFMAG))
2259 return FALSE;
2261 sprintf (decbuf, "%-12ld", (long) count);
2262 if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
2263 != XCOFFARMAG_ELEMENT_SIZE)
2264 return FALSE;
2265 for (i = 0; i < (size_t) count; i++)
2267 sprintf (decbuf, "%-12ld", (long) offsets[i]);
2268 if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
2269 abfd) != XCOFFARMAG_ELEMENT_SIZE)
2270 return FALSE;
2272 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2274 const char *name;
2275 bfd_size_type namlen;
2277 name = normalize_filename (sub);
2278 namlen = strlen (name);
2279 if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
2280 return FALSE;
2283 if (! do_pad (abfd, size & 1))
2284 return FALSE;
2286 /* Write out the armap, if appropriate. */
2287 if (! makemap || ! hasobjects)
2288 sprintf (fhdr.symoff, "%d", 0);
2289 else
2291 BFD_ASSERT (nextoff == bfd_tell (abfd));
2292 sprintf (fhdr.symoff, "%ld", (long) nextoff);
2293 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2294 if (! _bfd_compute_and_write_armap (abfd, 0))
2295 return FALSE;
2298 /* Write out the archive file header. */
2300 /* We need spaces, not null bytes, in the header. */
2301 for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2302 if (*p == '\0')
2303 *p = ' ';
2305 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2306 || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
2307 != SIZEOF_AR_FILE_HDR))
2308 return FALSE;
2310 return TRUE;
2313 static bfd_boolean
2314 xcoff_write_archive_contents_big (abfd)
2315 bfd *abfd;
2317 struct xcoff_ar_file_hdr_big fhdr;
2318 bfd_size_type count;
2319 bfd_size_type total_namlen;
2320 file_ptr *offsets;
2321 bfd_boolean makemap;
2322 bfd_boolean hasobjects;
2323 file_ptr prevoff, nextoff;
2324 bfd *current_bfd;
2325 size_t i;
2326 struct xcoff_ar_hdr_big *hdr, ahdr;
2327 bfd_size_type size;
2328 char *member_table, *mt;
2329 bfd_vma member_table_size;
2331 memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
2332 memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
2334 if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
2335 return FALSE;
2337 /* Calculate count and total_namlen. */
2338 makemap = bfd_has_map (abfd);
2339 hasobjects = FALSE;
2340 for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
2341 current_bfd != NULL;
2342 current_bfd = current_bfd->next, count++)
2344 total_namlen += strlen (normalize_filename (current_bfd)) + 1;
2346 if (makemap
2347 && ! hasobjects
2348 && bfd_check_format (current_bfd, bfd_object))
2349 hasobjects = TRUE;
2352 offsets = NULL;
2353 if (count)
2355 offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2356 if (offsets == NULL)
2357 return FALSE;
2360 prevoff = 0;
2361 nextoff = SIZEOF_AR_FILE_HDR_BIG;
2362 for (current_bfd = abfd->archive_head, i = 0;
2363 current_bfd != NULL;
2364 current_bfd = current_bfd->next, i++)
2366 const char *name;
2367 bfd_size_type namlen;
2368 struct xcoff_ar_hdr_big *ahdrp;
2369 bfd_size_type remaining;
2371 name = normalize_filename (current_bfd);
2372 namlen = strlen (name);
2374 if (current_bfd->arelt_data != NULL)
2375 ahdrp = arch_xhdr_big (current_bfd);
2376 else
2377 ahdrp = NULL;
2379 if (ahdrp == NULL)
2381 struct stat s;
2383 ahdrp = &ahdr;
2384 /* XXX This should actually be a call to stat64 (at least on
2385 32-bit machines).
2386 XXX This call will fail if the original object is not found. */
2387 if (stat (bfd_get_filename (current_bfd), &s) != 0)
2389 bfd_set_error (bfd_error_system_call);
2390 return FALSE;
2393 PRINT20 (ahdrp->size, s.st_size);
2394 PRINT12 (ahdrp->date, s.st_mtime);
2395 PRINT12 (ahdrp->uid, s.st_uid);
2396 PRINT12 (ahdrp->gid, s.st_gid);
2397 PRINT12_OCTAL (ahdrp->mode, s.st_mode);
2399 if (current_bfd->arelt_data == NULL)
2401 size = sizeof (struct areltdata);
2402 current_bfd->arelt_data = bfd_alloc (current_bfd, size);
2403 if (current_bfd->arelt_data == NULL)
2404 return FALSE;
2407 arch_eltdata (current_bfd)->parsed_size = s.st_size;
2410 PRINT20 (ahdrp->prevoff, prevoff);
2411 PRINT4 (ahdrp->namlen, namlen);
2413 /* If the length of the name is odd, we write out the null byte
2414 after the name as well. */
2415 namlen = (namlen + 1) &~ (bfd_size_type) 1;
2417 remaining = arelt_size (current_bfd);
2418 size = (SIZEOF_AR_HDR_BIG
2419 + namlen
2420 + SXCOFFARFMAG
2421 + remaining);
2423 BFD_ASSERT (nextoff == bfd_tell (abfd));
2425 /* Check for xcoff shared objects.
2426 Their text section needs to be aligned wrt the archive file position.
2427 This requires extra padding before the archive header. */
2428 if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
2429 SIZEOF_AR_HDR_BIG + namlen
2430 + SXCOFFARFMAG))
2431 return FALSE;
2433 offsets[i] = nextoff;
2435 prevoff = nextoff;
2436 nextoff += size + (size & 1);
2438 PRINT20 (ahdrp->nextoff, nextoff);
2440 if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
2441 != SIZEOF_AR_HDR_BIG)
2442 || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
2443 || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
2444 abfd) != SXCOFFARFMAG))
2445 return FALSE;
2447 if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
2448 return FALSE;
2450 if (! do_copy (abfd, current_bfd))
2451 return FALSE;
2453 if (! do_pad (abfd, size & 1))
2454 return FALSE;
2457 if (count)
2459 PRINT20 (fhdr.firstmemoff, offsets[0]);
2460 PRINT20 (fhdr.lastmemoff, prevoff);
2463 /* Write out the member table.
2464 Layout :
2466 standard big archive header
2467 0x0000 ar_size [0x14]
2468 0x0014 ar_nxtmem [0x14]
2469 0x0028 ar_prvmem [0x14]
2470 0x003C ar_date [0x0C]
2471 0x0048 ar_uid [0x0C]
2472 0x0054 ar_gid [0x0C]
2473 0x0060 ar_mod [0x0C]
2474 0x006C ar_namelen[0x04]
2475 0x0070 ar_fmag [0x02]
2477 Member table
2478 0x0072 count [0x14]
2479 0x0086 offsets [0x14 * counts]
2480 0x0086 + 0x14 * counts names [??]
2481 ?? pad to even bytes.
2484 BFD_ASSERT (nextoff == bfd_tell (abfd));
2486 member_table_size = (SIZEOF_AR_HDR_BIG
2487 + SXCOFFARFMAG
2488 + XCOFFARMAGBIG_ELEMENT_SIZE
2489 + count * XCOFFARMAGBIG_ELEMENT_SIZE
2490 + total_namlen);
2492 member_table_size += member_table_size & 1;
2493 member_table = bfd_zmalloc (member_table_size);
2494 if (member_table == NULL)
2495 return FALSE;
2497 hdr = (struct xcoff_ar_hdr_big *) member_table;
2499 PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
2500 + count * XCOFFARMAGBIG_ELEMENT_SIZE
2501 + total_namlen + (total_namlen & 1)));
2502 if (makemap && hasobjects)
2503 PRINT20 (hdr->nextoff, nextoff + member_table_size);
2504 else
2505 PRINT20 (hdr->nextoff, 0);
2506 PRINT20 (hdr->prevoff, prevoff);
2507 PRINT12 (hdr->date, 0);
2508 PRINT12 (hdr->uid, 0);
2509 PRINT12 (hdr->gid, 0);
2510 PRINT12 (hdr->mode, 0);
2511 PRINT4 (hdr->namlen, 0);
2513 mt = member_table + SIZEOF_AR_HDR_BIG;
2514 memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
2515 mt += SXCOFFARFMAG;
2517 PRINT20 (mt, count);
2518 mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2519 for (i = 0; i < (size_t) count; i++)
2521 PRINT20 (mt, offsets[i]);
2522 mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2525 if (count)
2527 free (offsets);
2528 offsets = NULL;
2531 for (current_bfd = abfd->archive_head; current_bfd != NULL;
2532 current_bfd = current_bfd->next)
2534 const char *name;
2535 size_t namlen;
2537 name = normalize_filename (current_bfd);
2538 namlen = sprintf (mt, "%s", name);
2539 mt += namlen + 1;
2542 if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
2543 return FALSE;
2545 free (member_table);
2547 PRINT20 (fhdr.memoff, nextoff);
2549 prevoff = nextoff;
2550 nextoff += member_table_size;
2552 /* Write out the armap, if appropriate. */
2554 if (! makemap || ! hasobjects)
2555 PRINT20 (fhdr.symoff, 0);
2556 else
2558 BFD_ASSERT (nextoff == bfd_tell (abfd));
2560 /* Save nextoff in fhdr.symoff so the armap routine can use it. */
2561 PRINT20 (fhdr.symoff, nextoff);
2563 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2564 if (! _bfd_compute_and_write_armap (abfd, 0))
2565 return FALSE;
2568 /* Write out the archive file header. */
2570 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2571 || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
2572 abfd) != SIZEOF_AR_FILE_HDR_BIG))
2573 return FALSE;
2575 return TRUE;
2578 bfd_boolean
2579 _bfd_xcoff_write_archive_contents (abfd)
2580 bfd *abfd;
2582 if (! xcoff_big_format_p (abfd))
2583 return xcoff_write_archive_contents_old (abfd);
2584 else
2585 return xcoff_write_archive_contents_big (abfd);
2588 /* We can't use the usual coff_sizeof_headers routine, because AIX
2589 always uses an a.out header. */
2592 _bfd_xcoff_sizeof_headers (bfd *abfd,
2593 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2595 int size;
2597 size = FILHSZ;
2598 if (xcoff_data (abfd)->full_aouthdr)
2599 size += AOUTSZ;
2600 else
2601 size += SMALL_AOUTSZ;
2602 size += abfd->section_count * SCNHSZ;
2603 return size;
2606 /* Routines to swap information in the XCOFF .loader section. If we
2607 ever need to write an XCOFF loader, this stuff will need to be
2608 moved to another file shared by the linker (which XCOFF calls the
2609 ``binder'') and the loader. */
2611 /* Swap in the ldhdr structure. */
2613 static void
2614 xcoff_swap_ldhdr_in (abfd, s, dst)
2615 bfd *abfd;
2616 const PTR s;
2617 struct internal_ldhdr *dst;
2619 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
2621 dst->l_version = bfd_get_32 (abfd, src->l_version);
2622 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
2623 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
2624 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
2625 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
2626 dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
2627 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
2628 dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
2631 /* Swap out the ldhdr structure. */
2633 static void
2634 xcoff_swap_ldhdr_out (abfd, src, d)
2635 bfd *abfd;
2636 const struct internal_ldhdr *src;
2637 PTR d;
2639 struct external_ldhdr *dst = (struct external_ldhdr *) d;
2641 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
2642 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
2643 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
2644 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
2645 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
2646 bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
2647 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
2648 bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
2651 /* Swap in the ldsym structure. */
2653 static void
2654 xcoff_swap_ldsym_in (abfd, s, dst)
2655 bfd *abfd;
2656 const PTR s;
2657 struct internal_ldsym *dst;
2659 const struct external_ldsym *src = (const struct external_ldsym *) s;
2661 if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
2662 memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2663 } else {
2664 dst->_l._l_l._l_zeroes = 0;
2665 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
2667 dst->l_value = bfd_get_32 (abfd, src->l_value);
2668 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
2669 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
2670 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
2671 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
2672 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
2675 /* Swap out the ldsym structure. */
2677 static void
2678 xcoff_swap_ldsym_out (abfd, src, d)
2679 bfd *abfd;
2680 const struct internal_ldsym *src;
2681 PTR d;
2683 struct external_ldsym *dst = (struct external_ldsym *) d;
2685 if (src->_l._l_l._l_zeroes != 0)
2686 memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2687 else
2689 bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
2690 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
2691 dst->_l._l_l._l_offset);
2693 bfd_put_32 (abfd, src->l_value, dst->l_value);
2694 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
2695 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
2696 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
2697 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
2698 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
2701 static void
2702 xcoff_swap_reloc_in (abfd, s, d)
2703 bfd *abfd;
2704 PTR s;
2705 PTR d;
2707 struct external_reloc *src = (struct external_reloc *) s;
2708 struct internal_reloc *dst = (struct internal_reloc *) d;
2710 memset (dst, 0, sizeof (struct internal_reloc));
2712 dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
2713 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
2714 dst->r_size = bfd_get_8 (abfd, src->r_size);
2715 dst->r_type = bfd_get_8 (abfd, src->r_type);
2718 static unsigned int
2719 xcoff_swap_reloc_out (abfd, s, d)
2720 bfd *abfd;
2721 PTR s;
2722 PTR d;
2724 struct internal_reloc *src = (struct internal_reloc *) s;
2725 struct external_reloc *dst = (struct external_reloc *) d;
2727 bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
2728 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
2729 bfd_put_8 (abfd, src->r_type, dst->r_type);
2730 bfd_put_8 (abfd, src->r_size, dst->r_size);
2732 return bfd_coff_relsz (abfd);
2735 /* Swap in the ldrel structure. */
2737 static void
2738 xcoff_swap_ldrel_in (abfd, s, dst)
2739 bfd *abfd;
2740 const PTR s;
2741 struct internal_ldrel *dst;
2743 const struct external_ldrel *src = (const struct external_ldrel *) s;
2745 dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
2746 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
2747 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
2748 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
2751 /* Swap out the ldrel structure. */
2753 static void
2754 xcoff_swap_ldrel_out (abfd, src, d)
2755 bfd *abfd;
2756 const struct internal_ldrel *src;
2757 PTR d;
2759 struct external_ldrel *dst = (struct external_ldrel *) d;
2761 bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
2762 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
2763 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
2764 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
2768 bfd_boolean
2769 xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
2770 val, addend, relocation, contents)
2771 bfd *input_bfd ATTRIBUTE_UNUSED;
2772 asection *input_section ATTRIBUTE_UNUSED;
2773 bfd *output_bfd ATTRIBUTE_UNUSED;
2774 struct internal_reloc *rel ATTRIBUTE_UNUSED;
2775 struct internal_syment *sym ATTRIBUTE_UNUSED;
2776 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2777 bfd_vma val ATTRIBUTE_UNUSED;
2778 bfd_vma addend ATTRIBUTE_UNUSED;
2779 bfd_vma *relocation ATTRIBUTE_UNUSED;
2780 bfd_byte *contents ATTRIBUTE_UNUSED;
2782 return TRUE;
2785 bfd_boolean
2786 xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
2787 val, addend, relocation, contents)
2788 bfd *input_bfd;
2789 asection *input_section ATTRIBUTE_UNUSED;
2790 bfd *output_bfd ATTRIBUTE_UNUSED;
2791 struct internal_reloc *rel;
2792 struct internal_syment *sym ATTRIBUTE_UNUSED;
2793 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2794 bfd_vma val ATTRIBUTE_UNUSED;
2795 bfd_vma addend ATTRIBUTE_UNUSED;
2796 bfd_vma *relocation ATTRIBUTE_UNUSED;
2797 bfd_byte *contents ATTRIBUTE_UNUSED;
2799 (*_bfd_error_handler)
2800 (_("%s: unsupported relocation type 0x%02x"),
2801 bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
2802 bfd_set_error (bfd_error_bad_value);
2803 return FALSE;
2806 bfd_boolean
2807 xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
2808 val, addend, relocation, contents)
2809 bfd *input_bfd ATTRIBUTE_UNUSED;
2810 asection *input_section ATTRIBUTE_UNUSED;
2811 bfd *output_bfd ATTRIBUTE_UNUSED;
2812 struct internal_reloc *rel ATTRIBUTE_UNUSED;
2813 struct internal_syment *sym ATTRIBUTE_UNUSED;
2814 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2815 bfd_vma val;
2816 bfd_vma addend;
2817 bfd_vma *relocation;
2818 bfd_byte *contents ATTRIBUTE_UNUSED;
2820 *relocation = val + addend;
2821 return TRUE;
2824 bfd_boolean
2825 xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
2826 val, addend, relocation, contents)
2827 bfd *input_bfd ATTRIBUTE_UNUSED;
2828 asection *input_section ATTRIBUTE_UNUSED;
2829 bfd *output_bfd ATTRIBUTE_UNUSED;
2830 struct internal_reloc *rel ATTRIBUTE_UNUSED;
2831 struct internal_syment *sym ATTRIBUTE_UNUSED;
2832 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2833 bfd_vma val;
2834 bfd_vma addend;
2835 bfd_vma *relocation;
2836 bfd_byte *contents ATTRIBUTE_UNUSED;
2838 *relocation = addend - val;
2839 return TRUE;
2842 bfd_boolean
2843 xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
2844 val, addend, relocation, contents)
2845 bfd *input_bfd ATTRIBUTE_UNUSED;
2846 asection *input_section;
2847 bfd *output_bfd ATTRIBUTE_UNUSED;
2848 struct internal_reloc *rel ATTRIBUTE_UNUSED;
2849 struct internal_syment *sym ATTRIBUTE_UNUSED;
2850 struct reloc_howto_struct *howto;
2851 bfd_vma val;
2852 bfd_vma addend;
2853 bfd_vma *relocation;
2854 bfd_byte *contents ATTRIBUTE_UNUSED;
2856 howto->pc_relative = TRUE;
2858 /* A PC relative reloc includes the section address. */
2859 addend += input_section->vma;
2861 *relocation = val + addend;
2862 *relocation -= (input_section->output_section->vma
2863 + input_section->output_offset);
2864 return TRUE;
2867 bfd_boolean
2868 xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
2869 val, addend, relocation, contents)
2870 bfd *input_bfd;
2871 asection *input_section ATTRIBUTE_UNUSED;
2872 bfd *output_bfd;
2873 struct internal_reloc *rel;
2874 struct internal_syment *sym;
2875 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2876 bfd_vma val;
2877 bfd_vma addend ATTRIBUTE_UNUSED;
2878 bfd_vma *relocation;
2879 bfd_byte *contents ATTRIBUTE_UNUSED;
2881 struct xcoff_link_hash_entry *h;
2883 if (0 > rel->r_symndx)
2884 return FALSE;
2886 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2888 if (h != NULL && h->smclas != XMC_TD)
2890 if (h->toc_section == NULL)
2892 (*_bfd_error_handler)
2893 (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
2894 bfd_get_filename (input_bfd), rel->r_vaddr,
2895 h->root.root.string);
2896 bfd_set_error (bfd_error_bad_value);
2897 return FALSE;
2900 BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
2901 val = (h->toc_section->output_section->vma
2902 + h->toc_section->output_offset);
2905 *relocation = ((val - xcoff_data (output_bfd)->toc)
2906 - (sym->n_value - xcoff_data (input_bfd)->toc));
2907 return TRUE;
2910 bfd_boolean
2911 xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto,
2912 val, addend, relocation, contents)
2913 bfd *input_bfd ATTRIBUTE_UNUSED;
2914 asection *input_section ATTRIBUTE_UNUSED;
2915 bfd *output_bfd ATTRIBUTE_UNUSED;
2916 struct internal_reloc *rel ATTRIBUTE_UNUSED;
2917 struct internal_syment *sym ATTRIBUTE_UNUSED;
2918 struct reloc_howto_struct *howto;
2919 bfd_vma val;
2920 bfd_vma addend;
2921 bfd_vma *relocation;
2922 bfd_byte *contents ATTRIBUTE_UNUSED;
2924 howto->src_mask &= ~3;
2925 howto->dst_mask = howto->src_mask;
2927 *relocation = val + addend;
2929 return TRUE;
2932 static bfd_boolean
2933 xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
2934 val, addend, relocation, contents)
2935 bfd *input_bfd;
2936 asection *input_section;
2937 bfd *output_bfd ATTRIBUTE_UNUSED;
2938 struct internal_reloc *rel;
2939 struct internal_syment *sym ATTRIBUTE_UNUSED;
2940 struct reloc_howto_struct *howto;
2941 bfd_vma val;
2942 bfd_vma addend;
2943 bfd_vma *relocation;
2944 bfd_byte *contents;
2946 struct xcoff_link_hash_entry *h;
2948 if (0 > rel->r_symndx)
2949 return FALSE;
2951 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2953 /* If we see an R_BR or R_RBR reloc which is jumping to global
2954 linkage code, and it is followed by an appropriate cror nop
2955 instruction, we replace the cror with lwz r2,20(r1). This
2956 restores the TOC after the glink code. Contrariwise, if the
2957 call is followed by a lwz r2,20(r1), but the call is not
2958 going to global linkage code, we can replace the load with a
2959 cror. */
2960 if (NULL != h
2961 && bfd_link_hash_defined == h->root.type
2962 && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
2964 bfd_byte *pnext;
2965 unsigned long next;
2967 pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
2968 next = bfd_get_32 (input_bfd, pnext);
2970 /* The _ptrgl function is magic. It is used by the AIX
2971 compiler to call a function through a pointer. */
2972 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
2974 if (next == 0x4def7b82 /* cror 15,15,15 */
2975 || next == 0x4ffffb82 /* cror 31,31,31 */
2976 || next == 0x60000000) /* ori r0,r0,0 */
2977 bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */
2980 else
2982 if (next == 0x80410014) /* lwz r1,20(r1) */
2983 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
2986 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
2988 /* Normally, this relocation is against a defined symbol. In the
2989 case where this is a partial link and the output section offset
2990 is greater than 2^25, the linker will return an invalid error
2991 message that the relocation has been truncated. Yes it has been
2992 truncated but no it not important. For this case, disable the
2993 overflow checking. */
2995 howto->complain_on_overflow = complain_overflow_dont;
2998 howto->pc_relative = TRUE;
2999 howto->src_mask &= ~3;
3000 howto->dst_mask = howto->src_mask;
3002 /* A PC relative reloc includes the section address. */
3003 addend += input_section->vma;
3005 *relocation = val + addend;
3006 *relocation -= (input_section->output_section->vma
3007 + input_section->output_offset);
3008 return TRUE;
3011 bfd_boolean
3012 xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
3013 val, addend, relocation, contents)
3014 bfd *input_bfd ATTRIBUTE_UNUSED;
3015 asection *input_section;
3016 bfd *output_bfd ATTRIBUTE_UNUSED;
3017 struct internal_reloc *rel ATTRIBUTE_UNUSED;
3018 struct internal_syment *sym ATTRIBUTE_UNUSED;
3019 struct reloc_howto_struct *howto;
3020 bfd_vma val ATTRIBUTE_UNUSED;
3021 bfd_vma addend;
3022 bfd_vma *relocation;
3023 bfd_byte *contents ATTRIBUTE_UNUSED;
3025 howto->pc_relative = TRUE;
3026 howto->src_mask &= ~3;
3027 howto->dst_mask = howto->src_mask;
3029 /* A PC relative reloc includes the section address. */
3030 addend += input_section->vma;
3032 *relocation = val + addend;
3033 *relocation -= (input_section->output_section->vma
3034 + input_section->output_offset);
3035 return TRUE;
3038 static bfd_boolean
3039 xcoff_complain_overflow_dont_func (input_bfd, val, relocation, howto)
3040 bfd *input_bfd ATTRIBUTE_UNUSED;
3041 bfd_vma val ATTRIBUTE_UNUSED;
3042 bfd_vma relocation ATTRIBUTE_UNUSED;
3043 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
3045 return FALSE;
3048 static bfd_boolean
3049 xcoff_complain_overflow_bitfield_func (input_bfd, val, relocation, howto)
3050 bfd *input_bfd;
3051 bfd_vma val;
3052 bfd_vma relocation;
3053 struct reloc_howto_struct *howto;
3055 bfd_vma addrmask, fieldmask, signmask, ss;
3056 bfd_vma a, b, sum;
3058 /* Get the values to be added together. For signed and unsigned
3059 relocations, we assume that all values should be truncated to
3060 the size of an address. For bitfields, all the bits matter.
3061 See also bfd_check_overflow. */
3062 fieldmask = N_ONES (howto->bitsize);
3063 addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3064 a = relocation;
3065 b = val & howto->src_mask;
3067 /* Much like unsigned, except no trimming with addrmask. In
3068 addition, the sum overflows if there is a carry out of
3069 the bfd_vma, i.e., the sum is less than either input
3070 operand. */
3071 a >>= howto->rightshift;
3072 b >>= howto->bitpos;
3074 /* Bitfields are sometimes used for signed numbers; for
3075 example, a 13-bit field sometimes represents values in
3076 0..8191 and sometimes represents values in -4096..4095.
3077 If the field is signed and a is -4095 (0x1001) and b is
3078 -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
3079 0x1fff is 0x3000). It's not clear how to handle this
3080 everywhere, since there is not way to know how many bits
3081 are significant in the relocation, but the original code
3082 assumed that it was fully sign extended, and we will keep
3083 that assumption. */
3084 signmask = (fieldmask >> 1) + 1;
3086 if ((a & ~ fieldmask) != 0)
3088 /* Some bits out of the field are set. This might not
3089 be a problem: if this is a signed bitfield, it is OK
3090 iff all the high bits are set, including the sign
3091 bit. We'll try setting all but the most significant
3092 bit in the original relocation value: if this is all
3093 ones, we are OK, assuming a signed bitfield. */
3094 ss = (signmask << howto->rightshift) - 1;
3095 if ((ss | relocation) != ~ (bfd_vma) 0)
3096 return TRUE;
3097 a &= fieldmask;
3100 /* We just assume (b & ~ fieldmask) == 0. */
3102 /* We explicitly permit wrap around if this relocation
3103 covers the high bit of an address. The Linux kernel
3104 relies on it, and it is the only way to write assembler
3105 code which can run when loaded at a location 0x80000000
3106 away from the location at which it is linked. */
3107 if (howto->bitsize + howto->rightshift
3108 == bfd_arch_bits_per_address (input_bfd))
3109 return FALSE;
3111 sum = a + b;
3112 if (sum < a || (sum & ~ fieldmask) != 0)
3114 /* There was a carry out, or the field overflow. Test
3115 for signed operands again. Here is the overflow test
3116 is as for complain_overflow_signed. */
3117 if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3118 return TRUE;
3121 return FALSE;
3124 static bfd_boolean
3125 xcoff_complain_overflow_signed_func (input_bfd, val, relocation, howto)
3126 bfd *input_bfd;
3127 bfd_vma val;
3128 bfd_vma relocation;
3129 struct reloc_howto_struct *howto;
3131 bfd_vma addrmask, fieldmask, signmask, ss;
3132 bfd_vma a, b, sum;
3134 /* Get the values to be added together. For signed and unsigned
3135 relocations, we assume that all values should be truncated to
3136 the size of an address. For bitfields, all the bits matter.
3137 See also bfd_check_overflow. */
3138 fieldmask = N_ONES (howto->bitsize);
3139 addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3140 a = relocation;
3141 b = val & howto->src_mask;
3143 a = (a & addrmask) >> howto->rightshift;
3145 /* If any sign bits are set, all sign bits must be set.
3146 That is, A must be a valid negative address after
3147 shifting. */
3148 signmask = ~ (fieldmask >> 1);
3149 ss = a & signmask;
3150 if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
3151 return TRUE;
3153 /* We only need this next bit of code if the sign bit of B
3154 is below the sign bit of A. This would only happen if
3155 SRC_MASK had fewer bits than BITSIZE. Note that if
3156 SRC_MASK has more bits than BITSIZE, we can get into
3157 trouble; we would need to verify that B is in range, as
3158 we do for A above. */
3159 signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
3160 if ((b & signmask) != 0)
3162 /* Set all the bits above the sign bit. */
3163 b -= signmask <<= 1;
3166 b = (b & addrmask) >> howto->bitpos;
3168 /* Now we can do the addition. */
3169 sum = a + b;
3171 /* See if the result has the correct sign. Bits above the
3172 sign bit are junk now; ignore them. If the sum is
3173 positive, make sure we did not have all negative inputs;
3174 if the sum is negative, make sure we did not have all
3175 positive inputs. The test below looks only at the sign
3176 bits, and it really just
3177 SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
3179 signmask = (fieldmask >> 1) + 1;
3180 if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3181 return TRUE;
3183 return FALSE;
3186 static bfd_boolean
3187 xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto)
3188 bfd *input_bfd;
3189 bfd_vma val;
3190 bfd_vma relocation;
3191 struct reloc_howto_struct *howto;
3193 bfd_vma addrmask, fieldmask;
3194 bfd_vma a, b, sum;
3196 /* Get the values to be added together. For signed and unsigned
3197 relocations, we assume that all values should be truncated to
3198 the size of an address. For bitfields, all the bits matter.
3199 See also bfd_check_overflow. */
3200 fieldmask = N_ONES (howto->bitsize);
3201 addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3202 a = relocation;
3203 b = val & howto->src_mask;
3205 /* Checking for an unsigned overflow is relatively easy:
3206 trim the addresses and add, and trim the result as well.
3207 Overflow is normally indicated when the result does not
3208 fit in the field. However, we also need to consider the
3209 case when, e.g., fieldmask is 0x7fffffff or smaller, an
3210 input is 0x80000000, and bfd_vma is only 32 bits; then we
3211 will get sum == 0, but there is an overflow, since the
3212 inputs did not fit in the field. Instead of doing a
3213 separate test, we can check for this by or-ing in the
3214 operands when testing for the sum overflowing its final
3215 field. */
3216 a = (a & addrmask) >> howto->rightshift;
3217 b = (b & addrmask) >> howto->bitpos;
3218 sum = (a + b) & addrmask;
3219 if ((a | b | sum) & ~ fieldmask)
3220 return TRUE;
3222 return FALSE;
3225 /* This is the relocation function for the RS/6000/POWER/PowerPC.
3226 This is currently the only processor which uses XCOFF; I hope that
3227 will never change.
3229 I took the relocation type definitions from two documents:
3230 the PowerPC AIX Version 4 Application Binary Interface, First
3231 Edition (April 1992), and the PowerOpen ABI, Big-Endian
3232 32-Bit Hardware Implementation (June 30, 1994). Differences
3233 between the documents are noted below.
3235 Unsupported r_type's
3237 R_RTB:
3238 R_RRTBI:
3239 R_RRTBA:
3241 These relocs are defined by the PowerPC ABI to be
3242 relative branches which use half of the difference
3243 between the symbol and the program counter. I can't
3244 quite figure out when this is useful. These relocs are
3245 not defined by the PowerOpen ABI.
3247 Supported r_type's
3249 R_POS:
3250 Simple positive relocation.
3252 R_NEG:
3253 Simple negative relocation.
3255 R_REL:
3256 Simple PC relative relocation.
3258 R_TOC:
3259 TOC relative relocation. The value in the instruction in
3260 the input file is the offset from the input file TOC to
3261 the desired location. We want the offset from the final
3262 TOC to the desired location. We have:
3263 isym = iTOC + in
3264 iinsn = in + o
3265 osym = oTOC + on
3266 oinsn = on + o
3267 so we must change insn by on - in.
3269 R_GL:
3270 GL linkage relocation. The value of this relocation
3271 is the address of the entry in the TOC section.
3273 R_TCL:
3274 Local object TOC address. I can't figure out the
3275 difference between this and case R_GL.
3277 R_TRL:
3278 TOC relative relocation. A TOC relative load instruction
3279 which may be changed to a load address instruction.
3280 FIXME: We don't currently implement this optimization.
3282 R_TRLA:
3283 TOC relative relocation. This is a TOC relative load
3284 address instruction which may be changed to a load
3285 instruction. FIXME: I don't know if this is the correct
3286 implementation.
3288 R_BA:
3289 Absolute branch. We don't want to mess with the lower
3290 two bits of the instruction.
3292 R_CAI:
3293 The PowerPC ABI defines this as an absolute call which
3294 may be modified to become a relative call. The PowerOpen
3295 ABI does not define this relocation type.
3297 R_RBA:
3298 Absolute branch which may be modified to become a
3299 relative branch.
3301 R_RBAC:
3302 The PowerPC ABI defines this as an absolute branch to a
3303 fixed address which may be modified to an absolute branch
3304 to a symbol. The PowerOpen ABI does not define this
3305 relocation type.
3307 R_RBRC:
3308 The PowerPC ABI defines this as an absolute branch to a
3309 fixed address which may be modified to a relative branch.
3310 The PowerOpen ABI does not define this relocation type.
3312 R_BR:
3313 Relative branch. We don't want to mess with the lower
3314 two bits of the instruction.
3316 R_CREL:
3317 The PowerPC ABI defines this as a relative call which may
3318 be modified to become an absolute call. The PowerOpen
3319 ABI does not define this relocation type.
3321 R_RBR:
3322 A relative branch which may be modified to become an
3323 absolute branch. FIXME: We don't implement this,
3324 although we should for symbols of storage mapping class
3325 XMC_XO.
3327 R_RL:
3328 The PowerPC AIX ABI describes this as a load which may be
3329 changed to a load address. The PowerOpen ABI says this
3330 is the same as case R_POS.
3332 R_RLA:
3333 The PowerPC AIX ABI describes this as a load address
3334 which may be changed to a load. The PowerOpen ABI says
3335 this is the same as R_POS.
3338 bfd_boolean
3339 xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
3340 input_section, contents, relocs, syms,
3341 sections)
3342 bfd *output_bfd;
3343 struct bfd_link_info *info;
3344 bfd *input_bfd;
3345 asection *input_section;
3346 bfd_byte *contents;
3347 struct internal_reloc *relocs;
3348 struct internal_syment *syms;
3349 asection **sections;
3351 struct internal_reloc *rel;
3352 struct internal_reloc *relend;
3354 rel = relocs;
3355 relend = rel + input_section->reloc_count;
3356 for (; rel < relend; rel++)
3358 long symndx;
3359 struct xcoff_link_hash_entry *h;
3360 struct internal_syment *sym;
3361 bfd_vma addend;
3362 bfd_vma val;
3363 struct reloc_howto_struct howto;
3364 bfd_vma relocation;
3365 bfd_vma value_to_relocate;
3366 bfd_vma address;
3367 bfd_byte *location;
3369 /* Relocation type R_REF is a special relocation type which is
3370 merely used to prevent garbage collection from occurring for
3371 the csect including the symbol which it references. */
3372 if (rel->r_type == R_REF)
3373 continue;
3375 /* howto */
3376 howto.type = rel->r_type;
3377 howto.rightshift = 0;
3378 howto.bitsize = (rel->r_size & 0x1f) + 1;
3379 howto.size = howto.bitsize > 16 ? 2 : 1;
3380 howto.pc_relative = FALSE;
3381 howto.bitpos = 0;
3382 howto.complain_on_overflow = (rel->r_size & 0x80
3383 ? complain_overflow_signed
3384 : complain_overflow_bitfield);
3385 howto.special_function = NULL;
3386 howto.name = "internal";
3387 howto.partial_inplace = TRUE;
3388 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
3389 howto.pcrel_offset = FALSE;
3391 /* symbol */
3392 val = 0;
3393 addend = 0;
3394 h = NULL;
3395 sym = NULL;
3396 symndx = rel->r_symndx;
3398 if (-1 != symndx)
3400 asection *sec;
3402 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
3403 sym = syms + symndx;
3404 addend = - sym->n_value;
3406 if (NULL == h)
3408 sec = sections[symndx];
3409 /* Hack to make sure we use the right TOC anchor value
3410 if this reloc is against the TOC anchor. */
3411 if (sec->name[3] == '0'
3412 && strcmp (sec->name, ".tc0") == 0)
3413 val = xcoff_data (output_bfd)->toc;
3414 else
3415 val = (sec->output_section->vma
3416 + sec->output_offset
3417 + sym->n_value
3418 - sec->vma);
3420 else
3422 if (h->root.type == bfd_link_hash_defined
3423 || h->root.type == bfd_link_hash_defweak)
3425 sec = h->root.u.def.section;
3426 val = (h->root.u.def.value
3427 + sec->output_section->vma
3428 + sec->output_offset);
3430 else if (h->root.type == bfd_link_hash_common)
3432 sec = h->root.u.c.p->section;
3433 val = (sec->output_section->vma
3434 + sec->output_offset);
3437 else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
3438 && ! info->relocatable)
3440 if (! ((*info->callbacks->undefined_symbol)
3441 (info, h->root.root.string, input_bfd, input_section,
3442 rel->r_vaddr - input_section->vma, TRUE)))
3443 return FALSE;
3445 /* Don't try to process the reloc. It can't help, and
3446 it may generate another error. */
3447 continue;
3452 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
3453 || !((*xcoff_calculate_relocation[rel->r_type])
3454 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
3455 addend, &relocation, contents)))
3456 return FALSE;
3458 /* address */
3459 address = rel->r_vaddr - input_section->vma;
3460 location = contents + address;
3462 if (address > input_section->size)
3463 abort ();
3465 /* Get the value we are going to relocate. */
3466 if (1 == howto.size)
3467 value_to_relocate = bfd_get_16 (input_bfd, location);
3468 else
3469 value_to_relocate = bfd_get_32 (input_bfd, location);
3471 /* overflow.
3473 FIXME: We may drop bits during the addition
3474 which we don't check for. We must either check at every single
3475 operation, which would be tedious, or we must do the computations
3476 in a type larger than bfd_vma, which would be inefficient. */
3478 if ((unsigned int) howto.complain_on_overflow
3479 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
3480 abort ();
3482 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
3483 (input_bfd, value_to_relocate, relocation, &howto)))
3485 const char *name;
3486 char buf[SYMNMLEN + 1];
3487 char reloc_type_name[10];
3489 if (symndx == -1)
3491 name = "*ABS*";
3493 else if (h != NULL)
3495 name = NULL;
3497 else
3499 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
3500 if (name == NULL)
3501 name = "UNKNOWN";
3503 sprintf (reloc_type_name, "0x%02x", rel->r_type);
3505 if (! ((*info->callbacks->reloc_overflow)
3506 (info, (h ? &h->root : NULL), name, reloc_type_name,
3507 (bfd_vma) 0, input_bfd, input_section,
3508 rel->r_vaddr - input_section->vma)))
3509 return FALSE;
3512 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
3513 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
3514 | (((value_to_relocate & howto.src_mask)
3515 + relocation) & howto.dst_mask));
3517 /* Put the value back in the object file. */
3518 if (1 == howto.size)
3519 bfd_put_16 (input_bfd, value_to_relocate, location);
3520 else
3521 bfd_put_32 (input_bfd, value_to_relocate, location);
3524 return TRUE;
3527 static bfd_boolean
3528 _bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
3529 bfd *abfd ATTRIBUTE_UNUSED;
3530 struct xcoff_loader_info *ldinfo;
3531 struct internal_ldsym *ldsym;
3532 const char *name;
3534 size_t len;
3535 len = strlen (name);
3537 if (len <= SYMNMLEN)
3538 strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3539 else
3541 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3543 bfd_size_type newalc;
3544 char *newstrings;
3546 newalc = ldinfo->string_alc * 2;
3547 if (newalc == 0)
3548 newalc = 32;
3549 while (ldinfo->string_size + len + 3 > newalc)
3550 newalc *= 2;
3552 newstrings = bfd_realloc (ldinfo->strings, newalc);
3553 if (newstrings == NULL)
3555 ldinfo->failed = TRUE;
3556 return FALSE;
3558 ldinfo->string_alc = newalc;
3559 ldinfo->strings = newstrings;
3562 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3563 ldinfo->strings + ldinfo->string_size);
3564 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3565 ldsym->_l._l_l._l_zeroes = 0;
3566 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3567 ldinfo->string_size += len + 3;
3570 return TRUE;
3573 static bfd_boolean
3574 _bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
3575 struct internal_syment *sym,
3576 const char *name)
3578 if (strlen (name) <= SYMNMLEN)
3580 strncpy (sym->_n._n_name, name, SYMNMLEN);
3582 else
3584 bfd_boolean hash;
3585 bfd_size_type indx;
3587 hash = TRUE;
3588 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
3589 hash = FALSE;
3590 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
3591 if (indx == (bfd_size_type) -1)
3592 return FALSE;
3593 sym->_n._n_n._n_zeroes = 0;
3594 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3596 return TRUE;
3599 static asection *
3600 xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
3601 bfd *abfd;
3602 union internal_auxent *aux;
3603 const char *symbol_name;
3605 asection *return_value = NULL;
3607 /* .sv64 = x_smclas == 17
3608 This is an invalid csect for 32 bit apps. */
3609 static const char *names[19] =
3611 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
3612 ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
3613 ".td", NULL, ".sv3264"
3616 if ((19 >= aux->x_csect.x_smclas)
3617 && (NULL != names[aux->x_csect.x_smclas]))
3619 return_value = bfd_make_section_anyway
3620 (abfd, names[aux->x_csect.x_smclas]);
3622 else
3624 (*_bfd_error_handler)
3625 (_("%B: symbol `%s' has unrecognized smclas %d"),
3626 abfd, symbol_name, aux->x_csect.x_smclas);
3627 bfd_set_error (bfd_error_bad_value);
3630 return return_value;
3633 static bfd_boolean
3634 xcoff_is_lineno_count_overflow (abfd, value)
3635 bfd *abfd ATTRIBUTE_UNUSED;
3636 bfd_vma value;
3638 if (0xffff <= value)
3639 return TRUE;
3641 return FALSE;
3644 static bfd_boolean
3645 xcoff_is_reloc_count_overflow (abfd, value)
3646 bfd *abfd ATTRIBUTE_UNUSED;
3647 bfd_vma value;
3649 if (0xffff <= value)
3650 return TRUE;
3652 return FALSE;
3655 static bfd_vma
3656 xcoff_loader_symbol_offset (abfd, ldhdr)
3657 bfd *abfd;
3658 struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
3660 return bfd_xcoff_ldhdrsz (abfd);
3663 static bfd_vma
3664 xcoff_loader_reloc_offset (abfd, ldhdr)
3665 bfd *abfd;
3666 struct internal_ldhdr *ldhdr;
3668 return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
3671 static bfd_boolean
3672 xcoff_generate_rtinit (abfd, init, fini, rtld)
3673 bfd *abfd;
3674 const char *init;
3675 const char *fini;
3676 bfd_boolean rtld;
3678 bfd_byte filehdr_ext[FILHSZ];
3679 bfd_byte scnhdr_ext[SCNHSZ];
3680 bfd_byte syment_ext[SYMESZ * 10];
3681 bfd_byte reloc_ext[RELSZ * 3];
3682 bfd_byte *data_buffer;
3683 bfd_size_type data_buffer_size;
3684 bfd_byte *string_table = NULL, *st_tmp = NULL;
3685 bfd_size_type string_table_size;
3686 bfd_vma val;
3687 size_t initsz, finisz;
3688 struct internal_filehdr filehdr;
3689 struct internal_scnhdr scnhdr;
3690 struct internal_syment syment;
3691 union internal_auxent auxent;
3692 struct internal_reloc reloc;
3694 char *data_name = ".data";
3695 char *rtinit_name = "__rtinit";
3696 char *rtld_name = "__rtld";
3698 if (! bfd_xcoff_rtinit_size (abfd))
3699 return FALSE;
3701 initsz = (init == NULL ? 0 : 1 + strlen (init));
3702 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3704 /* file header */
3705 memset (filehdr_ext, 0, FILHSZ);
3706 memset (&filehdr, 0, sizeof (struct internal_filehdr));
3707 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
3708 filehdr.f_nscns = 1;
3709 filehdr.f_timdat = 0;
3710 filehdr.f_nsyms = 0; /* at least 6, no more than 10 */
3711 filehdr.f_symptr = 0; /* set below */
3712 filehdr.f_opthdr = 0;
3713 filehdr.f_flags = 0;
3715 /* section header */
3716 memset (scnhdr_ext, 0, SCNHSZ);
3717 memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3718 memcpy (scnhdr.s_name, data_name, strlen (data_name));
3719 scnhdr.s_paddr = 0;
3720 scnhdr.s_vaddr = 0;
3721 scnhdr.s_size = 0; /* set below */
3722 scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3723 scnhdr.s_relptr = 0; /* set below */
3724 scnhdr.s_lnnoptr = 0;
3725 scnhdr.s_nreloc = 0; /* either 1 or 2 */
3726 scnhdr.s_nlnno = 0;
3727 scnhdr.s_flags = STYP_DATA;
3729 /* .data
3730 0x0000 0x00000000 : rtl
3731 0x0004 0x00000010 : offset to init, or 0
3732 0x0008 0x00000028 : offset to fini, or 0
3733 0x000C 0x0000000C : size of descriptor
3734 0x0010 0x00000000 : init, needs a reloc
3735 0x0014 0x00000040 : offset to init name
3736 0x0018 0x00000000 : flags, padded to a word
3737 0x001C 0x00000000 : empty init
3738 0x0020 0x00000000 :
3739 0x0024 0x00000000 :
3740 0x0028 0x00000000 : fini, needs a reloc
3741 0x002C 0x00000??? : offset to fini name
3742 0x0030 0x00000000 : flags, padded to a word
3743 0x0034 0x00000000 : empty fini
3744 0x0038 0x00000000 :
3745 0x003C 0x00000000 :
3746 0x0040 init name
3747 0x0040 + initsz fini name */
3749 data_buffer_size = 0x0040 + initsz + finisz;
3750 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
3751 data_buffer = NULL;
3752 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
3753 if (data_buffer == NULL)
3754 return FALSE;
3756 if (initsz)
3758 val = 0x10;
3759 bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
3760 val = 0x40;
3761 bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
3762 memcpy (&data_buffer[val], init, initsz);
3765 if (finisz)
3767 val = 0x28;
3768 bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
3769 val = 0x40 + initsz;
3770 bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
3771 memcpy (&data_buffer[val], fini, finisz);
3774 val = 0x0C;
3775 bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
3777 scnhdr.s_size = data_buffer_size;
3779 /* string table */
3780 string_table_size = 0;
3781 if (initsz > 9)
3782 string_table_size += initsz;
3783 if (finisz > 9)
3784 string_table_size += finisz;
3785 if (string_table_size)
3787 string_table_size += 4;
3788 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
3789 if (string_table == NULL)
3790 return FALSE;
3792 val = string_table_size;
3793 bfd_h_put_32 (abfd, val, &string_table[0]);
3794 st_tmp = string_table + 4;
3797 /* symbols
3798 0. .data csect
3799 2. __rtinit
3800 4. init function
3801 6. fini function
3802 8. __rtld */
3803 memset (syment_ext, 0, 10 * SYMESZ);
3804 memset (reloc_ext, 0, 3 * RELSZ);
3806 /* .data csect */
3807 memset (&syment, 0, sizeof (struct internal_syment));
3808 memset (&auxent, 0, sizeof (union internal_auxent));
3809 memcpy (syment._n._n_name, data_name, strlen (data_name));
3810 syment.n_scnum = 1;
3811 syment.n_sclass = C_HIDEXT;
3812 syment.n_numaux = 1;
3813 auxent.x_csect.x_scnlen.l = data_buffer_size;
3814 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
3815 auxent.x_csect.x_smclas = XMC_RW;
3816 bfd_coff_swap_sym_out (abfd, &syment,
3817 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3818 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3819 syment.n_numaux,
3820 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3821 filehdr.f_nsyms += 2;
3823 /* __rtinit */
3824 memset (&syment, 0, sizeof (struct internal_syment));
3825 memset (&auxent, 0, sizeof (union internal_auxent));
3826 memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
3827 syment.n_scnum = 1;
3828 syment.n_sclass = C_EXT;
3829 syment.n_numaux = 1;
3830 auxent.x_csect.x_smtyp = XTY_LD;
3831 auxent.x_csect.x_smclas = XMC_RW;
3832 bfd_coff_swap_sym_out (abfd, &syment,
3833 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3834 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3835 syment.n_numaux,
3836 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3837 filehdr.f_nsyms += 2;
3839 /* init */
3840 if (initsz)
3842 memset (&syment, 0, sizeof (struct internal_syment));
3843 memset (&auxent, 0, sizeof (union internal_auxent));
3845 if (initsz > 9)
3847 syment._n._n_n._n_offset = st_tmp - string_table;
3848 memcpy (st_tmp, init, initsz);
3849 st_tmp += initsz;
3851 else
3852 memcpy (syment._n._n_name, init, initsz - 1);
3854 syment.n_sclass = C_EXT;
3855 syment.n_numaux = 1;
3856 bfd_coff_swap_sym_out (abfd, &syment,
3857 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3858 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3859 syment.n_numaux,
3860 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3862 /* reloc */
3863 memset (&reloc, 0, sizeof (struct internal_reloc));
3864 reloc.r_vaddr = 0x0010;
3865 reloc.r_symndx = filehdr.f_nsyms;
3866 reloc.r_type = R_POS;
3867 reloc.r_size = 31;
3868 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
3870 filehdr.f_nsyms += 2;
3871 scnhdr.s_nreloc += 1;
3874 /* fini */
3875 if (finisz)
3877 memset (&syment, 0, sizeof (struct internal_syment));
3878 memset (&auxent, 0, sizeof (union internal_auxent));
3880 if (finisz > 9)
3882 syment._n._n_n._n_offset = st_tmp - string_table;
3883 memcpy (st_tmp, fini, finisz);
3884 st_tmp += finisz;
3886 else
3887 memcpy (syment._n._n_name, fini, finisz - 1);
3889 syment.n_sclass = C_EXT;
3890 syment.n_numaux = 1;
3891 bfd_coff_swap_sym_out (abfd, &syment,
3892 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3893 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3894 syment.n_numaux,
3895 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3897 /* reloc */
3898 memset (&reloc, 0, sizeof (struct internal_reloc));
3899 reloc.r_vaddr = 0x0028;
3900 reloc.r_symndx = filehdr.f_nsyms;
3901 reloc.r_type = R_POS;
3902 reloc.r_size = 31;
3903 bfd_coff_swap_reloc_out (abfd, &reloc,
3904 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3906 filehdr.f_nsyms += 2;
3907 scnhdr.s_nreloc += 1;
3910 if (rtld)
3912 memset (&syment, 0, sizeof (struct internal_syment));
3913 memset (&auxent, 0, sizeof (union internal_auxent));
3914 memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
3915 syment.n_sclass = C_EXT;
3916 syment.n_numaux = 1;
3917 bfd_coff_swap_sym_out (abfd, &syment,
3918 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3919 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3920 syment.n_numaux,
3921 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3923 /* reloc */
3924 memset (&reloc, 0, sizeof (struct internal_reloc));
3925 reloc.r_vaddr = 0x0000;
3926 reloc.r_symndx = filehdr.f_nsyms;
3927 reloc.r_type = R_POS;
3928 reloc.r_size = 31;
3929 bfd_coff_swap_reloc_out (abfd, &reloc,
3930 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3932 filehdr.f_nsyms += 2;
3933 scnhdr.s_nreloc += 1;
3936 scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
3937 filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
3939 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
3940 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
3941 bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
3942 bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
3943 bfd_bwrite (data_buffer, data_buffer_size, abfd);
3944 bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
3945 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
3946 bfd_bwrite (string_table, string_table_size, abfd);
3948 free (data_buffer);
3949 data_buffer = NULL;
3951 return TRUE;
3955 static reloc_howto_type xcoff_dynamic_reloc =
3956 HOWTO (0, /* type */
3957 0, /* rightshift */
3958 2, /* size (0 = byte, 1 = short, 2 = long) */
3959 32, /* bitsize */
3960 FALSE, /* pc_relative */
3961 0, /* bitpos */
3962 complain_overflow_bitfield, /* complain_on_overflow */
3963 0, /* special_function */
3964 "R_POS", /* name */
3965 TRUE, /* partial_inplace */
3966 0xffffffff, /* src_mask */
3967 0xffffffff, /* dst_mask */
3968 FALSE); /* pcrel_offset */
3970 /* glink
3972 The first word of global linkage code must be modified by filling in
3973 the correct TOC offset. */
3975 static unsigned long xcoff_glink_code[9] =
3977 0x81820000, /* lwz r12,0(r2) */
3978 0x90410014, /* stw r2,20(r1) */
3979 0x800c0000, /* lwz r0,0(r12) */
3980 0x804c0004, /* lwz r2,4(r12) */
3981 0x7c0903a6, /* mtctr r0 */
3982 0x4e800420, /* bctr */
3983 0x00000000, /* start of traceback table */
3984 0x000c8000, /* traceback table */
3985 0x00000000, /* traceback table */
3989 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
3991 { /* COFF backend, defined in libcoff.h. */
3992 _bfd_xcoff_swap_aux_in,
3993 _bfd_xcoff_swap_sym_in,
3994 coff_swap_lineno_in,
3995 _bfd_xcoff_swap_aux_out,
3996 _bfd_xcoff_swap_sym_out,
3997 coff_swap_lineno_out,
3998 xcoff_swap_reloc_out,
3999 coff_swap_filehdr_out,
4000 coff_swap_aouthdr_out,
4001 coff_swap_scnhdr_out,
4002 FILHSZ,
4003 AOUTSZ,
4004 SCNHSZ,
4005 SYMESZ,
4006 AUXESZ,
4007 RELSZ,
4008 LINESZ,
4009 FILNMLEN,
4010 TRUE, /* _bfd_coff_long_filenames */
4011 FALSE, /* _bfd_coff_long_section_names */
4012 3, /* _bfd_coff_default_section_alignment_power */
4013 FALSE, /* _bfd_coff_force_symnames_in_strings */
4014 2, /* _bfd_coff_debug_string_prefix_length */
4015 coff_swap_filehdr_in,
4016 coff_swap_aouthdr_in,
4017 coff_swap_scnhdr_in,
4018 xcoff_swap_reloc_in,
4019 coff_bad_format_hook,
4020 coff_set_arch_mach_hook,
4021 coff_mkobject_hook,
4022 styp_to_sec_flags,
4023 coff_set_alignment_hook,
4024 coff_slurp_symbol_table,
4025 symname_in_debug_hook,
4026 coff_pointerize_aux_hook,
4027 coff_print_aux,
4028 dummy_reloc16_extra_cases,
4029 dummy_reloc16_estimate,
4030 NULL, /* bfd_coff_sym_is_global */
4031 coff_compute_section_file_positions,
4032 NULL, /* _bfd_coff_start_final_link */
4033 xcoff_ppc_relocate_section,
4034 coff_rtype_to_howto,
4035 NULL, /* _bfd_coff_adjust_symndx */
4036 _bfd_generic_link_add_one_symbol,
4037 coff_link_output_has_begun,
4038 coff_final_link_postscript
4041 0x01DF, /* magic number */
4042 bfd_arch_rs6000,
4043 bfd_mach_rs6k,
4045 /* Function pointers to xcoff specific swap routines. */
4046 xcoff_swap_ldhdr_in,
4047 xcoff_swap_ldhdr_out,
4048 xcoff_swap_ldsym_in,
4049 xcoff_swap_ldsym_out,
4050 xcoff_swap_ldrel_in,
4051 xcoff_swap_ldrel_out,
4053 /* Sizes. */
4054 LDHDRSZ,
4055 LDSYMSZ,
4056 LDRELSZ,
4057 12, /* _xcoff_function_descriptor_size */
4058 SMALL_AOUTSZ,
4060 /* Versions. */
4061 1, /* _xcoff_ldhdr_version */
4063 _bfd_xcoff_put_symbol_name,
4064 _bfd_xcoff_put_ldsymbol_name,
4065 &xcoff_dynamic_reloc,
4066 xcoff_create_csect_from_smclas,
4068 /* Lineno and reloc count overflow. */
4069 xcoff_is_lineno_count_overflow,
4070 xcoff_is_reloc_count_overflow,
4072 xcoff_loader_symbol_offset,
4073 xcoff_loader_reloc_offset,
4075 /* glink. */
4076 &xcoff_glink_code[0],
4077 36, /* _xcoff_glink_size */
4079 /* rtinit */
4080 64, /* _xcoff_rtinit_size */
4081 xcoff_generate_rtinit,
4084 /* The transfer vector that leads the outside world to all of the above. */
4085 const bfd_target rs6000coff_vec =
4087 "aixcoff-rs6000",
4088 bfd_target_xcoff_flavour,
4089 BFD_ENDIAN_BIG, /* data byte order is big */
4090 BFD_ENDIAN_BIG, /* header byte order is big */
4092 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4093 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4095 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
4096 0, /* leading char */
4097 '/', /* ar_pad_char */
4098 15, /* ar_max_namelen */
4100 /* data */
4101 bfd_getb64,
4102 bfd_getb_signed_64,
4103 bfd_putb64,
4104 bfd_getb32,
4105 bfd_getb_signed_32,
4106 bfd_putb32,
4107 bfd_getb16,
4108 bfd_getb_signed_16,
4109 bfd_putb16,
4111 /* hdrs */
4112 bfd_getb64,
4113 bfd_getb_signed_64,
4114 bfd_putb64,
4115 bfd_getb32,
4116 bfd_getb_signed_32,
4117 bfd_putb32,
4118 bfd_getb16,
4119 bfd_getb_signed_16,
4120 bfd_putb16,
4122 { /* bfd_check_format */
4123 _bfd_dummy_target,
4124 coff_object_p,
4125 _bfd_xcoff_archive_p,
4126 CORE_FILE_P
4129 { /* bfd_set_format */
4130 bfd_false,
4131 coff_mkobject,
4132 _bfd_generic_mkarchive,
4133 bfd_false
4136 {/* bfd_write_contents */
4137 bfd_false,
4138 coff_write_object_contents,
4139 _bfd_xcoff_write_archive_contents,
4140 bfd_false
4143 /* Generic */
4144 bfd_true,
4145 bfd_true,
4146 coff_new_section_hook,
4147 _bfd_generic_get_section_contents,
4148 _bfd_generic_get_section_contents_in_window,
4150 /* Copy */
4151 _bfd_xcoff_copy_private_bfd_data,
4152 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4153 _bfd_generic_init_private_section_data,
4154 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4155 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4156 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4157 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
4158 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
4160 /* Core */
4161 coff_core_file_failing_command,
4162 coff_core_file_failing_signal,
4163 coff_core_file_matches_executable_p,
4165 /* Archive */
4166 _bfd_xcoff_slurp_armap,
4167 bfd_false,
4168 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4169 bfd_dont_truncate_arname,
4170 _bfd_xcoff_write_armap,
4171 _bfd_xcoff_read_ar_hdr,
4172 _bfd_xcoff_openr_next_archived_file,
4173 _bfd_generic_get_elt_at_index,
4174 _bfd_xcoff_stat_arch_elt,
4175 bfd_true,
4177 /* Symbols */
4178 coff_get_symtab_upper_bound,
4179 coff_canonicalize_symtab,
4180 coff_make_empty_symbol,
4181 coff_print_symbol,
4182 coff_get_symbol_info,
4183 _bfd_xcoff_is_local_label_name,
4184 coff_bfd_is_target_special_symbol,
4185 coff_get_lineno,
4186 coff_find_nearest_line,
4187 _bfd_generic_find_line,
4188 coff_find_inliner_info,
4189 coff_bfd_make_debug_symbol,
4190 _bfd_generic_read_minisymbols,
4191 _bfd_generic_minisymbol_to_symbol,
4193 /* Reloc */
4194 coff_get_reloc_upper_bound,
4195 coff_canonicalize_reloc,
4196 _bfd_xcoff_reloc_type_lookup,
4197 _bfd_xcoff_reloc_name_lookup,
4199 /* Write */
4200 coff_set_arch_mach,
4201 coff_set_section_contents,
4203 /* Link */
4204 _bfd_xcoff_sizeof_headers,
4205 bfd_generic_get_relocated_section_contents,
4206 bfd_generic_relax_section,
4207 _bfd_xcoff_bfd_link_hash_table_create,
4208 _bfd_generic_link_hash_table_free,
4209 _bfd_xcoff_bfd_link_add_symbols,
4210 _bfd_generic_link_just_syms,
4211 _bfd_xcoff_bfd_final_link,
4212 _bfd_generic_link_split_section,
4213 bfd_generic_gc_sections,
4214 bfd_generic_merge_sections,
4215 bfd_generic_is_group_section,
4216 bfd_generic_discard_group,
4217 _bfd_generic_section_already_linked,
4219 /* Dynamic */
4220 _bfd_xcoff_get_dynamic_symtab_upper_bound,
4221 _bfd_xcoff_canonicalize_dynamic_symtab,
4222 _bfd_nodynamic_get_synthetic_symtab,
4223 _bfd_xcoff_get_dynamic_reloc_upper_bound,
4224 _bfd_xcoff_canonicalize_dynamic_reloc,
4226 /* Opposite endian version, none exists */
4227 NULL,
4229 (void *) &bfd_xcoff_backend_data,
4232 /* xcoff-powermac target
4233 Old target.
4234 Only difference between this target and the rs6000 target is the
4235 the default architecture and machine type used in coffcode.h
4237 PowerPC Macs use the same magic numbers as RS/6000
4238 (because that's how they were bootstrapped originally),
4239 but they are always PowerPC architecture. */
4240 static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
4242 { /* COFF backend, defined in libcoff.h. */
4243 _bfd_xcoff_swap_aux_in,
4244 _bfd_xcoff_swap_sym_in,
4245 coff_swap_lineno_in,
4246 _bfd_xcoff_swap_aux_out,
4247 _bfd_xcoff_swap_sym_out,
4248 coff_swap_lineno_out,
4249 xcoff_swap_reloc_out,
4250 coff_swap_filehdr_out,
4251 coff_swap_aouthdr_out,
4252 coff_swap_scnhdr_out,
4253 FILHSZ,
4254 AOUTSZ,
4255 SCNHSZ,
4256 SYMESZ,
4257 AUXESZ,
4258 RELSZ,
4259 LINESZ,
4260 FILNMLEN,
4261 TRUE, /* _bfd_coff_long_filenames */
4262 FALSE, /* _bfd_coff_long_section_names */
4263 3, /* _bfd_coff_default_section_alignment_power */
4264 FALSE, /* _bfd_coff_force_symnames_in_strings */
4265 2, /* _bfd_coff_debug_string_prefix_length */
4266 coff_swap_filehdr_in,
4267 coff_swap_aouthdr_in,
4268 coff_swap_scnhdr_in,
4269 xcoff_swap_reloc_in,
4270 coff_bad_format_hook,
4271 coff_set_arch_mach_hook,
4272 coff_mkobject_hook,
4273 styp_to_sec_flags,
4274 coff_set_alignment_hook,
4275 coff_slurp_symbol_table,
4276 symname_in_debug_hook,
4277 coff_pointerize_aux_hook,
4278 coff_print_aux,
4279 dummy_reloc16_extra_cases,
4280 dummy_reloc16_estimate,
4281 NULL, /* bfd_coff_sym_is_global */
4282 coff_compute_section_file_positions,
4283 NULL, /* _bfd_coff_start_final_link */
4284 xcoff_ppc_relocate_section,
4285 coff_rtype_to_howto,
4286 NULL, /* _bfd_coff_adjust_symndx */
4287 _bfd_generic_link_add_one_symbol,
4288 coff_link_output_has_begun,
4289 coff_final_link_postscript
4292 0x01DF, /* magic number */
4293 bfd_arch_powerpc,
4294 bfd_mach_ppc,
4296 /* Function pointers to xcoff specific swap routines. */
4297 xcoff_swap_ldhdr_in,
4298 xcoff_swap_ldhdr_out,
4299 xcoff_swap_ldsym_in,
4300 xcoff_swap_ldsym_out,
4301 xcoff_swap_ldrel_in,
4302 xcoff_swap_ldrel_out,
4304 /* Sizes. */
4305 LDHDRSZ,
4306 LDSYMSZ,
4307 LDRELSZ,
4308 12, /* _xcoff_function_descriptor_size */
4309 SMALL_AOUTSZ,
4311 /* Versions. */
4312 1, /* _xcoff_ldhdr_version */
4314 _bfd_xcoff_put_symbol_name,
4315 _bfd_xcoff_put_ldsymbol_name,
4316 &xcoff_dynamic_reloc,
4317 xcoff_create_csect_from_smclas,
4319 /* Lineno and reloc count overflow. */
4320 xcoff_is_lineno_count_overflow,
4321 xcoff_is_reloc_count_overflow,
4323 xcoff_loader_symbol_offset,
4324 xcoff_loader_reloc_offset,
4326 /* glink. */
4327 &xcoff_glink_code[0],
4328 36, /* _xcoff_glink_size */
4330 /* rtinit */
4331 0, /* _xcoff_rtinit_size */
4332 xcoff_generate_rtinit,
4335 /* The transfer vector that leads the outside world to all of the above. */
4336 const bfd_target pmac_xcoff_vec =
4338 "xcoff-powermac",
4339 bfd_target_xcoff_flavour,
4340 BFD_ENDIAN_BIG, /* data byte order is big */
4341 BFD_ENDIAN_BIG, /* header byte order is big */
4343 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4344 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4346 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
4347 0, /* leading char */
4348 '/', /* ar_pad_char */
4349 15, /* ar_max_namelen */
4351 /* data */
4352 bfd_getb64,
4353 bfd_getb_signed_64,
4354 bfd_putb64,
4355 bfd_getb32,
4356 bfd_getb_signed_32,
4357 bfd_putb32,
4358 bfd_getb16,
4359 bfd_getb_signed_16,
4360 bfd_putb16,
4362 /* hdrs */
4363 bfd_getb64,
4364 bfd_getb_signed_64,
4365 bfd_putb64,
4366 bfd_getb32,
4367 bfd_getb_signed_32,
4368 bfd_putb32,
4369 bfd_getb16,
4370 bfd_getb_signed_16,
4371 bfd_putb16,
4373 { /* bfd_check_format */
4374 _bfd_dummy_target,
4375 coff_object_p,
4376 _bfd_xcoff_archive_p,
4377 CORE_FILE_P
4380 { /* bfd_set_format */
4381 bfd_false,
4382 coff_mkobject,
4383 _bfd_generic_mkarchive,
4384 bfd_false
4387 {/* bfd_write_contents */
4388 bfd_false,
4389 coff_write_object_contents,
4390 _bfd_xcoff_write_archive_contents,
4391 bfd_false
4394 /* Generic */
4395 bfd_true,
4396 bfd_true,
4397 coff_new_section_hook,
4398 _bfd_generic_get_section_contents,
4399 _bfd_generic_get_section_contents_in_window,
4401 /* Copy */
4402 _bfd_xcoff_copy_private_bfd_data,
4403 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4404 _bfd_generic_init_private_section_data,
4405 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4406 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4407 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4408 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
4409 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
4411 /* Core */
4412 coff_core_file_failing_command,
4413 coff_core_file_failing_signal,
4414 coff_core_file_matches_executable_p,
4416 /* Archive */
4417 _bfd_xcoff_slurp_armap,
4418 bfd_false,
4419 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4420 bfd_dont_truncate_arname,
4421 _bfd_xcoff_write_armap,
4422 _bfd_xcoff_read_ar_hdr,
4423 _bfd_xcoff_openr_next_archived_file,
4424 _bfd_generic_get_elt_at_index,
4425 _bfd_xcoff_stat_arch_elt,
4426 bfd_true,
4428 /* Symbols */
4429 coff_get_symtab_upper_bound,
4430 coff_canonicalize_symtab,
4431 coff_make_empty_symbol,
4432 coff_print_symbol,
4433 coff_get_symbol_info,
4434 _bfd_xcoff_is_local_label_name,
4435 coff_bfd_is_target_special_symbol,
4436 coff_get_lineno,
4437 coff_find_nearest_line,
4438 _bfd_generic_find_line,
4439 coff_find_inliner_info,
4440 coff_bfd_make_debug_symbol,
4441 _bfd_generic_read_minisymbols,
4442 _bfd_generic_minisymbol_to_symbol,
4444 /* Reloc */
4445 coff_get_reloc_upper_bound,
4446 coff_canonicalize_reloc,
4447 _bfd_xcoff_reloc_type_lookup,
4448 _bfd_xcoff_reloc_name_lookup,
4450 /* Write */
4451 coff_set_arch_mach,
4452 coff_set_section_contents,
4454 /* Link */
4455 _bfd_xcoff_sizeof_headers,
4456 bfd_generic_get_relocated_section_contents,
4457 bfd_generic_relax_section,
4458 _bfd_xcoff_bfd_link_hash_table_create,
4459 _bfd_generic_link_hash_table_free,
4460 _bfd_xcoff_bfd_link_add_symbols,
4461 _bfd_generic_link_just_syms,
4462 _bfd_xcoff_bfd_final_link,
4463 _bfd_generic_link_split_section,
4464 bfd_generic_gc_sections,
4465 bfd_generic_merge_sections,
4466 bfd_generic_is_group_section,
4467 bfd_generic_discard_group,
4468 _bfd_generic_section_already_linked,
4470 /* Dynamic */
4471 _bfd_xcoff_get_dynamic_symtab_upper_bound,
4472 _bfd_xcoff_canonicalize_dynamic_symtab,
4473 _bfd_nodynamic_get_synthetic_symtab,
4474 _bfd_xcoff_get_dynamic_reloc_upper_bound,
4475 _bfd_xcoff_canonicalize_dynamic_reloc,
4477 /* Opposite endian version, none exists */
4478 NULL,
4480 (void *) &bfd_pmac_xcoff_backend_data,