2011-03-24 Paolo Bonzini <bonzini@gnu.org>
[binutils.git] / bfd / coff64-rs6000.c
blobb154b6762101753bbe8dee531052296100bda6fd
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3 2010
4 Free Software Foundation, Inc.
5 Written Clinton Popetz.
6 Contributed by Cygnus Support.
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
25 #include "sysdep.h"
26 #include "bfd.h"
27 #include "bfdlink.h"
28 #include "libbfd.h"
29 #include "coff/internal.h"
30 #include "coff/xcoff.h"
31 #include "coff/rs6k64.h"
32 #include "libcoff.h"
33 #include "libxcoff.h"
35 #define GET_FILEHDR_SYMPTR H_GET_64
36 #define PUT_FILEHDR_SYMPTR H_PUT_64
37 #define GET_AOUTHDR_DATA_START H_GET_64
38 #define PUT_AOUTHDR_DATA_START H_PUT_64
39 #define GET_AOUTHDR_TEXT_START H_GET_64
40 #define PUT_AOUTHDR_TEXT_START H_PUT_64
41 #define GET_AOUTHDR_TSIZE H_GET_64
42 #define PUT_AOUTHDR_TSIZE H_PUT_64
43 #define GET_AOUTHDR_DSIZE H_GET_64
44 #define PUT_AOUTHDR_DSIZE H_PUT_64
45 #define GET_AOUTHDR_BSIZE H_GET_64
46 #define PUT_AOUTHDR_BSIZE H_PUT_64
47 #define GET_AOUTHDR_ENTRY H_GET_64
48 #define PUT_AOUTHDR_ENTRY H_PUT_64
49 #define GET_SCNHDR_PADDR H_GET_64
50 #define PUT_SCNHDR_PADDR H_PUT_64
51 #define GET_SCNHDR_VADDR H_GET_64
52 #define PUT_SCNHDR_VADDR H_PUT_64
53 #define GET_SCNHDR_SIZE H_GET_64
54 #define PUT_SCNHDR_SIZE H_PUT_64
55 #define GET_SCNHDR_SCNPTR H_GET_64
56 #define PUT_SCNHDR_SCNPTR H_PUT_64
57 #define GET_SCNHDR_RELPTR H_GET_64
58 #define PUT_SCNHDR_RELPTR H_PUT_64
59 #define GET_SCNHDR_LNNOPTR H_GET_64
60 #define PUT_SCNHDR_LNNOPTR H_PUT_64
61 #define GET_SCNHDR_NRELOC H_GET_32
62 #define MAX_SCNHDR_NRELOC 0xffffffff
63 #define PUT_SCNHDR_NRELOC H_PUT_32
64 #define GET_SCNHDR_NLNNO H_GET_32
65 #define MAX_SCNHDR_NLNNO 0xffffffff
66 #define PUT_SCNHDR_NLNNO H_PUT_32
67 #define GET_RELOC_VADDR H_GET_64
68 #define PUT_RELOC_VADDR H_PUT_64
70 #define COFF_FORCE_SYMBOLS_IN_STRINGS
71 #define COFF_DEBUG_STRING_WIDE_PREFIX
74 #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
75 do \
76 { \
77 memset (((SCNHDR *) EXT)->s_pad, 0, \
78 sizeof (((SCNHDR *) EXT)->s_pad)); \
79 } \
80 while (0)
82 #define NO_COFF_LINENOS
84 #define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
85 #define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
87 static void _bfd_xcoff64_swap_lineno_in
88 PARAMS ((bfd *, PTR, PTR));
89 static unsigned int _bfd_xcoff64_swap_lineno_out
90 PARAMS ((bfd *, PTR, PTR));
91 static bfd_boolean _bfd_xcoff64_put_symbol_name
92 PARAMS ((bfd *, struct bfd_strtab_hash *, struct internal_syment *,
93 const char *));
94 static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
95 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
96 const char *));
97 static void _bfd_xcoff64_swap_sym_in
98 PARAMS ((bfd *, PTR, PTR));
99 static unsigned int _bfd_xcoff64_swap_sym_out
100 PARAMS ((bfd *, PTR, PTR));
101 static void _bfd_xcoff64_swap_aux_in
102 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
103 static unsigned int _bfd_xcoff64_swap_aux_out
104 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
105 static void xcoff64_swap_reloc_in
106 PARAMS ((bfd *, PTR, PTR));
107 static unsigned int xcoff64_swap_reloc_out
108 PARAMS ((bfd *, PTR, PTR));
109 extern bfd_boolean _bfd_xcoff_mkobject
110 PARAMS ((bfd *));
111 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
112 PARAMS ((bfd *, bfd *));
113 extern bfd_boolean _bfd_xcoff_is_local_label_name
114 PARAMS ((bfd *, const char *));
115 extern void xcoff64_rtype2howto
116 PARAMS ((arelent *, struct internal_reloc *));
117 extern reloc_howto_type * xcoff64_reloc_type_lookup
118 PARAMS ((bfd *, bfd_reloc_code_real_type));
119 extern bfd_boolean _bfd_xcoff_slurp_armap
120 PARAMS ((bfd *));
121 extern PTR _bfd_xcoff_read_ar_hdr
122 PARAMS ((bfd *));
123 extern bfd *_bfd_xcoff_openr_next_archived_file
124 PARAMS ((bfd *, bfd *));
125 extern int _bfd_xcoff_stat_arch_elt
126 PARAMS ((bfd *, struct stat *));
127 extern bfd_boolean _bfd_xcoff_write_armap
128 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
129 extern bfd_boolean _bfd_xcoff_write_archive_contents
130 PARAMS ((bfd *));
131 extern int _bfd_xcoff_sizeof_headers
132 PARAMS ((bfd *, struct bfd_link_info *));
133 extern void _bfd_xcoff_swap_sym_in
134 PARAMS ((bfd *, PTR, PTR));
135 extern unsigned int _bfd_xcoff_swap_sym_out
136 PARAMS ((bfd *, PTR, PTR));
137 extern void _bfd_xcoff_swap_aux_in
138 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
139 extern unsigned int _bfd_xcoff_swap_aux_out
140 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
141 static void xcoff64_swap_ldhdr_in
142 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
143 static void xcoff64_swap_ldhdr_out
144 PARAMS ((bfd *, const struct internal_ldhdr *, PTR d));
145 static void xcoff64_swap_ldsym_in
146 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
147 static void xcoff64_swap_ldsym_out
148 PARAMS ((bfd *, const struct internal_ldsym *, PTR d));
149 static void xcoff64_swap_ldrel_in
150 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
151 static void xcoff64_swap_ldrel_out
152 PARAMS ((bfd *, const struct internal_ldrel *, PTR d));
153 static bfd_boolean xcoff64_write_object_contents
154 PARAMS ((bfd *));
155 static bfd_boolean xcoff64_ppc_relocate_section
156 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
157 struct internal_reloc *, struct internal_syment *,
158 asection **));
159 static bfd_boolean xcoff64_slurp_armap
160 PARAMS ((bfd *));
161 static const bfd_target *xcoff64_archive_p
162 PARAMS ((bfd *));
163 static bfd *xcoff64_openr_next_archived_file
164 PARAMS ((bfd *, bfd *));
165 static int xcoff64_sizeof_headers
166 PARAMS ((bfd *, struct bfd_link_info *));
167 static asection *xcoff64_create_csect_from_smclas
168 PARAMS ((bfd *, union internal_auxent *, const char *));
169 static bfd_boolean xcoff64_is_lineno_count_overflow
170 PARAMS ((bfd *, bfd_vma));
171 static bfd_boolean xcoff64_is_reloc_count_overflow
172 PARAMS ((bfd *, bfd_vma));
173 static bfd_vma xcoff64_loader_symbol_offset
174 PARAMS ((bfd *, struct internal_ldhdr *));
175 static bfd_vma xcoff64_loader_reloc_offset
176 PARAMS ((bfd *, struct internal_ldhdr *));
177 static bfd_boolean xcoff64_generate_rtinit
178 PARAMS ((bfd *, const char *, const char *, bfd_boolean));
179 static bfd_boolean xcoff64_bad_format_hook
180 PARAMS ((bfd *, PTR ));
182 /* Relocation functions */
183 static bfd_boolean xcoff64_reloc_type_br
184 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
186 bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
187 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
189 xcoff_reloc_type_pos, /* R_POS (0x00) */
190 xcoff_reloc_type_neg, /* R_NEG (0x01) */
191 xcoff_reloc_type_rel, /* R_REL (0x02) */
192 xcoff_reloc_type_toc, /* R_TOC (0x03) */
193 xcoff_reloc_type_fail, /* R_RTB (0x04) */
194 xcoff_reloc_type_toc, /* R_GL (0x05) */
195 xcoff_reloc_type_toc, /* R_TCL (0x06) */
196 xcoff_reloc_type_fail, /* (0x07) */
197 xcoff_reloc_type_ba, /* R_BA (0x08) */
198 xcoff_reloc_type_fail, /* (0x09) */
199 xcoff64_reloc_type_br, /* R_BR (0x0a) */
200 xcoff_reloc_type_fail, /* (0x0b) */
201 xcoff_reloc_type_pos, /* R_RL (0x0c) */
202 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
203 xcoff_reloc_type_fail, /* (0x0e) */
204 xcoff_reloc_type_noop, /* R_REF (0x0f) */
205 xcoff_reloc_type_fail, /* (0x10) */
206 xcoff_reloc_type_fail, /* (0x11) */
207 xcoff_reloc_type_toc, /* R_TRL (0x12) */
208 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
209 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
210 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
211 xcoff_reloc_type_ba, /* R_CAI (0x16) */
212 xcoff_reloc_type_crel, /* R_CREL (0x17) */
213 xcoff_reloc_type_ba, /* R_RBA (0x18) */
214 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
215 xcoff64_reloc_type_br, /* R_RBR (0x1a) */
216 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
219 /* coffcode.h needs these to be defined. */
220 /* Internalcoff.h and coffcode.h modify themselves based on these flags. */
221 #define XCOFF64
222 #define RS6000COFF_C 1
224 #define SELECT_RELOC(internal, howto) \
226 internal.r_type = howto->type; \
227 internal.r_size = \
228 ((howto->complain_on_overflow == complain_overflow_signed \
229 ? 0x80 \
230 : 0) \
231 | (howto->bitsize - 1)); \
234 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
235 #define COFF_LONG_FILENAMES
236 #define NO_COFF_SYMBOLS
237 #define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
238 #define coff_mkobject _bfd_xcoff_mkobject
239 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
240 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
241 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
242 #define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
243 #ifdef AIX_CORE
244 extern const bfd_target * rs6000coff_core_p
245 PARAMS ((bfd *abfd));
246 extern bfd_boolean rs6000coff_core_file_matches_executable_p
247 PARAMS ((bfd *cbfd, bfd *ebfd));
248 extern char *rs6000coff_core_file_failing_command
249 PARAMS ((bfd *abfd));
250 extern int rs6000coff_core_file_failing_signal
251 PARAMS ((bfd *abfd));
252 #define CORE_FILE_P rs6000coff_core_p
253 #define coff_core_file_failing_command \
254 rs6000coff_core_file_failing_command
255 #define coff_core_file_failing_signal \
256 rs6000coff_core_file_failing_signal
257 #define coff_core_file_matches_executable_p \
258 rs6000coff_core_file_matches_executable_p
259 #define coff_core_file_pid \
260 _bfd_nocore_core_file_pid
261 #else
262 #define CORE_FILE_P _bfd_dummy_target
263 #define coff_core_file_failing_command \
264 _bfd_nocore_core_file_failing_command
265 #define coff_core_file_failing_signal \
266 _bfd_nocore_core_file_failing_signal
267 #define coff_core_file_matches_executable_p \
268 _bfd_nocore_core_file_matches_executable_p
269 #define coff_core_file_pid \
270 _bfd_nocore_core_file_pid
271 #endif
272 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
273 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
274 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
275 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
276 #define coff_swap_reloc_in xcoff64_swap_reloc_in
277 #define coff_swap_reloc_out xcoff64_swap_reloc_out
278 #define NO_COFF_RELOCS
280 #ifndef bfd_pe_print_pdata
281 #define bfd_pe_print_pdata NULL
282 #endif
284 #include "coffcode.h"
286 /* For XCOFF64, the effective width of symndx changes depending on
287 whether we are the first entry. Sigh. */
288 static void
289 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
290 bfd *abfd;
291 PTR ext1;
292 PTR in1;
294 LINENO *ext = (LINENO *) ext1;
295 struct internal_lineno *in = (struct internal_lineno *) in1;
297 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
298 if (in->l_lnno == 0)
299 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
300 else
301 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
304 static unsigned int
305 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
306 bfd *abfd;
307 PTR inp;
308 PTR outp;
310 struct internal_lineno *in = (struct internal_lineno *) inp;
311 struct external_lineno *ext = (struct external_lineno *) outp;
313 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
314 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
316 if (in->l_lnno == 0)
317 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
318 else
319 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
321 return bfd_coff_linesz (abfd);
324 static void
325 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
326 bfd *abfd;
327 PTR ext1;
328 PTR in1;
330 struct external_syment *ext = (struct external_syment *) ext1;
331 struct internal_syment *in = (struct internal_syment *) in1;
333 in->_n._n_n._n_zeroes = 0;
334 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
335 in->n_value = H_GET_64 (abfd, ext->e_value);
336 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
337 in->n_type = H_GET_16 (abfd, ext->e_type);
338 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
339 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
342 static unsigned int
343 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
344 bfd *abfd;
345 PTR inp;
346 PTR extp;
348 struct internal_syment *in = (struct internal_syment *) inp;
349 struct external_syment *ext = (struct external_syment *) extp;
351 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
352 H_PUT_64 (abfd, in->n_value, ext->e_value);
353 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
354 H_PUT_16 (abfd, in->n_type, ext->e_type);
355 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
356 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
357 return bfd_coff_symesz (abfd);
360 static void
361 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, in_class, indx, numaux, in1)
362 bfd *abfd;
363 PTR ext1;
364 int type;
365 int in_class;
366 int indx;
367 int numaux;
368 PTR in1;
370 union external_auxent *ext = (union external_auxent *) ext1;
371 union internal_auxent *in = (union internal_auxent *) in1;
373 switch (in_class)
375 case C_FILE:
376 if (ext->x_file.x_n.x_zeroes[0] == 0)
378 in->x_file.x_n.x_zeroes = 0;
379 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
381 else
383 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
385 goto end;
387 /* RS/6000 "csect" auxents */
388 case C_EXT:
389 case C_AIX_WEAKEXT:
390 case C_HIDEXT:
391 if (indx + 1 == numaux)
393 bfd_signed_vma h = 0;
394 bfd_vma l = 0;
396 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
397 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
399 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
401 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
402 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
403 /* We don't have to hack bitfields in x_smtyp because it's
404 defined by shifts-and-ands, which are equivalent on all
405 byte orders. */
406 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
407 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
408 goto end;
410 break;
412 case C_STAT:
413 case C_LEAFSTAT:
414 case C_HIDDEN:
415 if (type == T_NULL)
417 /* PE defines some extra fields; we zero them out for
418 safety. */
419 in->x_scn.x_checksum = 0;
420 in->x_scn.x_associated = 0;
421 in->x_scn.x_comdat = 0;
423 goto end;
425 break;
428 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
429 || ISTAG (in_class))
431 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
432 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
433 in->x_sym.x_fcnary.x_fcn.x_endndx.l
434 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
436 if (ISFCN (type))
438 in->x_sym.x_misc.x_fsize
439 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
441 else
443 in->x_sym.x_misc.x_lnsz.x_lnno
444 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
445 in->x_sym.x_misc.x_lnsz.x_size
446 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
449 end: ;
452 static unsigned int
453 _bfd_xcoff64_swap_aux_out (abfd, inp, type, in_class, indx, numaux, extp)
454 bfd *abfd;
455 PTR inp;
456 int type;
457 int in_class;
458 int indx ATTRIBUTE_UNUSED;
459 int numaux ATTRIBUTE_UNUSED;
460 PTR extp;
462 union internal_auxent *in = (union internal_auxent *) inp;
463 union external_auxent *ext = (union external_auxent *) extp;
465 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
466 switch (in_class)
468 case C_FILE:
469 if (in->x_file.x_n.x_zeroes == 0)
471 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
472 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
474 else
476 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
478 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
479 goto end;
481 /* RS/6000 "csect" auxents */
482 case C_EXT:
483 case C_AIX_WEAKEXT:
484 case C_HIDEXT:
485 if (indx + 1 == numaux)
487 bfd_vma temp;
489 temp = in->x_csect.x_scnlen.l & 0xffffffff;
490 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
491 temp = in->x_csect.x_scnlen.l >> 32;
492 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
493 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
494 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
495 /* We don't have to hack bitfields in x_smtyp because it's
496 defined by shifts-and-ands, which are equivalent on all
497 byte orders. */
498 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
499 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
500 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
501 goto end;
503 break;
505 case C_STAT:
506 case C_LEAFSTAT:
507 case C_HIDDEN:
508 if (type == T_NULL)
510 goto end;
512 break;
515 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
516 || ISTAG (in_class))
518 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
519 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
520 H_PUT_8 (abfd, _AUX_FCN,
521 ext->x_auxtype.x_auxtype);
522 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
523 ext->x_sym.x_fcnary.x_fcn.x_endndx);
525 if (ISFCN (type))
527 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
528 ext->x_sym.x_fcnary.x_fcn.x_fsize);
530 else
532 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
533 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
534 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
535 ext->x_sym.x_fcnary.x_lnsz.x_size);
538 end:
540 return bfd_coff_auxesz (abfd);
543 static bfd_boolean
544 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
545 bfd *abfd;
546 struct bfd_strtab_hash *strtab;
547 struct internal_syment *sym;
548 const char *name;
550 bfd_boolean hash;
551 bfd_size_type indx;
553 hash = TRUE;
555 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
556 hash = FALSE;
558 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
560 if (indx == (bfd_size_type) -1)
561 return FALSE;
563 sym->_n._n_n._n_zeroes = 0;
564 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
566 return TRUE;
569 static bfd_boolean
570 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
571 bfd *abfd ATTRIBUTE_UNUSED;
572 struct xcoff_loader_info *ldinfo;
573 struct internal_ldsym *ldsym;
574 const char *name;
576 size_t len;
577 len = strlen (name);
579 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
581 bfd_size_type newalc;
582 char *newstrings;
584 newalc = ldinfo->string_alc * 2;
585 if (newalc == 0)
586 newalc = 32;
587 while (ldinfo->string_size + len + 3 > newalc)
588 newalc *= 2;
590 newstrings = bfd_realloc (ldinfo->strings, newalc);
591 if (newstrings == NULL)
593 ldinfo->failed = TRUE;
594 return FALSE;
596 ldinfo->string_alc = newalc;
597 ldinfo->strings = newstrings;
600 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
601 ldinfo->strings + ldinfo->string_size);
602 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
603 ldsym->_l._l_l._l_zeroes = 0;
604 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
605 ldinfo->string_size += len + 3;
607 return TRUE;
610 /* Routines to swap information in the XCOFF .loader section. If we
611 ever need to write an XCOFF loader, this stuff will need to be
612 moved to another file shared by the linker (which XCOFF calls the
613 ``binder'') and the loader. */
615 /* Swap in the ldhdr structure. */
617 static void
618 xcoff64_swap_ldhdr_in (abfd, s, dst)
619 bfd *abfd;
620 const PTR s;
621 struct internal_ldhdr *dst;
623 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
625 dst->l_version = bfd_get_32 (abfd, src->l_version);
626 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
627 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
628 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
629 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
630 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
631 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
632 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
633 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
634 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
637 /* Swap out the ldhdr structure. */
639 static void
640 xcoff64_swap_ldhdr_out (abfd, src, d)
641 bfd *abfd;
642 const struct internal_ldhdr *src;
643 PTR d;
645 struct external_ldhdr *dst = (struct external_ldhdr *) d;
647 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
648 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
649 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
650 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
651 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
652 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
653 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
654 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
655 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
656 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
659 /* Swap in the ldsym structure. */
661 static void
662 xcoff64_swap_ldsym_in (abfd, s, dst)
663 bfd *abfd;
664 const PTR s;
665 struct internal_ldsym *dst;
667 const struct external_ldsym *src = (const struct external_ldsym *) s;
668 /* XCOFF64 does not use l_zeroes like XCOFF32
669 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
670 as an offset into the loader symbol table. */
671 dst->_l._l_l._l_zeroes = 0;
672 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
673 dst->l_value = bfd_get_64 (abfd, src->l_value);
674 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
675 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
676 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
677 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
678 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
681 /* Swap out the ldsym structure. */
683 static void
684 xcoff64_swap_ldsym_out (abfd, src, d)
685 bfd *abfd;
686 const struct internal_ldsym *src;
687 PTR d;
689 struct external_ldsym *dst = (struct external_ldsym *) d;
691 bfd_put_64 (abfd, src->l_value, dst->l_value);
692 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
693 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
694 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
695 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
696 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
697 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
700 static void
701 xcoff64_swap_reloc_in (abfd, s, d)
702 bfd *abfd;
703 PTR s;
704 PTR d;
706 struct external_reloc *src = (struct external_reloc *) s;
707 struct internal_reloc *dst = (struct internal_reloc *) d;
709 memset (dst, 0, sizeof (struct internal_reloc));
711 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
712 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
713 dst->r_size = bfd_get_8 (abfd, src->r_size);
714 dst->r_type = bfd_get_8 (abfd, src->r_type);
717 static unsigned int
718 xcoff64_swap_reloc_out (abfd, s, d)
719 bfd *abfd;
720 PTR s;
721 PTR d;
723 struct internal_reloc *src = (struct internal_reloc *) s;
724 struct external_reloc *dst = (struct external_reloc *) d;
726 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
727 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
728 bfd_put_8 (abfd, src->r_type, dst->r_type);
729 bfd_put_8 (abfd, src->r_size, dst->r_size);
731 return bfd_coff_relsz (abfd);
734 /* Swap in the ldrel structure. */
736 static void
737 xcoff64_swap_ldrel_in (abfd, s, dst)
738 bfd *abfd;
739 const PTR s;
740 struct internal_ldrel *dst;
742 const struct external_ldrel *src = (const struct external_ldrel *) s;
744 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
745 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
746 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
747 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
750 /* Swap out the ldrel structure. */
752 static void
753 xcoff64_swap_ldrel_out (abfd, src, d)
754 bfd *abfd;
755 const struct internal_ldrel *src;
756 PTR d;
758 struct external_ldrel *dst = (struct external_ldrel *) d;
760 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
761 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
762 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
763 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
766 static bfd_boolean
767 xcoff64_write_object_contents (abfd)
768 bfd *abfd;
770 asection *current;
771 bfd_boolean hasrelocs = FALSE;
772 bfd_boolean haslinno = FALSE;
773 file_ptr scn_base;
774 file_ptr reloc_base;
775 file_ptr lineno_base;
776 file_ptr sym_base;
777 unsigned long reloc_size = 0;
778 unsigned long lnno_size = 0;
779 asection *text_sec = ((void *) 0);
780 asection *data_sec = ((void *) 0);
781 asection *bss_sec = ((void *) 0);
782 struct internal_filehdr internal_f;
783 struct internal_aouthdr internal_a;
785 bfd_set_error (bfd_error_system_call);
787 if (! abfd->output_has_begun)
789 if (! bfd_coff_compute_section_file_positions (abfd))
790 return FALSE;
793 /* Work out the size of the reloc and linno areas. */
794 reloc_base = obj_relocbase (abfd);
796 for (current = abfd->sections; current != NULL; current = current->next)
797 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
799 lineno_base = reloc_base + reloc_size;
801 /* Make a pass through the symbol table to count line number entries and
802 put them into the correct asections. */
803 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
805 sym_base = lineno_base + lnno_size;
807 /* Indicate in each section->line_filepos its actual file address. */
808 for (current = abfd->sections; current != NULL; current = current->next)
810 if (current->lineno_count)
812 current->line_filepos = lineno_base;
813 current->moving_line_filepos = lineno_base;
814 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
816 else
818 current->line_filepos = 0;
821 if (current->reloc_count)
823 current->rel_filepos = reloc_base;
824 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
826 else
828 current->rel_filepos = 0;
832 if ((abfd->flags & EXEC_P) != 0)
834 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
835 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
837 else
839 scn_base = bfd_coff_filhsz (abfd);
840 internal_f.f_opthdr = 0;
843 internal_f.f_nscns = 0;
845 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
846 return FALSE;
848 for (current = abfd->sections; current != NULL; current = current->next)
850 struct internal_scnhdr section;
851 struct external_scnhdr buff;
852 bfd_size_type amount;
854 internal_f.f_nscns++;
856 strncpy (section.s_name, current->name, SCNNMLEN);
858 section.s_vaddr = current->vma;
859 section.s_paddr = current->lma;
860 section.s_size = current->size;
862 /* If this section has no size or is unloadable then the scnptr
863 will be 0 too. */
864 if (current->size == 0
865 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
867 section.s_scnptr = 0;
869 else
871 section.s_scnptr = current->filepos;
874 section.s_relptr = current->rel_filepos;
875 section.s_lnnoptr = current->line_filepos;
876 section.s_nreloc = current->reloc_count;
878 section.s_nlnno = current->lineno_count;
879 if (current->reloc_count != 0)
880 hasrelocs = TRUE;
881 if (current->lineno_count != 0)
882 haslinno = TRUE;
884 section.s_flags = sec_to_styp_flags (current->name, current->flags);
886 if (!strcmp (current->name, _TEXT))
888 text_sec = current;
890 else if (!strcmp (current->name, _DATA))
892 data_sec = current;
894 else if (!strcmp (current->name, _BSS))
896 bss_sec = current;
899 amount = bfd_coff_scnhsz (abfd);
900 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
901 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
902 return FALSE;
905 internal_f.f_timdat = 0;
907 internal_f.f_flags = 0;
909 if (!hasrelocs)
910 internal_f.f_flags |= F_RELFLG;
911 if (!haslinno)
912 internal_f.f_flags |= F_LNNO;
913 if (abfd->flags & EXEC_P)
914 internal_f.f_flags |= F_EXEC;
916 /* FIXME: this is wrong for PPC_PE! */
917 if (bfd_little_endian (abfd))
918 internal_f.f_flags |= F_AR32WR;
919 else
920 internal_f.f_flags |= F_AR32W;
922 if ((abfd->flags & DYNAMIC) != 0)
923 internal_f.f_flags |= F_SHROBJ;
924 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
925 internal_f.f_flags |= F_DYNLOAD;
927 memset (&internal_a, 0, sizeof internal_a);
929 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
930 internal_a.magic = (abfd->flags & D_PAGED
931 ? RS6K_AOUTHDR_ZMAGIC
932 : (abfd->flags & WP_TEXT
933 ? RS6K_AOUTHDR_NMAGIC
934 : RS6K_AOUTHDR_OMAGIC));
936 /* FIXME: Does anybody ever set this to another value? */
937 internal_a.vstamp = 0;
939 /* Now should write relocs, strings, syms. */
940 obj_sym_filepos (abfd) = sym_base;
942 internal_f.f_symptr = 0;
943 internal_f.f_nsyms = 0;
945 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
946 backend linker, and obj_raw_syment_count is not valid until after
947 coff_write_symbols is called. */
948 if (bfd_get_symcount (abfd) != 0)
950 int firstundef;
952 if (!coff_renumber_symbols (abfd, &firstundef))
953 return FALSE;
954 coff_mangle_symbols (abfd);
955 if (! coff_write_symbols (abfd))
956 return FALSE;
957 if (! coff_write_linenumbers (abfd))
958 return FALSE;
959 if (! coff_write_relocs (abfd, firstundef))
960 return FALSE;
962 internal_f.f_symptr = sym_base;
963 internal_f.f_nsyms = bfd_get_symcount (abfd);
965 else if (obj_raw_syment_count (abfd) != 0)
967 internal_f.f_symptr = sym_base;
969 /* AIX appears to require that F_RELFLG not be set if there are
970 local symbols but no relocations. */
971 internal_f.f_flags &=~ F_RELFLG;
973 else
975 internal_f.f_flags |= F_LSYMS;
978 if (text_sec)
980 internal_a.tsize = text_sec->size;
981 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
984 if (data_sec)
986 internal_a.dsize = data_sec->size;
987 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
990 if (bss_sec)
992 internal_a.bsize = bss_sec->size;
993 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
994 internal_a.data_start = bss_sec->vma;
997 internal_a.entry = bfd_get_start_address (abfd);
998 internal_f.f_nsyms = obj_raw_syment_count (abfd);
1000 if (xcoff_data (abfd)->full_aouthdr)
1002 bfd_vma toc;
1003 asection *loader_sec;
1005 internal_a.vstamp = 1;
1007 internal_a.o_snentry = xcoff_data (abfd)->snentry;
1008 if (internal_a.o_snentry == 0)
1009 internal_a.entry = (bfd_vma) -1;
1011 if (text_sec != NULL)
1013 internal_a.o_sntext = text_sec->target_index;
1014 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
1016 else
1018 internal_a.o_sntext = 0;
1019 internal_a.o_algntext = 0;
1022 if (data_sec != NULL)
1024 internal_a.o_sndata = data_sec->target_index;
1025 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1027 else
1029 internal_a.o_sndata = 0;
1030 internal_a.o_algndata = 0;
1033 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1034 if (loader_sec != NULL)
1035 internal_a.o_snloader = loader_sec->target_index;
1036 else
1037 internal_a.o_snloader = 0;
1038 if (bss_sec != NULL)
1039 internal_a.o_snbss = bss_sec->target_index;
1040 else
1041 internal_a.o_snbss = 0;
1043 toc = xcoff_data (abfd)->toc;
1044 internal_a.o_toc = toc;
1045 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1047 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1048 if (xcoff_data (abfd)->cputype != -1)
1049 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1050 else
1052 switch (bfd_get_arch (abfd))
1054 case bfd_arch_rs6000:
1055 internal_a.o_cputype = 4;
1056 break;
1057 case bfd_arch_powerpc:
1058 if (bfd_get_mach (abfd) == bfd_mach_ppc)
1059 internal_a.o_cputype = 3;
1060 else if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
1061 internal_a.o_cputype = 2;
1062 else
1063 internal_a.o_cputype = 1;
1064 break;
1065 default:
1066 abort ();
1069 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1070 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
1073 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
1074 return FALSE;
1077 char * buff;
1078 bfd_size_type amount = bfd_coff_filhsz (abfd);
1080 buff = bfd_malloc (amount);
1081 if (buff == NULL)
1082 return FALSE;
1084 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1085 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1087 free (buff);
1089 if (amount != bfd_coff_filhsz (abfd))
1090 return FALSE;
1093 if (abfd->flags & EXEC_P)
1095 char * buff;
1096 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1098 buff = bfd_malloc (amount);
1099 if (buff == NULL)
1100 return FALSE;
1102 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
1103 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1105 free (buff);
1107 if (amount != bfd_coff_aoutsz (abfd))
1108 return FALSE;
1111 return TRUE;
1114 static bfd_boolean
1115 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
1116 val, addend, relocation, contents)
1117 bfd *input_bfd;
1118 asection *input_section;
1119 bfd *output_bfd ATTRIBUTE_UNUSED;
1120 struct internal_reloc *rel;
1121 struct internal_syment *sym ATTRIBUTE_UNUSED;
1122 struct reloc_howto_struct *howto;
1123 bfd_vma val;
1124 bfd_vma addend;
1125 bfd_vma *relocation;
1126 bfd_byte *contents;
1128 struct xcoff_link_hash_entry *h;
1129 bfd_vma section_offset;
1131 if (0 > rel->r_symndx)
1132 return FALSE;
1134 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1135 section_offset = rel->r_vaddr - input_section->vma;
1137 /* If we see an R_BR or R_RBR reloc which is jumping to global
1138 linkage code, and it is followed by an appropriate cror nop
1139 instruction, we replace the cror with ld r2,40(r1). This
1140 restores the TOC after the glink code. Contrariwise, if the
1141 call is followed by a ld r2,40(r1), but the call is not
1142 going to global linkage code, we can replace the load with a
1143 cror. */
1144 if (NULL != h
1145 && (bfd_link_hash_defined == h->root.type
1146 || bfd_link_hash_defweak == h->root.type)
1147 && section_offset + 8 <= input_section->size)
1149 bfd_byte *pnext;
1150 unsigned long next;
1152 pnext = contents + section_offset + 4;
1153 next = bfd_get_32 (input_bfd, pnext);
1155 /* The _ptrgl function is magic. It is used by the AIX compiler to call
1156 a function through a pointer. */
1157 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
1159 if (next == 0x4def7b82 /* cror 15,15,15 */
1160 || next == 0x4ffffb82 /* cror 31,31,31 */
1161 || next == 0x60000000) /* ori r0,r0,0 */
1162 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1164 else
1166 if (next == 0xe8410028) /* ld r2,40(r1) */
1167 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1170 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
1172 /* Normally, this relocation is against a defined symbol. In the
1173 case where this is a partial link and the output section offset
1174 is greater than 2^25, the linker will return an invalid error
1175 message that the relocation has been truncated. Yes it has been
1176 truncated but no it not important. For this case, disable the
1177 overflow checking. */
1178 howto->complain_on_overflow = complain_overflow_dont;
1181 /* The original PC-relative relocation is biased by -r_vaddr, so adding
1182 the value below will give the absolute target address. */
1183 *relocation = val + addend + rel->r_vaddr;
1185 howto->src_mask &= ~3;
1186 howto->dst_mask = howto->src_mask;
1188 if (h != NULL
1189 && (h->root.type == bfd_link_hash_defined
1190 || h->root.type == bfd_link_hash_defweak)
1191 && bfd_is_abs_section (h->root.u.def.section)
1192 && section_offset + 4 <= input_section->size)
1194 bfd_byte *ptr;
1195 bfd_vma insn;
1197 /* Turn the relative branch into an absolute one by setting the
1198 AA bit. */
1199 ptr = contents + section_offset;
1200 insn = bfd_get_32 (input_bfd, ptr);
1201 insn |= 2;
1202 bfd_put_32 (input_bfd, insn, ptr);
1204 /* Make the howto absolute too. */
1205 howto->pc_relative = FALSE;
1206 howto->complain_on_overflow = complain_overflow_bitfield;
1208 else
1210 /* Use a PC-relative howto and subtract the instruction's address
1211 from the target address we calculated above. */
1212 howto->pc_relative = TRUE;
1213 *relocation -= (input_section->output_section->vma
1214 + input_section->output_offset
1215 + section_offset);
1217 return TRUE;
1220 /* This is the relocation function for the PowerPC64.
1221 See xcoff_ppc_relocation_section for more information. */
1223 bfd_boolean
1224 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1225 input_section, contents, relocs, syms,
1226 sections)
1227 bfd *output_bfd;
1228 struct bfd_link_info *info;
1229 bfd *input_bfd;
1230 asection *input_section;
1231 bfd_byte *contents;
1232 struct internal_reloc *relocs;
1233 struct internal_syment *syms;
1234 asection **sections;
1236 struct internal_reloc *rel;
1237 struct internal_reloc *relend;
1239 rel = relocs;
1240 relend = rel + input_section->reloc_count;
1241 for (; rel < relend; rel++)
1243 long symndx;
1244 struct xcoff_link_hash_entry *h;
1245 struct internal_syment *sym;
1246 bfd_vma addend;
1247 bfd_vma val;
1248 struct reloc_howto_struct howto;
1249 bfd_vma relocation;
1250 bfd_vma value_to_relocate;
1251 bfd_vma address;
1252 bfd_byte *location;
1254 /* Relocation type R_REF is a special relocation type which is
1255 merely used to prevent garbage collection from occurring for
1256 the csect including the symbol which it references. */
1257 if (rel->r_type == R_REF)
1258 continue;
1260 /* howto */
1261 howto.type = rel->r_type;
1262 howto.rightshift = 0;
1263 howto.bitsize = (rel->r_size & 0x3f) + 1;
1264 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
1265 howto.pc_relative = FALSE;
1266 howto.bitpos = 0;
1267 howto.complain_on_overflow = (rel->r_size & 0x80
1268 ? complain_overflow_signed
1269 : complain_overflow_bitfield);
1270 howto.special_function = NULL;
1271 howto.name = "internal";
1272 howto.partial_inplace = TRUE;
1273 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
1274 howto.pcrel_offset = FALSE;
1276 /* symbol */
1277 val = 0;
1278 addend = 0;
1279 h = NULL;
1280 sym = NULL;
1281 symndx = rel->r_symndx;
1283 if (-1 != symndx)
1285 asection *sec;
1287 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1288 sym = syms + symndx;
1289 addend = - sym->n_value;
1291 if (NULL == h)
1293 sec = sections[symndx];
1294 /* Hack to make sure we use the right TOC anchor value
1295 if this reloc is against the TOC anchor. */
1296 if (sec->name[3] == '0'
1297 && strcmp (sec->name, ".tc0") == 0)
1298 val = xcoff_data (output_bfd)->toc;
1299 else
1300 val = (sec->output_section->vma
1301 + sec->output_offset
1302 + sym->n_value
1303 - sec->vma);
1305 else
1307 if (info->unresolved_syms_in_objects != RM_IGNORE
1308 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
1310 if (! ((*info->callbacks->undefined_symbol)
1311 (info, h->root.root.string,
1312 input_bfd, input_section,
1313 rel->r_vaddr - input_section->vma,
1314 (info->unresolved_syms_in_objects
1315 == RM_GENERATE_ERROR))))
1316 return FALSE;
1318 if (h->root.type == bfd_link_hash_defined
1319 || h->root.type == bfd_link_hash_defweak)
1321 sec = h->root.u.def.section;
1322 val = (h->root.u.def.value
1323 + sec->output_section->vma
1324 + sec->output_offset);
1326 else if (h->root.type == bfd_link_hash_common)
1328 sec = h->root.u.c.p->section;
1329 val = (sec->output_section->vma
1330 + sec->output_offset);
1332 else
1334 BFD_ASSERT (info->relocatable
1335 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
1336 || (h->flags & XCOFF_IMPORT) != 0);
1341 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
1342 || !((*xcoff64_calculate_relocation[rel->r_type])
1343 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1344 addend, &relocation, contents)))
1345 return FALSE;
1347 /* address */
1348 address = rel->r_vaddr - input_section->vma;
1349 location = contents + address;
1351 if (address > input_section->size)
1352 abort ();
1354 /* Get the value we are going to relocate. */
1355 if (1 == howto.size)
1356 value_to_relocate = bfd_get_16 (input_bfd, location);
1357 else if (2 == howto.size)
1358 value_to_relocate = bfd_get_32 (input_bfd, location);
1359 else
1360 value_to_relocate = bfd_get_64 (input_bfd, location);
1362 /* overflow.
1364 FIXME: We may drop bits during the addition
1365 which we don't check for. We must either check at every single
1366 operation, which would be tedious, or we must do the computations
1367 in a type larger than bfd_vma, which would be inefficient. */
1369 if ((unsigned int) howto.complain_on_overflow
1370 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1371 abort ();
1373 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1374 (input_bfd, value_to_relocate, relocation, &howto)))
1376 const char *name;
1377 char buf[SYMNMLEN + 1];
1378 char reloc_type_name[10];
1380 if (symndx == -1)
1382 name = "*ABS*";
1384 else if (h != NULL)
1386 name = NULL;
1388 else
1390 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1391 if (name == NULL)
1392 name = "UNKNOWN";
1394 sprintf (reloc_type_name, "0x%02x", rel->r_type);
1396 if (! ((*info->callbacks->reloc_overflow)
1397 (info, (h ? &h->root : NULL), name, reloc_type_name,
1398 (bfd_vma) 0, input_bfd, input_section,
1399 rel->r_vaddr - input_section->vma)))
1400 return FALSE;
1403 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
1404 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1405 | (((value_to_relocate & howto.src_mask)
1406 + relocation) & howto.dst_mask));
1408 /* Put the value back in the object file. */
1409 if (1 == howto.size)
1410 bfd_put_16 (input_bfd, value_to_relocate, location);
1411 else if (2 == howto.size)
1412 bfd_put_32 (input_bfd, value_to_relocate, location);
1413 else
1414 bfd_put_64 (input_bfd, value_to_relocate, location);
1417 return TRUE;
1421 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1422 bitsize and whether they are signed or not, along with a
1423 conventional type. This table is for the types, which are used for
1424 different algorithms for putting in the reloc. Many of these
1425 relocs need special_function entries, which I have not written. */
1427 reloc_howto_type xcoff64_howto_table[] =
1429 /* Standard 64 bit relocation. */
1430 HOWTO (R_POS, /* type */
1431 0, /* rightshift */
1432 4, /* size (0 = byte, 1 = short, 2 = long) */
1433 64, /* bitsize */
1434 FALSE, /* pc_relative */
1435 0, /* bitpos */
1436 complain_overflow_bitfield, /* complain_on_overflow */
1437 0, /* special_function */
1438 "R_POS_64", /* name */
1439 TRUE, /* partial_inplace */
1440 MINUS_ONE, /* src_mask */
1441 MINUS_ONE, /* dst_mask */
1442 FALSE), /* pcrel_offset */
1444 /* 64 bit relocation, but store negative value. */
1445 HOWTO (R_NEG, /* type */
1446 0, /* rightshift */
1447 -4, /* size (0 = byte, 1 = short, 2 = long) */
1448 64, /* bitsize */
1449 FALSE, /* pc_relative */
1450 0, /* bitpos */
1451 complain_overflow_bitfield, /* complain_on_overflow */
1452 0, /* special_function */
1453 "R_NEG", /* name */
1454 TRUE, /* partial_inplace */
1455 MINUS_ONE, /* src_mask */
1456 MINUS_ONE, /* dst_mask */
1457 FALSE), /* pcrel_offset */
1459 /* 32 bit PC relative relocation. */
1460 HOWTO (R_REL, /* type */
1461 0, /* rightshift */
1462 2, /* size (0 = byte, 1 = short, 2 = long) */
1463 32, /* bitsize */
1464 TRUE, /* pc_relative */
1465 0, /* bitpos */
1466 complain_overflow_signed, /* complain_on_overflow */
1467 0, /* special_function */
1468 "R_REL", /* name */
1469 TRUE, /* partial_inplace */
1470 0xffffffff, /* src_mask */
1471 0xffffffff, /* dst_mask */
1472 FALSE), /* pcrel_offset */
1474 /* 16 bit TOC relative relocation. */
1475 HOWTO (R_TOC, /* type */
1476 0, /* rightshift */
1477 1, /* size (0 = byte, 1 = short, 2 = long) */
1478 16, /* bitsize */
1479 FALSE, /* pc_relative */
1480 0, /* bitpos */
1481 complain_overflow_bitfield, /* complain_on_overflow */
1482 0, /* special_function */
1483 "R_TOC", /* name */
1484 TRUE, /* partial_inplace */
1485 0xffff, /* src_mask */
1486 0xffff, /* dst_mask */
1487 FALSE), /* pcrel_offset */
1489 /* I don't really know what this is. */
1490 HOWTO (R_RTB, /* type */
1491 1, /* rightshift */
1492 2, /* size (0 = byte, 1 = short, 2 = long) */
1493 32, /* bitsize */
1494 FALSE, /* pc_relative */
1495 0, /* bitpos */
1496 complain_overflow_bitfield, /* complain_on_overflow */
1497 0, /* special_function */
1498 "R_RTB", /* name */
1499 TRUE, /* partial_inplace */
1500 0xffffffff, /* src_mask */
1501 0xffffffff, /* dst_mask */
1502 FALSE), /* pcrel_offset */
1504 /* External TOC relative symbol. */
1505 HOWTO (R_GL, /* type */
1506 0, /* rightshift */
1507 1, /* size (0 = byte, 1 = short, 2 = long) */
1508 16, /* bitsize */
1509 FALSE, /* pc_relative */
1510 0, /* bitpos */
1511 complain_overflow_bitfield, /* complain_on_overflow */
1512 0, /* special_function */
1513 "R_GL", /* name */
1514 TRUE, /* partial_inplace */
1515 0xffff, /* src_mask */
1516 0xffff, /* dst_mask */
1517 FALSE), /* pcrel_offset */
1519 /* Local TOC relative symbol. */
1520 HOWTO (R_TCL, /* type */
1521 0, /* rightshift */
1522 1, /* size (0 = byte, 1 = short, 2 = long) */
1523 16, /* bitsize */
1524 FALSE, /* pc_relative */
1525 0, /* bitpos */
1526 complain_overflow_bitfield, /* complain_on_overflow */
1527 0, /* special_function */
1528 "R_TCL", /* name */
1529 TRUE, /* partial_inplace */
1530 0xffff, /* src_mask */
1531 0xffff, /* dst_mask */
1532 FALSE), /* pcrel_offset */
1534 EMPTY_HOWTO (7),
1536 /* Non modifiable absolute branch. */
1537 HOWTO (R_BA, /* type */
1538 0, /* rightshift */
1539 2, /* size (0 = byte, 1 = short, 2 = long) */
1540 26, /* bitsize */
1541 FALSE, /* pc_relative */
1542 0, /* bitpos */
1543 complain_overflow_bitfield, /* complain_on_overflow */
1544 0, /* special_function */
1545 "R_BA_26", /* name */
1546 TRUE, /* partial_inplace */
1547 0x03fffffc, /* src_mask */
1548 0x03fffffc, /* dst_mask */
1549 FALSE), /* pcrel_offset */
1551 EMPTY_HOWTO (9),
1553 /* Non modifiable relative branch. */
1554 HOWTO (R_BR, /* type */
1555 0, /* rightshift */
1556 2, /* size (0 = byte, 1 = short, 2 = long) */
1557 26, /* bitsize */
1558 TRUE, /* pc_relative */
1559 0, /* bitpos */
1560 complain_overflow_signed, /* complain_on_overflow */
1561 0, /* special_function */
1562 "R_BR", /* name */
1563 TRUE, /* partial_inplace */
1564 0x03fffffc, /* src_mask */
1565 0x03fffffc, /* dst_mask */
1566 FALSE), /* pcrel_offset */
1568 EMPTY_HOWTO (0xb),
1570 /* Indirect load. */
1571 HOWTO (R_RL, /* type */
1572 0, /* rightshift */
1573 1, /* size (0 = byte, 1 = short, 2 = long) */
1574 16, /* bitsize */
1575 FALSE, /* pc_relative */
1576 0, /* bitpos */
1577 complain_overflow_bitfield, /* complain_on_overflow */
1578 0, /* special_function */
1579 "R_RL", /* name */
1580 TRUE, /* partial_inplace */
1581 0xffff, /* src_mask */
1582 0xffff, /* dst_mask */
1583 FALSE), /* pcrel_offset */
1585 /* Load address. */
1586 HOWTO (R_RLA, /* type */
1587 0, /* rightshift */
1588 1, /* size (0 = byte, 1 = short, 2 = long) */
1589 16, /* bitsize */
1590 FALSE, /* pc_relative */
1591 0, /* bitpos */
1592 complain_overflow_bitfield, /* complain_on_overflow */
1593 0, /* special_function */
1594 "R_RLA", /* name */
1595 TRUE, /* partial_inplace */
1596 0xffff, /* src_mask */
1597 0xffff, /* dst_mask */
1598 FALSE), /* pcrel_offset */
1600 EMPTY_HOWTO (0xe),
1602 /* Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
1603 HOWTO (R_REF, /* type */
1604 0, /* rightshift */
1605 0, /* size (0 = byte, 1 = short, 2 = long) */
1606 1, /* bitsize */
1607 FALSE, /* pc_relative */
1608 0, /* bitpos */
1609 complain_overflow_dont, /* complain_on_overflow */
1610 0, /* special_function */
1611 "R_REF", /* name */
1612 FALSE, /* partial_inplace */
1613 0, /* src_mask */
1614 0, /* dst_mask */
1615 FALSE), /* pcrel_offset */
1617 EMPTY_HOWTO (0x10),
1618 EMPTY_HOWTO (0x11),
1620 /* TOC relative indirect load. */
1621 HOWTO (R_TRL, /* type */
1622 0, /* rightshift */
1623 1, /* size (0 = byte, 1 = short, 2 = long) */
1624 16, /* bitsize */
1625 FALSE, /* pc_relative */
1626 0, /* bitpos */
1627 complain_overflow_bitfield, /* complain_on_overflow */
1628 0, /* special_function */
1629 "R_TRL", /* name */
1630 TRUE, /* partial_inplace */
1631 0xffff, /* src_mask */
1632 0xffff, /* dst_mask */
1633 FALSE), /* pcrel_offset */
1635 /* TOC relative load address. */
1636 HOWTO (R_TRLA, /* type */
1637 0, /* rightshift */
1638 1, /* size (0 = byte, 1 = short, 2 = long) */
1639 16, /* bitsize */
1640 FALSE, /* pc_relative */
1641 0, /* bitpos */
1642 complain_overflow_bitfield, /* complain_on_overflow */
1643 0, /* special_function */
1644 "R_TRLA", /* name */
1645 TRUE, /* partial_inplace */
1646 0xffff, /* src_mask */
1647 0xffff, /* dst_mask */
1648 FALSE), /* pcrel_offset */
1650 /* Modifiable relative branch. */
1651 HOWTO (R_RRTBI, /* type */
1652 1, /* rightshift */
1653 2, /* size (0 = byte, 1 = short, 2 = long) */
1654 32, /* bitsize */
1655 FALSE, /* pc_relative */
1656 0, /* bitpos */
1657 complain_overflow_bitfield, /* complain_on_overflow */
1658 0, /* special_function */
1659 "R_RRTBI", /* name */
1660 TRUE, /* partial_inplace */
1661 0xffffffff, /* src_mask */
1662 0xffffffff, /* dst_mask */
1663 FALSE), /* pcrel_offset */
1665 /* Modifiable absolute branch. */
1666 HOWTO (R_RRTBA, /* type */
1667 1, /* rightshift */
1668 2, /* size (0 = byte, 1 = short, 2 = long) */
1669 32, /* bitsize */
1670 FALSE, /* pc_relative */
1671 0, /* bitpos */
1672 complain_overflow_bitfield, /* complain_on_overflow */
1673 0, /* special_function */
1674 "R_RRTBA", /* name */
1675 TRUE, /* partial_inplace */
1676 0xffffffff, /* src_mask */
1677 0xffffffff, /* dst_mask */
1678 FALSE), /* pcrel_offset */
1680 /* Modifiable call absolute indirect. */
1681 HOWTO (R_CAI, /* type */
1682 0, /* rightshift */
1683 1, /* size (0 = byte, 1 = short, 2 = long) */
1684 16, /* bitsize */
1685 FALSE, /* pc_relative */
1686 0, /* bitpos */
1687 complain_overflow_bitfield, /* complain_on_overflow */
1688 0, /* special_function */
1689 "R_CAI", /* name */
1690 TRUE, /* partial_inplace */
1691 0xffff, /* src_mask */
1692 0xffff, /* dst_mask */
1693 FALSE), /* pcrel_offset */
1695 /* Modifiable call relative. */
1696 HOWTO (R_CREL, /* type */
1697 0, /* rightshift */
1698 1, /* size (0 = byte, 1 = short, 2 = long) */
1699 16, /* bitsize */
1700 FALSE, /* pc_relative */
1701 0, /* bitpos */
1702 complain_overflow_bitfield, /* complain_on_overflow */
1703 0, /* special_function */
1704 "R_CREL", /* name */
1705 TRUE, /* partial_inplace */
1706 0xffff, /* src_mask */
1707 0xffff, /* dst_mask */
1708 FALSE), /* pcrel_offset */
1710 /* Modifiable branch absolute. */
1711 HOWTO (R_RBA, /* type */
1712 0, /* rightshift */
1713 2, /* size (0 = byte, 1 = short, 2 = long) */
1714 26, /* bitsize */
1715 FALSE, /* pc_relative */
1716 0, /* bitpos */
1717 complain_overflow_bitfield, /* complain_on_overflow */
1718 0, /* special_function */
1719 "R_RBA", /* name */
1720 TRUE, /* partial_inplace */
1721 0x03fffffc, /* src_mask */
1722 0x03fffffc, /* dst_mask */
1723 FALSE), /* pcrel_offset */
1725 /* Modifiable branch absolute. */
1726 HOWTO (R_RBAC, /* type */
1727 0, /* rightshift */
1728 2, /* size (0 = byte, 1 = short, 2 = long) */
1729 32, /* bitsize */
1730 FALSE, /* pc_relative */
1731 0, /* bitpos */
1732 complain_overflow_bitfield, /* complain_on_overflow */
1733 0, /* special_function */
1734 "R_RBAC", /* name */
1735 TRUE, /* partial_inplace */
1736 0xffffffff, /* src_mask */
1737 0xffffffff, /* dst_mask */
1738 FALSE), /* pcrel_offset */
1740 /* Modifiable branch relative. */
1741 HOWTO (R_RBR, /* type */
1742 0, /* rightshift */
1743 2, /* size (0 = byte, 1 = short, 2 = long) */
1744 26, /* bitsize */
1745 FALSE, /* pc_relative */
1746 0, /* bitpos */
1747 complain_overflow_signed, /* complain_on_overflow */
1748 0, /* special_function */
1749 "R_RBR_26", /* name */
1750 TRUE, /* partial_inplace */
1751 0x03fffffc, /* src_mask */
1752 0x03fffffc, /* dst_mask */
1753 FALSE), /* pcrel_offset */
1755 /* Modifiable branch absolute. */
1756 HOWTO (R_RBRC, /* type */
1757 0, /* rightshift */
1758 1, /* size (0 = byte, 1 = short, 2 = long) */
1759 16, /* bitsize */
1760 FALSE, /* pc_relative */
1761 0, /* bitpos */
1762 complain_overflow_bitfield, /* complain_on_overflow */
1763 0, /* special_function */
1764 "R_RBRC", /* name */
1765 TRUE, /* partial_inplace */
1766 0xffff, /* src_mask */
1767 0xffff, /* dst_mask */
1768 FALSE), /* pcrel_offset */
1770 HOWTO (R_POS, /* type */
1771 0, /* rightshift */
1772 2, /* size (0 = byte, 1 = short, 2 = long) */
1773 32, /* bitsize */
1774 FALSE, /* pc_relative */
1775 0, /* bitpos */
1776 complain_overflow_bitfield, /* complain_on_overflow */
1777 0, /* special_function */
1778 "R_POS_32", /* name */
1779 TRUE, /* partial_inplace */
1780 0xffffffff, /* src_mask */
1781 0xffffffff, /* dst_mask */
1782 FALSE), /* pcrel_offset */
1784 /* 16 bit Non modifiable absolute branch. */
1785 HOWTO (R_BA, /* type */
1786 0, /* rightshift */
1787 1, /* size (0 = byte, 1 = short, 2 = long) */
1788 16, /* bitsize */
1789 FALSE, /* pc_relative */
1790 0, /* bitpos */
1791 complain_overflow_bitfield, /* complain_on_overflow */
1792 0, /* special_function */
1793 "R_BA_16", /* name */
1794 TRUE, /* partial_inplace */
1795 0xfffc, /* src_mask */
1796 0xfffc, /* dst_mask */
1797 FALSE), /* pcrel_offset */
1799 /* Modifiable branch relative. */
1800 HOWTO (R_RBR, /* type */
1801 0, /* rightshift */
1802 1, /* size (0 = byte, 1 = short, 2 = long) */
1803 16, /* bitsize */
1804 FALSE, /* pc_relative */
1805 0, /* bitpos */
1806 complain_overflow_signed, /* complain_on_overflow */
1807 0, /* special_function */
1808 "R_RBR_16", /* name */
1809 TRUE, /* partial_inplace */
1810 0xffff, /* src_mask */
1811 0xffff, /* dst_mask */
1812 FALSE), /* pcrel_offset */
1814 /* Modifiable branch absolute. */
1815 HOWTO (R_RBA, /* type */
1816 0, /* rightshift */
1817 1, /* size (0 = byte, 1 = short, 2 = long) */
1818 16, /* bitsize */
1819 FALSE, /* pc_relative */
1820 0, /* bitpos */
1821 complain_overflow_bitfield, /* complain_on_overflow */
1822 0, /* special_function */
1823 "R_RBA_16", /* name */
1824 TRUE, /* partial_inplace */
1825 0xffff, /* src_mask */
1826 0xffff, /* dst_mask */
1827 FALSE), /* pcrel_offset */
1831 void
1832 xcoff64_rtype2howto (relent, internal)
1833 arelent *relent;
1834 struct internal_reloc *internal;
1836 if (internal->r_type > R_RBRC)
1837 abort ();
1839 /* Default howto layout works most of the time */
1840 relent->howto = &xcoff64_howto_table[internal->r_type];
1842 /* Special case some 16 bit reloc */
1843 if (15 == (internal->r_size & 0x3f))
1845 if (R_BA == internal->r_type)
1846 relent->howto = &xcoff64_howto_table[0x1d];
1847 else if (R_RBR == internal->r_type)
1848 relent->howto = &xcoff64_howto_table[0x1e];
1849 else if (R_RBA == internal->r_type)
1850 relent->howto = &xcoff64_howto_table[0x1f];
1852 /* Special case 32 bit */
1853 else if (31 == (internal->r_size & 0x3f))
1855 if (R_POS == internal->r_type)
1856 relent->howto = &xcoff64_howto_table[0x1c];
1859 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1860 relocation, as well as indicating whether it is signed or not.
1861 Doublecheck that the relocation information gathered from the
1862 type matches this information. The bitsize is not significant
1863 for R_REF relocs. */
1864 if (relent->howto->dst_mask != 0
1865 && (relent->howto->bitsize
1866 != ((unsigned int) internal->r_size & 0x3f) + 1))
1867 abort ();
1870 reloc_howto_type *
1871 xcoff64_reloc_type_lookup (abfd, code)
1872 bfd *abfd ATTRIBUTE_UNUSED;
1873 bfd_reloc_code_real_type code;
1875 switch (code)
1877 case BFD_RELOC_PPC_B26:
1878 return &xcoff64_howto_table[0xa];
1879 case BFD_RELOC_PPC_BA16:
1880 return &xcoff64_howto_table[0x1d];
1881 case BFD_RELOC_PPC_BA26:
1882 return &xcoff64_howto_table[8];
1883 case BFD_RELOC_PPC_TOC16:
1884 return &xcoff64_howto_table[3];
1885 case BFD_RELOC_32:
1886 case BFD_RELOC_CTOR:
1887 return &xcoff64_howto_table[0x1c];
1888 case BFD_RELOC_64:
1889 return &xcoff64_howto_table[0];
1890 case BFD_RELOC_NONE:
1891 return &xcoff64_howto_table[0xf];
1892 default:
1893 return NULL;
1897 static reloc_howto_type *
1898 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1899 const char *r_name)
1901 unsigned int i;
1903 for (i = 0;
1904 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1905 i++)
1906 if (xcoff64_howto_table[i].name != NULL
1907 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1908 return &xcoff64_howto_table[i];
1910 return NULL;
1913 /* Read in the armap of an XCOFF archive. */
1915 static bfd_boolean
1916 xcoff64_slurp_armap (abfd)
1917 bfd *abfd;
1919 file_ptr off;
1920 size_t namlen;
1921 bfd_size_type sz, amt;
1922 bfd_byte *contents, *cend;
1923 bfd_vma c, i;
1924 carsym *arsym;
1925 bfd_byte *p;
1926 file_ptr pos;
1928 /* This is for the new format. */
1929 struct xcoff_ar_hdr_big hdr;
1931 if (xcoff_ardata (abfd) == NULL)
1933 bfd_has_map (abfd) = FALSE;
1934 return TRUE;
1937 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1938 (const char **) NULL, 10);
1939 if (off == 0)
1941 bfd_has_map (abfd) = FALSE;
1942 return TRUE;
1945 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1946 return FALSE;
1948 /* The symbol table starts with a normal archive header. */
1949 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1950 != SIZEOF_AR_HDR_BIG)
1951 return FALSE;
1953 /* Skip the name (normally empty). */
1954 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1955 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1956 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1957 return FALSE;
1959 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1961 /* Read in the entire symbol table. */
1962 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1963 if (contents == NULL)
1964 return FALSE;
1965 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1966 return FALSE;
1968 /* The symbol table starts with an eight byte count. */
1969 c = H_GET_64 (abfd, contents);
1971 if (c * 8 >= sz)
1973 bfd_set_error (bfd_error_bad_value);
1974 return FALSE;
1976 amt = c;
1977 amt *= sizeof (carsym);
1978 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1979 if (bfd_ardata (abfd)->symdefs == NULL)
1980 return FALSE;
1982 /* After the count comes a list of eight byte file offsets. */
1983 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1984 i < c;
1985 ++i, ++arsym, p += 8)
1986 arsym->file_offset = H_GET_64 (abfd, p);
1988 /* After the file offsets come null terminated symbol names. */
1989 cend = contents + sz;
1990 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1991 i < c;
1992 ++i, ++arsym, p += strlen ((char *) p) + 1)
1994 if (p >= cend)
1996 bfd_set_error (bfd_error_bad_value);
1997 return FALSE;
1999 arsym->name = (char *) p;
2002 bfd_ardata (abfd)->symdef_count = c;
2003 bfd_has_map (abfd) = TRUE;
2005 return TRUE;
2009 /* See if this is an NEW XCOFF archive. */
2011 static const bfd_target *
2012 xcoff64_archive_p (abfd)
2013 bfd *abfd;
2015 struct artdata *tdata_hold;
2016 char magic[SXCOFFARMAG];
2017 /* This is the new format. */
2018 struct xcoff_ar_file_hdr_big hdr;
2019 bfd_size_type amt = SXCOFFARMAG;
2021 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2023 if (bfd_get_error () != bfd_error_system_call)
2024 bfd_set_error (bfd_error_wrong_format);
2025 return NULL;
2028 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2030 bfd_set_error (bfd_error_wrong_format);
2031 return NULL;
2034 /* Copy over the magic string. */
2035 memcpy (hdr.magic, magic, SXCOFFARMAG);
2037 /* Now read the rest of the file header. */
2038 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2039 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
2041 if (bfd_get_error () != bfd_error_system_call)
2042 bfd_set_error (bfd_error_wrong_format);
2043 return NULL;
2046 tdata_hold = bfd_ardata (abfd);
2048 amt = sizeof (struct artdata);
2049 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2050 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2051 goto error_ret_restore;
2053 /* Already cleared by bfd_zalloc above.
2054 bfd_ardata (abfd)->cache = NULL;
2055 bfd_ardata (abfd)->archive_head = NULL;
2056 bfd_ardata (abfd)->symdefs = NULL;
2057 bfd_ardata (abfd)->extended_names = NULL;
2058 bfd_ardata (abfd)->extended_names_size = 0; */
2059 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2060 (const char **) NULL,
2061 10);
2063 amt = SIZEOF_AR_FILE_HDR_BIG;
2064 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2065 if (bfd_ardata (abfd)->tdata == NULL)
2066 goto error_ret;
2068 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2070 if (! xcoff64_slurp_armap (abfd))
2072 error_ret:
2073 bfd_release (abfd, bfd_ardata (abfd));
2074 error_ret_restore:
2075 bfd_ardata (abfd) = tdata_hold;
2076 return NULL;
2079 return abfd->xvec;
2083 /* Open the next element in an XCOFF archive. */
2085 static bfd *
2086 xcoff64_openr_next_archived_file (archive, last_file)
2087 bfd *archive;
2088 bfd *last_file;
2090 bfd_vma filestart;
2092 if ((xcoff_ardata (archive) == NULL)
2093 || ! xcoff_big_format_p (archive))
2095 bfd_set_error (bfd_error_invalid_operation);
2096 return NULL;
2099 if (last_file == NULL)
2101 filestart = bfd_ardata (archive)->first_file_filepos;
2103 else
2105 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2106 (const char **) NULL, 10);
2109 if (filestart == 0
2110 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2111 (const char **) NULL, 10)
2112 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2113 (const char **) NULL, 10))
2115 bfd_set_error (bfd_error_no_more_archived_files);
2116 return NULL;
2119 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2122 /* We can't use the usual coff_sizeof_headers routine, because AIX
2123 always uses an a.out header. */
2125 static int
2126 xcoff64_sizeof_headers (bfd *abfd,
2127 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2129 int size;
2131 size = bfd_coff_filhsz (abfd);
2133 /* Don't think the small aout header can be used since some of the
2134 old elements have been reordered past the end of the old coff
2135 small aout size. */
2137 if (xcoff_data (abfd)->full_aouthdr)
2138 size += bfd_coff_aoutsz (abfd);
2140 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2141 return size;
2146 static asection *
2147 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2148 bfd *abfd;
2149 union internal_auxent *aux;
2150 const char *symbol_name;
2152 asection *return_value = NULL;
2154 /* Changes from 32 :
2155 .sv == 8, is only for 32 bit programs
2156 .ti == 12 and .tb == 13 are now reserved. */
2157 static const char *names[19] =
2159 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2160 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2161 ".td", ".sv64", ".sv3264"
2164 if ((19 >= aux->x_csect.x_smclas)
2165 && (NULL != names[aux->x_csect.x_smclas]))
2168 return_value = bfd_make_section_anyway
2169 (abfd, names[aux->x_csect.x_smclas]);
2172 else
2174 (*_bfd_error_handler)
2175 (_("%B: symbol `%s' has unrecognized smclas %d"),
2176 abfd, symbol_name, aux->x_csect.x_smclas);
2177 bfd_set_error (bfd_error_bad_value);
2180 return return_value;
2183 static bfd_boolean
2184 xcoff64_is_lineno_count_overflow (abfd, value)
2185 bfd *abfd ATTRIBUTE_UNUSED;
2186 bfd_vma value ATTRIBUTE_UNUSED;
2188 return FALSE;
2191 static bfd_boolean
2192 xcoff64_is_reloc_count_overflow (abfd, value)
2193 bfd *abfd ATTRIBUTE_UNUSED;
2194 bfd_vma value ATTRIBUTE_UNUSED;
2196 return FALSE;
2199 static bfd_vma
2200 xcoff64_loader_symbol_offset (abfd, ldhdr)
2201 bfd *abfd ATTRIBUTE_UNUSED;
2202 struct internal_ldhdr *ldhdr;
2204 return (ldhdr->l_symoff);
2207 static bfd_vma
2208 xcoff64_loader_reloc_offset (abfd, ldhdr)
2209 bfd *abfd ATTRIBUTE_UNUSED;
2210 struct internal_ldhdr *ldhdr;
2212 return (ldhdr->l_rldoff);
2215 static bfd_boolean
2216 xcoff64_bad_format_hook (abfd, filehdr)
2217 bfd * abfd;
2218 PTR filehdr;
2220 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2222 /* Check flavor first. */
2223 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2224 return FALSE;
2226 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2227 return FALSE;
2229 return TRUE;
2232 static bfd_boolean
2233 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2234 bfd *abfd;
2235 const char *init;
2236 const char *fini;
2237 bfd_boolean rtld;
2239 bfd_byte filehdr_ext[FILHSZ];
2240 bfd_byte scnhdr_ext[SCNHSZ * 3];
2241 bfd_byte syment_ext[SYMESZ * 10];
2242 bfd_byte reloc_ext[RELSZ * 3];
2243 bfd_byte *data_buffer;
2244 bfd_size_type data_buffer_size;
2245 bfd_byte *string_table, *st_tmp;
2246 bfd_size_type string_table_size;
2247 bfd_vma val;
2248 size_t initsz, finisz;
2249 struct internal_filehdr filehdr;
2250 struct internal_scnhdr text_scnhdr;
2251 struct internal_scnhdr data_scnhdr;
2252 struct internal_scnhdr bss_scnhdr;
2253 struct internal_syment syment;
2254 union internal_auxent auxent;
2255 struct internal_reloc reloc;
2257 char *text_name = ".text";
2258 char *data_name = ".data";
2259 char *bss_name = ".bss";
2260 char *rtinit_name = "__rtinit";
2261 char *rtld_name = "__rtld";
2263 if (! bfd_xcoff_rtinit_size (abfd))
2264 return FALSE;
2266 initsz = (init == NULL ? 0 : 1 + strlen (init));
2267 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2269 /* File header. */
2270 memset (filehdr_ext, 0, FILHSZ);
2271 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2272 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2273 filehdr.f_nscns = 3;
2274 filehdr.f_timdat = 0;
2275 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2276 filehdr.f_symptr = 0; /* set below */
2277 filehdr.f_opthdr = 0;
2278 filehdr.f_flags = 0;
2280 /* Section headers. */
2281 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2283 /* Text. */
2284 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2285 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2286 text_scnhdr.s_paddr = 0;
2287 text_scnhdr.s_vaddr = 0;
2288 text_scnhdr.s_size = 0;
2289 text_scnhdr.s_scnptr = 0;
2290 text_scnhdr.s_relptr = 0;
2291 text_scnhdr.s_lnnoptr = 0;
2292 text_scnhdr.s_nreloc = 0;
2293 text_scnhdr.s_nlnno = 0;
2294 text_scnhdr.s_flags = STYP_TEXT;
2296 /* Data. */
2297 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2298 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2299 data_scnhdr.s_paddr = 0;
2300 data_scnhdr.s_vaddr = 0;
2301 data_scnhdr.s_size = 0; /* set below */
2302 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2303 data_scnhdr.s_relptr = 0; /* set below */
2304 data_scnhdr.s_lnnoptr = 0;
2305 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2306 data_scnhdr.s_nlnno = 0;
2307 data_scnhdr.s_flags = STYP_DATA;
2309 /* Bss. */
2310 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2311 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2312 bss_scnhdr.s_paddr = 0; /* set below */
2313 bss_scnhdr.s_vaddr = 0; /* set below */
2314 bss_scnhdr.s_size = 0; /* set below */
2315 bss_scnhdr.s_scnptr = 0;
2316 bss_scnhdr.s_relptr = 0;
2317 bss_scnhdr.s_lnnoptr = 0;
2318 bss_scnhdr.s_nreloc = 0;
2319 bss_scnhdr.s_nlnno = 0;
2320 bss_scnhdr.s_flags = STYP_BSS;
2322 /* .data
2323 0x0000 0x00000000 : rtl
2324 0x0004 0x00000000 :
2325 0x0008 0x00000018 : offset to init, or 0
2326 0x000C 0x00000038 : offset to fini, or 0
2327 0x0010 0x00000010 : size of descriptor
2328 0x0014 0x00000000 : pad
2329 0x0018 0x00000000 : init, needs a reloc
2330 0x001C 0x00000000 :
2331 0x0020 0x00000058 : offset to init name
2332 0x0024 0x00000000 : flags, padded to a word
2333 0x0028 0x00000000 : empty init
2334 0x002C 0x00000000 :
2335 0x0030 0x00000000 :
2336 0x0034 0x00000000 :
2337 0x0038 0x00000000 : fini, needs a reloc
2338 0x003C 0x00000000 :
2339 0x0040 0x00000??? : offset to fini name
2340 0x0044 0x00000000 : flags, padded to a word
2341 0x0048 0x00000000 : empty fini
2342 0x004C 0x00000000 :
2343 0x0050 0x00000000 :
2344 0x0054 0x00000000 :
2345 0x0058 init name
2346 0x0058 + initsz fini name */
2348 data_buffer_size = 0x0058 + initsz + finisz;
2349 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2350 data_buffer = NULL;
2351 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2352 if (data_buffer == NULL)
2353 return FALSE;
2355 if (initsz)
2357 val = 0x18;
2358 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2359 val = 0x58;
2360 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2361 memcpy (&data_buffer[val], init, initsz);
2364 if (finisz)
2366 val = 0x38;
2367 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2368 val = 0x58 + initsz;
2369 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2370 memcpy (&data_buffer[val], fini, finisz);
2373 val = 0x10;
2374 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2375 data_scnhdr.s_size = data_buffer_size;
2376 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2378 /* String table. */
2379 string_table_size = 4;
2380 string_table_size += strlen (data_name) + 1;
2381 string_table_size += strlen (rtinit_name) + 1;
2382 string_table_size += initsz;
2383 string_table_size += finisz;
2384 if (rtld)
2385 string_table_size += strlen (rtld_name) + 1;
2387 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2388 if (string_table == NULL)
2389 return FALSE;
2391 val = string_table_size;
2392 bfd_put_32 (abfd, val, &string_table[0]);
2393 st_tmp = string_table + 4;
2395 /* symbols
2396 0. .data csect
2397 2. __rtinit
2398 4. init function
2399 6. fini function
2400 8. __rtld */
2401 memset (syment_ext, 0, 10 * SYMESZ);
2402 memset (reloc_ext, 0, 3 * RELSZ);
2404 /* .data csect */
2405 memset (&syment, 0, sizeof (struct internal_syment));
2406 memset (&auxent, 0, sizeof (union internal_auxent));
2408 syment._n._n_n._n_offset = st_tmp - string_table;
2409 memcpy (st_tmp, data_name, strlen (data_name));
2410 st_tmp += strlen (data_name) + 1;
2412 syment.n_scnum = 2;
2413 syment.n_sclass = C_HIDEXT;
2414 syment.n_numaux = 1;
2415 auxent.x_csect.x_scnlen.l = data_buffer_size;
2416 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2417 auxent.x_csect.x_smclas = XMC_RW;
2418 bfd_coff_swap_sym_out (abfd, &syment,
2419 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2420 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2421 syment.n_numaux,
2422 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2423 filehdr.f_nsyms += 2;
2425 /* __rtinit */
2426 memset (&syment, 0, sizeof (struct internal_syment));
2427 memset (&auxent, 0, sizeof (union internal_auxent));
2428 syment._n._n_n._n_offset = st_tmp - string_table;
2429 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2430 st_tmp += strlen (rtinit_name) + 1;
2432 syment.n_scnum = 2;
2433 syment.n_sclass = C_EXT;
2434 syment.n_numaux = 1;
2435 auxent.x_csect.x_smtyp = XTY_LD;
2436 auxent.x_csect.x_smclas = XMC_RW;
2437 bfd_coff_swap_sym_out (abfd, &syment,
2438 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2439 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2440 syment.n_numaux,
2441 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2442 filehdr.f_nsyms += 2;
2444 /* Init. */
2445 if (initsz)
2447 memset (&syment, 0, sizeof (struct internal_syment));
2448 memset (&auxent, 0, sizeof (union internal_auxent));
2450 syment._n._n_n._n_offset = st_tmp - string_table;
2451 memcpy (st_tmp, init, initsz);
2452 st_tmp += initsz;
2454 syment.n_sclass = C_EXT;
2455 syment.n_numaux = 1;
2456 bfd_coff_swap_sym_out (abfd, &syment,
2457 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2458 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2459 syment.n_numaux,
2460 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2461 /* Reloc. */
2462 memset (&reloc, 0, sizeof (struct internal_reloc));
2463 reloc.r_vaddr = 0x0018;
2464 reloc.r_symndx = filehdr.f_nsyms;
2465 reloc.r_type = R_POS;
2466 reloc.r_size = 63;
2467 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2469 filehdr.f_nsyms += 2;
2470 data_scnhdr.s_nreloc += 1;
2473 /* Finit. */
2474 if (finisz)
2476 memset (&syment, 0, sizeof (struct internal_syment));
2477 memset (&auxent, 0, sizeof (union internal_auxent));
2479 syment._n._n_n._n_offset = st_tmp - string_table;
2480 memcpy (st_tmp, fini, finisz);
2481 st_tmp += finisz;
2483 syment.n_sclass = C_EXT;
2484 syment.n_numaux = 1;
2485 bfd_coff_swap_sym_out (abfd, &syment,
2486 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2487 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2488 syment.n_numaux,
2489 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2491 /* Reloc. */
2492 memset (&reloc, 0, sizeof (struct internal_reloc));
2493 reloc.r_vaddr = 0x0038;
2494 reloc.r_symndx = filehdr.f_nsyms;
2495 reloc.r_type = R_POS;
2496 reloc.r_size = 63;
2497 bfd_coff_swap_reloc_out (abfd, &reloc,
2498 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2500 filehdr.f_nsyms += 2;
2501 data_scnhdr.s_nreloc += 1;
2504 if (rtld)
2506 memset (&syment, 0, sizeof (struct internal_syment));
2507 memset (&auxent, 0, sizeof (union internal_auxent));
2509 syment._n._n_n._n_offset = st_tmp - string_table;
2510 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2511 st_tmp += strlen (rtld_name) + 1;
2513 syment.n_sclass = C_EXT;
2514 syment.n_numaux = 1;
2515 bfd_coff_swap_sym_out (abfd, &syment,
2516 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2517 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2518 syment.n_numaux,
2519 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2521 /* Reloc. */
2522 memset (&reloc, 0, sizeof (struct internal_reloc));
2523 reloc.r_vaddr = 0x0000;
2524 reloc.r_symndx = filehdr.f_nsyms;
2525 reloc.r_type = R_POS;
2526 reloc.r_size = 63;
2527 bfd_coff_swap_reloc_out (abfd, &reloc,
2528 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2530 filehdr.f_nsyms += 2;
2531 data_scnhdr.s_nreloc += 1;
2533 bss_scnhdr.s_size = 0;
2536 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2537 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2539 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2540 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2541 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2542 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2543 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2544 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2545 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2546 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2547 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2548 bfd_bwrite (string_table, string_table_size, abfd);
2550 free (data_buffer);
2551 data_buffer = NULL;
2553 return TRUE;
2556 /* The typical dynamic reloc. */
2558 static reloc_howto_type xcoff64_dynamic_reloc =
2559 HOWTO (0, /* type */
2560 0, /* rightshift */
2561 4, /* size (0 = byte, 1 = short, 2 = long) */
2562 64, /* bitsize */
2563 FALSE, /* pc_relative */
2564 0, /* bitpos */
2565 complain_overflow_bitfield, /* complain_on_overflow */
2566 0, /* special_function */
2567 "R_POS", /* name */
2568 TRUE, /* partial_inplace */
2569 MINUS_ONE, /* src_mask */
2570 MINUS_ONE, /* dst_mask */
2571 FALSE); /* pcrel_offset */
2573 static unsigned long xcoff64_glink_code[10] =
2575 0xe9820000, /* ld r12,0(r2) */
2576 0xf8410028, /* std r2,40(r1) */
2577 0xe80c0000, /* ld r0,0(r12) */
2578 0xe84c0008, /* ld r0,8(r12) */
2579 0x7c0903a6, /* mtctr r0 */
2580 0x4e800420, /* bctr */
2581 0x00000000, /* start of traceback table */
2582 0x000ca000, /* traceback table */
2583 0x00000000, /* traceback table */
2584 0x00000018, /* ??? */
2587 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2589 { /* COFF backend, defined in libcoff.h. */
2590 _bfd_xcoff64_swap_aux_in,
2591 _bfd_xcoff64_swap_sym_in,
2592 _bfd_xcoff64_swap_lineno_in,
2593 _bfd_xcoff64_swap_aux_out,
2594 _bfd_xcoff64_swap_sym_out,
2595 _bfd_xcoff64_swap_lineno_out,
2596 xcoff64_swap_reloc_out,
2597 coff_swap_filehdr_out,
2598 coff_swap_aouthdr_out,
2599 coff_swap_scnhdr_out,
2600 FILHSZ,
2601 AOUTSZ,
2602 SCNHSZ,
2603 SYMESZ,
2604 AUXESZ,
2605 RELSZ,
2606 LINESZ,
2607 FILNMLEN,
2608 TRUE, /* _bfd_coff_long_filenames */
2609 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2610 3, /* _bfd_coff_default_section_alignment_power */
2611 TRUE, /* _bfd_coff_force_symnames_in_strings */
2612 4, /* _bfd_coff_debug_string_prefix_length */
2613 coff_swap_filehdr_in,
2614 coff_swap_aouthdr_in,
2615 coff_swap_scnhdr_in,
2616 xcoff64_swap_reloc_in,
2617 xcoff64_bad_format_hook,
2618 coff_set_arch_mach_hook,
2619 coff_mkobject_hook,
2620 styp_to_sec_flags,
2621 coff_set_alignment_hook,
2622 coff_slurp_symbol_table,
2623 symname_in_debug_hook,
2624 coff_pointerize_aux_hook,
2625 coff_print_aux,
2626 dummy_reloc16_extra_cases,
2627 dummy_reloc16_estimate,
2628 NULL, /* bfd_coff_symbol_classification */
2629 coff_compute_section_file_positions,
2630 NULL, /* _bfd_coff_start_final_link */
2631 xcoff64_ppc_relocate_section,
2632 coff_rtype_to_howto,
2633 NULL, /* _bfd_coff_adjust_symndx */
2634 _bfd_generic_link_add_one_symbol,
2635 coff_link_output_has_begun,
2636 coff_final_link_postscript,
2637 NULL /* print_pdata. */
2640 0x01EF, /* magic number */
2641 bfd_arch_powerpc,
2642 bfd_mach_ppc_620,
2644 /* Function pointers to xcoff specific swap routines. */
2645 xcoff64_swap_ldhdr_in,
2646 xcoff64_swap_ldhdr_out,
2647 xcoff64_swap_ldsym_in,
2648 xcoff64_swap_ldsym_out,
2649 xcoff64_swap_ldrel_in,
2650 xcoff64_swap_ldrel_out,
2652 /* Sizes. */
2653 LDHDRSZ,
2654 LDSYMSZ,
2655 LDRELSZ,
2656 24, /* _xcoff_function_descriptor_size */
2657 0, /* _xcoff_small_aout_header_size */
2659 /* Versions. */
2660 2, /* _xcoff_ldhdr_version */
2662 _bfd_xcoff64_put_symbol_name,
2663 _bfd_xcoff64_put_ldsymbol_name,
2664 &xcoff64_dynamic_reloc,
2665 xcoff64_create_csect_from_smclas,
2667 /* Lineno and reloc count overflow. */
2668 xcoff64_is_lineno_count_overflow,
2669 xcoff64_is_reloc_count_overflow,
2671 xcoff64_loader_symbol_offset,
2672 xcoff64_loader_reloc_offset,
2674 /* glink. */
2675 &xcoff64_glink_code[0],
2676 40, /* _xcoff_glink_size */
2678 /* rtinit. */
2679 88, /* _xcoff_rtinit_size */
2680 xcoff64_generate_rtinit,
2683 /* The transfer vector that leads the outside world to all of the above. */
2684 const bfd_target rs6000coff64_vec =
2686 "aixcoff64-rs6000",
2687 bfd_target_xcoff_flavour,
2688 BFD_ENDIAN_BIG, /* data byte order is big */
2689 BFD_ENDIAN_BIG, /* header byte order is big */
2691 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2692 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2694 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2695 0, /* leading char */
2696 '/', /* ar_pad_char */
2697 15, /* ar_max_namelen */
2699 /* data */
2700 bfd_getb64,
2701 bfd_getb_signed_64,
2702 bfd_putb64,
2703 bfd_getb32,
2704 bfd_getb_signed_32,
2705 bfd_putb32,
2706 bfd_getb16,
2707 bfd_getb_signed_16,
2708 bfd_putb16,
2710 /* hdrs */
2711 bfd_getb64,
2712 bfd_getb_signed_64,
2713 bfd_putb64,
2714 bfd_getb32,
2715 bfd_getb_signed_32,
2716 bfd_putb32,
2717 bfd_getb16,
2718 bfd_getb_signed_16,
2719 bfd_putb16,
2721 { /* bfd_check_format */
2722 _bfd_dummy_target,
2723 coff_object_p,
2724 xcoff64_archive_p,
2725 CORE_FILE_P
2728 { /* bfd_set_format */
2729 bfd_false,
2730 coff_mkobject,
2731 _bfd_generic_mkarchive,
2732 bfd_false
2735 {/* bfd_write_contents */
2736 bfd_false,
2737 xcoff64_write_object_contents,
2738 _bfd_xcoff_write_archive_contents,
2739 bfd_false
2742 /* Generic */
2743 bfd_true,
2744 bfd_true,
2745 coff_new_section_hook,
2746 _bfd_generic_get_section_contents,
2747 _bfd_generic_get_section_contents_in_window,
2749 /* Copy */
2750 _bfd_xcoff_copy_private_bfd_data,
2751 _bfd_generic_bfd_merge_private_bfd_data,
2752 _bfd_generic_init_private_section_data,
2753 _bfd_generic_bfd_copy_private_section_data,
2754 _bfd_generic_bfd_copy_private_symbol_data,
2755 _bfd_generic_bfd_copy_private_header_data,
2756 _bfd_generic_bfd_set_private_flags,
2757 _bfd_generic_bfd_print_private_bfd_data,
2759 /* Core */
2760 BFD_JUMP_TABLE_CORE (coff),
2762 /* Archive */
2763 xcoff64_slurp_armap,
2764 _bfd_noarchive_slurp_extended_name_table,
2765 _bfd_noarchive_construct_extended_name_table,
2766 bfd_dont_truncate_arname,
2767 _bfd_xcoff_write_armap,
2768 _bfd_xcoff_read_ar_hdr,
2769 _bfd_generic_write_ar_hdr,
2770 xcoff64_openr_next_archived_file,
2771 _bfd_generic_get_elt_at_index,
2772 _bfd_xcoff_stat_arch_elt,
2773 bfd_true,
2775 /* Symbols */
2776 coff_get_symtab_upper_bound,
2777 coff_canonicalize_symtab,
2778 coff_make_empty_symbol,
2779 coff_print_symbol,
2780 coff_get_symbol_info,
2781 _bfd_xcoff_is_local_label_name,
2782 coff_bfd_is_target_special_symbol,
2783 coff_get_lineno,
2784 coff_find_nearest_line,
2785 _bfd_generic_find_line,
2786 coff_find_inliner_info,
2787 coff_bfd_make_debug_symbol,
2788 _bfd_generic_read_minisymbols,
2789 _bfd_generic_minisymbol_to_symbol,
2791 /* Reloc */
2792 coff_get_reloc_upper_bound,
2793 coff_canonicalize_reloc,
2794 xcoff64_reloc_type_lookup,
2795 xcoff64_reloc_name_lookup,
2797 /* Write */
2798 coff_set_arch_mach,
2799 coff_set_section_contents,
2801 /* Link */
2802 xcoff64_sizeof_headers,
2803 bfd_generic_get_relocated_section_contents,
2804 bfd_generic_relax_section,
2805 _bfd_xcoff_bfd_link_hash_table_create,
2806 _bfd_generic_link_hash_table_free,
2807 _bfd_xcoff_bfd_link_add_symbols,
2808 _bfd_generic_link_just_syms,
2809 _bfd_generic_copy_link_hash_symbol_type,
2810 _bfd_xcoff_bfd_final_link,
2811 _bfd_generic_link_split_section,
2812 bfd_generic_gc_sections,
2813 bfd_generic_merge_sections,
2814 bfd_generic_is_group_section,
2815 bfd_generic_discard_group,
2816 _bfd_generic_section_already_linked,
2817 _bfd_xcoff_define_common_symbol,
2819 /* Dynamic */
2820 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2821 _bfd_xcoff_canonicalize_dynamic_symtab,
2822 _bfd_nodynamic_get_synthetic_symtab,
2823 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2824 _bfd_xcoff_canonicalize_dynamic_reloc,
2826 /* Opposite endian version, none exists */
2827 NULL,
2829 (void *) &bfd_xcoff_backend_data,
2832 extern const bfd_target *xcoff64_core_p
2833 PARAMS ((bfd *));
2834 extern bfd_boolean xcoff64_core_file_matches_executable_p
2835 PARAMS ((bfd *, bfd *));
2836 extern char *xcoff64_core_file_failing_command
2837 PARAMS ((bfd *));
2838 extern int xcoff64_core_file_failing_signal
2839 PARAMS ((bfd *));
2840 #define xcoff64_core_file_pid \
2841 _bfd_nocore_core_file_pid
2843 /* AIX 5 */
2844 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2846 { /* COFF backend, defined in libcoff.h. */
2847 _bfd_xcoff64_swap_aux_in,
2848 _bfd_xcoff64_swap_sym_in,
2849 _bfd_xcoff64_swap_lineno_in,
2850 _bfd_xcoff64_swap_aux_out,
2851 _bfd_xcoff64_swap_sym_out,
2852 _bfd_xcoff64_swap_lineno_out,
2853 xcoff64_swap_reloc_out,
2854 coff_swap_filehdr_out,
2855 coff_swap_aouthdr_out,
2856 coff_swap_scnhdr_out,
2857 FILHSZ,
2858 AOUTSZ,
2859 SCNHSZ,
2860 SYMESZ,
2861 AUXESZ,
2862 RELSZ,
2863 LINESZ,
2864 FILNMLEN,
2865 TRUE, /* _bfd_coff_long_filenames */
2866 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2867 3, /* _bfd_coff_default_section_alignment_power */
2868 TRUE, /* _bfd_coff_force_symnames_in_strings */
2869 4, /* _bfd_coff_debug_string_prefix_length */
2870 coff_swap_filehdr_in,
2871 coff_swap_aouthdr_in,
2872 coff_swap_scnhdr_in,
2873 xcoff64_swap_reloc_in,
2874 xcoff64_bad_format_hook,
2875 coff_set_arch_mach_hook,
2876 coff_mkobject_hook,
2877 styp_to_sec_flags,
2878 coff_set_alignment_hook,
2879 coff_slurp_symbol_table,
2880 symname_in_debug_hook,
2881 coff_pointerize_aux_hook,
2882 coff_print_aux,
2883 dummy_reloc16_extra_cases,
2884 dummy_reloc16_estimate,
2885 NULL, /* bfd_coff_sym_is_global */
2886 coff_compute_section_file_positions,
2887 NULL, /* _bfd_coff_start_final_link */
2888 xcoff64_ppc_relocate_section,
2889 coff_rtype_to_howto,
2890 NULL, /* _bfd_coff_adjust_symndx */
2891 _bfd_generic_link_add_one_symbol,
2892 coff_link_output_has_begun,
2893 coff_final_link_postscript,
2894 NULL /* print_pdata. */
2897 U64_TOCMAGIC, /* magic number */
2898 bfd_arch_powerpc,
2899 bfd_mach_ppc_620,
2901 /* Function pointers to xcoff specific swap routines. */
2902 xcoff64_swap_ldhdr_in,
2903 xcoff64_swap_ldhdr_out,
2904 xcoff64_swap_ldsym_in,
2905 xcoff64_swap_ldsym_out,
2906 xcoff64_swap_ldrel_in,
2907 xcoff64_swap_ldrel_out,
2909 /* Sizes. */
2910 LDHDRSZ,
2911 LDSYMSZ,
2912 LDRELSZ,
2913 24, /* _xcoff_function_descriptor_size */
2914 0, /* _xcoff_small_aout_header_size */
2915 /* Versions. */
2916 2, /* _xcoff_ldhdr_version */
2918 _bfd_xcoff64_put_symbol_name,
2919 _bfd_xcoff64_put_ldsymbol_name,
2920 &xcoff64_dynamic_reloc,
2921 xcoff64_create_csect_from_smclas,
2923 /* Lineno and reloc count overflow. */
2924 xcoff64_is_lineno_count_overflow,
2925 xcoff64_is_reloc_count_overflow,
2927 xcoff64_loader_symbol_offset,
2928 xcoff64_loader_reloc_offset,
2930 /* glink. */
2931 &xcoff64_glink_code[0],
2932 40, /* _xcoff_glink_size */
2934 /* rtinit. */
2935 88, /* _xcoff_rtinit_size */
2936 xcoff64_generate_rtinit,
2939 /* The transfer vector that leads the outside world to all of the above. */
2940 const bfd_target aix5coff64_vec =
2942 "aix5coff64-rs6000",
2943 bfd_target_xcoff_flavour,
2944 BFD_ENDIAN_BIG, /* data byte order is big */
2945 BFD_ENDIAN_BIG, /* header byte order is big */
2947 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2948 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2950 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2951 0, /* leading char */
2952 '/', /* ar_pad_char */
2953 15, /* ar_max_namelen */
2955 /* data */
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 /* hdrs */
2967 bfd_getb64,
2968 bfd_getb_signed_64,
2969 bfd_putb64,
2970 bfd_getb32,
2971 bfd_getb_signed_32,
2972 bfd_putb32,
2973 bfd_getb16,
2974 bfd_getb_signed_16,
2975 bfd_putb16,
2977 { /* bfd_check_format */
2978 _bfd_dummy_target,
2979 coff_object_p,
2980 xcoff64_archive_p,
2981 xcoff64_core_p
2984 { /* bfd_set_format */
2985 bfd_false,
2986 coff_mkobject,
2987 _bfd_generic_mkarchive,
2988 bfd_false
2991 {/* bfd_write_contents */
2992 bfd_false,
2993 xcoff64_write_object_contents,
2994 _bfd_xcoff_write_archive_contents,
2995 bfd_false
2998 /* Generic */
2999 bfd_true,
3000 bfd_true,
3001 coff_new_section_hook,
3002 _bfd_generic_get_section_contents,
3003 _bfd_generic_get_section_contents_in_window,
3005 /* Copy */
3006 _bfd_xcoff_copy_private_bfd_data,
3007 _bfd_generic_bfd_merge_private_bfd_data,
3008 _bfd_generic_init_private_section_data,
3009 _bfd_generic_bfd_copy_private_section_data,
3010 _bfd_generic_bfd_copy_private_symbol_data,
3011 _bfd_generic_bfd_copy_private_header_data,
3012 _bfd_generic_bfd_set_private_flags,
3013 _bfd_generic_bfd_print_private_bfd_data,
3015 /* Core */
3016 BFD_JUMP_TABLE_CORE (xcoff64),
3018 /* Archive */
3019 xcoff64_slurp_armap,
3020 _bfd_noarchive_slurp_extended_name_table,
3021 _bfd_noarchive_construct_extended_name_table,
3022 bfd_dont_truncate_arname,
3023 _bfd_xcoff_write_armap,
3024 _bfd_xcoff_read_ar_hdr,
3025 _bfd_generic_write_ar_hdr,
3026 xcoff64_openr_next_archived_file,
3027 _bfd_generic_get_elt_at_index,
3028 _bfd_xcoff_stat_arch_elt,
3029 bfd_true,
3031 /* Symbols */
3032 coff_get_symtab_upper_bound,
3033 coff_canonicalize_symtab,
3034 coff_make_empty_symbol,
3035 coff_print_symbol,
3036 coff_get_symbol_info,
3037 _bfd_xcoff_is_local_label_name,
3038 coff_bfd_is_target_special_symbol,
3039 coff_get_lineno,
3040 coff_find_nearest_line,
3041 _bfd_generic_find_line,
3042 coff_find_inliner_info,
3043 coff_bfd_make_debug_symbol,
3044 _bfd_generic_read_minisymbols,
3045 _bfd_generic_minisymbol_to_symbol,
3047 /* Reloc */
3048 coff_get_reloc_upper_bound,
3049 coff_canonicalize_reloc,
3050 xcoff64_reloc_type_lookup,
3051 xcoff64_reloc_name_lookup,
3053 /* Write */
3054 coff_set_arch_mach,
3055 coff_set_section_contents,
3057 /* Link */
3058 xcoff64_sizeof_headers,
3059 bfd_generic_get_relocated_section_contents,
3060 bfd_generic_relax_section,
3061 _bfd_xcoff_bfd_link_hash_table_create,
3062 _bfd_generic_link_hash_table_free,
3063 _bfd_xcoff_bfd_link_add_symbols,
3064 _bfd_generic_link_just_syms,
3065 _bfd_generic_copy_link_hash_symbol_type,
3066 _bfd_xcoff_bfd_final_link,
3067 _bfd_generic_link_split_section,
3068 bfd_generic_gc_sections,
3069 bfd_generic_merge_sections,
3070 bfd_generic_is_group_section,
3071 bfd_generic_discard_group,
3072 _bfd_generic_section_already_linked,
3073 _bfd_xcoff_define_common_symbol,
3075 /* Dynamic */
3076 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3077 _bfd_xcoff_canonicalize_dynamic_symtab,
3078 _bfd_nodynamic_get_synthetic_symtab,
3079 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3080 _bfd_xcoff_canonicalize_dynamic_reloc,
3082 /* Opposite endian version, none exists. */
3083 NULL,
3085 (void *) & bfd_xcoff_aix5_backend_data,