daily update
[binutils.git] / bfd / coff64-rs6000.c
blobee797ed4a28f23ed3443244b370b55148aaad5a6
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
4 Written Clinton Popetz.
5 Contributed by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "bfdlink.h"
27 #include "libbfd.h"
28 #include "coff/internal.h"
29 #include "coff/xcoff.h"
30 #include "coff/rs6k64.h"
31 #include "libcoff.h"
32 #include "libxcoff.h"
34 #define GET_FILEHDR_SYMPTR H_GET_64
35 #define PUT_FILEHDR_SYMPTR H_PUT_64
36 #define GET_AOUTHDR_DATA_START H_GET_64
37 #define PUT_AOUTHDR_DATA_START H_PUT_64
38 #define GET_AOUTHDR_TEXT_START H_GET_64
39 #define PUT_AOUTHDR_TEXT_START H_PUT_64
40 #define GET_AOUTHDR_TSIZE H_GET_64
41 #define PUT_AOUTHDR_TSIZE H_PUT_64
42 #define GET_AOUTHDR_DSIZE H_GET_64
43 #define PUT_AOUTHDR_DSIZE H_PUT_64
44 #define GET_AOUTHDR_BSIZE H_GET_64
45 #define PUT_AOUTHDR_BSIZE H_PUT_64
46 #define GET_AOUTHDR_ENTRY H_GET_64
47 #define PUT_AOUTHDR_ENTRY H_PUT_64
48 #define GET_SCNHDR_PADDR H_GET_64
49 #define PUT_SCNHDR_PADDR H_PUT_64
50 #define GET_SCNHDR_VADDR H_GET_64
51 #define PUT_SCNHDR_VADDR H_PUT_64
52 #define GET_SCNHDR_SIZE H_GET_64
53 #define PUT_SCNHDR_SIZE H_PUT_64
54 #define GET_SCNHDR_SCNPTR H_GET_64
55 #define PUT_SCNHDR_SCNPTR H_PUT_64
56 #define GET_SCNHDR_RELPTR H_GET_64
57 #define PUT_SCNHDR_RELPTR H_PUT_64
58 #define GET_SCNHDR_LNNOPTR H_GET_64
59 #define PUT_SCNHDR_LNNOPTR H_PUT_64
60 #define GET_SCNHDR_NRELOC H_GET_32
61 #define MAX_SCNHDR_NRELOC 0xffffffff
62 #define PUT_SCNHDR_NRELOC H_PUT_32
63 #define GET_SCNHDR_NLNNO H_GET_32
64 #define MAX_SCNHDR_NLNNO 0xffffffff
65 #define PUT_SCNHDR_NLNNO H_PUT_32
66 #define GET_RELOC_VADDR H_GET_64
67 #define PUT_RELOC_VADDR H_PUT_64
69 #define COFF_FORCE_SYMBOLS_IN_STRINGS
70 #define COFF_DEBUG_STRING_WIDE_PREFIX
73 #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
74 do \
75 { \
76 memset (((SCNHDR *) EXT)->s_pad, 0, \
77 sizeof (((SCNHDR *) EXT)->s_pad)); \
78 } \
79 while (0)
81 #define NO_COFF_LINENOS
83 #define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
84 #define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
86 static void _bfd_xcoff64_swap_lineno_in
87 PARAMS ((bfd *, PTR, PTR));
88 static unsigned int _bfd_xcoff64_swap_lineno_out
89 PARAMS ((bfd *, PTR, PTR));
90 static bfd_boolean _bfd_xcoff64_put_symbol_name
91 PARAMS ((bfd *, struct bfd_strtab_hash *, struct internal_syment *,
92 const char *));
93 static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
94 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
95 const char *));
96 static void _bfd_xcoff64_swap_sym_in
97 PARAMS ((bfd *, PTR, PTR));
98 static unsigned int _bfd_xcoff64_swap_sym_out
99 PARAMS ((bfd *, PTR, PTR));
100 static void _bfd_xcoff64_swap_aux_in
101 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
102 static unsigned int _bfd_xcoff64_swap_aux_out
103 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
104 static void xcoff64_swap_reloc_in
105 PARAMS ((bfd *, PTR, PTR));
106 static unsigned int xcoff64_swap_reloc_out
107 PARAMS ((bfd *, PTR, PTR));
108 extern bfd_boolean _bfd_xcoff_mkobject
109 PARAMS ((bfd *));
110 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
111 PARAMS ((bfd *, bfd *));
112 extern bfd_boolean _bfd_xcoff_is_local_label_name
113 PARAMS ((bfd *, const char *));
114 extern void xcoff64_rtype2howto
115 PARAMS ((arelent *, struct internal_reloc *));
116 extern reloc_howto_type * xcoff64_reloc_type_lookup
117 PARAMS ((bfd *, bfd_reloc_code_real_type));
118 extern bfd_boolean _bfd_xcoff_slurp_armap
119 PARAMS ((bfd *));
120 extern PTR _bfd_xcoff_read_ar_hdr
121 PARAMS ((bfd *));
122 extern bfd *_bfd_xcoff_openr_next_archived_file
123 PARAMS ((bfd *, bfd *));
124 extern int _bfd_xcoff_stat_arch_elt
125 PARAMS ((bfd *, struct stat *));
126 extern bfd_boolean _bfd_xcoff_write_armap
127 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
128 extern bfd_boolean _bfd_xcoff_write_archive_contents
129 PARAMS ((bfd *));
130 extern int _bfd_xcoff_sizeof_headers
131 PARAMS ((bfd *, struct bfd_link_info *));
132 extern void _bfd_xcoff_swap_sym_in
133 PARAMS ((bfd *, PTR, PTR));
134 extern unsigned int _bfd_xcoff_swap_sym_out
135 PARAMS ((bfd *, PTR, PTR));
136 extern void _bfd_xcoff_swap_aux_in
137 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
138 extern unsigned int _bfd_xcoff_swap_aux_out
139 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
140 static void xcoff64_swap_ldhdr_in
141 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
142 static void xcoff64_swap_ldhdr_out
143 PARAMS ((bfd *, const struct internal_ldhdr *, PTR d));
144 static void xcoff64_swap_ldsym_in
145 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
146 static void xcoff64_swap_ldsym_out
147 PARAMS ((bfd *, const struct internal_ldsym *, PTR d));
148 static void xcoff64_swap_ldrel_in
149 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
150 static void xcoff64_swap_ldrel_out
151 PARAMS ((bfd *, const struct internal_ldrel *, PTR d));
152 static bfd_boolean xcoff64_write_object_contents
153 PARAMS ((bfd *));
154 static bfd_boolean xcoff64_ppc_relocate_section
155 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
156 struct internal_reloc *, struct internal_syment *,
157 asection **));
158 static bfd_boolean xcoff64_slurp_armap
159 PARAMS ((bfd *));
160 static const bfd_target *xcoff64_archive_p
161 PARAMS ((bfd *));
162 static bfd *xcoff64_openr_next_archived_file
163 PARAMS ((bfd *, bfd *));
164 static int xcoff64_sizeof_headers
165 PARAMS ((bfd *, struct bfd_link_info *));
166 static asection *xcoff64_create_csect_from_smclas
167 PARAMS ((bfd *, union internal_auxent *, const char *));
168 static bfd_boolean xcoff64_is_lineno_count_overflow
169 PARAMS ((bfd *, bfd_vma));
170 static bfd_boolean xcoff64_is_reloc_count_overflow
171 PARAMS ((bfd *, bfd_vma));
172 static bfd_vma xcoff64_loader_symbol_offset
173 PARAMS ((bfd *, struct internal_ldhdr *));
174 static bfd_vma xcoff64_loader_reloc_offset
175 PARAMS ((bfd *, struct internal_ldhdr *));
176 static bfd_boolean xcoff64_generate_rtinit
177 PARAMS ((bfd *, const char *, const char *, bfd_boolean));
178 static bfd_boolean xcoff64_bad_format_hook
179 PARAMS ((bfd *, PTR ));
181 /* Relocation functions */
182 static bfd_boolean xcoff64_reloc_type_br
183 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
185 bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
186 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
188 xcoff_reloc_type_pos, /* R_POS (0x00) */
189 xcoff_reloc_type_neg, /* R_NEG (0x01) */
190 xcoff_reloc_type_rel, /* R_REL (0x02) */
191 xcoff_reloc_type_toc, /* R_TOC (0x03) */
192 xcoff_reloc_type_fail, /* R_RTB (0x04) */
193 xcoff_reloc_type_toc, /* R_GL (0x05) */
194 xcoff_reloc_type_toc, /* R_TCL (0x06) */
195 xcoff_reloc_type_fail, /* (0x07) */
196 xcoff_reloc_type_ba, /* R_BA (0x08) */
197 xcoff_reloc_type_fail, /* (0x09) */
198 xcoff64_reloc_type_br, /* R_BR (0x0a) */
199 xcoff_reloc_type_fail, /* (0x0b) */
200 xcoff_reloc_type_pos, /* R_RL (0x0c) */
201 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
202 xcoff_reloc_type_fail, /* (0x0e) */
203 xcoff_reloc_type_noop, /* R_REF (0x0f) */
204 xcoff_reloc_type_fail, /* (0x10) */
205 xcoff_reloc_type_fail, /* (0x11) */
206 xcoff_reloc_type_toc, /* R_TRL (0x12) */
207 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
208 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
209 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
210 xcoff_reloc_type_ba, /* R_CAI (0x16) */
211 xcoff_reloc_type_crel, /* R_CREL (0x17) */
212 xcoff_reloc_type_ba, /* R_RBA (0x18) */
213 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
214 xcoff64_reloc_type_br, /* R_RBR (0x1a) */
215 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
218 /* coffcode.h needs these to be defined. */
219 /* Internalcoff.h and coffcode.h modify themselves based on these flags. */
220 #define XCOFF64
221 #define RS6000COFF_C 1
223 #define SELECT_RELOC(internal, howto) \
225 internal.r_type = howto->type; \
226 internal.r_size = \
227 ((howto->complain_on_overflow == complain_overflow_signed \
228 ? 0x80 \
229 : 0) \
230 | (howto->bitsize - 1)); \
233 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
234 #define COFF_LONG_FILENAMES
235 #define NO_COFF_SYMBOLS
236 #define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
237 #define coff_mkobject _bfd_xcoff_mkobject
238 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
239 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
240 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
241 #define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
242 #ifdef AIX_CORE
243 extern const bfd_target * rs6000coff_core_p
244 PARAMS ((bfd *abfd));
245 extern bfd_boolean rs6000coff_core_file_matches_executable_p
246 PARAMS ((bfd *cbfd, bfd *ebfd));
247 extern char *rs6000coff_core_file_failing_command
248 PARAMS ((bfd *abfd));
249 extern int rs6000coff_core_file_failing_signal
250 PARAMS ((bfd *abfd));
251 #define CORE_FILE_P rs6000coff_core_p
252 #define coff_core_file_failing_command \
253 rs6000coff_core_file_failing_command
254 #define coff_core_file_failing_signal \
255 rs6000coff_core_file_failing_signal
256 #define coff_core_file_matches_executable_p \
257 rs6000coff_core_file_matches_executable_p
258 #else
259 #define CORE_FILE_P _bfd_dummy_target
260 #define coff_core_file_failing_command \
261 _bfd_nocore_core_file_failing_command
262 #define coff_core_file_failing_signal \
263 _bfd_nocore_core_file_failing_signal
264 #define coff_core_file_matches_executable_p \
265 _bfd_nocore_core_file_matches_executable_p
266 #endif
267 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
268 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
269 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
270 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
271 #define coff_swap_reloc_in xcoff64_swap_reloc_in
272 #define coff_swap_reloc_out xcoff64_swap_reloc_out
273 #define NO_COFF_RELOCS
275 #ifndef bfd_pe_print_pdata
276 #define bfd_pe_print_pdata NULL
277 #endif
279 #include "coffcode.h"
281 /* For XCOFF64, the effective width of symndx changes depending on
282 whether we are the first entry. Sigh. */
283 static void
284 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
285 bfd *abfd;
286 PTR ext1;
287 PTR in1;
289 LINENO *ext = (LINENO *) ext1;
290 struct internal_lineno *in = (struct internal_lineno *) in1;
292 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
293 if (in->l_lnno == 0)
294 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
295 else
296 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
299 static unsigned int
300 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
301 bfd *abfd;
302 PTR inp;
303 PTR outp;
305 struct internal_lineno *in = (struct internal_lineno *) inp;
306 struct external_lineno *ext = (struct external_lineno *) outp;
308 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
309 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
311 if (in->l_lnno == 0)
312 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
313 else
314 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
316 return bfd_coff_linesz (abfd);
319 static void
320 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
321 bfd *abfd;
322 PTR ext1;
323 PTR in1;
325 struct external_syment *ext = (struct external_syment *) ext1;
326 struct internal_syment *in = (struct internal_syment *) in1;
328 in->_n._n_n._n_zeroes = 0;
329 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
330 in->n_value = H_GET_64 (abfd, ext->e_value);
331 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
332 in->n_type = H_GET_16 (abfd, ext->e_type);
333 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
334 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
337 static unsigned int
338 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
339 bfd *abfd;
340 PTR inp;
341 PTR extp;
343 struct internal_syment *in = (struct internal_syment *) inp;
344 struct external_syment *ext = (struct external_syment *) extp;
346 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
347 H_PUT_64 (abfd, in->n_value, ext->e_value);
348 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
349 H_PUT_16 (abfd, in->n_type, ext->e_type);
350 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
351 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
352 return bfd_coff_symesz (abfd);
355 static void
356 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
357 bfd *abfd;
358 PTR ext1;
359 int type;
360 int class;
361 int indx;
362 int numaux;
363 PTR in1;
365 union external_auxent *ext = (union external_auxent *) ext1;
366 union internal_auxent *in = (union internal_auxent *) in1;
368 switch (class)
370 case C_FILE:
371 if (ext->x_file.x_n.x_zeroes[0] == 0)
373 in->x_file.x_n.x_zeroes = 0;
374 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
376 else
378 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
380 goto end;
382 /* RS/6000 "csect" auxents */
383 case C_EXT:
384 case C_HIDEXT:
385 if (indx + 1 == numaux)
387 bfd_signed_vma h = 0;
388 bfd_vma l = 0;
390 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
391 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
393 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
395 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
396 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
397 /* We don't have to hack bitfields in x_smtyp because it's
398 defined by shifts-and-ands, which are equivalent on all
399 byte orders. */
400 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
401 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
402 goto end;
404 break;
406 case C_STAT:
407 case C_LEAFSTAT:
408 case C_HIDDEN:
409 if (type == T_NULL)
411 /* PE defines some extra fields; we zero them out for
412 safety. */
413 in->x_scn.x_checksum = 0;
414 in->x_scn.x_associated = 0;
415 in->x_scn.x_comdat = 0;
417 goto end;
419 break;
422 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
424 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
425 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
426 in->x_sym.x_fcnary.x_fcn.x_endndx.l
427 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
429 if (ISFCN (type))
431 in->x_sym.x_misc.x_fsize
432 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
434 else
436 in->x_sym.x_misc.x_lnsz.x_lnno
437 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
438 in->x_sym.x_misc.x_lnsz.x_size
439 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
442 end: ;
445 static unsigned int
446 _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
447 bfd *abfd;
448 PTR inp;
449 int type;
450 int class;
451 int indx ATTRIBUTE_UNUSED;
452 int numaux ATTRIBUTE_UNUSED;
453 PTR extp;
455 union internal_auxent *in = (union internal_auxent *) inp;
456 union external_auxent *ext = (union external_auxent *) extp;
458 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
459 switch (class)
461 case C_FILE:
462 if (in->x_file.x_n.x_zeroes == 0)
464 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
465 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
467 else
469 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
471 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
472 goto end;
474 /* RS/6000 "csect" auxents */
475 case C_EXT:
476 case C_HIDEXT:
477 if (indx + 1 == numaux)
479 bfd_vma temp;
481 temp = in->x_csect.x_scnlen.l & 0xffffffff;
482 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
483 temp = in->x_csect.x_scnlen.l >> 32;
484 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
485 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
486 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
487 /* We don't have to hack bitfields in x_smtyp because it's
488 defined by shifts-and-ands, which are equivalent on all
489 byte orders. */
490 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
491 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
492 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
493 goto end;
495 break;
497 case C_STAT:
498 case C_LEAFSTAT:
499 case C_HIDDEN:
500 if (type == T_NULL)
502 goto end;
504 break;
507 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
509 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
510 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
511 H_PUT_8 (abfd, _AUX_FCN,
512 ext->x_auxtype.x_auxtype);
513 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
514 ext->x_sym.x_fcnary.x_fcn.x_endndx);
516 if (ISFCN (type))
518 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
519 ext->x_sym.x_fcnary.x_fcn.x_fsize);
521 else
523 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
524 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
525 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
526 ext->x_sym.x_fcnary.x_lnsz.x_size);
529 end:
531 return bfd_coff_auxesz (abfd);
534 static bfd_boolean
535 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
536 bfd *abfd;
537 struct bfd_strtab_hash *strtab;
538 struct internal_syment *sym;
539 const char *name;
541 bfd_boolean hash;
542 bfd_size_type indx;
544 hash = TRUE;
546 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
547 hash = FALSE;
549 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
551 if (indx == (bfd_size_type) -1)
552 return FALSE;
554 sym->_n._n_n._n_zeroes = 0;
555 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
557 return TRUE;
560 static bfd_boolean
561 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
562 bfd *abfd ATTRIBUTE_UNUSED;
563 struct xcoff_loader_info *ldinfo;
564 struct internal_ldsym *ldsym;
565 const char *name;
567 size_t len;
568 len = strlen (name);
570 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
572 bfd_size_type newalc;
573 char *newstrings;
575 newalc = ldinfo->string_alc * 2;
576 if (newalc == 0)
577 newalc = 32;
578 while (ldinfo->string_size + len + 3 > newalc)
579 newalc *= 2;
581 newstrings = bfd_realloc (ldinfo->strings, newalc);
582 if (newstrings == NULL)
584 ldinfo->failed = TRUE;
585 return FALSE;
587 ldinfo->string_alc = newalc;
588 ldinfo->strings = newstrings;
591 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
592 ldinfo->strings + ldinfo->string_size);
593 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
594 ldsym->_l._l_l._l_zeroes = 0;
595 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
596 ldinfo->string_size += len + 3;
598 return TRUE;
601 /* Routines to swap information in the XCOFF .loader section. If we
602 ever need to write an XCOFF loader, this stuff will need to be
603 moved to another file shared by the linker (which XCOFF calls the
604 ``binder'') and the loader. */
606 /* Swap in the ldhdr structure. */
608 static void
609 xcoff64_swap_ldhdr_in (abfd, s, dst)
610 bfd *abfd;
611 const PTR s;
612 struct internal_ldhdr *dst;
614 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
616 dst->l_version = bfd_get_32 (abfd, src->l_version);
617 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
618 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
619 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
620 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
621 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
622 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
623 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
624 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
625 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
628 /* Swap out the ldhdr structure. */
630 static void
631 xcoff64_swap_ldhdr_out (abfd, src, d)
632 bfd *abfd;
633 const struct internal_ldhdr *src;
634 PTR d;
636 struct external_ldhdr *dst = (struct external_ldhdr *) d;
638 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
639 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
640 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
641 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
642 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
643 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
644 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
645 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
646 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
647 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
650 /* Swap in the ldsym structure. */
652 static void
653 xcoff64_swap_ldsym_in (abfd, s, dst)
654 bfd *abfd;
655 const PTR s;
656 struct internal_ldsym *dst;
658 const struct external_ldsym *src = (const struct external_ldsym *) s;
659 /* XCOFF64 does not use l_zeroes like XCOFF32
660 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
661 as an offset into the loader symbol table. */
662 dst->_l._l_l._l_zeroes = 0;
663 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
664 dst->l_value = bfd_get_64 (abfd, src->l_value);
665 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
666 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
667 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
668 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
669 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
672 /* Swap out the ldsym structure. */
674 static void
675 xcoff64_swap_ldsym_out (abfd, src, d)
676 bfd *abfd;
677 const struct internal_ldsym *src;
678 PTR d;
680 struct external_ldsym *dst = (struct external_ldsym *) d;
682 bfd_put_64 (abfd, src->l_value, dst->l_value);
683 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
684 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
685 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
686 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
687 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
688 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
691 static void
692 xcoff64_swap_reloc_in (abfd, s, d)
693 bfd *abfd;
694 PTR s;
695 PTR d;
697 struct external_reloc *src = (struct external_reloc *) s;
698 struct internal_reloc *dst = (struct internal_reloc *) d;
700 memset (dst, 0, sizeof (struct internal_reloc));
702 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
703 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
704 dst->r_size = bfd_get_8 (abfd, src->r_size);
705 dst->r_type = bfd_get_8 (abfd, src->r_type);
708 static unsigned int
709 xcoff64_swap_reloc_out (abfd, s, d)
710 bfd *abfd;
711 PTR s;
712 PTR d;
714 struct internal_reloc *src = (struct internal_reloc *) s;
715 struct external_reloc *dst = (struct external_reloc *) d;
717 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
718 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
719 bfd_put_8 (abfd, src->r_type, dst->r_type);
720 bfd_put_8 (abfd, src->r_size, dst->r_size);
722 return bfd_coff_relsz (abfd);
725 /* Swap in the ldrel structure. */
727 static void
728 xcoff64_swap_ldrel_in (abfd, s, dst)
729 bfd *abfd;
730 const PTR s;
731 struct internal_ldrel *dst;
733 const struct external_ldrel *src = (const struct external_ldrel *) s;
735 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
736 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
737 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
738 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
741 /* Swap out the ldrel structure. */
743 static void
744 xcoff64_swap_ldrel_out (abfd, src, d)
745 bfd *abfd;
746 const struct internal_ldrel *src;
747 PTR d;
749 struct external_ldrel *dst = (struct external_ldrel *) d;
751 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
752 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
753 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
754 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
757 static bfd_boolean
758 xcoff64_write_object_contents (abfd)
759 bfd *abfd;
761 asection *current;
762 bfd_boolean hasrelocs = FALSE;
763 bfd_boolean haslinno = FALSE;
764 file_ptr scn_base;
765 file_ptr reloc_base;
766 file_ptr lineno_base;
767 file_ptr sym_base;
768 unsigned long reloc_size = 0;
769 unsigned long lnno_size = 0;
770 bfd_boolean long_section_names;
771 asection *text_sec = ((void *) 0);
772 asection *data_sec = ((void *) 0);
773 asection *bss_sec = ((void *) 0);
774 struct internal_filehdr internal_f;
775 struct internal_aouthdr internal_a;
777 bfd_set_error (bfd_error_system_call);
779 if (! abfd->output_has_begun)
781 if (! bfd_coff_compute_section_file_positions (abfd))
782 return FALSE;
785 /* Work out the size of the reloc and linno areas. */
786 reloc_base = obj_relocbase (abfd);
788 for (current = abfd->sections; current != NULL; current = current->next)
789 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
791 lineno_base = reloc_base + reloc_size;
793 /* Make a pass through the symbol table to count line number entries and
794 put them into the correct asections. */
795 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
797 sym_base = lineno_base + lnno_size;
799 /* Indicate in each section->line_filepos its actual file address. */
800 for (current = abfd->sections; current != NULL; current = current->next)
802 if (current->lineno_count)
804 current->line_filepos = lineno_base;
805 current->moving_line_filepos = lineno_base;
806 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
808 else
810 current->line_filepos = 0;
813 if (current->reloc_count)
815 current->rel_filepos = reloc_base;
816 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
818 else
820 current->rel_filepos = 0;
824 if ((abfd->flags & EXEC_P) != 0)
826 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
827 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
829 else
831 scn_base = bfd_coff_filhsz (abfd);
832 internal_f.f_opthdr = 0;
835 internal_f.f_nscns = 0;
837 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
838 return FALSE;
840 long_section_names = FALSE;
841 for (current = abfd->sections; current != NULL; current = current->next)
843 struct internal_scnhdr section;
844 struct external_scnhdr buff;
845 bfd_size_type amount;
847 internal_f.f_nscns++;
849 strncpy (section.s_name, current->name, SCNNMLEN);
851 section.s_vaddr = current->vma;
852 section.s_paddr = current->lma;
853 section.s_size = current->size;
855 /* If this section has no size or is unloadable then the scnptr
856 will be 0 too. */
857 if (current->size == 0
858 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
860 section.s_scnptr = 0;
862 else
864 section.s_scnptr = current->filepos;
867 section.s_relptr = current->rel_filepos;
868 section.s_lnnoptr = current->line_filepos;
869 section.s_nreloc = current->reloc_count;
871 section.s_nlnno = current->lineno_count;
872 if (current->reloc_count != 0)
873 hasrelocs = TRUE;
874 if (current->lineno_count != 0)
875 haslinno = TRUE;
877 section.s_flags = sec_to_styp_flags (current->name, current->flags);
879 if (!strcmp (current->name, _TEXT))
881 text_sec = current;
883 else if (!strcmp (current->name, _DATA))
885 data_sec = current;
887 else if (!strcmp (current->name, _BSS))
889 bss_sec = current;
892 amount = bfd_coff_scnhsz (abfd);
893 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
894 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
895 return FALSE;
898 internal_f.f_timdat = 0;
900 internal_f.f_flags = 0;
902 if (!hasrelocs)
903 internal_f.f_flags |= F_RELFLG;
904 if (!haslinno)
905 internal_f.f_flags |= F_LNNO;
906 if (abfd->flags & EXEC_P)
907 internal_f.f_flags |= F_EXEC;
909 /* FIXME: this is wrong for PPC_PE! */
910 if (bfd_little_endian (abfd))
911 internal_f.f_flags |= F_AR32WR;
912 else
913 internal_f.f_flags |= F_AR32W;
915 if ((abfd->flags & DYNAMIC) != 0)
916 internal_f.f_flags |= F_SHROBJ;
917 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
918 internal_f.f_flags |= F_DYNLOAD;
920 memset (&internal_a, 0, sizeof internal_a);
922 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
923 internal_a.magic = (abfd->flags & D_PAGED
924 ? RS6K_AOUTHDR_ZMAGIC
925 : (abfd->flags & WP_TEXT
926 ? RS6K_AOUTHDR_NMAGIC
927 : RS6K_AOUTHDR_OMAGIC));
929 /* FIXME: Does anybody ever set this to another value? */
930 internal_a.vstamp = 0;
932 /* Now should write relocs, strings, syms. */
933 obj_sym_filepos (abfd) = sym_base;
935 internal_f.f_symptr = 0;
936 internal_f.f_nsyms = 0;
938 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
939 backend linker, and obj_raw_syment_count is not valid until after
940 coff_write_symbols is called. */
941 if (bfd_get_symcount (abfd) != 0)
943 int firstundef;
945 if (!coff_renumber_symbols (abfd, &firstundef))
946 return FALSE;
947 coff_mangle_symbols (abfd);
948 if (! coff_write_symbols (abfd))
949 return FALSE;
950 if (! coff_write_linenumbers (abfd))
951 return FALSE;
952 if (! coff_write_relocs (abfd, firstundef))
953 return FALSE;
955 internal_f.f_symptr = sym_base;
956 internal_f.f_nsyms = bfd_get_symcount (abfd);
958 else if (obj_raw_syment_count (abfd) != 0)
960 internal_f.f_symptr = sym_base;
962 /* AIX appears to require that F_RELFLG not be set if there are
963 local symbols but no relocations. */
964 internal_f.f_flags &=~ F_RELFLG;
966 else
968 internal_f.f_flags |= F_LSYMS;
971 if (text_sec)
973 internal_a.tsize = text_sec->size;
974 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
977 if (data_sec)
979 internal_a.dsize = data_sec->size;
980 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
983 if (bss_sec)
985 internal_a.bsize = bss_sec->size;
986 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
987 internal_a.data_start = bss_sec->vma;
990 internal_a.entry = bfd_get_start_address (abfd);
991 internal_f.f_nsyms = obj_raw_syment_count (abfd);
993 if (xcoff_data (abfd)->full_aouthdr)
995 bfd_vma toc;
996 asection *loader_sec;
998 internal_a.vstamp = 1;
1000 internal_a.o_snentry = xcoff_data (abfd)->snentry;
1001 if (internal_a.o_snentry == 0)
1002 internal_a.entry = (bfd_vma) -1;
1004 if (text_sec != NULL)
1006 internal_a.o_sntext = text_sec->target_index;
1007 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
1009 else
1011 internal_a.o_sntext = 0;
1012 internal_a.o_algntext = 0;
1015 if (data_sec != NULL)
1017 internal_a.o_sndata = data_sec->target_index;
1018 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1020 else
1022 internal_a.o_sndata = 0;
1023 internal_a.o_algndata = 0;
1026 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1027 if (loader_sec != NULL)
1028 internal_a.o_snloader = loader_sec->target_index;
1029 else
1030 internal_a.o_snloader = 0;
1031 if (bss_sec != NULL)
1032 internal_a.o_snbss = bss_sec->target_index;
1033 else
1034 internal_a.o_snbss = 0;
1036 toc = xcoff_data (abfd)->toc;
1037 internal_a.o_toc = toc;
1038 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1040 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1041 if (xcoff_data (abfd)->cputype != -1)
1042 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1043 else
1045 switch (bfd_get_arch (abfd))
1047 case bfd_arch_rs6000:
1048 internal_a.o_cputype = 4;
1049 break;
1050 case bfd_arch_powerpc:
1051 if (bfd_get_mach (abfd) == bfd_mach_ppc)
1052 internal_a.o_cputype = 3;
1053 else
1054 internal_a.o_cputype = 1;
1055 break;
1056 default:
1057 abort ();
1060 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1061 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
1064 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
1065 return FALSE;
1068 char * buff;
1069 bfd_size_type amount = bfd_coff_filhsz (abfd);
1071 buff = bfd_malloc (amount);
1072 if (buff == NULL)
1073 return FALSE;
1075 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1076 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1078 free (buff);
1080 if (amount != bfd_coff_filhsz (abfd))
1081 return FALSE;
1084 if (abfd->flags & EXEC_P)
1086 char * buff;
1087 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1089 buff = bfd_malloc (amount);
1090 if (buff == NULL)
1091 return FALSE;
1093 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
1094 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1096 free (buff);
1098 if (amount != bfd_coff_aoutsz (abfd))
1099 return FALSE;
1102 return TRUE;
1105 static bfd_boolean
1106 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
1107 val, addend, relocation, contents)
1108 bfd *input_bfd;
1109 asection *input_section;
1110 bfd *output_bfd ATTRIBUTE_UNUSED;
1111 struct internal_reloc *rel;
1112 struct internal_syment *sym ATTRIBUTE_UNUSED;
1113 struct reloc_howto_struct *howto;
1114 bfd_vma val;
1115 bfd_vma addend;
1116 bfd_vma *relocation;
1117 bfd_byte *contents;
1119 struct xcoff_link_hash_entry *h;
1121 if (0 > rel->r_symndx)
1122 return FALSE;
1124 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1126 /* If we see an R_BR or R_RBR reloc which is jumping to global
1127 linkage code, and it is followed by an appropriate cror nop
1128 instruction, we replace the cror with ld r2,40(r1). This
1129 restores the TOC after the glink code. Contrariwise, if the
1130 call is followed by a ld r2,40(r1), but the call is not
1131 going to global linkage code, we can replace the load with a
1132 cror. */
1133 if (NULL != h
1134 && bfd_link_hash_defined == h->root.type
1135 && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
1137 bfd_byte *pnext;
1138 unsigned long next;
1140 pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
1141 next = bfd_get_32 (input_bfd, pnext);
1143 /* The _ptrgl function is magic. It is used by the AIX compiler to call
1144 a function through a pointer. */
1145 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
1147 if (next == 0x4def7b82 /* cror 15,15,15 */
1148 || next == 0x4ffffb82 /* cror 31,31,31 */
1149 || next == 0x60000000) /* ori r0,r0,0 */
1150 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1152 else
1154 if (next == 0xe8410028) /* ld r2,40(r1) */
1155 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1158 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
1160 /* Normally, this relocation is against a defined symbol. In the
1161 case where this is a partial link and the output section offset
1162 is greater than 2^25, the linker will return an invalid error
1163 message that the relocation has been truncated. Yes it has been
1164 truncated but no it not important. For this case, disable the
1165 overflow checking. */
1166 howto->complain_on_overflow = complain_overflow_dont;
1169 howto->pc_relative = TRUE;
1170 howto->src_mask &= ~3;
1171 howto->dst_mask = howto->src_mask;
1173 /* A PC relative reloc includes the section address. */
1174 addend += input_section->vma;
1176 *relocation = val + addend;
1177 *relocation -= (input_section->output_section->vma
1178 + input_section->output_offset);
1179 return TRUE;
1182 /* This is the relocation function for the PowerPC64.
1183 See xcoff_ppc_relocation_section for more information. */
1185 bfd_boolean
1186 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1187 input_section, contents, relocs, syms,
1188 sections)
1189 bfd *output_bfd;
1190 struct bfd_link_info *info;
1191 bfd *input_bfd;
1192 asection *input_section;
1193 bfd_byte *contents;
1194 struct internal_reloc *relocs;
1195 struct internal_syment *syms;
1196 asection **sections;
1198 struct internal_reloc *rel;
1199 struct internal_reloc *relend;
1201 rel = relocs;
1202 relend = rel + input_section->reloc_count;
1203 for (; rel < relend; rel++)
1205 long symndx;
1206 struct xcoff_link_hash_entry *h;
1207 struct internal_syment *sym;
1208 bfd_vma addend;
1209 bfd_vma val;
1210 struct reloc_howto_struct howto;
1211 bfd_vma relocation;
1212 bfd_vma value_to_relocate;
1213 bfd_vma address;
1214 bfd_byte *location;
1216 /* Relocation type R_REF is a special relocation type which is
1217 merely used to prevent garbage collection from occurring for
1218 the csect including the symbol which it references. */
1219 if (rel->r_type == R_REF)
1220 continue;
1222 /* howto */
1223 howto.type = rel->r_type;
1224 howto.rightshift = 0;
1225 howto.bitsize = (rel->r_size & 0x3f) + 1;
1226 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
1227 howto.pc_relative = FALSE;
1228 howto.bitpos = 0;
1229 howto.complain_on_overflow = (rel->r_size & 0x80
1230 ? complain_overflow_signed
1231 : complain_overflow_bitfield);
1232 howto.special_function = NULL;
1233 howto.name = "internal";
1234 howto.partial_inplace = TRUE;
1235 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
1236 howto.pcrel_offset = FALSE;
1238 /* symbol */
1239 val = 0;
1240 addend = 0;
1241 h = NULL;
1242 sym = NULL;
1243 symndx = rel->r_symndx;
1245 if (-1 != symndx)
1247 asection *sec;
1249 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1250 sym = syms + symndx;
1251 addend = - sym->n_value;
1253 if (NULL == h)
1255 sec = sections[symndx];
1256 /* Hack to make sure we use the right TOC anchor value
1257 if this reloc is against the TOC anchor. */
1258 if (sec->name[3] == '0'
1259 && strcmp (sec->name, ".tc0") == 0)
1260 val = xcoff_data (output_bfd)->toc;
1261 else
1262 val = (sec->output_section->vma
1263 + sec->output_offset
1264 + sym->n_value
1265 - sec->vma);
1267 else
1269 if (h->root.type == bfd_link_hash_defined
1270 || h->root.type == bfd_link_hash_defweak)
1272 sec = h->root.u.def.section;
1273 val = (h->root.u.def.value
1274 + sec->output_section->vma
1275 + sec->output_offset);
1277 else if (h->root.type == bfd_link_hash_common)
1279 sec = h->root.u.c.p->section;
1280 val = (sec->output_section->vma
1281 + sec->output_offset);
1283 else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
1284 && ! info->relocatable)
1286 if (! ((*info->callbacks->undefined_symbol)
1287 (info, h->root.root.string, input_bfd, input_section,
1288 rel->r_vaddr - input_section->vma, TRUE)))
1289 return FALSE;
1291 /* Don't try to process the reloc. It can't help, and
1292 it may generate another error. */
1293 continue;
1298 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
1299 || !((*xcoff64_calculate_relocation[rel->r_type])
1300 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1301 addend, &relocation, contents)))
1302 return FALSE;
1304 /* address */
1305 address = rel->r_vaddr - input_section->vma;
1306 location = contents + address;
1308 if (address > input_section->size)
1309 abort ();
1311 /* Get the value we are going to relocate. */
1312 if (1 == howto.size)
1313 value_to_relocate = bfd_get_16 (input_bfd, location);
1314 else if (2 == howto.size)
1315 value_to_relocate = bfd_get_32 (input_bfd, location);
1316 else
1317 value_to_relocate = bfd_get_64 (input_bfd, location);
1319 /* overflow.
1321 FIXME: We may drop bits during the addition
1322 which we don't check for. We must either check at every single
1323 operation, which would be tedious, or we must do the computations
1324 in a type larger than bfd_vma, which would be inefficient. */
1326 if ((unsigned int) howto.complain_on_overflow
1327 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1328 abort ();
1330 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1331 (input_bfd, value_to_relocate, relocation, &howto)))
1333 const char *name;
1334 char buf[SYMNMLEN + 1];
1335 char reloc_type_name[10];
1337 if (symndx == -1)
1339 name = "*ABS*";
1341 else if (h != NULL)
1343 name = NULL;
1345 else
1347 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1348 if (name == NULL)
1349 name = "UNKNOWN";
1351 sprintf (reloc_type_name, "0x%02x", rel->r_type);
1353 if (! ((*info->callbacks->reloc_overflow)
1354 (info, (h ? &h->root : NULL), name, reloc_type_name,
1355 (bfd_vma) 0, input_bfd, input_section,
1356 rel->r_vaddr - input_section->vma)))
1357 return FALSE;
1360 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
1361 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1362 | (((value_to_relocate & howto.src_mask)
1363 + relocation) & howto.dst_mask));
1365 /* Put the value back in the object file. */
1366 if (1 == howto.size)
1367 bfd_put_16 (input_bfd, value_to_relocate, location);
1368 else if (2 == howto.size)
1369 bfd_put_32 (input_bfd, value_to_relocate, location);
1370 else
1371 bfd_put_64 (input_bfd, value_to_relocate, location);
1374 return TRUE;
1378 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1379 bitsize and whether they are signed or not, along with a
1380 conventional type. This table is for the types, which are used for
1381 different algorithms for putting in the reloc. Many of these
1382 relocs need special_function entries, which I have not written. */
1384 reloc_howto_type xcoff64_howto_table[] =
1386 /* Standard 64 bit relocation. */
1387 HOWTO (R_POS, /* type */
1388 0, /* rightshift */
1389 4, /* size (0 = byte, 1 = short, 2 = long) */
1390 64, /* bitsize */
1391 FALSE, /* pc_relative */
1392 0, /* bitpos */
1393 complain_overflow_bitfield, /* complain_on_overflow */
1394 0, /* special_function */
1395 "R_POS_64", /* name */
1396 TRUE, /* partial_inplace */
1397 MINUS_ONE, /* src_mask */
1398 MINUS_ONE, /* dst_mask */
1399 FALSE), /* pcrel_offset */
1401 /* 64 bit relocation, but store negative value. */
1402 HOWTO (R_NEG, /* type */
1403 0, /* rightshift */
1404 -4, /* size (0 = byte, 1 = short, 2 = long) */
1405 64, /* bitsize */
1406 FALSE, /* pc_relative */
1407 0, /* bitpos */
1408 complain_overflow_bitfield, /* complain_on_overflow */
1409 0, /* special_function */
1410 "R_NEG", /* name */
1411 TRUE, /* partial_inplace */
1412 MINUS_ONE, /* src_mask */
1413 MINUS_ONE, /* dst_mask */
1414 FALSE), /* pcrel_offset */
1416 /* 32 bit PC relative relocation. */
1417 HOWTO (R_REL, /* type */
1418 0, /* rightshift */
1419 2, /* size (0 = byte, 1 = short, 2 = long) */
1420 32, /* bitsize */
1421 TRUE, /* pc_relative */
1422 0, /* bitpos */
1423 complain_overflow_signed, /* complain_on_overflow */
1424 0, /* special_function */
1425 "R_REL", /* name */
1426 TRUE, /* partial_inplace */
1427 0xffffffff, /* src_mask */
1428 0xffffffff, /* dst_mask */
1429 FALSE), /* pcrel_offset */
1431 /* 16 bit TOC relative relocation. */
1432 HOWTO (R_TOC, /* type */
1433 0, /* rightshift */
1434 1, /* size (0 = byte, 1 = short, 2 = long) */
1435 16, /* bitsize */
1436 FALSE, /* pc_relative */
1437 0, /* bitpos */
1438 complain_overflow_bitfield, /* complain_on_overflow */
1439 0, /* special_function */
1440 "R_TOC", /* name */
1441 TRUE, /* partial_inplace */
1442 0xffff, /* src_mask */
1443 0xffff, /* dst_mask */
1444 FALSE), /* pcrel_offset */
1446 /* I don't really know what this is. */
1447 HOWTO (R_RTB, /* type */
1448 1, /* rightshift */
1449 2, /* size (0 = byte, 1 = short, 2 = long) */
1450 32, /* bitsize */
1451 FALSE, /* pc_relative */
1452 0, /* bitpos */
1453 complain_overflow_bitfield, /* complain_on_overflow */
1454 0, /* special_function */
1455 "R_RTB", /* name */
1456 TRUE, /* partial_inplace */
1457 0xffffffff, /* src_mask */
1458 0xffffffff, /* dst_mask */
1459 FALSE), /* pcrel_offset */
1461 /* External TOC relative symbol. */
1462 HOWTO (R_GL, /* type */
1463 0, /* rightshift */
1464 1, /* size (0 = byte, 1 = short, 2 = long) */
1465 16, /* bitsize */
1466 FALSE, /* pc_relative */
1467 0, /* bitpos */
1468 complain_overflow_bitfield, /* complain_on_overflow */
1469 0, /* special_function */
1470 "R_GL", /* name */
1471 TRUE, /* partial_inplace */
1472 0xffff, /* src_mask */
1473 0xffff, /* dst_mask */
1474 FALSE), /* pcrel_offset */
1476 /* Local TOC relative symbol. */
1477 HOWTO (R_TCL, /* type */
1478 0, /* rightshift */
1479 1, /* size (0 = byte, 1 = short, 2 = long) */
1480 16, /* bitsize */
1481 FALSE, /* pc_relative */
1482 0, /* bitpos */
1483 complain_overflow_bitfield, /* complain_on_overflow */
1484 0, /* special_function */
1485 "R_TCL", /* name */
1486 TRUE, /* partial_inplace */
1487 0xffff, /* src_mask */
1488 0xffff, /* dst_mask */
1489 FALSE), /* pcrel_offset */
1491 EMPTY_HOWTO (7),
1493 /* Non modifiable absolute branch. */
1494 HOWTO (R_BA, /* type */
1495 0, /* rightshift */
1496 2, /* size (0 = byte, 1 = short, 2 = long) */
1497 26, /* bitsize */
1498 FALSE, /* pc_relative */
1499 0, /* bitpos */
1500 complain_overflow_bitfield, /* complain_on_overflow */
1501 0, /* special_function */
1502 "R_BA_26", /* name */
1503 TRUE, /* partial_inplace */
1504 0x03fffffc, /* src_mask */
1505 0x03fffffc, /* dst_mask */
1506 FALSE), /* pcrel_offset */
1508 EMPTY_HOWTO (9),
1510 /* Non modifiable relative branch. */
1511 HOWTO (R_BR, /* type */
1512 0, /* rightshift */
1513 2, /* size (0 = byte, 1 = short, 2 = long) */
1514 26, /* bitsize */
1515 TRUE, /* pc_relative */
1516 0, /* bitpos */
1517 complain_overflow_signed, /* complain_on_overflow */
1518 0, /* special_function */
1519 "R_BR", /* name */
1520 TRUE, /* partial_inplace */
1521 0x03fffffc, /* src_mask */
1522 0x03fffffc, /* dst_mask */
1523 FALSE), /* pcrel_offset */
1525 EMPTY_HOWTO (0xb),
1527 /* Indirect load. */
1528 HOWTO (R_RL, /* type */
1529 0, /* rightshift */
1530 1, /* size (0 = byte, 1 = short, 2 = long) */
1531 16, /* bitsize */
1532 FALSE, /* pc_relative */
1533 0, /* bitpos */
1534 complain_overflow_bitfield, /* complain_on_overflow */
1535 0, /* special_function */
1536 "R_RL", /* name */
1537 TRUE, /* partial_inplace */
1538 0xffff, /* src_mask */
1539 0xffff, /* dst_mask */
1540 FALSE), /* pcrel_offset */
1542 /* Load address. */
1543 HOWTO (R_RLA, /* type */
1544 0, /* rightshift */
1545 1, /* size (0 = byte, 1 = short, 2 = long) */
1546 16, /* bitsize */
1547 FALSE, /* pc_relative */
1548 0, /* bitpos */
1549 complain_overflow_bitfield, /* complain_on_overflow */
1550 0, /* special_function */
1551 "R_RLA", /* name */
1552 TRUE, /* partial_inplace */
1553 0xffff, /* src_mask */
1554 0xffff, /* dst_mask */
1555 FALSE), /* pcrel_offset */
1557 EMPTY_HOWTO (0xe),
1559 /* Non-relocating reference. */
1560 HOWTO (R_REF, /* type */
1561 0, /* rightshift */
1562 2, /* size (0 = byte, 1 = short, 2 = long) */
1563 32, /* bitsize */
1564 FALSE, /* pc_relative */
1565 0, /* bitpos */
1566 complain_overflow_dont, /* complain_on_overflow */
1567 0, /* special_function */
1568 "R_REF", /* name */
1569 FALSE, /* partial_inplace */
1570 0, /* src_mask */
1571 0, /* dst_mask */
1572 FALSE), /* pcrel_offset */
1574 EMPTY_HOWTO (0x10),
1575 EMPTY_HOWTO (0x11),
1577 /* TOC relative indirect load. */
1578 HOWTO (R_TRL, /* type */
1579 0, /* rightshift */
1580 1, /* size (0 = byte, 1 = short, 2 = long) */
1581 16, /* bitsize */
1582 FALSE, /* pc_relative */
1583 0, /* bitpos */
1584 complain_overflow_bitfield, /* complain_on_overflow */
1585 0, /* special_function */
1586 "R_TRL", /* name */
1587 TRUE, /* partial_inplace */
1588 0xffff, /* src_mask */
1589 0xffff, /* dst_mask */
1590 FALSE), /* pcrel_offset */
1592 /* TOC relative load address. */
1593 HOWTO (R_TRLA, /* type */
1594 0, /* rightshift */
1595 1, /* size (0 = byte, 1 = short, 2 = long) */
1596 16, /* bitsize */
1597 FALSE, /* pc_relative */
1598 0, /* bitpos */
1599 complain_overflow_bitfield, /* complain_on_overflow */
1600 0, /* special_function */
1601 "R_TRLA", /* name */
1602 TRUE, /* partial_inplace */
1603 0xffff, /* src_mask */
1604 0xffff, /* dst_mask */
1605 FALSE), /* pcrel_offset */
1607 /* Modifiable relative branch. */
1608 HOWTO (R_RRTBI, /* type */
1609 1, /* rightshift */
1610 2, /* size (0 = byte, 1 = short, 2 = long) */
1611 32, /* bitsize */
1612 FALSE, /* pc_relative */
1613 0, /* bitpos */
1614 complain_overflow_bitfield, /* complain_on_overflow */
1615 0, /* special_function */
1616 "R_RRTBI", /* name */
1617 TRUE, /* partial_inplace */
1618 0xffffffff, /* src_mask */
1619 0xffffffff, /* dst_mask */
1620 FALSE), /* pcrel_offset */
1622 /* Modifiable absolute branch. */
1623 HOWTO (R_RRTBA, /* type */
1624 1, /* rightshift */
1625 2, /* size (0 = byte, 1 = short, 2 = long) */
1626 32, /* bitsize */
1627 FALSE, /* pc_relative */
1628 0, /* bitpos */
1629 complain_overflow_bitfield, /* complain_on_overflow */
1630 0, /* special_function */
1631 "R_RRTBA", /* name */
1632 TRUE, /* partial_inplace */
1633 0xffffffff, /* src_mask */
1634 0xffffffff, /* dst_mask */
1635 FALSE), /* pcrel_offset */
1637 /* Modifiable call absolute indirect. */
1638 HOWTO (R_CAI, /* type */
1639 0, /* rightshift */
1640 1, /* size (0 = byte, 1 = short, 2 = long) */
1641 16, /* bitsize */
1642 FALSE, /* pc_relative */
1643 0, /* bitpos */
1644 complain_overflow_bitfield, /* complain_on_overflow */
1645 0, /* special_function */
1646 "R_CAI", /* name */
1647 TRUE, /* partial_inplace */
1648 0xffff, /* src_mask */
1649 0xffff, /* dst_mask */
1650 FALSE), /* pcrel_offset */
1652 /* Modifiable call relative. */
1653 HOWTO (R_CREL, /* type */
1654 0, /* rightshift */
1655 1, /* size (0 = byte, 1 = short, 2 = long) */
1656 16, /* bitsize */
1657 FALSE, /* pc_relative */
1658 0, /* bitpos */
1659 complain_overflow_bitfield, /* complain_on_overflow */
1660 0, /* special_function */
1661 "R_CREL", /* name */
1662 TRUE, /* partial_inplace */
1663 0xffff, /* src_mask */
1664 0xffff, /* dst_mask */
1665 FALSE), /* pcrel_offset */
1667 /* Modifiable branch absolute. */
1668 HOWTO (R_RBA, /* type */
1669 0, /* rightshift */
1670 2, /* size (0 = byte, 1 = short, 2 = long) */
1671 26, /* bitsize */
1672 FALSE, /* pc_relative */
1673 0, /* bitpos */
1674 complain_overflow_bitfield, /* complain_on_overflow */
1675 0, /* special_function */
1676 "R_RBA", /* name */
1677 TRUE, /* partial_inplace */
1678 0x03fffffc, /* src_mask */
1679 0x03fffffc, /* dst_mask */
1680 FALSE), /* pcrel_offset */
1682 /* Modifiable branch absolute. */
1683 HOWTO (R_RBAC, /* type */
1684 0, /* rightshift */
1685 2, /* size (0 = byte, 1 = short, 2 = long) */
1686 32, /* bitsize */
1687 FALSE, /* pc_relative */
1688 0, /* bitpos */
1689 complain_overflow_bitfield, /* complain_on_overflow */
1690 0, /* special_function */
1691 "R_RBAC", /* name */
1692 TRUE, /* partial_inplace */
1693 0xffffffff, /* src_mask */
1694 0xffffffff, /* dst_mask */
1695 FALSE), /* pcrel_offset */
1697 /* Modifiable branch relative. */
1698 HOWTO (R_RBR, /* type */
1699 0, /* rightshift */
1700 2, /* size (0 = byte, 1 = short, 2 = long) */
1701 26, /* bitsize */
1702 FALSE, /* pc_relative */
1703 0, /* bitpos */
1704 complain_overflow_signed, /* complain_on_overflow */
1705 0, /* special_function */
1706 "R_RBR_26", /* name */
1707 TRUE, /* partial_inplace */
1708 0x03fffffc, /* src_mask */
1709 0x03fffffc, /* dst_mask */
1710 FALSE), /* pcrel_offset */
1712 /* Modifiable branch absolute. */
1713 HOWTO (R_RBRC, /* type */
1714 0, /* rightshift */
1715 1, /* size (0 = byte, 1 = short, 2 = long) */
1716 16, /* bitsize */
1717 FALSE, /* pc_relative */
1718 0, /* bitpos */
1719 complain_overflow_bitfield, /* complain_on_overflow */
1720 0, /* special_function */
1721 "R_RBRC", /* name */
1722 TRUE, /* partial_inplace */
1723 0xffff, /* src_mask */
1724 0xffff, /* dst_mask */
1725 FALSE), /* pcrel_offset */
1727 HOWTO (R_POS, /* type */
1728 0, /* rightshift */
1729 2, /* size (0 = byte, 1 = short, 2 = long) */
1730 32, /* bitsize */
1731 FALSE, /* pc_relative */
1732 0, /* bitpos */
1733 complain_overflow_bitfield, /* complain_on_overflow */
1734 0, /* special_function */
1735 "R_POS_32", /* name */
1736 TRUE, /* partial_inplace */
1737 0xffffffff, /* src_mask */
1738 0xffffffff, /* dst_mask */
1739 FALSE), /* pcrel_offset */
1741 /* 16 bit Non modifiable absolute branch. */
1742 HOWTO (R_BA, /* type */
1743 0, /* rightshift */
1744 1, /* size (0 = byte, 1 = short, 2 = long) */
1745 16, /* bitsize */
1746 FALSE, /* pc_relative */
1747 0, /* bitpos */
1748 complain_overflow_bitfield, /* complain_on_overflow */
1749 0, /* special_function */
1750 "R_BA_16", /* name */
1751 TRUE, /* partial_inplace */
1752 0xfffc, /* src_mask */
1753 0xfffc, /* dst_mask */
1754 FALSE), /* pcrel_offset */
1756 /* Modifiable branch relative. */
1757 HOWTO (R_RBR, /* type */
1758 0, /* rightshift */
1759 1, /* size (0 = byte, 1 = short, 2 = long) */
1760 16, /* bitsize */
1761 FALSE, /* pc_relative */
1762 0, /* bitpos */
1763 complain_overflow_signed, /* complain_on_overflow */
1764 0, /* special_function */
1765 "R_RBR_16", /* name */
1766 TRUE, /* partial_inplace */
1767 0xffff, /* src_mask */
1768 0xffff, /* dst_mask */
1769 FALSE), /* pcrel_offset */
1771 /* Modifiable branch absolute. */
1772 HOWTO (R_RBA, /* type */
1773 0, /* rightshift */
1774 1, /* size (0 = byte, 1 = short, 2 = long) */
1775 16, /* bitsize */
1776 FALSE, /* pc_relative */
1777 0, /* bitpos */
1778 complain_overflow_bitfield, /* complain_on_overflow */
1779 0, /* special_function */
1780 "R_RBA_16", /* name */
1781 TRUE, /* partial_inplace */
1782 0xffff, /* src_mask */
1783 0xffff, /* dst_mask */
1784 FALSE), /* pcrel_offset */
1788 void
1789 xcoff64_rtype2howto (relent, internal)
1790 arelent *relent;
1791 struct internal_reloc *internal;
1793 if (internal->r_type > R_RBRC)
1794 abort ();
1796 /* Default howto layout works most of the time */
1797 relent->howto = &xcoff64_howto_table[internal->r_type];
1799 /* Special case some 16 bit reloc */
1800 if (15 == (internal->r_size & 0x3f))
1802 if (R_BA == internal->r_type)
1803 relent->howto = &xcoff64_howto_table[0x1d];
1804 else if (R_RBR == internal->r_type)
1805 relent->howto = &xcoff64_howto_table[0x1e];
1806 else if (R_RBA == internal->r_type)
1807 relent->howto = &xcoff64_howto_table[0x1f];
1809 /* Special case 32 bit */
1810 else if (31 == (internal->r_size & 0x3f))
1812 if (R_POS == internal->r_type)
1813 relent->howto = &xcoff64_howto_table[0x1c];
1816 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1817 relocation, as well as indicating whether it is signed or not.
1818 Doublecheck that the relocation information gathered from the
1819 type matches this information. The bitsize is not significant
1820 for R_REF relocs. */
1821 if (relent->howto->dst_mask != 0
1822 && (relent->howto->bitsize
1823 != ((unsigned int) internal->r_size & 0x3f) + 1))
1824 abort ();
1827 reloc_howto_type *
1828 xcoff64_reloc_type_lookup (abfd, code)
1829 bfd *abfd ATTRIBUTE_UNUSED;
1830 bfd_reloc_code_real_type code;
1832 switch (code)
1834 case BFD_RELOC_PPC_B26:
1835 return &xcoff64_howto_table[0xa];
1836 case BFD_RELOC_PPC_BA16:
1837 return &xcoff64_howto_table[0x1d];
1838 case BFD_RELOC_PPC_BA26:
1839 return &xcoff64_howto_table[8];
1840 case BFD_RELOC_PPC_TOC16:
1841 return &xcoff64_howto_table[3];
1842 case BFD_RELOC_32:
1843 case BFD_RELOC_CTOR:
1844 return &xcoff64_howto_table[0x1c];
1845 case BFD_RELOC_64:
1846 return &xcoff64_howto_table[0];
1847 default:
1848 return NULL;
1852 static reloc_howto_type *
1853 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1854 const char *r_name)
1856 unsigned int i;
1858 for (i = 0;
1859 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1860 i++)
1861 if (xcoff64_howto_table[i].name != NULL
1862 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1863 return &xcoff64_howto_table[i];
1865 return NULL;
1868 /* Read in the armap of an XCOFF archive. */
1870 static bfd_boolean
1871 xcoff64_slurp_armap (abfd)
1872 bfd *abfd;
1874 file_ptr off;
1875 size_t namlen;
1876 bfd_size_type sz, amt;
1877 bfd_byte *contents, *cend;
1878 bfd_vma c, i;
1879 carsym *arsym;
1880 bfd_byte *p;
1881 file_ptr pos;
1883 /* This is for the new format. */
1884 struct xcoff_ar_hdr_big hdr;
1886 if (xcoff_ardata (abfd) == NULL)
1888 bfd_has_map (abfd) = FALSE;
1889 return TRUE;
1892 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1893 (const char **) NULL, 10);
1894 if (off == 0)
1896 bfd_has_map (abfd) = FALSE;
1897 return TRUE;
1900 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1901 return FALSE;
1903 /* The symbol table starts with a normal archive header. */
1904 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1905 != SIZEOF_AR_HDR_BIG)
1906 return FALSE;
1908 /* Skip the name (normally empty). */
1909 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1910 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1911 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1912 return FALSE;
1914 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1916 /* Read in the entire symbol table. */
1917 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1918 if (contents == NULL)
1919 return FALSE;
1920 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1921 return FALSE;
1923 /* The symbol table starts with an eight byte count. */
1924 c = H_GET_64 (abfd, contents);
1926 if (c * 8 >= sz)
1928 bfd_set_error (bfd_error_bad_value);
1929 return FALSE;
1931 amt = c;
1932 amt *= sizeof (carsym);
1933 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1934 if (bfd_ardata (abfd)->symdefs == NULL)
1935 return FALSE;
1937 /* After the count comes a list of eight byte file offsets. */
1938 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1939 i < c;
1940 ++i, ++arsym, p += 8)
1941 arsym->file_offset = H_GET_64 (abfd, p);
1943 /* After the file offsets come null terminated symbol names. */
1944 cend = contents + sz;
1945 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1946 i < c;
1947 ++i, ++arsym, p += strlen ((char *) p) + 1)
1949 if (p >= cend)
1951 bfd_set_error (bfd_error_bad_value);
1952 return FALSE;
1954 arsym->name = (char *) p;
1957 bfd_ardata (abfd)->symdef_count = c;
1958 bfd_has_map (abfd) = TRUE;
1960 return TRUE;
1964 /* See if this is an NEW XCOFF archive. */
1966 static const bfd_target *
1967 xcoff64_archive_p (abfd)
1968 bfd *abfd;
1970 struct artdata *tdata_hold;
1971 char magic[SXCOFFARMAG];
1972 /* This is the new format. */
1973 struct xcoff_ar_file_hdr_big hdr;
1974 bfd_size_type amt = SXCOFFARMAG;
1976 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
1978 if (bfd_get_error () != bfd_error_system_call)
1979 bfd_set_error (bfd_error_wrong_format);
1980 return NULL;
1983 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1985 bfd_set_error (bfd_error_wrong_format);
1986 return NULL;
1989 /* Copy over the magic string. */
1990 memcpy (hdr.magic, magic, SXCOFFARMAG);
1992 /* Now read the rest of the file header. */
1993 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1994 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1996 if (bfd_get_error () != bfd_error_system_call)
1997 bfd_set_error (bfd_error_wrong_format);
1998 return NULL;
2001 tdata_hold = bfd_ardata (abfd);
2003 amt = sizeof (struct artdata);
2004 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2005 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2006 goto error_ret_restore;
2008 /* Already cleared by bfd_zalloc above.
2009 bfd_ardata (abfd)->cache = NULL;
2010 bfd_ardata (abfd)->archive_head = NULL;
2011 bfd_ardata (abfd)->symdefs = NULL;
2012 bfd_ardata (abfd)->extended_names = NULL;
2013 bfd_ardata (abfd)->extended_names_size = 0; */
2014 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2015 (const char **) NULL,
2016 10);
2018 amt = SIZEOF_AR_FILE_HDR_BIG;
2019 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2020 if (bfd_ardata (abfd)->tdata == NULL)
2021 goto error_ret;
2023 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2025 if (! xcoff64_slurp_armap (abfd))
2027 error_ret:
2028 bfd_release (abfd, bfd_ardata (abfd));
2029 error_ret_restore:
2030 bfd_ardata (abfd) = tdata_hold;
2031 return NULL;
2034 return abfd->xvec;
2038 /* Open the next element in an XCOFF archive. */
2040 static bfd *
2041 xcoff64_openr_next_archived_file (archive, last_file)
2042 bfd *archive;
2043 bfd *last_file;
2045 bfd_vma filestart;
2047 if ((xcoff_ardata (archive) == NULL)
2048 || ! xcoff_big_format_p (archive))
2050 bfd_set_error (bfd_error_invalid_operation);
2051 return NULL;
2054 if (last_file == NULL)
2056 filestart = bfd_ardata (archive)->first_file_filepos;
2058 else
2060 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2061 (const char **) NULL, 10);
2064 if (filestart == 0
2065 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2066 (const char **) NULL, 10)
2067 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2068 (const char **) NULL, 10))
2070 bfd_set_error (bfd_error_no_more_archived_files);
2071 return NULL;
2074 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2077 /* We can't use the usual coff_sizeof_headers routine, because AIX
2078 always uses an a.out header. */
2080 static int
2081 xcoff64_sizeof_headers (bfd *abfd,
2082 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2084 int size;
2086 size = bfd_coff_filhsz (abfd);
2088 /* Don't think the small aout header can be used since some of the
2089 old elements have been reordered past the end of the old coff
2090 small aout size. */
2092 if (xcoff_data (abfd)->full_aouthdr)
2093 size += bfd_coff_aoutsz (abfd);
2095 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2096 return size;
2101 static asection *
2102 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2103 bfd *abfd;
2104 union internal_auxent *aux;
2105 const char *symbol_name;
2107 asection *return_value = NULL;
2109 /* Changes from 32 :
2110 .sv == 8, is only for 32 bit programs
2111 .ti == 12 and .tb == 13 are now reserved. */
2112 static const char *names[19] =
2114 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2115 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2116 ".td", ".sv64", ".sv3264"
2119 if ((19 >= aux->x_csect.x_smclas)
2120 && (NULL != names[aux->x_csect.x_smclas]))
2123 return_value = bfd_make_section_anyway
2124 (abfd, names[aux->x_csect.x_smclas]);
2127 else
2129 (*_bfd_error_handler)
2130 (_("%B: symbol `%s' has unrecognized smclas %d"),
2131 abfd, symbol_name, aux->x_csect.x_smclas);
2132 bfd_set_error (bfd_error_bad_value);
2135 return return_value;
2138 static bfd_boolean
2139 xcoff64_is_lineno_count_overflow (abfd, value)
2140 bfd *abfd ATTRIBUTE_UNUSED;
2141 bfd_vma value ATTRIBUTE_UNUSED;
2143 return FALSE;
2146 static bfd_boolean
2147 xcoff64_is_reloc_count_overflow (abfd, value)
2148 bfd *abfd ATTRIBUTE_UNUSED;
2149 bfd_vma value ATTRIBUTE_UNUSED;
2151 return FALSE;
2154 static bfd_vma
2155 xcoff64_loader_symbol_offset (abfd, ldhdr)
2156 bfd *abfd ATTRIBUTE_UNUSED;
2157 struct internal_ldhdr *ldhdr;
2159 return (ldhdr->l_symoff);
2162 static bfd_vma
2163 xcoff64_loader_reloc_offset (abfd, ldhdr)
2164 bfd *abfd ATTRIBUTE_UNUSED;
2165 struct internal_ldhdr *ldhdr;
2167 return (ldhdr->l_rldoff);
2170 static bfd_boolean
2171 xcoff64_bad_format_hook (abfd, filehdr)
2172 bfd * abfd;
2173 PTR filehdr;
2175 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2177 /* Check flavor first. */
2178 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2179 return FALSE;
2181 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2182 return FALSE;
2184 return TRUE;
2187 static bfd_boolean
2188 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2189 bfd *abfd;
2190 const char *init;
2191 const char *fini;
2192 bfd_boolean rtld;
2194 bfd_byte filehdr_ext[FILHSZ];
2195 bfd_byte scnhdr_ext[SCNHSZ * 3];
2196 bfd_byte syment_ext[SYMESZ * 10];
2197 bfd_byte reloc_ext[RELSZ * 3];
2198 bfd_byte *data_buffer;
2199 bfd_size_type data_buffer_size;
2200 bfd_byte *string_table, *st_tmp;
2201 bfd_size_type string_table_size;
2202 bfd_vma val;
2203 size_t initsz, finisz;
2204 struct internal_filehdr filehdr;
2205 struct internal_scnhdr text_scnhdr;
2206 struct internal_scnhdr data_scnhdr;
2207 struct internal_scnhdr bss_scnhdr;
2208 struct internal_syment syment;
2209 union internal_auxent auxent;
2210 struct internal_reloc reloc;
2212 char *text_name = ".text";
2213 char *data_name = ".data";
2214 char *bss_name = ".bss";
2215 char *rtinit_name = "__rtinit";
2216 char *rtld_name = "__rtld";
2218 if (! bfd_xcoff_rtinit_size (abfd))
2219 return FALSE;
2221 initsz = (init == NULL ? 0 : 1 + strlen (init));
2222 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2224 /* File header. */
2225 memset (filehdr_ext, 0, FILHSZ);
2226 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2227 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2228 filehdr.f_nscns = 3;
2229 filehdr.f_timdat = 0;
2230 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2231 filehdr.f_symptr = 0; /* set below */
2232 filehdr.f_opthdr = 0;
2233 filehdr.f_flags = 0;
2235 /* Section headers. */
2236 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2238 /* Text. */
2239 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2240 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2241 text_scnhdr.s_paddr = 0;
2242 text_scnhdr.s_vaddr = 0;
2243 text_scnhdr.s_size = 0;
2244 text_scnhdr.s_scnptr = 0;
2245 text_scnhdr.s_relptr = 0;
2246 text_scnhdr.s_lnnoptr = 0;
2247 text_scnhdr.s_nreloc = 0;
2248 text_scnhdr.s_nlnno = 0;
2249 text_scnhdr.s_flags = STYP_TEXT;
2251 /* Data. */
2252 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2253 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2254 data_scnhdr.s_paddr = 0;
2255 data_scnhdr.s_vaddr = 0;
2256 data_scnhdr.s_size = 0; /* set below */
2257 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2258 data_scnhdr.s_relptr = 0; /* set below */
2259 data_scnhdr.s_lnnoptr = 0;
2260 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2261 data_scnhdr.s_nlnno = 0;
2262 data_scnhdr.s_flags = STYP_DATA;
2264 /* Bss. */
2265 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2266 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2267 bss_scnhdr.s_paddr = 0; /* set below */
2268 bss_scnhdr.s_vaddr = 0; /* set below */
2269 bss_scnhdr.s_size = 0; /* set below */
2270 bss_scnhdr.s_scnptr = 0;
2271 bss_scnhdr.s_relptr = 0;
2272 bss_scnhdr.s_lnnoptr = 0;
2273 bss_scnhdr.s_nreloc = 0;
2274 bss_scnhdr.s_nlnno = 0;
2275 bss_scnhdr.s_flags = STYP_BSS;
2277 /* .data
2278 0x0000 0x00000000 : rtl
2279 0x0004 0x00000000 :
2280 0x0008 0x00000018 : offset to init, or 0
2281 0x000C 0x00000038 : offset to fini, or 0
2282 0x0010 0x00000010 : size of descriptor
2283 0x0014 0x00000000 : pad
2284 0x0018 0x00000000 : init, needs a reloc
2285 0x001C 0x00000000 :
2286 0x0020 0x00000058 : offset to init name
2287 0x0024 0x00000000 : flags, padded to a word
2288 0x0028 0x00000000 : empty init
2289 0x002C 0x00000000 :
2290 0x0030 0x00000000 :
2291 0x0034 0x00000000 :
2292 0x0038 0x00000000 : fini, needs a reloc
2293 0x003C 0x00000000 :
2294 0x0040 0x00000??? : offset to fini name
2295 0x0044 0x00000000 : flags, padded to a word
2296 0x0048 0x00000000 : empty fini
2297 0x004C 0x00000000 :
2298 0x0050 0x00000000 :
2299 0x0054 0x00000000 :
2300 0x0058 init name
2301 0x0058 + initsz fini name */
2303 data_buffer_size = 0x0058 + initsz + finisz;
2304 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2305 data_buffer = NULL;
2306 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2307 if (data_buffer == NULL)
2308 return FALSE;
2310 if (initsz)
2312 val = 0x18;
2313 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2314 val = 0x58;
2315 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2316 memcpy (&data_buffer[val], init, initsz);
2319 if (finisz)
2321 val = 0x38;
2322 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2323 val = 0x58 + initsz;
2324 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2325 memcpy (&data_buffer[val], fini, finisz);
2328 val = 0x10;
2329 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2330 data_scnhdr.s_size = data_buffer_size;
2331 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2333 /* String table. */
2334 string_table_size = 4;
2335 string_table_size += strlen (data_name) + 1;
2336 string_table_size += strlen (rtinit_name) + 1;
2337 string_table_size += initsz;
2338 string_table_size += finisz;
2339 if (rtld)
2340 string_table_size += strlen (rtld_name) + 1;
2342 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2343 if (string_table == NULL)
2344 return FALSE;
2346 val = string_table_size;
2347 bfd_put_32 (abfd, val, &string_table[0]);
2348 st_tmp = string_table + 4;
2350 /* symbols
2351 0. .data csect
2352 2. __rtinit
2353 4. init function
2354 6. fini function
2355 8. __rtld */
2356 memset (syment_ext, 0, 10 * SYMESZ);
2357 memset (reloc_ext, 0, 3 * RELSZ);
2359 /* .data csect */
2360 memset (&syment, 0, sizeof (struct internal_syment));
2361 memset (&auxent, 0, sizeof (union internal_auxent));
2363 syment._n._n_n._n_offset = st_tmp - string_table;
2364 memcpy (st_tmp, data_name, strlen (data_name));
2365 st_tmp += strlen (data_name) + 1;
2367 syment.n_scnum = 2;
2368 syment.n_sclass = C_HIDEXT;
2369 syment.n_numaux = 1;
2370 auxent.x_csect.x_scnlen.l = data_buffer_size;
2371 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2372 auxent.x_csect.x_smclas = XMC_RW;
2373 bfd_coff_swap_sym_out (abfd, &syment,
2374 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2375 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2376 syment.n_numaux,
2377 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2378 filehdr.f_nsyms += 2;
2380 /* __rtinit */
2381 memset (&syment, 0, sizeof (struct internal_syment));
2382 memset (&auxent, 0, sizeof (union internal_auxent));
2383 syment._n._n_n._n_offset = st_tmp - string_table;
2384 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2385 st_tmp += strlen (rtinit_name) + 1;
2387 syment.n_scnum = 2;
2388 syment.n_sclass = C_EXT;
2389 syment.n_numaux = 1;
2390 auxent.x_csect.x_smtyp = XTY_LD;
2391 auxent.x_csect.x_smclas = XMC_RW;
2392 bfd_coff_swap_sym_out (abfd, &syment,
2393 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2394 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2395 syment.n_numaux,
2396 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2397 filehdr.f_nsyms += 2;
2399 /* Init. */
2400 if (initsz)
2402 memset (&syment, 0, sizeof (struct internal_syment));
2403 memset (&auxent, 0, sizeof (union internal_auxent));
2405 syment._n._n_n._n_offset = st_tmp - string_table;
2406 memcpy (st_tmp, init, initsz);
2407 st_tmp += initsz;
2409 syment.n_sclass = C_EXT;
2410 syment.n_numaux = 1;
2411 bfd_coff_swap_sym_out (abfd, &syment,
2412 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2413 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2414 syment.n_numaux,
2415 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2416 /* Reloc. */
2417 memset (&reloc, 0, sizeof (struct internal_reloc));
2418 reloc.r_vaddr = 0x0018;
2419 reloc.r_symndx = filehdr.f_nsyms;
2420 reloc.r_type = R_POS;
2421 reloc.r_size = 63;
2422 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2424 filehdr.f_nsyms += 2;
2425 data_scnhdr.s_nreloc += 1;
2428 /* Finit. */
2429 if (finisz)
2431 memset (&syment, 0, sizeof (struct internal_syment));
2432 memset (&auxent, 0, sizeof (union internal_auxent));
2434 syment._n._n_n._n_offset = st_tmp - string_table;
2435 memcpy (st_tmp, fini, finisz);
2436 st_tmp += finisz;
2438 syment.n_sclass = C_EXT;
2439 syment.n_numaux = 1;
2440 bfd_coff_swap_sym_out (abfd, &syment,
2441 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2442 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2443 syment.n_numaux,
2444 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2446 /* Reloc. */
2447 memset (&reloc, 0, sizeof (struct internal_reloc));
2448 reloc.r_vaddr = 0x0038;
2449 reloc.r_symndx = filehdr.f_nsyms;
2450 reloc.r_type = R_POS;
2451 reloc.r_size = 63;
2452 bfd_coff_swap_reloc_out (abfd, &reloc,
2453 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2455 filehdr.f_nsyms += 2;
2456 data_scnhdr.s_nreloc += 1;
2459 if (rtld)
2461 memset (&syment, 0, sizeof (struct internal_syment));
2462 memset (&auxent, 0, sizeof (union internal_auxent));
2464 syment._n._n_n._n_offset = st_tmp - string_table;
2465 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2466 st_tmp += strlen (rtld_name) + 1;
2468 syment.n_sclass = C_EXT;
2469 syment.n_numaux = 1;
2470 bfd_coff_swap_sym_out (abfd, &syment,
2471 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2472 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2473 syment.n_numaux,
2474 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2476 /* Reloc. */
2477 memset (&reloc, 0, sizeof (struct internal_reloc));
2478 reloc.r_vaddr = 0x0000;
2479 reloc.r_symndx = filehdr.f_nsyms;
2480 reloc.r_type = R_POS;
2481 reloc.r_size = 63;
2482 bfd_coff_swap_reloc_out (abfd, &reloc,
2483 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2485 filehdr.f_nsyms += 2;
2486 data_scnhdr.s_nreloc += 1;
2488 bss_scnhdr.s_size = 0;
2491 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2492 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2494 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2495 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2496 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2497 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2498 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2499 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2500 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2501 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2502 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2503 bfd_bwrite (string_table, string_table_size, abfd);
2505 free (data_buffer);
2506 data_buffer = NULL;
2508 return TRUE;
2511 /* The typical dynamic reloc. */
2513 static reloc_howto_type xcoff64_dynamic_reloc =
2514 HOWTO (0, /* type */
2515 0, /* rightshift */
2516 4, /* size (0 = byte, 1 = short, 2 = long) */
2517 64, /* bitsize */
2518 FALSE, /* pc_relative */
2519 0, /* bitpos */
2520 complain_overflow_bitfield, /* complain_on_overflow */
2521 0, /* special_function */
2522 "R_POS", /* name */
2523 TRUE, /* partial_inplace */
2524 MINUS_ONE, /* src_mask */
2525 MINUS_ONE, /* dst_mask */
2526 FALSE); /* pcrel_offset */
2528 static unsigned long xcoff64_glink_code[10] =
2530 0xe9820000, /* ld r12,0(r2) */
2531 0xf8410028, /* std r2,40(r1) */
2532 0xe80c0000, /* ld r0,0(r12) */
2533 0xe84c0008, /* ld r0,8(r12) */
2534 0x7c0903a6, /* mtctr r0 */
2535 0x4e800420, /* bctr */
2536 0x00000000, /* start of traceback table */
2537 0x000ca000, /* traceback table */
2538 0x00000000, /* traceback table */
2539 0x00000018, /* ??? */
2542 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2544 { /* COFF backend, defined in libcoff.h. */
2545 _bfd_xcoff64_swap_aux_in,
2546 _bfd_xcoff64_swap_sym_in,
2547 _bfd_xcoff64_swap_lineno_in,
2548 _bfd_xcoff64_swap_aux_out,
2549 _bfd_xcoff64_swap_sym_out,
2550 _bfd_xcoff64_swap_lineno_out,
2551 xcoff64_swap_reloc_out,
2552 coff_swap_filehdr_out,
2553 coff_swap_aouthdr_out,
2554 coff_swap_scnhdr_out,
2555 FILHSZ,
2556 AOUTSZ,
2557 SCNHSZ,
2558 SYMESZ,
2559 AUXESZ,
2560 RELSZ,
2561 LINESZ,
2562 FILNMLEN,
2563 TRUE, /* _bfd_coff_long_filenames */
2564 FALSE, /* _bfd_coff_long_section_names */
2565 3, /* _bfd_coff_default_section_alignment_power */
2566 TRUE, /* _bfd_coff_force_symnames_in_strings */
2567 4, /* _bfd_coff_debug_string_prefix_length */
2568 coff_swap_filehdr_in,
2569 coff_swap_aouthdr_in,
2570 coff_swap_scnhdr_in,
2571 xcoff64_swap_reloc_in,
2572 xcoff64_bad_format_hook,
2573 coff_set_arch_mach_hook,
2574 coff_mkobject_hook,
2575 styp_to_sec_flags,
2576 coff_set_alignment_hook,
2577 coff_slurp_symbol_table,
2578 symname_in_debug_hook,
2579 coff_pointerize_aux_hook,
2580 coff_print_aux,
2581 dummy_reloc16_extra_cases,
2582 dummy_reloc16_estimate,
2583 NULL, /* bfd_coff_symbol_classification */
2584 coff_compute_section_file_positions,
2585 NULL, /* _bfd_coff_start_final_link */
2586 xcoff64_ppc_relocate_section,
2587 coff_rtype_to_howto,
2588 NULL, /* _bfd_coff_adjust_symndx */
2589 _bfd_generic_link_add_one_symbol,
2590 coff_link_output_has_begun,
2591 coff_final_link_postscript,
2592 NULL /* print_pdata. */
2595 0x01EF, /* magic number */
2596 bfd_arch_powerpc,
2597 bfd_mach_ppc_620,
2599 /* Function pointers to xcoff specific swap routines. */
2600 xcoff64_swap_ldhdr_in,
2601 xcoff64_swap_ldhdr_out,
2602 xcoff64_swap_ldsym_in,
2603 xcoff64_swap_ldsym_out,
2604 xcoff64_swap_ldrel_in,
2605 xcoff64_swap_ldrel_out,
2607 /* Sizes. */
2608 LDHDRSZ,
2609 LDSYMSZ,
2610 LDRELSZ,
2611 24, /* _xcoff_function_descriptor_size */
2612 0, /* _xcoff_small_aout_header_size */
2614 /* Versions. */
2615 2, /* _xcoff_ldhdr_version */
2617 _bfd_xcoff64_put_symbol_name,
2618 _bfd_xcoff64_put_ldsymbol_name,
2619 &xcoff64_dynamic_reloc,
2620 xcoff64_create_csect_from_smclas,
2622 /* Lineno and reloc count overflow. */
2623 xcoff64_is_lineno_count_overflow,
2624 xcoff64_is_reloc_count_overflow,
2626 xcoff64_loader_symbol_offset,
2627 xcoff64_loader_reloc_offset,
2629 /* glink. */
2630 &xcoff64_glink_code[0],
2631 40, /* _xcoff_glink_size */
2633 /* rtinit. */
2634 88, /* _xcoff_rtinit_size */
2635 xcoff64_generate_rtinit,
2638 /* The transfer vector that leads the outside world to all of the above. */
2639 const bfd_target rs6000coff64_vec =
2641 "aixcoff64-rs6000",
2642 bfd_target_xcoff_flavour,
2643 BFD_ENDIAN_BIG, /* data byte order is big */
2644 BFD_ENDIAN_BIG, /* header byte order is big */
2646 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2647 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2649 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2650 0, /* leading char */
2651 '/', /* ar_pad_char */
2652 15, /* ar_max_namelen */
2654 /* data */
2655 bfd_getb64,
2656 bfd_getb_signed_64,
2657 bfd_putb64,
2658 bfd_getb32,
2659 bfd_getb_signed_32,
2660 bfd_putb32,
2661 bfd_getb16,
2662 bfd_getb_signed_16,
2663 bfd_putb16,
2665 /* hdrs */
2666 bfd_getb64,
2667 bfd_getb_signed_64,
2668 bfd_putb64,
2669 bfd_getb32,
2670 bfd_getb_signed_32,
2671 bfd_putb32,
2672 bfd_getb16,
2673 bfd_getb_signed_16,
2674 bfd_putb16,
2676 { /* bfd_check_format */
2677 _bfd_dummy_target,
2678 coff_object_p,
2679 xcoff64_archive_p,
2680 CORE_FILE_P
2683 { /* bfd_set_format */
2684 bfd_false,
2685 coff_mkobject,
2686 _bfd_generic_mkarchive,
2687 bfd_false
2690 {/* bfd_write_contents */
2691 bfd_false,
2692 xcoff64_write_object_contents,
2693 _bfd_xcoff_write_archive_contents,
2694 bfd_false
2697 /* Generic */
2698 bfd_true,
2699 bfd_true,
2700 coff_new_section_hook,
2701 _bfd_generic_get_section_contents,
2702 _bfd_generic_get_section_contents_in_window,
2704 /* Copy */
2705 _bfd_xcoff_copy_private_bfd_data,
2706 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2707 _bfd_generic_init_private_section_data,
2708 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2709 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2710 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2711 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2712 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
2714 /* Core */
2715 coff_core_file_failing_command,
2716 coff_core_file_failing_signal,
2717 coff_core_file_matches_executable_p,
2719 /* Archive */
2720 xcoff64_slurp_armap,
2721 bfd_false,
2722 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2723 bfd_dont_truncate_arname,
2724 _bfd_xcoff_write_armap,
2725 _bfd_xcoff_read_ar_hdr,
2726 xcoff64_openr_next_archived_file,
2727 _bfd_generic_get_elt_at_index,
2728 _bfd_xcoff_stat_arch_elt,
2729 bfd_true,
2731 /* Symbols */
2732 coff_get_symtab_upper_bound,
2733 coff_canonicalize_symtab,
2734 coff_make_empty_symbol,
2735 coff_print_symbol,
2736 coff_get_symbol_info,
2737 _bfd_xcoff_is_local_label_name,
2738 coff_bfd_is_target_special_symbol,
2739 coff_get_lineno,
2740 coff_find_nearest_line,
2741 _bfd_generic_find_line,
2742 coff_find_inliner_info,
2743 coff_bfd_make_debug_symbol,
2744 _bfd_generic_read_minisymbols,
2745 _bfd_generic_minisymbol_to_symbol,
2747 /* Reloc */
2748 coff_get_reloc_upper_bound,
2749 coff_canonicalize_reloc,
2750 xcoff64_reloc_type_lookup,
2751 xcoff64_reloc_name_lookup,
2753 /* Write */
2754 coff_set_arch_mach,
2755 coff_set_section_contents,
2757 /* Link */
2758 xcoff64_sizeof_headers,
2759 bfd_generic_get_relocated_section_contents,
2760 bfd_generic_relax_section,
2761 _bfd_xcoff_bfd_link_hash_table_create,
2762 _bfd_generic_link_hash_table_free,
2763 _bfd_xcoff_bfd_link_add_symbols,
2764 _bfd_generic_link_just_syms,
2765 _bfd_xcoff_bfd_final_link,
2766 _bfd_generic_link_split_section,
2767 bfd_generic_gc_sections,
2768 bfd_generic_merge_sections,
2769 bfd_generic_is_group_section,
2770 bfd_generic_discard_group,
2771 _bfd_generic_section_already_linked,
2773 /* Dynamic */
2774 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2775 _bfd_xcoff_canonicalize_dynamic_symtab,
2776 _bfd_nodynamic_get_synthetic_symtab,
2777 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2778 _bfd_xcoff_canonicalize_dynamic_reloc,
2780 /* Opposite endian version, none exists */
2781 NULL,
2783 (void *) &bfd_xcoff_backend_data,
2786 extern const bfd_target *xcoff64_core_p
2787 PARAMS ((bfd *));
2788 extern bfd_boolean xcoff64_core_file_matches_executable_p
2789 PARAMS ((bfd *, bfd *));
2790 extern char *xcoff64_core_file_failing_command
2791 PARAMS ((bfd *));
2792 extern int xcoff64_core_file_failing_signal
2793 PARAMS ((bfd *));
2795 /* AIX 5 */
2796 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2798 { /* COFF backend, defined in libcoff.h. */
2799 _bfd_xcoff64_swap_aux_in,
2800 _bfd_xcoff64_swap_sym_in,
2801 _bfd_xcoff64_swap_lineno_in,
2802 _bfd_xcoff64_swap_aux_out,
2803 _bfd_xcoff64_swap_sym_out,
2804 _bfd_xcoff64_swap_lineno_out,
2805 xcoff64_swap_reloc_out,
2806 coff_swap_filehdr_out,
2807 coff_swap_aouthdr_out,
2808 coff_swap_scnhdr_out,
2809 FILHSZ,
2810 AOUTSZ,
2811 SCNHSZ,
2812 SYMESZ,
2813 AUXESZ,
2814 RELSZ,
2815 LINESZ,
2816 FILNMLEN,
2817 TRUE, /* _bfd_coff_long_filenames */
2818 FALSE, /* _bfd_coff_long_section_names */
2819 3, /* _bfd_coff_default_section_alignment_power */
2820 TRUE, /* _bfd_coff_force_symnames_in_strings */
2821 4, /* _bfd_coff_debug_string_prefix_length */
2822 coff_swap_filehdr_in,
2823 coff_swap_aouthdr_in,
2824 coff_swap_scnhdr_in,
2825 xcoff64_swap_reloc_in,
2826 xcoff64_bad_format_hook,
2827 coff_set_arch_mach_hook,
2828 coff_mkobject_hook,
2829 styp_to_sec_flags,
2830 coff_set_alignment_hook,
2831 coff_slurp_symbol_table,
2832 symname_in_debug_hook,
2833 coff_pointerize_aux_hook,
2834 coff_print_aux,
2835 dummy_reloc16_extra_cases,
2836 dummy_reloc16_estimate,
2837 NULL, /* bfd_coff_sym_is_global */
2838 coff_compute_section_file_positions,
2839 NULL, /* _bfd_coff_start_final_link */
2840 xcoff64_ppc_relocate_section,
2841 coff_rtype_to_howto,
2842 NULL, /* _bfd_coff_adjust_symndx */
2843 _bfd_generic_link_add_one_symbol,
2844 coff_link_output_has_begun,
2845 coff_final_link_postscript,
2846 NULL /* print_pdata. */
2849 U64_TOCMAGIC, /* magic number */
2850 bfd_arch_powerpc,
2851 bfd_mach_ppc_620,
2853 /* Function pointers to xcoff specific swap routines. */
2854 xcoff64_swap_ldhdr_in,
2855 xcoff64_swap_ldhdr_out,
2856 xcoff64_swap_ldsym_in,
2857 xcoff64_swap_ldsym_out,
2858 xcoff64_swap_ldrel_in,
2859 xcoff64_swap_ldrel_out,
2861 /* Sizes. */
2862 LDHDRSZ,
2863 LDSYMSZ,
2864 LDRELSZ,
2865 24, /* _xcoff_function_descriptor_size */
2866 0, /* _xcoff_small_aout_header_size */
2867 /* Versions. */
2868 2, /* _xcoff_ldhdr_version */
2870 _bfd_xcoff64_put_symbol_name,
2871 _bfd_xcoff64_put_ldsymbol_name,
2872 &xcoff64_dynamic_reloc,
2873 xcoff64_create_csect_from_smclas,
2875 /* Lineno and reloc count overflow. */
2876 xcoff64_is_lineno_count_overflow,
2877 xcoff64_is_reloc_count_overflow,
2879 xcoff64_loader_symbol_offset,
2880 xcoff64_loader_reloc_offset,
2882 /* glink. */
2883 &xcoff64_glink_code[0],
2884 40, /* _xcoff_glink_size */
2886 /* rtinit. */
2887 88, /* _xcoff_rtinit_size */
2888 xcoff64_generate_rtinit,
2891 /* The transfer vector that leads the outside world to all of the above. */
2892 const bfd_target aix5coff64_vec =
2894 "aix5coff64-rs6000",
2895 bfd_target_xcoff_flavour,
2896 BFD_ENDIAN_BIG, /* data byte order is big */
2897 BFD_ENDIAN_BIG, /* header byte order is big */
2899 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2900 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2902 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2903 0, /* leading char */
2904 '/', /* ar_pad_char */
2905 15, /* ar_max_namelen */
2907 /* data */
2908 bfd_getb64,
2909 bfd_getb_signed_64,
2910 bfd_putb64,
2911 bfd_getb32,
2912 bfd_getb_signed_32,
2913 bfd_putb32,
2914 bfd_getb16,
2915 bfd_getb_signed_16,
2916 bfd_putb16,
2918 /* hdrs */
2919 bfd_getb64,
2920 bfd_getb_signed_64,
2921 bfd_putb64,
2922 bfd_getb32,
2923 bfd_getb_signed_32,
2924 bfd_putb32,
2925 bfd_getb16,
2926 bfd_getb_signed_16,
2927 bfd_putb16,
2929 { /* bfd_check_format */
2930 _bfd_dummy_target,
2931 coff_object_p,
2932 xcoff64_archive_p,
2933 xcoff64_core_p
2936 { /* bfd_set_format */
2937 bfd_false,
2938 coff_mkobject,
2939 _bfd_generic_mkarchive,
2940 bfd_false
2943 {/* bfd_write_contents */
2944 bfd_false,
2945 xcoff64_write_object_contents,
2946 _bfd_xcoff_write_archive_contents,
2947 bfd_false
2950 /* Generic */
2951 bfd_true,
2952 bfd_true,
2953 coff_new_section_hook,
2954 _bfd_generic_get_section_contents,
2955 _bfd_generic_get_section_contents_in_window,
2957 /* Copy */
2958 _bfd_xcoff_copy_private_bfd_data,
2959 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2960 _bfd_generic_init_private_section_data,
2961 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2962 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2963 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2964 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2965 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
2967 /* Core */
2968 xcoff64_core_file_failing_command,
2969 xcoff64_core_file_failing_signal,
2970 xcoff64_core_file_matches_executable_p,
2972 /* Archive */
2973 xcoff64_slurp_armap,
2974 bfd_false,
2975 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2976 bfd_dont_truncate_arname,
2977 _bfd_xcoff_write_armap,
2978 _bfd_xcoff_read_ar_hdr,
2979 xcoff64_openr_next_archived_file,
2980 _bfd_generic_get_elt_at_index,
2981 _bfd_xcoff_stat_arch_elt,
2982 bfd_true,
2984 /* Symbols */
2985 coff_get_symtab_upper_bound,
2986 coff_canonicalize_symtab,
2987 coff_make_empty_symbol,
2988 coff_print_symbol,
2989 coff_get_symbol_info,
2990 _bfd_xcoff_is_local_label_name,
2991 coff_bfd_is_target_special_symbol,
2992 coff_get_lineno,
2993 coff_find_nearest_line,
2994 _bfd_generic_find_line,
2995 coff_find_inliner_info,
2996 coff_bfd_make_debug_symbol,
2997 _bfd_generic_read_minisymbols,
2998 _bfd_generic_minisymbol_to_symbol,
3000 /* Reloc */
3001 coff_get_reloc_upper_bound,
3002 coff_canonicalize_reloc,
3003 xcoff64_reloc_type_lookup,
3004 xcoff64_reloc_name_lookup,
3006 /* Write */
3007 coff_set_arch_mach,
3008 coff_set_section_contents,
3010 /* Link */
3011 xcoff64_sizeof_headers,
3012 bfd_generic_get_relocated_section_contents,
3013 bfd_generic_relax_section,
3014 _bfd_xcoff_bfd_link_hash_table_create,
3015 _bfd_generic_link_hash_table_free,
3016 _bfd_xcoff_bfd_link_add_symbols,
3017 _bfd_generic_link_just_syms,
3018 _bfd_xcoff_bfd_final_link,
3019 _bfd_generic_link_split_section,
3020 bfd_generic_gc_sections,
3021 bfd_generic_merge_sections,
3022 bfd_generic_is_group_section,
3023 bfd_generic_discard_group,
3024 _bfd_generic_section_already_linked,
3026 /* Dynamic */
3027 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3028 _bfd_xcoff_canonicalize_dynamic_symtab,
3029 _bfd_nodynamic_get_synthetic_symtab,
3030 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3031 _bfd_xcoff_canonicalize_dynamic_reloc,
3033 /* Opposite endian version, none exists. */
3034 NULL,
3036 (void *) & bfd_xcoff_aix5_backend_data,