* config.sub, config.guess: Update from upstream sources.
[binutils.git] / bfd / coff64-rs6000.c
blob3a27ee07ce51ff856b0771578faedfd729b6b3e3
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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_AIX_WEAKEXT:
385 case C_HIDEXT:
386 if (indx + 1 == numaux)
388 bfd_signed_vma h = 0;
389 bfd_vma l = 0;
391 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
392 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
394 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
396 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
397 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
398 /* We don't have to hack bitfields in x_smtyp because it's
399 defined by shifts-and-ands, which are equivalent on all
400 byte orders. */
401 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
402 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
403 goto end;
405 break;
407 case C_STAT:
408 case C_LEAFSTAT:
409 case C_HIDDEN:
410 if (type == T_NULL)
412 /* PE defines some extra fields; we zero them out for
413 safety. */
414 in->x_scn.x_checksum = 0;
415 in->x_scn.x_associated = 0;
416 in->x_scn.x_comdat = 0;
418 goto end;
420 break;
423 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
425 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
426 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
427 in->x_sym.x_fcnary.x_fcn.x_endndx.l
428 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
430 if (ISFCN (type))
432 in->x_sym.x_misc.x_fsize
433 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
435 else
437 in->x_sym.x_misc.x_lnsz.x_lnno
438 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
439 in->x_sym.x_misc.x_lnsz.x_size
440 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
443 end: ;
446 static unsigned int
447 _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
448 bfd *abfd;
449 PTR inp;
450 int type;
451 int class;
452 int indx ATTRIBUTE_UNUSED;
453 int numaux ATTRIBUTE_UNUSED;
454 PTR extp;
456 union internal_auxent *in = (union internal_auxent *) inp;
457 union external_auxent *ext = (union external_auxent *) extp;
459 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
460 switch (class)
462 case C_FILE:
463 if (in->x_file.x_n.x_zeroes == 0)
465 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
466 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
468 else
470 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
472 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
473 goto end;
475 /* RS/6000 "csect" auxents */
476 case C_EXT:
477 case C_AIX_WEAKEXT:
478 case C_HIDEXT:
479 if (indx + 1 == numaux)
481 bfd_vma temp;
483 temp = in->x_csect.x_scnlen.l & 0xffffffff;
484 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
485 temp = in->x_csect.x_scnlen.l >> 32;
486 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
487 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
488 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
489 /* We don't have to hack bitfields in x_smtyp because it's
490 defined by shifts-and-ands, which are equivalent on all
491 byte orders. */
492 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
493 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
494 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
495 goto end;
497 break;
499 case C_STAT:
500 case C_LEAFSTAT:
501 case C_HIDDEN:
502 if (type == T_NULL)
504 goto end;
506 break;
509 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
511 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
512 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
513 H_PUT_8 (abfd, _AUX_FCN,
514 ext->x_auxtype.x_auxtype);
515 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
516 ext->x_sym.x_fcnary.x_fcn.x_endndx);
518 if (ISFCN (type))
520 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
521 ext->x_sym.x_fcnary.x_fcn.x_fsize);
523 else
525 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
526 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
527 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
528 ext->x_sym.x_fcnary.x_lnsz.x_size);
531 end:
533 return bfd_coff_auxesz (abfd);
536 static bfd_boolean
537 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
538 bfd *abfd;
539 struct bfd_strtab_hash *strtab;
540 struct internal_syment *sym;
541 const char *name;
543 bfd_boolean hash;
544 bfd_size_type indx;
546 hash = TRUE;
548 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
549 hash = FALSE;
551 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
553 if (indx == (bfd_size_type) -1)
554 return FALSE;
556 sym->_n._n_n._n_zeroes = 0;
557 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
559 return TRUE;
562 static bfd_boolean
563 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
564 bfd *abfd ATTRIBUTE_UNUSED;
565 struct xcoff_loader_info *ldinfo;
566 struct internal_ldsym *ldsym;
567 const char *name;
569 size_t len;
570 len = strlen (name);
572 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
574 bfd_size_type newalc;
575 char *newstrings;
577 newalc = ldinfo->string_alc * 2;
578 if (newalc == 0)
579 newalc = 32;
580 while (ldinfo->string_size + len + 3 > newalc)
581 newalc *= 2;
583 newstrings = bfd_realloc (ldinfo->strings, newalc);
584 if (newstrings == NULL)
586 ldinfo->failed = TRUE;
587 return FALSE;
589 ldinfo->string_alc = newalc;
590 ldinfo->strings = newstrings;
593 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
594 ldinfo->strings + ldinfo->string_size);
595 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
596 ldsym->_l._l_l._l_zeroes = 0;
597 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
598 ldinfo->string_size += len + 3;
600 return TRUE;
603 /* Routines to swap information in the XCOFF .loader section. If we
604 ever need to write an XCOFF loader, this stuff will need to be
605 moved to another file shared by the linker (which XCOFF calls the
606 ``binder'') and the loader. */
608 /* Swap in the ldhdr structure. */
610 static void
611 xcoff64_swap_ldhdr_in (abfd, s, dst)
612 bfd *abfd;
613 const PTR s;
614 struct internal_ldhdr *dst;
616 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
618 dst->l_version = bfd_get_32 (abfd, src->l_version);
619 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
620 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
621 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
622 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
623 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
624 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
625 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
626 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
627 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
630 /* Swap out the ldhdr structure. */
632 static void
633 xcoff64_swap_ldhdr_out (abfd, src, d)
634 bfd *abfd;
635 const struct internal_ldhdr *src;
636 PTR d;
638 struct external_ldhdr *dst = (struct external_ldhdr *) d;
640 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
641 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
642 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
643 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
644 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
645 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
646 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
647 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
648 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
649 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
652 /* Swap in the ldsym structure. */
654 static void
655 xcoff64_swap_ldsym_in (abfd, s, dst)
656 bfd *abfd;
657 const PTR s;
658 struct internal_ldsym *dst;
660 const struct external_ldsym *src = (const struct external_ldsym *) s;
661 /* XCOFF64 does not use l_zeroes like XCOFF32
662 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
663 as an offset into the loader symbol table. */
664 dst->_l._l_l._l_zeroes = 0;
665 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
666 dst->l_value = bfd_get_64 (abfd, src->l_value);
667 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
668 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
669 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
670 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
671 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
674 /* Swap out the ldsym structure. */
676 static void
677 xcoff64_swap_ldsym_out (abfd, src, d)
678 bfd *abfd;
679 const struct internal_ldsym *src;
680 PTR d;
682 struct external_ldsym *dst = (struct external_ldsym *) d;
684 bfd_put_64 (abfd, src->l_value, dst->l_value);
685 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
686 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
687 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
688 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
689 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
690 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
693 static void
694 xcoff64_swap_reloc_in (abfd, s, d)
695 bfd *abfd;
696 PTR s;
697 PTR d;
699 struct external_reloc *src = (struct external_reloc *) s;
700 struct internal_reloc *dst = (struct internal_reloc *) d;
702 memset (dst, 0, sizeof (struct internal_reloc));
704 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
705 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
706 dst->r_size = bfd_get_8 (abfd, src->r_size);
707 dst->r_type = bfd_get_8 (abfd, src->r_type);
710 static unsigned int
711 xcoff64_swap_reloc_out (abfd, s, d)
712 bfd *abfd;
713 PTR s;
714 PTR d;
716 struct internal_reloc *src = (struct internal_reloc *) s;
717 struct external_reloc *dst = (struct external_reloc *) d;
719 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
720 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
721 bfd_put_8 (abfd, src->r_type, dst->r_type);
722 bfd_put_8 (abfd, src->r_size, dst->r_size);
724 return bfd_coff_relsz (abfd);
727 /* Swap in the ldrel structure. */
729 static void
730 xcoff64_swap_ldrel_in (abfd, s, dst)
731 bfd *abfd;
732 const PTR s;
733 struct internal_ldrel *dst;
735 const struct external_ldrel *src = (const struct external_ldrel *) s;
737 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
738 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
739 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
740 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
743 /* Swap out the ldrel structure. */
745 static void
746 xcoff64_swap_ldrel_out (abfd, src, d)
747 bfd *abfd;
748 const struct internal_ldrel *src;
749 PTR d;
751 struct external_ldrel *dst = (struct external_ldrel *) d;
753 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
754 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
755 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
756 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
759 static bfd_boolean
760 xcoff64_write_object_contents (abfd)
761 bfd *abfd;
763 asection *current;
764 bfd_boolean hasrelocs = FALSE;
765 bfd_boolean haslinno = FALSE;
766 file_ptr scn_base;
767 file_ptr reloc_base;
768 file_ptr lineno_base;
769 file_ptr sym_base;
770 unsigned long reloc_size = 0;
771 unsigned long lnno_size = 0;
772 asection *text_sec = ((void *) 0);
773 asection *data_sec = ((void *) 0);
774 asection *bss_sec = ((void *) 0);
775 struct internal_filehdr internal_f;
776 struct internal_aouthdr internal_a;
778 bfd_set_error (bfd_error_system_call);
780 if (! abfd->output_has_begun)
782 if (! bfd_coff_compute_section_file_positions (abfd))
783 return FALSE;
786 /* Work out the size of the reloc and linno areas. */
787 reloc_base = obj_relocbase (abfd);
789 for (current = abfd->sections; current != NULL; current = current->next)
790 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
792 lineno_base = reloc_base + reloc_size;
794 /* Make a pass through the symbol table to count line number entries and
795 put them into the correct asections. */
796 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
798 sym_base = lineno_base + lnno_size;
800 /* Indicate in each section->line_filepos its actual file address. */
801 for (current = abfd->sections; current != NULL; current = current->next)
803 if (current->lineno_count)
805 current->line_filepos = lineno_base;
806 current->moving_line_filepos = lineno_base;
807 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
809 else
811 current->line_filepos = 0;
814 if (current->reloc_count)
816 current->rel_filepos = reloc_base;
817 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
819 else
821 current->rel_filepos = 0;
825 if ((abfd->flags & EXEC_P) != 0)
827 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
828 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
830 else
832 scn_base = bfd_coff_filhsz (abfd);
833 internal_f.f_opthdr = 0;
836 internal_f.f_nscns = 0;
838 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
839 return 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 if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
1054 internal_a.o_cputype = 2;
1055 else
1056 internal_a.o_cputype = 1;
1057 break;
1058 default:
1059 abort ();
1062 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1063 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
1066 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
1067 return FALSE;
1070 char * buff;
1071 bfd_size_type amount = bfd_coff_filhsz (abfd);
1073 buff = bfd_malloc (amount);
1074 if (buff == NULL)
1075 return FALSE;
1077 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1078 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1080 free (buff);
1082 if (amount != bfd_coff_filhsz (abfd))
1083 return FALSE;
1086 if (abfd->flags & EXEC_P)
1088 char * buff;
1089 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1091 buff = bfd_malloc (amount);
1092 if (buff == NULL)
1093 return FALSE;
1095 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
1096 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1098 free (buff);
1100 if (amount != bfd_coff_aoutsz (abfd))
1101 return FALSE;
1104 return TRUE;
1107 static bfd_boolean
1108 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
1109 val, addend, relocation, contents)
1110 bfd *input_bfd;
1111 asection *input_section;
1112 bfd *output_bfd ATTRIBUTE_UNUSED;
1113 struct internal_reloc *rel;
1114 struct internal_syment *sym ATTRIBUTE_UNUSED;
1115 struct reloc_howto_struct *howto;
1116 bfd_vma val;
1117 bfd_vma addend;
1118 bfd_vma *relocation;
1119 bfd_byte *contents;
1121 struct xcoff_link_hash_entry *h;
1122 bfd_vma section_offset;
1124 if (0 > rel->r_symndx)
1125 return FALSE;
1127 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1128 section_offset = rel->r_vaddr - input_section->vma;
1130 /* If we see an R_BR or R_RBR reloc which is jumping to global
1131 linkage code, and it is followed by an appropriate cror nop
1132 instruction, we replace the cror with ld r2,40(r1). This
1133 restores the TOC after the glink code. Contrariwise, if the
1134 call is followed by a ld r2,40(r1), but the call is not
1135 going to global linkage code, we can replace the load with a
1136 cror. */
1137 if (NULL != h
1138 && (bfd_link_hash_defined == h->root.type
1139 || bfd_link_hash_defweak == h->root.type)
1140 && section_offset + 8 <= input_section->size)
1142 bfd_byte *pnext;
1143 unsigned long next;
1145 pnext = contents + section_offset + 4;
1146 next = bfd_get_32 (input_bfd, pnext);
1148 /* The _ptrgl function is magic. It is used by the AIX compiler to call
1149 a function through a pointer. */
1150 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
1152 if (next == 0x4def7b82 /* cror 15,15,15 */
1153 || next == 0x4ffffb82 /* cror 31,31,31 */
1154 || next == 0x60000000) /* ori r0,r0,0 */
1155 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1157 else
1159 if (next == 0xe8410028) /* ld r2,40(r1) */
1160 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1163 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
1165 /* Normally, this relocation is against a defined symbol. In the
1166 case where this is a partial link and the output section offset
1167 is greater than 2^25, the linker will return an invalid error
1168 message that the relocation has been truncated. Yes it has been
1169 truncated but no it not important. For this case, disable the
1170 overflow checking. */
1171 howto->complain_on_overflow = complain_overflow_dont;
1174 /* The original PC-relative relocation is biased by -r_vaddr, so adding
1175 the value below will give the absolute target address. */
1176 *relocation = val + addend + rel->r_vaddr;
1178 howto->src_mask &= ~3;
1179 howto->dst_mask = howto->src_mask;
1181 if (h != NULL
1182 && (h->root.type == bfd_link_hash_defined
1183 || h->root.type == bfd_link_hash_defweak)
1184 && bfd_is_abs_section (h->root.u.def.section)
1185 && section_offset + 4 <= input_section->size)
1187 bfd_byte *ptr;
1188 bfd_vma insn;
1190 /* Turn the relative branch into an absolute one by setting the
1191 AA bit. */
1192 ptr = contents + section_offset;
1193 insn = bfd_get_32 (input_bfd, ptr);
1194 insn |= 2;
1195 bfd_put_32 (input_bfd, insn, ptr);
1197 /* Make the howto absolute too. */
1198 howto->pc_relative = FALSE;
1199 howto->complain_on_overflow = complain_overflow_bitfield;
1201 else
1203 /* Use a PC-relative howto and subtract the instruction's address
1204 from the target address we calculated above. */
1205 howto->pc_relative = TRUE;
1206 *relocation -= (input_section->output_section->vma
1207 + input_section->output_offset
1208 + section_offset);
1210 return TRUE;
1213 /* This is the relocation function for the PowerPC64.
1214 See xcoff_ppc_relocation_section for more information. */
1216 bfd_boolean
1217 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1218 input_section, contents, relocs, syms,
1219 sections)
1220 bfd *output_bfd;
1221 struct bfd_link_info *info;
1222 bfd *input_bfd;
1223 asection *input_section;
1224 bfd_byte *contents;
1225 struct internal_reloc *relocs;
1226 struct internal_syment *syms;
1227 asection **sections;
1229 struct internal_reloc *rel;
1230 struct internal_reloc *relend;
1232 rel = relocs;
1233 relend = rel + input_section->reloc_count;
1234 for (; rel < relend; rel++)
1236 long symndx;
1237 struct xcoff_link_hash_entry *h;
1238 struct internal_syment *sym;
1239 bfd_vma addend;
1240 bfd_vma val;
1241 struct reloc_howto_struct howto;
1242 bfd_vma relocation;
1243 bfd_vma value_to_relocate;
1244 bfd_vma address;
1245 bfd_byte *location;
1247 /* Relocation type R_REF is a special relocation type which is
1248 merely used to prevent garbage collection from occurring for
1249 the csect including the symbol which it references. */
1250 if (rel->r_type == R_REF)
1251 continue;
1253 /* howto */
1254 howto.type = rel->r_type;
1255 howto.rightshift = 0;
1256 howto.bitsize = (rel->r_size & 0x3f) + 1;
1257 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
1258 howto.pc_relative = FALSE;
1259 howto.bitpos = 0;
1260 howto.complain_on_overflow = (rel->r_size & 0x80
1261 ? complain_overflow_signed
1262 : complain_overflow_bitfield);
1263 howto.special_function = NULL;
1264 howto.name = "internal";
1265 howto.partial_inplace = TRUE;
1266 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
1267 howto.pcrel_offset = FALSE;
1269 /* symbol */
1270 val = 0;
1271 addend = 0;
1272 h = NULL;
1273 sym = NULL;
1274 symndx = rel->r_symndx;
1276 if (-1 != symndx)
1278 asection *sec;
1280 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1281 sym = syms + symndx;
1282 addend = - sym->n_value;
1284 if (NULL == h)
1286 sec = sections[symndx];
1287 /* Hack to make sure we use the right TOC anchor value
1288 if this reloc is against the TOC anchor. */
1289 if (sec->name[3] == '0'
1290 && strcmp (sec->name, ".tc0") == 0)
1291 val = xcoff_data (output_bfd)->toc;
1292 else
1293 val = (sec->output_section->vma
1294 + sec->output_offset
1295 + sym->n_value
1296 - sec->vma);
1298 else
1300 if (info->unresolved_syms_in_objects != RM_IGNORE
1301 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
1303 if (! ((*info->callbacks->undefined_symbol)
1304 (info, h->root.root.string,
1305 input_bfd, input_section,
1306 rel->r_vaddr - input_section->vma,
1307 (info->unresolved_syms_in_objects
1308 == RM_GENERATE_ERROR))))
1309 return FALSE;
1311 if (h->root.type == bfd_link_hash_defined
1312 || h->root.type == bfd_link_hash_defweak)
1314 sec = h->root.u.def.section;
1315 val = (h->root.u.def.value
1316 + sec->output_section->vma
1317 + sec->output_offset);
1319 else if (h->root.type == bfd_link_hash_common)
1321 sec = h->root.u.c.p->section;
1322 val = (sec->output_section->vma
1323 + sec->output_offset);
1325 else
1327 BFD_ASSERT (info->relocatable
1328 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
1329 || (h->flags & XCOFF_IMPORT) != 0);
1334 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
1335 || !((*xcoff64_calculate_relocation[rel->r_type])
1336 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1337 addend, &relocation, contents)))
1338 return FALSE;
1340 /* address */
1341 address = rel->r_vaddr - input_section->vma;
1342 location = contents + address;
1344 if (address > input_section->size)
1345 abort ();
1347 /* Get the value we are going to relocate. */
1348 if (1 == howto.size)
1349 value_to_relocate = bfd_get_16 (input_bfd, location);
1350 else if (2 == howto.size)
1351 value_to_relocate = bfd_get_32 (input_bfd, location);
1352 else
1353 value_to_relocate = bfd_get_64 (input_bfd, location);
1355 /* overflow.
1357 FIXME: We may drop bits during the addition
1358 which we don't check for. We must either check at every single
1359 operation, which would be tedious, or we must do the computations
1360 in a type larger than bfd_vma, which would be inefficient. */
1362 if ((unsigned int) howto.complain_on_overflow
1363 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1364 abort ();
1366 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1367 (input_bfd, value_to_relocate, relocation, &howto)))
1369 const char *name;
1370 char buf[SYMNMLEN + 1];
1371 char reloc_type_name[10];
1373 if (symndx == -1)
1375 name = "*ABS*";
1377 else if (h != NULL)
1379 name = NULL;
1381 else
1383 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1384 if (name == NULL)
1385 name = "UNKNOWN";
1387 sprintf (reloc_type_name, "0x%02x", rel->r_type);
1389 if (! ((*info->callbacks->reloc_overflow)
1390 (info, (h ? &h->root : NULL), name, reloc_type_name,
1391 (bfd_vma) 0, input_bfd, input_section,
1392 rel->r_vaddr - input_section->vma)))
1393 return FALSE;
1396 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
1397 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1398 | (((value_to_relocate & howto.src_mask)
1399 + relocation) & howto.dst_mask));
1401 /* Put the value back in the object file. */
1402 if (1 == howto.size)
1403 bfd_put_16 (input_bfd, value_to_relocate, location);
1404 else if (2 == howto.size)
1405 bfd_put_32 (input_bfd, value_to_relocate, location);
1406 else
1407 bfd_put_64 (input_bfd, value_to_relocate, location);
1410 return TRUE;
1414 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1415 bitsize and whether they are signed or not, along with a
1416 conventional type. This table is for the types, which are used for
1417 different algorithms for putting in the reloc. Many of these
1418 relocs need special_function entries, which I have not written. */
1420 reloc_howto_type xcoff64_howto_table[] =
1422 /* Standard 64 bit relocation. */
1423 HOWTO (R_POS, /* type */
1424 0, /* rightshift */
1425 4, /* size (0 = byte, 1 = short, 2 = long) */
1426 64, /* bitsize */
1427 FALSE, /* pc_relative */
1428 0, /* bitpos */
1429 complain_overflow_bitfield, /* complain_on_overflow */
1430 0, /* special_function */
1431 "R_POS_64", /* name */
1432 TRUE, /* partial_inplace */
1433 MINUS_ONE, /* src_mask */
1434 MINUS_ONE, /* dst_mask */
1435 FALSE), /* pcrel_offset */
1437 /* 64 bit relocation, but store negative value. */
1438 HOWTO (R_NEG, /* type */
1439 0, /* rightshift */
1440 -4, /* size (0 = byte, 1 = short, 2 = long) */
1441 64, /* bitsize */
1442 FALSE, /* pc_relative */
1443 0, /* bitpos */
1444 complain_overflow_bitfield, /* complain_on_overflow */
1445 0, /* special_function */
1446 "R_NEG", /* name */
1447 TRUE, /* partial_inplace */
1448 MINUS_ONE, /* src_mask */
1449 MINUS_ONE, /* dst_mask */
1450 FALSE), /* pcrel_offset */
1452 /* 32 bit PC relative relocation. */
1453 HOWTO (R_REL, /* type */
1454 0, /* rightshift */
1455 2, /* size (0 = byte, 1 = short, 2 = long) */
1456 32, /* bitsize */
1457 TRUE, /* pc_relative */
1458 0, /* bitpos */
1459 complain_overflow_signed, /* complain_on_overflow */
1460 0, /* special_function */
1461 "R_REL", /* name */
1462 TRUE, /* partial_inplace */
1463 0xffffffff, /* src_mask */
1464 0xffffffff, /* dst_mask */
1465 FALSE), /* pcrel_offset */
1467 /* 16 bit TOC relative relocation. */
1468 HOWTO (R_TOC, /* type */
1469 0, /* rightshift */
1470 1, /* size (0 = byte, 1 = short, 2 = long) */
1471 16, /* bitsize */
1472 FALSE, /* pc_relative */
1473 0, /* bitpos */
1474 complain_overflow_bitfield, /* complain_on_overflow */
1475 0, /* special_function */
1476 "R_TOC", /* name */
1477 TRUE, /* partial_inplace */
1478 0xffff, /* src_mask */
1479 0xffff, /* dst_mask */
1480 FALSE), /* pcrel_offset */
1482 /* I don't really know what this is. */
1483 HOWTO (R_RTB, /* type */
1484 1, /* rightshift */
1485 2, /* size (0 = byte, 1 = short, 2 = long) */
1486 32, /* bitsize */
1487 FALSE, /* pc_relative */
1488 0, /* bitpos */
1489 complain_overflow_bitfield, /* complain_on_overflow */
1490 0, /* special_function */
1491 "R_RTB", /* name */
1492 TRUE, /* partial_inplace */
1493 0xffffffff, /* src_mask */
1494 0xffffffff, /* dst_mask */
1495 FALSE), /* pcrel_offset */
1497 /* External TOC relative symbol. */
1498 HOWTO (R_GL, /* type */
1499 0, /* rightshift */
1500 1, /* size (0 = byte, 1 = short, 2 = long) */
1501 16, /* bitsize */
1502 FALSE, /* pc_relative */
1503 0, /* bitpos */
1504 complain_overflow_bitfield, /* complain_on_overflow */
1505 0, /* special_function */
1506 "R_GL", /* name */
1507 TRUE, /* partial_inplace */
1508 0xffff, /* src_mask */
1509 0xffff, /* dst_mask */
1510 FALSE), /* pcrel_offset */
1512 /* Local TOC relative symbol. */
1513 HOWTO (R_TCL, /* type */
1514 0, /* rightshift */
1515 1, /* size (0 = byte, 1 = short, 2 = long) */
1516 16, /* bitsize */
1517 FALSE, /* pc_relative */
1518 0, /* bitpos */
1519 complain_overflow_bitfield, /* complain_on_overflow */
1520 0, /* special_function */
1521 "R_TCL", /* name */
1522 TRUE, /* partial_inplace */
1523 0xffff, /* src_mask */
1524 0xffff, /* dst_mask */
1525 FALSE), /* pcrel_offset */
1527 EMPTY_HOWTO (7),
1529 /* Non modifiable absolute branch. */
1530 HOWTO (R_BA, /* type */
1531 0, /* rightshift */
1532 2, /* size (0 = byte, 1 = short, 2 = long) */
1533 26, /* bitsize */
1534 FALSE, /* pc_relative */
1535 0, /* bitpos */
1536 complain_overflow_bitfield, /* complain_on_overflow */
1537 0, /* special_function */
1538 "R_BA_26", /* name */
1539 TRUE, /* partial_inplace */
1540 0x03fffffc, /* src_mask */
1541 0x03fffffc, /* dst_mask */
1542 FALSE), /* pcrel_offset */
1544 EMPTY_HOWTO (9),
1546 /* Non modifiable relative branch. */
1547 HOWTO (R_BR, /* type */
1548 0, /* rightshift */
1549 2, /* size (0 = byte, 1 = short, 2 = long) */
1550 26, /* bitsize */
1551 TRUE, /* pc_relative */
1552 0, /* bitpos */
1553 complain_overflow_signed, /* complain_on_overflow */
1554 0, /* special_function */
1555 "R_BR", /* name */
1556 TRUE, /* partial_inplace */
1557 0x03fffffc, /* src_mask */
1558 0x03fffffc, /* dst_mask */
1559 FALSE), /* pcrel_offset */
1561 EMPTY_HOWTO (0xb),
1563 /* Indirect load. */
1564 HOWTO (R_RL, /* type */
1565 0, /* rightshift */
1566 1, /* size (0 = byte, 1 = short, 2 = long) */
1567 16, /* bitsize */
1568 FALSE, /* pc_relative */
1569 0, /* bitpos */
1570 complain_overflow_bitfield, /* complain_on_overflow */
1571 0, /* special_function */
1572 "R_RL", /* name */
1573 TRUE, /* partial_inplace */
1574 0xffff, /* src_mask */
1575 0xffff, /* dst_mask */
1576 FALSE), /* pcrel_offset */
1578 /* Load address. */
1579 HOWTO (R_RLA, /* type */
1580 0, /* rightshift */
1581 1, /* size (0 = byte, 1 = short, 2 = long) */
1582 16, /* bitsize */
1583 FALSE, /* pc_relative */
1584 0, /* bitpos */
1585 complain_overflow_bitfield, /* complain_on_overflow */
1586 0, /* special_function */
1587 "R_RLA", /* name */
1588 TRUE, /* partial_inplace */
1589 0xffff, /* src_mask */
1590 0xffff, /* dst_mask */
1591 FALSE), /* pcrel_offset */
1593 EMPTY_HOWTO (0xe),
1595 /* Non-relocating reference. */
1596 HOWTO (R_REF, /* type */
1597 0, /* rightshift */
1598 2, /* size (0 = byte, 1 = short, 2 = long) */
1599 32, /* bitsize */
1600 FALSE, /* pc_relative */
1601 0, /* bitpos */
1602 complain_overflow_dont, /* complain_on_overflow */
1603 0, /* special_function */
1604 "R_REF", /* name */
1605 FALSE, /* partial_inplace */
1606 0, /* src_mask */
1607 0, /* dst_mask */
1608 FALSE), /* pcrel_offset */
1610 EMPTY_HOWTO (0x10),
1611 EMPTY_HOWTO (0x11),
1613 /* TOC relative indirect load. */
1614 HOWTO (R_TRL, /* type */
1615 0, /* rightshift */
1616 1, /* size (0 = byte, 1 = short, 2 = long) */
1617 16, /* bitsize */
1618 FALSE, /* pc_relative */
1619 0, /* bitpos */
1620 complain_overflow_bitfield, /* complain_on_overflow */
1621 0, /* special_function */
1622 "R_TRL", /* name */
1623 TRUE, /* partial_inplace */
1624 0xffff, /* src_mask */
1625 0xffff, /* dst_mask */
1626 FALSE), /* pcrel_offset */
1628 /* TOC relative load address. */
1629 HOWTO (R_TRLA, /* type */
1630 0, /* rightshift */
1631 1, /* size (0 = byte, 1 = short, 2 = long) */
1632 16, /* bitsize */
1633 FALSE, /* pc_relative */
1634 0, /* bitpos */
1635 complain_overflow_bitfield, /* complain_on_overflow */
1636 0, /* special_function */
1637 "R_TRLA", /* name */
1638 TRUE, /* partial_inplace */
1639 0xffff, /* src_mask */
1640 0xffff, /* dst_mask */
1641 FALSE), /* pcrel_offset */
1643 /* Modifiable relative branch. */
1644 HOWTO (R_RRTBI, /* type */
1645 1, /* rightshift */
1646 2, /* size (0 = byte, 1 = short, 2 = long) */
1647 32, /* bitsize */
1648 FALSE, /* pc_relative */
1649 0, /* bitpos */
1650 complain_overflow_bitfield, /* complain_on_overflow */
1651 0, /* special_function */
1652 "R_RRTBI", /* name */
1653 TRUE, /* partial_inplace */
1654 0xffffffff, /* src_mask */
1655 0xffffffff, /* dst_mask */
1656 FALSE), /* pcrel_offset */
1658 /* Modifiable absolute branch. */
1659 HOWTO (R_RRTBA, /* type */
1660 1, /* rightshift */
1661 2, /* size (0 = byte, 1 = short, 2 = long) */
1662 32, /* bitsize */
1663 FALSE, /* pc_relative */
1664 0, /* bitpos */
1665 complain_overflow_bitfield, /* complain_on_overflow */
1666 0, /* special_function */
1667 "R_RRTBA", /* name */
1668 TRUE, /* partial_inplace */
1669 0xffffffff, /* src_mask */
1670 0xffffffff, /* dst_mask */
1671 FALSE), /* pcrel_offset */
1673 /* Modifiable call absolute indirect. */
1674 HOWTO (R_CAI, /* type */
1675 0, /* rightshift */
1676 1, /* size (0 = byte, 1 = short, 2 = long) */
1677 16, /* bitsize */
1678 FALSE, /* pc_relative */
1679 0, /* bitpos */
1680 complain_overflow_bitfield, /* complain_on_overflow */
1681 0, /* special_function */
1682 "R_CAI", /* name */
1683 TRUE, /* partial_inplace */
1684 0xffff, /* src_mask */
1685 0xffff, /* dst_mask */
1686 FALSE), /* pcrel_offset */
1688 /* Modifiable call relative. */
1689 HOWTO (R_CREL, /* type */
1690 0, /* rightshift */
1691 1, /* size (0 = byte, 1 = short, 2 = long) */
1692 16, /* bitsize */
1693 FALSE, /* pc_relative */
1694 0, /* bitpos */
1695 complain_overflow_bitfield, /* complain_on_overflow */
1696 0, /* special_function */
1697 "R_CREL", /* name */
1698 TRUE, /* partial_inplace */
1699 0xffff, /* src_mask */
1700 0xffff, /* dst_mask */
1701 FALSE), /* pcrel_offset */
1703 /* Modifiable branch absolute. */
1704 HOWTO (R_RBA, /* type */
1705 0, /* rightshift */
1706 2, /* size (0 = byte, 1 = short, 2 = long) */
1707 26, /* bitsize */
1708 FALSE, /* pc_relative */
1709 0, /* bitpos */
1710 complain_overflow_bitfield, /* complain_on_overflow */
1711 0, /* special_function */
1712 "R_RBA", /* name */
1713 TRUE, /* partial_inplace */
1714 0x03fffffc, /* src_mask */
1715 0x03fffffc, /* dst_mask */
1716 FALSE), /* pcrel_offset */
1718 /* Modifiable branch absolute. */
1719 HOWTO (R_RBAC, /* type */
1720 0, /* rightshift */
1721 2, /* size (0 = byte, 1 = short, 2 = long) */
1722 32, /* bitsize */
1723 FALSE, /* pc_relative */
1724 0, /* bitpos */
1725 complain_overflow_bitfield, /* complain_on_overflow */
1726 0, /* special_function */
1727 "R_RBAC", /* name */
1728 TRUE, /* partial_inplace */
1729 0xffffffff, /* src_mask */
1730 0xffffffff, /* dst_mask */
1731 FALSE), /* pcrel_offset */
1733 /* Modifiable branch relative. */
1734 HOWTO (R_RBR, /* type */
1735 0, /* rightshift */
1736 2, /* size (0 = byte, 1 = short, 2 = long) */
1737 26, /* bitsize */
1738 FALSE, /* pc_relative */
1739 0, /* bitpos */
1740 complain_overflow_signed, /* complain_on_overflow */
1741 0, /* special_function */
1742 "R_RBR_26", /* name */
1743 TRUE, /* partial_inplace */
1744 0x03fffffc, /* src_mask */
1745 0x03fffffc, /* dst_mask */
1746 FALSE), /* pcrel_offset */
1748 /* Modifiable branch absolute. */
1749 HOWTO (R_RBRC, /* type */
1750 0, /* rightshift */
1751 1, /* size (0 = byte, 1 = short, 2 = long) */
1752 16, /* bitsize */
1753 FALSE, /* pc_relative */
1754 0, /* bitpos */
1755 complain_overflow_bitfield, /* complain_on_overflow */
1756 0, /* special_function */
1757 "R_RBRC", /* name */
1758 TRUE, /* partial_inplace */
1759 0xffff, /* src_mask */
1760 0xffff, /* dst_mask */
1761 FALSE), /* pcrel_offset */
1763 HOWTO (R_POS, /* type */
1764 0, /* rightshift */
1765 2, /* size (0 = byte, 1 = short, 2 = long) */
1766 32, /* bitsize */
1767 FALSE, /* pc_relative */
1768 0, /* bitpos */
1769 complain_overflow_bitfield, /* complain_on_overflow */
1770 0, /* special_function */
1771 "R_POS_32", /* name */
1772 TRUE, /* partial_inplace */
1773 0xffffffff, /* src_mask */
1774 0xffffffff, /* dst_mask */
1775 FALSE), /* pcrel_offset */
1777 /* 16 bit Non modifiable absolute branch. */
1778 HOWTO (R_BA, /* type */
1779 0, /* rightshift */
1780 1, /* size (0 = byte, 1 = short, 2 = long) */
1781 16, /* bitsize */
1782 FALSE, /* pc_relative */
1783 0, /* bitpos */
1784 complain_overflow_bitfield, /* complain_on_overflow */
1785 0, /* special_function */
1786 "R_BA_16", /* name */
1787 TRUE, /* partial_inplace */
1788 0xfffc, /* src_mask */
1789 0xfffc, /* dst_mask */
1790 FALSE), /* pcrel_offset */
1792 /* Modifiable branch relative. */
1793 HOWTO (R_RBR, /* type */
1794 0, /* rightshift */
1795 1, /* size (0 = byte, 1 = short, 2 = long) */
1796 16, /* bitsize */
1797 FALSE, /* pc_relative */
1798 0, /* bitpos */
1799 complain_overflow_signed, /* complain_on_overflow */
1800 0, /* special_function */
1801 "R_RBR_16", /* name */
1802 TRUE, /* partial_inplace */
1803 0xffff, /* src_mask */
1804 0xffff, /* dst_mask */
1805 FALSE), /* pcrel_offset */
1807 /* Modifiable branch absolute. */
1808 HOWTO (R_RBA, /* type */
1809 0, /* rightshift */
1810 1, /* size (0 = byte, 1 = short, 2 = long) */
1811 16, /* bitsize */
1812 FALSE, /* pc_relative */
1813 0, /* bitpos */
1814 complain_overflow_bitfield, /* complain_on_overflow */
1815 0, /* special_function */
1816 "R_RBA_16", /* name */
1817 TRUE, /* partial_inplace */
1818 0xffff, /* src_mask */
1819 0xffff, /* dst_mask */
1820 FALSE), /* pcrel_offset */
1824 void
1825 xcoff64_rtype2howto (relent, internal)
1826 arelent *relent;
1827 struct internal_reloc *internal;
1829 if (internal->r_type > R_RBRC)
1830 abort ();
1832 /* Default howto layout works most of the time */
1833 relent->howto = &xcoff64_howto_table[internal->r_type];
1835 /* Special case some 16 bit reloc */
1836 if (15 == (internal->r_size & 0x3f))
1838 if (R_BA == internal->r_type)
1839 relent->howto = &xcoff64_howto_table[0x1d];
1840 else if (R_RBR == internal->r_type)
1841 relent->howto = &xcoff64_howto_table[0x1e];
1842 else if (R_RBA == internal->r_type)
1843 relent->howto = &xcoff64_howto_table[0x1f];
1845 /* Special case 32 bit */
1846 else if (31 == (internal->r_size & 0x3f))
1848 if (R_POS == internal->r_type)
1849 relent->howto = &xcoff64_howto_table[0x1c];
1852 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1853 relocation, as well as indicating whether it is signed or not.
1854 Doublecheck that the relocation information gathered from the
1855 type matches this information. The bitsize is not significant
1856 for R_REF relocs. */
1857 if (relent->howto->dst_mask != 0
1858 && (relent->howto->bitsize
1859 != ((unsigned int) internal->r_size & 0x3f) + 1))
1860 abort ();
1863 reloc_howto_type *
1864 xcoff64_reloc_type_lookup (abfd, code)
1865 bfd *abfd ATTRIBUTE_UNUSED;
1866 bfd_reloc_code_real_type code;
1868 switch (code)
1870 case BFD_RELOC_PPC_B26:
1871 return &xcoff64_howto_table[0xa];
1872 case BFD_RELOC_PPC_BA16:
1873 return &xcoff64_howto_table[0x1d];
1874 case BFD_RELOC_PPC_BA26:
1875 return &xcoff64_howto_table[8];
1876 case BFD_RELOC_PPC_TOC16:
1877 return &xcoff64_howto_table[3];
1878 case BFD_RELOC_32:
1879 case BFD_RELOC_CTOR:
1880 return &xcoff64_howto_table[0x1c];
1881 case BFD_RELOC_64:
1882 return &xcoff64_howto_table[0];
1883 default:
1884 return NULL;
1888 static reloc_howto_type *
1889 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1890 const char *r_name)
1892 unsigned int i;
1894 for (i = 0;
1895 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1896 i++)
1897 if (xcoff64_howto_table[i].name != NULL
1898 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1899 return &xcoff64_howto_table[i];
1901 return NULL;
1904 /* Read in the armap of an XCOFF archive. */
1906 static bfd_boolean
1907 xcoff64_slurp_armap (abfd)
1908 bfd *abfd;
1910 file_ptr off;
1911 size_t namlen;
1912 bfd_size_type sz, amt;
1913 bfd_byte *contents, *cend;
1914 bfd_vma c, i;
1915 carsym *arsym;
1916 bfd_byte *p;
1917 file_ptr pos;
1919 /* This is for the new format. */
1920 struct xcoff_ar_hdr_big hdr;
1922 if (xcoff_ardata (abfd) == NULL)
1924 bfd_has_map (abfd) = FALSE;
1925 return TRUE;
1928 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1929 (const char **) NULL, 10);
1930 if (off == 0)
1932 bfd_has_map (abfd) = FALSE;
1933 return TRUE;
1936 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1937 return FALSE;
1939 /* The symbol table starts with a normal archive header. */
1940 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1941 != SIZEOF_AR_HDR_BIG)
1942 return FALSE;
1944 /* Skip the name (normally empty). */
1945 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1946 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1947 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1948 return FALSE;
1950 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1952 /* Read in the entire symbol table. */
1953 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1954 if (contents == NULL)
1955 return FALSE;
1956 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1957 return FALSE;
1959 /* The symbol table starts with an eight byte count. */
1960 c = H_GET_64 (abfd, contents);
1962 if (c * 8 >= sz)
1964 bfd_set_error (bfd_error_bad_value);
1965 return FALSE;
1967 amt = c;
1968 amt *= sizeof (carsym);
1969 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1970 if (bfd_ardata (abfd)->symdefs == NULL)
1971 return FALSE;
1973 /* After the count comes a list of eight byte file offsets. */
1974 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1975 i < c;
1976 ++i, ++arsym, p += 8)
1977 arsym->file_offset = H_GET_64 (abfd, p);
1979 /* After the file offsets come null terminated symbol names. */
1980 cend = contents + sz;
1981 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1982 i < c;
1983 ++i, ++arsym, p += strlen ((char *) p) + 1)
1985 if (p >= cend)
1987 bfd_set_error (bfd_error_bad_value);
1988 return FALSE;
1990 arsym->name = (char *) p;
1993 bfd_ardata (abfd)->symdef_count = c;
1994 bfd_has_map (abfd) = TRUE;
1996 return TRUE;
2000 /* See if this is an NEW XCOFF archive. */
2002 static const bfd_target *
2003 xcoff64_archive_p (abfd)
2004 bfd *abfd;
2006 struct artdata *tdata_hold;
2007 char magic[SXCOFFARMAG];
2008 /* This is the new format. */
2009 struct xcoff_ar_file_hdr_big hdr;
2010 bfd_size_type amt = SXCOFFARMAG;
2012 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2014 if (bfd_get_error () != bfd_error_system_call)
2015 bfd_set_error (bfd_error_wrong_format);
2016 return NULL;
2019 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2021 bfd_set_error (bfd_error_wrong_format);
2022 return NULL;
2025 /* Copy over the magic string. */
2026 memcpy (hdr.magic, magic, SXCOFFARMAG);
2028 /* Now read the rest of the file header. */
2029 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2030 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
2032 if (bfd_get_error () != bfd_error_system_call)
2033 bfd_set_error (bfd_error_wrong_format);
2034 return NULL;
2037 tdata_hold = bfd_ardata (abfd);
2039 amt = sizeof (struct artdata);
2040 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2041 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2042 goto error_ret_restore;
2044 /* Already cleared by bfd_zalloc above.
2045 bfd_ardata (abfd)->cache = NULL;
2046 bfd_ardata (abfd)->archive_head = NULL;
2047 bfd_ardata (abfd)->symdefs = NULL;
2048 bfd_ardata (abfd)->extended_names = NULL;
2049 bfd_ardata (abfd)->extended_names_size = 0; */
2050 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2051 (const char **) NULL,
2052 10);
2054 amt = SIZEOF_AR_FILE_HDR_BIG;
2055 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2056 if (bfd_ardata (abfd)->tdata == NULL)
2057 goto error_ret;
2059 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2061 if (! xcoff64_slurp_armap (abfd))
2063 error_ret:
2064 bfd_release (abfd, bfd_ardata (abfd));
2065 error_ret_restore:
2066 bfd_ardata (abfd) = tdata_hold;
2067 return NULL;
2070 return abfd->xvec;
2074 /* Open the next element in an XCOFF archive. */
2076 static bfd *
2077 xcoff64_openr_next_archived_file (archive, last_file)
2078 bfd *archive;
2079 bfd *last_file;
2081 bfd_vma filestart;
2083 if ((xcoff_ardata (archive) == NULL)
2084 || ! xcoff_big_format_p (archive))
2086 bfd_set_error (bfd_error_invalid_operation);
2087 return NULL;
2090 if (last_file == NULL)
2092 filestart = bfd_ardata (archive)->first_file_filepos;
2094 else
2096 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2097 (const char **) NULL, 10);
2100 if (filestart == 0
2101 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2102 (const char **) NULL, 10)
2103 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2104 (const char **) NULL, 10))
2106 bfd_set_error (bfd_error_no_more_archived_files);
2107 return NULL;
2110 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2113 /* We can't use the usual coff_sizeof_headers routine, because AIX
2114 always uses an a.out header. */
2116 static int
2117 xcoff64_sizeof_headers (bfd *abfd,
2118 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2120 int size;
2122 size = bfd_coff_filhsz (abfd);
2124 /* Don't think the small aout header can be used since some of the
2125 old elements have been reordered past the end of the old coff
2126 small aout size. */
2128 if (xcoff_data (abfd)->full_aouthdr)
2129 size += bfd_coff_aoutsz (abfd);
2131 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2132 return size;
2137 static asection *
2138 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2139 bfd *abfd;
2140 union internal_auxent *aux;
2141 const char *symbol_name;
2143 asection *return_value = NULL;
2145 /* Changes from 32 :
2146 .sv == 8, is only for 32 bit programs
2147 .ti == 12 and .tb == 13 are now reserved. */
2148 static const char *names[19] =
2150 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2151 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2152 ".td", ".sv64", ".sv3264"
2155 if ((19 >= aux->x_csect.x_smclas)
2156 && (NULL != names[aux->x_csect.x_smclas]))
2159 return_value = bfd_make_section_anyway
2160 (abfd, names[aux->x_csect.x_smclas]);
2163 else
2165 (*_bfd_error_handler)
2166 (_("%B: symbol `%s' has unrecognized smclas %d"),
2167 abfd, symbol_name, aux->x_csect.x_smclas);
2168 bfd_set_error (bfd_error_bad_value);
2171 return return_value;
2174 static bfd_boolean
2175 xcoff64_is_lineno_count_overflow (abfd, value)
2176 bfd *abfd ATTRIBUTE_UNUSED;
2177 bfd_vma value ATTRIBUTE_UNUSED;
2179 return FALSE;
2182 static bfd_boolean
2183 xcoff64_is_reloc_count_overflow (abfd, value)
2184 bfd *abfd ATTRIBUTE_UNUSED;
2185 bfd_vma value ATTRIBUTE_UNUSED;
2187 return FALSE;
2190 static bfd_vma
2191 xcoff64_loader_symbol_offset (abfd, ldhdr)
2192 bfd *abfd ATTRIBUTE_UNUSED;
2193 struct internal_ldhdr *ldhdr;
2195 return (ldhdr->l_symoff);
2198 static bfd_vma
2199 xcoff64_loader_reloc_offset (abfd, ldhdr)
2200 bfd *abfd ATTRIBUTE_UNUSED;
2201 struct internal_ldhdr *ldhdr;
2203 return (ldhdr->l_rldoff);
2206 static bfd_boolean
2207 xcoff64_bad_format_hook (abfd, filehdr)
2208 bfd * abfd;
2209 PTR filehdr;
2211 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2213 /* Check flavor first. */
2214 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2215 return FALSE;
2217 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2218 return FALSE;
2220 return TRUE;
2223 static bfd_boolean
2224 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2225 bfd *abfd;
2226 const char *init;
2227 const char *fini;
2228 bfd_boolean rtld;
2230 bfd_byte filehdr_ext[FILHSZ];
2231 bfd_byte scnhdr_ext[SCNHSZ * 3];
2232 bfd_byte syment_ext[SYMESZ * 10];
2233 bfd_byte reloc_ext[RELSZ * 3];
2234 bfd_byte *data_buffer;
2235 bfd_size_type data_buffer_size;
2236 bfd_byte *string_table, *st_tmp;
2237 bfd_size_type string_table_size;
2238 bfd_vma val;
2239 size_t initsz, finisz;
2240 struct internal_filehdr filehdr;
2241 struct internal_scnhdr text_scnhdr;
2242 struct internal_scnhdr data_scnhdr;
2243 struct internal_scnhdr bss_scnhdr;
2244 struct internal_syment syment;
2245 union internal_auxent auxent;
2246 struct internal_reloc reloc;
2248 char *text_name = ".text";
2249 char *data_name = ".data";
2250 char *bss_name = ".bss";
2251 char *rtinit_name = "__rtinit";
2252 char *rtld_name = "__rtld";
2254 if (! bfd_xcoff_rtinit_size (abfd))
2255 return FALSE;
2257 initsz = (init == NULL ? 0 : 1 + strlen (init));
2258 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2260 /* File header. */
2261 memset (filehdr_ext, 0, FILHSZ);
2262 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2263 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2264 filehdr.f_nscns = 3;
2265 filehdr.f_timdat = 0;
2266 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2267 filehdr.f_symptr = 0; /* set below */
2268 filehdr.f_opthdr = 0;
2269 filehdr.f_flags = 0;
2271 /* Section headers. */
2272 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2274 /* Text. */
2275 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2276 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2277 text_scnhdr.s_paddr = 0;
2278 text_scnhdr.s_vaddr = 0;
2279 text_scnhdr.s_size = 0;
2280 text_scnhdr.s_scnptr = 0;
2281 text_scnhdr.s_relptr = 0;
2282 text_scnhdr.s_lnnoptr = 0;
2283 text_scnhdr.s_nreloc = 0;
2284 text_scnhdr.s_nlnno = 0;
2285 text_scnhdr.s_flags = STYP_TEXT;
2287 /* Data. */
2288 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2289 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2290 data_scnhdr.s_paddr = 0;
2291 data_scnhdr.s_vaddr = 0;
2292 data_scnhdr.s_size = 0; /* set below */
2293 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2294 data_scnhdr.s_relptr = 0; /* set below */
2295 data_scnhdr.s_lnnoptr = 0;
2296 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2297 data_scnhdr.s_nlnno = 0;
2298 data_scnhdr.s_flags = STYP_DATA;
2300 /* Bss. */
2301 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2302 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2303 bss_scnhdr.s_paddr = 0; /* set below */
2304 bss_scnhdr.s_vaddr = 0; /* set below */
2305 bss_scnhdr.s_size = 0; /* set below */
2306 bss_scnhdr.s_scnptr = 0;
2307 bss_scnhdr.s_relptr = 0;
2308 bss_scnhdr.s_lnnoptr = 0;
2309 bss_scnhdr.s_nreloc = 0;
2310 bss_scnhdr.s_nlnno = 0;
2311 bss_scnhdr.s_flags = STYP_BSS;
2313 /* .data
2314 0x0000 0x00000000 : rtl
2315 0x0004 0x00000000 :
2316 0x0008 0x00000018 : offset to init, or 0
2317 0x000C 0x00000038 : offset to fini, or 0
2318 0x0010 0x00000010 : size of descriptor
2319 0x0014 0x00000000 : pad
2320 0x0018 0x00000000 : init, needs a reloc
2321 0x001C 0x00000000 :
2322 0x0020 0x00000058 : offset to init name
2323 0x0024 0x00000000 : flags, padded to a word
2324 0x0028 0x00000000 : empty init
2325 0x002C 0x00000000 :
2326 0x0030 0x00000000 :
2327 0x0034 0x00000000 :
2328 0x0038 0x00000000 : fini, needs a reloc
2329 0x003C 0x00000000 :
2330 0x0040 0x00000??? : offset to fini name
2331 0x0044 0x00000000 : flags, padded to a word
2332 0x0048 0x00000000 : empty fini
2333 0x004C 0x00000000 :
2334 0x0050 0x00000000 :
2335 0x0054 0x00000000 :
2336 0x0058 init name
2337 0x0058 + initsz fini name */
2339 data_buffer_size = 0x0058 + initsz + finisz;
2340 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2341 data_buffer = NULL;
2342 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2343 if (data_buffer == NULL)
2344 return FALSE;
2346 if (initsz)
2348 val = 0x18;
2349 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2350 val = 0x58;
2351 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2352 memcpy (&data_buffer[val], init, initsz);
2355 if (finisz)
2357 val = 0x38;
2358 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2359 val = 0x58 + initsz;
2360 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2361 memcpy (&data_buffer[val], fini, finisz);
2364 val = 0x10;
2365 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2366 data_scnhdr.s_size = data_buffer_size;
2367 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2369 /* String table. */
2370 string_table_size = 4;
2371 string_table_size += strlen (data_name) + 1;
2372 string_table_size += strlen (rtinit_name) + 1;
2373 string_table_size += initsz;
2374 string_table_size += finisz;
2375 if (rtld)
2376 string_table_size += strlen (rtld_name) + 1;
2378 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2379 if (string_table == NULL)
2380 return FALSE;
2382 val = string_table_size;
2383 bfd_put_32 (abfd, val, &string_table[0]);
2384 st_tmp = string_table + 4;
2386 /* symbols
2387 0. .data csect
2388 2. __rtinit
2389 4. init function
2390 6. fini function
2391 8. __rtld */
2392 memset (syment_ext, 0, 10 * SYMESZ);
2393 memset (reloc_ext, 0, 3 * RELSZ);
2395 /* .data csect */
2396 memset (&syment, 0, sizeof (struct internal_syment));
2397 memset (&auxent, 0, sizeof (union internal_auxent));
2399 syment._n._n_n._n_offset = st_tmp - string_table;
2400 memcpy (st_tmp, data_name, strlen (data_name));
2401 st_tmp += strlen (data_name) + 1;
2403 syment.n_scnum = 2;
2404 syment.n_sclass = C_HIDEXT;
2405 syment.n_numaux = 1;
2406 auxent.x_csect.x_scnlen.l = data_buffer_size;
2407 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2408 auxent.x_csect.x_smclas = XMC_RW;
2409 bfd_coff_swap_sym_out (abfd, &syment,
2410 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2411 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2412 syment.n_numaux,
2413 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2414 filehdr.f_nsyms += 2;
2416 /* __rtinit */
2417 memset (&syment, 0, sizeof (struct internal_syment));
2418 memset (&auxent, 0, sizeof (union internal_auxent));
2419 syment._n._n_n._n_offset = st_tmp - string_table;
2420 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2421 st_tmp += strlen (rtinit_name) + 1;
2423 syment.n_scnum = 2;
2424 syment.n_sclass = C_EXT;
2425 syment.n_numaux = 1;
2426 auxent.x_csect.x_smtyp = XTY_LD;
2427 auxent.x_csect.x_smclas = XMC_RW;
2428 bfd_coff_swap_sym_out (abfd, &syment,
2429 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2430 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2431 syment.n_numaux,
2432 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2433 filehdr.f_nsyms += 2;
2435 /* Init. */
2436 if (initsz)
2438 memset (&syment, 0, sizeof (struct internal_syment));
2439 memset (&auxent, 0, sizeof (union internal_auxent));
2441 syment._n._n_n._n_offset = st_tmp - string_table;
2442 memcpy (st_tmp, init, initsz);
2443 st_tmp += initsz;
2445 syment.n_sclass = C_EXT;
2446 syment.n_numaux = 1;
2447 bfd_coff_swap_sym_out (abfd, &syment,
2448 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2449 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2450 syment.n_numaux,
2451 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2452 /* Reloc. */
2453 memset (&reloc, 0, sizeof (struct internal_reloc));
2454 reloc.r_vaddr = 0x0018;
2455 reloc.r_symndx = filehdr.f_nsyms;
2456 reloc.r_type = R_POS;
2457 reloc.r_size = 63;
2458 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2460 filehdr.f_nsyms += 2;
2461 data_scnhdr.s_nreloc += 1;
2464 /* Finit. */
2465 if (finisz)
2467 memset (&syment, 0, sizeof (struct internal_syment));
2468 memset (&auxent, 0, sizeof (union internal_auxent));
2470 syment._n._n_n._n_offset = st_tmp - string_table;
2471 memcpy (st_tmp, fini, finisz);
2472 st_tmp += finisz;
2474 syment.n_sclass = C_EXT;
2475 syment.n_numaux = 1;
2476 bfd_coff_swap_sym_out (abfd, &syment,
2477 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2478 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2479 syment.n_numaux,
2480 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2482 /* Reloc. */
2483 memset (&reloc, 0, sizeof (struct internal_reloc));
2484 reloc.r_vaddr = 0x0038;
2485 reloc.r_symndx = filehdr.f_nsyms;
2486 reloc.r_type = R_POS;
2487 reloc.r_size = 63;
2488 bfd_coff_swap_reloc_out (abfd, &reloc,
2489 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2491 filehdr.f_nsyms += 2;
2492 data_scnhdr.s_nreloc += 1;
2495 if (rtld)
2497 memset (&syment, 0, sizeof (struct internal_syment));
2498 memset (&auxent, 0, sizeof (union internal_auxent));
2500 syment._n._n_n._n_offset = st_tmp - string_table;
2501 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2502 st_tmp += strlen (rtld_name) + 1;
2504 syment.n_sclass = C_EXT;
2505 syment.n_numaux = 1;
2506 bfd_coff_swap_sym_out (abfd, &syment,
2507 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2508 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2509 syment.n_numaux,
2510 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2512 /* Reloc. */
2513 memset (&reloc, 0, sizeof (struct internal_reloc));
2514 reloc.r_vaddr = 0x0000;
2515 reloc.r_symndx = filehdr.f_nsyms;
2516 reloc.r_type = R_POS;
2517 reloc.r_size = 63;
2518 bfd_coff_swap_reloc_out (abfd, &reloc,
2519 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2521 filehdr.f_nsyms += 2;
2522 data_scnhdr.s_nreloc += 1;
2524 bss_scnhdr.s_size = 0;
2527 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2528 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2530 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2531 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2532 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2533 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2534 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2535 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2536 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2537 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2538 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2539 bfd_bwrite (string_table, string_table_size, abfd);
2541 free (data_buffer);
2542 data_buffer = NULL;
2544 return TRUE;
2547 /* The typical dynamic reloc. */
2549 static reloc_howto_type xcoff64_dynamic_reloc =
2550 HOWTO (0, /* type */
2551 0, /* rightshift */
2552 4, /* size (0 = byte, 1 = short, 2 = long) */
2553 64, /* bitsize */
2554 FALSE, /* pc_relative */
2555 0, /* bitpos */
2556 complain_overflow_bitfield, /* complain_on_overflow */
2557 0, /* special_function */
2558 "R_POS", /* name */
2559 TRUE, /* partial_inplace */
2560 MINUS_ONE, /* src_mask */
2561 MINUS_ONE, /* dst_mask */
2562 FALSE); /* pcrel_offset */
2564 static unsigned long xcoff64_glink_code[10] =
2566 0xe9820000, /* ld r12,0(r2) */
2567 0xf8410028, /* std r2,40(r1) */
2568 0xe80c0000, /* ld r0,0(r12) */
2569 0xe84c0008, /* ld r0,8(r12) */
2570 0x7c0903a6, /* mtctr r0 */
2571 0x4e800420, /* bctr */
2572 0x00000000, /* start of traceback table */
2573 0x000ca000, /* traceback table */
2574 0x00000000, /* traceback table */
2575 0x00000018, /* ??? */
2578 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2580 { /* COFF backend, defined in libcoff.h. */
2581 _bfd_xcoff64_swap_aux_in,
2582 _bfd_xcoff64_swap_sym_in,
2583 _bfd_xcoff64_swap_lineno_in,
2584 _bfd_xcoff64_swap_aux_out,
2585 _bfd_xcoff64_swap_sym_out,
2586 _bfd_xcoff64_swap_lineno_out,
2587 xcoff64_swap_reloc_out,
2588 coff_swap_filehdr_out,
2589 coff_swap_aouthdr_out,
2590 coff_swap_scnhdr_out,
2591 FILHSZ,
2592 AOUTSZ,
2593 SCNHSZ,
2594 SYMESZ,
2595 AUXESZ,
2596 RELSZ,
2597 LINESZ,
2598 FILNMLEN,
2599 TRUE, /* _bfd_coff_long_filenames */
2600 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2601 3, /* _bfd_coff_default_section_alignment_power */
2602 TRUE, /* _bfd_coff_force_symnames_in_strings */
2603 4, /* _bfd_coff_debug_string_prefix_length */
2604 coff_swap_filehdr_in,
2605 coff_swap_aouthdr_in,
2606 coff_swap_scnhdr_in,
2607 xcoff64_swap_reloc_in,
2608 xcoff64_bad_format_hook,
2609 coff_set_arch_mach_hook,
2610 coff_mkobject_hook,
2611 styp_to_sec_flags,
2612 coff_set_alignment_hook,
2613 coff_slurp_symbol_table,
2614 symname_in_debug_hook,
2615 coff_pointerize_aux_hook,
2616 coff_print_aux,
2617 dummy_reloc16_extra_cases,
2618 dummy_reloc16_estimate,
2619 NULL, /* bfd_coff_symbol_classification */
2620 coff_compute_section_file_positions,
2621 NULL, /* _bfd_coff_start_final_link */
2622 xcoff64_ppc_relocate_section,
2623 coff_rtype_to_howto,
2624 NULL, /* _bfd_coff_adjust_symndx */
2625 _bfd_generic_link_add_one_symbol,
2626 coff_link_output_has_begun,
2627 coff_final_link_postscript,
2628 NULL /* print_pdata. */
2631 0x01EF, /* magic number */
2632 bfd_arch_powerpc,
2633 bfd_mach_ppc_620,
2635 /* Function pointers to xcoff specific swap routines. */
2636 xcoff64_swap_ldhdr_in,
2637 xcoff64_swap_ldhdr_out,
2638 xcoff64_swap_ldsym_in,
2639 xcoff64_swap_ldsym_out,
2640 xcoff64_swap_ldrel_in,
2641 xcoff64_swap_ldrel_out,
2643 /* Sizes. */
2644 LDHDRSZ,
2645 LDSYMSZ,
2646 LDRELSZ,
2647 24, /* _xcoff_function_descriptor_size */
2648 0, /* _xcoff_small_aout_header_size */
2650 /* Versions. */
2651 2, /* _xcoff_ldhdr_version */
2653 _bfd_xcoff64_put_symbol_name,
2654 _bfd_xcoff64_put_ldsymbol_name,
2655 &xcoff64_dynamic_reloc,
2656 xcoff64_create_csect_from_smclas,
2658 /* Lineno and reloc count overflow. */
2659 xcoff64_is_lineno_count_overflow,
2660 xcoff64_is_reloc_count_overflow,
2662 xcoff64_loader_symbol_offset,
2663 xcoff64_loader_reloc_offset,
2665 /* glink. */
2666 &xcoff64_glink_code[0],
2667 40, /* _xcoff_glink_size */
2669 /* rtinit. */
2670 88, /* _xcoff_rtinit_size */
2671 xcoff64_generate_rtinit,
2674 /* The transfer vector that leads the outside world to all of the above. */
2675 const bfd_target rs6000coff64_vec =
2677 "aixcoff64-rs6000",
2678 bfd_target_xcoff_flavour,
2679 BFD_ENDIAN_BIG, /* data byte order is big */
2680 BFD_ENDIAN_BIG, /* header byte order is big */
2682 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2683 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2685 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2686 0, /* leading char */
2687 '/', /* ar_pad_char */
2688 15, /* ar_max_namelen */
2690 /* data */
2691 bfd_getb64,
2692 bfd_getb_signed_64,
2693 bfd_putb64,
2694 bfd_getb32,
2695 bfd_getb_signed_32,
2696 bfd_putb32,
2697 bfd_getb16,
2698 bfd_getb_signed_16,
2699 bfd_putb16,
2701 /* hdrs */
2702 bfd_getb64,
2703 bfd_getb_signed_64,
2704 bfd_putb64,
2705 bfd_getb32,
2706 bfd_getb_signed_32,
2707 bfd_putb32,
2708 bfd_getb16,
2709 bfd_getb_signed_16,
2710 bfd_putb16,
2712 { /* bfd_check_format */
2713 _bfd_dummy_target,
2714 coff_object_p,
2715 xcoff64_archive_p,
2716 CORE_FILE_P
2719 { /* bfd_set_format */
2720 bfd_false,
2721 coff_mkobject,
2722 _bfd_generic_mkarchive,
2723 bfd_false
2726 {/* bfd_write_contents */
2727 bfd_false,
2728 xcoff64_write_object_contents,
2729 _bfd_xcoff_write_archive_contents,
2730 bfd_false
2733 /* Generic */
2734 bfd_true,
2735 bfd_true,
2736 coff_new_section_hook,
2737 _bfd_generic_get_section_contents,
2738 _bfd_generic_get_section_contents_in_window,
2740 /* Copy */
2741 _bfd_xcoff_copy_private_bfd_data,
2742 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2743 _bfd_generic_init_private_section_data,
2744 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2745 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2746 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2747 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2748 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
2750 /* Core */
2751 coff_core_file_failing_command,
2752 coff_core_file_failing_signal,
2753 coff_core_file_matches_executable_p,
2755 /* Archive */
2756 xcoff64_slurp_armap,
2757 bfd_false,
2758 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2759 bfd_dont_truncate_arname,
2760 _bfd_xcoff_write_armap,
2761 _bfd_xcoff_read_ar_hdr,
2762 xcoff64_openr_next_archived_file,
2763 _bfd_generic_get_elt_at_index,
2764 _bfd_xcoff_stat_arch_elt,
2765 bfd_true,
2767 /* Symbols */
2768 coff_get_symtab_upper_bound,
2769 coff_canonicalize_symtab,
2770 coff_make_empty_symbol,
2771 coff_print_symbol,
2772 coff_get_symbol_info,
2773 _bfd_xcoff_is_local_label_name,
2774 coff_bfd_is_target_special_symbol,
2775 coff_get_lineno,
2776 coff_find_nearest_line,
2777 _bfd_generic_find_line,
2778 coff_find_inliner_info,
2779 coff_bfd_make_debug_symbol,
2780 _bfd_generic_read_minisymbols,
2781 _bfd_generic_minisymbol_to_symbol,
2783 /* Reloc */
2784 coff_get_reloc_upper_bound,
2785 coff_canonicalize_reloc,
2786 xcoff64_reloc_type_lookup,
2787 xcoff64_reloc_name_lookup,
2789 /* Write */
2790 coff_set_arch_mach,
2791 coff_set_section_contents,
2793 /* Link */
2794 xcoff64_sizeof_headers,
2795 bfd_generic_get_relocated_section_contents,
2796 bfd_generic_relax_section,
2797 _bfd_xcoff_bfd_link_hash_table_create,
2798 _bfd_generic_link_hash_table_free,
2799 _bfd_xcoff_bfd_link_add_symbols,
2800 _bfd_generic_link_just_syms,
2801 _bfd_xcoff_bfd_final_link,
2802 _bfd_generic_link_split_section,
2803 bfd_generic_gc_sections,
2804 bfd_generic_merge_sections,
2805 bfd_generic_is_group_section,
2806 bfd_generic_discard_group,
2807 _bfd_generic_section_already_linked,
2808 _bfd_xcoff_define_common_symbol,
2810 /* Dynamic */
2811 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2812 _bfd_xcoff_canonicalize_dynamic_symtab,
2813 _bfd_nodynamic_get_synthetic_symtab,
2814 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2815 _bfd_xcoff_canonicalize_dynamic_reloc,
2817 /* Opposite endian version, none exists */
2818 NULL,
2820 (void *) &bfd_xcoff_backend_data,
2823 extern const bfd_target *xcoff64_core_p
2824 PARAMS ((bfd *));
2825 extern bfd_boolean xcoff64_core_file_matches_executable_p
2826 PARAMS ((bfd *, bfd *));
2827 extern char *xcoff64_core_file_failing_command
2828 PARAMS ((bfd *));
2829 extern int xcoff64_core_file_failing_signal
2830 PARAMS ((bfd *));
2832 /* AIX 5 */
2833 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2835 { /* COFF backend, defined in libcoff.h. */
2836 _bfd_xcoff64_swap_aux_in,
2837 _bfd_xcoff64_swap_sym_in,
2838 _bfd_xcoff64_swap_lineno_in,
2839 _bfd_xcoff64_swap_aux_out,
2840 _bfd_xcoff64_swap_sym_out,
2841 _bfd_xcoff64_swap_lineno_out,
2842 xcoff64_swap_reloc_out,
2843 coff_swap_filehdr_out,
2844 coff_swap_aouthdr_out,
2845 coff_swap_scnhdr_out,
2846 FILHSZ,
2847 AOUTSZ,
2848 SCNHSZ,
2849 SYMESZ,
2850 AUXESZ,
2851 RELSZ,
2852 LINESZ,
2853 FILNMLEN,
2854 TRUE, /* _bfd_coff_long_filenames */
2855 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2856 3, /* _bfd_coff_default_section_alignment_power */
2857 TRUE, /* _bfd_coff_force_symnames_in_strings */
2858 4, /* _bfd_coff_debug_string_prefix_length */
2859 coff_swap_filehdr_in,
2860 coff_swap_aouthdr_in,
2861 coff_swap_scnhdr_in,
2862 xcoff64_swap_reloc_in,
2863 xcoff64_bad_format_hook,
2864 coff_set_arch_mach_hook,
2865 coff_mkobject_hook,
2866 styp_to_sec_flags,
2867 coff_set_alignment_hook,
2868 coff_slurp_symbol_table,
2869 symname_in_debug_hook,
2870 coff_pointerize_aux_hook,
2871 coff_print_aux,
2872 dummy_reloc16_extra_cases,
2873 dummy_reloc16_estimate,
2874 NULL, /* bfd_coff_sym_is_global */
2875 coff_compute_section_file_positions,
2876 NULL, /* _bfd_coff_start_final_link */
2877 xcoff64_ppc_relocate_section,
2878 coff_rtype_to_howto,
2879 NULL, /* _bfd_coff_adjust_symndx */
2880 _bfd_generic_link_add_one_symbol,
2881 coff_link_output_has_begun,
2882 coff_final_link_postscript,
2883 NULL /* print_pdata. */
2886 U64_TOCMAGIC, /* magic number */
2887 bfd_arch_powerpc,
2888 bfd_mach_ppc_620,
2890 /* Function pointers to xcoff specific swap routines. */
2891 xcoff64_swap_ldhdr_in,
2892 xcoff64_swap_ldhdr_out,
2893 xcoff64_swap_ldsym_in,
2894 xcoff64_swap_ldsym_out,
2895 xcoff64_swap_ldrel_in,
2896 xcoff64_swap_ldrel_out,
2898 /* Sizes. */
2899 LDHDRSZ,
2900 LDSYMSZ,
2901 LDRELSZ,
2902 24, /* _xcoff_function_descriptor_size */
2903 0, /* _xcoff_small_aout_header_size */
2904 /* Versions. */
2905 2, /* _xcoff_ldhdr_version */
2907 _bfd_xcoff64_put_symbol_name,
2908 _bfd_xcoff64_put_ldsymbol_name,
2909 &xcoff64_dynamic_reloc,
2910 xcoff64_create_csect_from_smclas,
2912 /* Lineno and reloc count overflow. */
2913 xcoff64_is_lineno_count_overflow,
2914 xcoff64_is_reloc_count_overflow,
2916 xcoff64_loader_symbol_offset,
2917 xcoff64_loader_reloc_offset,
2919 /* glink. */
2920 &xcoff64_glink_code[0],
2921 40, /* _xcoff_glink_size */
2923 /* rtinit. */
2924 88, /* _xcoff_rtinit_size */
2925 xcoff64_generate_rtinit,
2928 /* The transfer vector that leads the outside world to all of the above. */
2929 const bfd_target aix5coff64_vec =
2931 "aix5coff64-rs6000",
2932 bfd_target_xcoff_flavour,
2933 BFD_ENDIAN_BIG, /* data byte order is big */
2934 BFD_ENDIAN_BIG, /* header byte order is big */
2936 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2937 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2939 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2940 0, /* leading char */
2941 '/', /* ar_pad_char */
2942 15, /* ar_max_namelen */
2944 /* data */
2945 bfd_getb64,
2946 bfd_getb_signed_64,
2947 bfd_putb64,
2948 bfd_getb32,
2949 bfd_getb_signed_32,
2950 bfd_putb32,
2951 bfd_getb16,
2952 bfd_getb_signed_16,
2953 bfd_putb16,
2955 /* hdrs */
2956 bfd_getb64,
2957 bfd_getb_signed_64,
2958 bfd_putb64,
2959 bfd_getb32,
2960 bfd_getb_signed_32,
2961 bfd_putb32,
2962 bfd_getb16,
2963 bfd_getb_signed_16,
2964 bfd_putb16,
2966 { /* bfd_check_format */
2967 _bfd_dummy_target,
2968 coff_object_p,
2969 xcoff64_archive_p,
2970 xcoff64_core_p
2973 { /* bfd_set_format */
2974 bfd_false,
2975 coff_mkobject,
2976 _bfd_generic_mkarchive,
2977 bfd_false
2980 {/* bfd_write_contents */
2981 bfd_false,
2982 xcoff64_write_object_contents,
2983 _bfd_xcoff_write_archive_contents,
2984 bfd_false
2987 /* Generic */
2988 bfd_true,
2989 bfd_true,
2990 coff_new_section_hook,
2991 _bfd_generic_get_section_contents,
2992 _bfd_generic_get_section_contents_in_window,
2994 /* Copy */
2995 _bfd_xcoff_copy_private_bfd_data,
2996 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2997 _bfd_generic_init_private_section_data,
2998 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2999 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
3000 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
3001 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
3002 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
3004 /* Core */
3005 xcoff64_core_file_failing_command,
3006 xcoff64_core_file_failing_signal,
3007 xcoff64_core_file_matches_executable_p,
3009 /* Archive */
3010 xcoff64_slurp_armap,
3011 bfd_false,
3012 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
3013 bfd_dont_truncate_arname,
3014 _bfd_xcoff_write_armap,
3015 _bfd_xcoff_read_ar_hdr,
3016 xcoff64_openr_next_archived_file,
3017 _bfd_generic_get_elt_at_index,
3018 _bfd_xcoff_stat_arch_elt,
3019 bfd_true,
3021 /* Symbols */
3022 coff_get_symtab_upper_bound,
3023 coff_canonicalize_symtab,
3024 coff_make_empty_symbol,
3025 coff_print_symbol,
3026 coff_get_symbol_info,
3027 _bfd_xcoff_is_local_label_name,
3028 coff_bfd_is_target_special_symbol,
3029 coff_get_lineno,
3030 coff_find_nearest_line,
3031 _bfd_generic_find_line,
3032 coff_find_inliner_info,
3033 coff_bfd_make_debug_symbol,
3034 _bfd_generic_read_minisymbols,
3035 _bfd_generic_minisymbol_to_symbol,
3037 /* Reloc */
3038 coff_get_reloc_upper_bound,
3039 coff_canonicalize_reloc,
3040 xcoff64_reloc_type_lookup,
3041 xcoff64_reloc_name_lookup,
3043 /* Write */
3044 coff_set_arch_mach,
3045 coff_set_section_contents,
3047 /* Link */
3048 xcoff64_sizeof_headers,
3049 bfd_generic_get_relocated_section_contents,
3050 bfd_generic_relax_section,
3051 _bfd_xcoff_bfd_link_hash_table_create,
3052 _bfd_generic_link_hash_table_free,
3053 _bfd_xcoff_bfd_link_add_symbols,
3054 _bfd_generic_link_just_syms,
3055 _bfd_xcoff_bfd_final_link,
3056 _bfd_generic_link_split_section,
3057 bfd_generic_gc_sections,
3058 bfd_generic_merge_sections,
3059 bfd_generic_is_group_section,
3060 bfd_generic_discard_group,
3061 _bfd_generic_section_already_linked,
3062 _bfd_xcoff_define_common_symbol,
3064 /* Dynamic */
3065 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3066 _bfd_xcoff_canonicalize_dynamic_symtab,
3067 _bfd_nodynamic_get_synthetic_symtab,
3068 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3069 _bfd_xcoff_canonicalize_dynamic_reloc,
3071 /* Opposite endian version, none exists. */
3072 NULL,
3074 (void *) & bfd_xcoff_aix5_backend_data,