PR binutils/11742
[binutils.git] / bfd / coff64-rs6000.c
blob99cbfb7136d0a7ad3e65e6ffa4c6cb75d1c890d6
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 #else
260 #define CORE_FILE_P _bfd_dummy_target
261 #define coff_core_file_failing_command \
262 _bfd_nocore_core_file_failing_command
263 #define coff_core_file_failing_signal \
264 _bfd_nocore_core_file_failing_signal
265 #define coff_core_file_matches_executable_p \
266 _bfd_nocore_core_file_matches_executable_p
267 #endif
268 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
269 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
270 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
271 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
272 #define coff_swap_reloc_in xcoff64_swap_reloc_in
273 #define coff_swap_reloc_out xcoff64_swap_reloc_out
274 #define NO_COFF_RELOCS
276 #ifndef bfd_pe_print_pdata
277 #define bfd_pe_print_pdata NULL
278 #endif
280 #include "coffcode.h"
282 /* For XCOFF64, the effective width of symndx changes depending on
283 whether we are the first entry. Sigh. */
284 static void
285 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
286 bfd *abfd;
287 PTR ext1;
288 PTR in1;
290 LINENO *ext = (LINENO *) ext1;
291 struct internal_lineno *in = (struct internal_lineno *) in1;
293 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
294 if (in->l_lnno == 0)
295 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
296 else
297 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
300 static unsigned int
301 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
302 bfd *abfd;
303 PTR inp;
304 PTR outp;
306 struct internal_lineno *in = (struct internal_lineno *) inp;
307 struct external_lineno *ext = (struct external_lineno *) outp;
309 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
310 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
312 if (in->l_lnno == 0)
313 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
314 else
315 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
317 return bfd_coff_linesz (abfd);
320 static void
321 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
322 bfd *abfd;
323 PTR ext1;
324 PTR in1;
326 struct external_syment *ext = (struct external_syment *) ext1;
327 struct internal_syment *in = (struct internal_syment *) in1;
329 in->_n._n_n._n_zeroes = 0;
330 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
331 in->n_value = H_GET_64 (abfd, ext->e_value);
332 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
333 in->n_type = H_GET_16 (abfd, ext->e_type);
334 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
335 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
338 static unsigned int
339 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
340 bfd *abfd;
341 PTR inp;
342 PTR extp;
344 struct internal_syment *in = (struct internal_syment *) inp;
345 struct external_syment *ext = (struct external_syment *) extp;
347 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
348 H_PUT_64 (abfd, in->n_value, ext->e_value);
349 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
350 H_PUT_16 (abfd, in->n_type, ext->e_type);
351 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
352 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
353 return bfd_coff_symesz (abfd);
356 static void
357 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, in_class, indx, numaux, in1)
358 bfd *abfd;
359 PTR ext1;
360 int type;
361 int in_class;
362 int indx;
363 int numaux;
364 PTR in1;
366 union external_auxent *ext = (union external_auxent *) ext1;
367 union internal_auxent *in = (union internal_auxent *) in1;
369 switch (in_class)
371 case C_FILE:
372 if (ext->x_file.x_n.x_zeroes[0] == 0)
374 in->x_file.x_n.x_zeroes = 0;
375 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
377 else
379 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
381 goto end;
383 /* RS/6000 "csect" auxents */
384 case C_EXT:
385 case C_AIX_WEAKEXT:
386 case C_HIDEXT:
387 if (indx + 1 == numaux)
389 bfd_signed_vma h = 0;
390 bfd_vma l = 0;
392 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
393 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
395 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
397 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
398 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
399 /* We don't have to hack bitfields in x_smtyp because it's
400 defined by shifts-and-ands, which are equivalent on all
401 byte orders. */
402 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
403 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
404 goto end;
406 break;
408 case C_STAT:
409 case C_LEAFSTAT:
410 case C_HIDDEN:
411 if (type == T_NULL)
413 /* PE defines some extra fields; we zero them out for
414 safety. */
415 in->x_scn.x_checksum = 0;
416 in->x_scn.x_associated = 0;
417 in->x_scn.x_comdat = 0;
419 goto end;
421 break;
424 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
425 || ISTAG (in_class))
427 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
428 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
429 in->x_sym.x_fcnary.x_fcn.x_endndx.l
430 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
432 if (ISFCN (type))
434 in->x_sym.x_misc.x_fsize
435 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
437 else
439 in->x_sym.x_misc.x_lnsz.x_lnno
440 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
441 in->x_sym.x_misc.x_lnsz.x_size
442 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
445 end: ;
448 static unsigned int
449 _bfd_xcoff64_swap_aux_out (abfd, inp, type, in_class, indx, numaux, extp)
450 bfd *abfd;
451 PTR inp;
452 int type;
453 int in_class;
454 int indx ATTRIBUTE_UNUSED;
455 int numaux ATTRIBUTE_UNUSED;
456 PTR extp;
458 union internal_auxent *in = (union internal_auxent *) inp;
459 union external_auxent *ext = (union external_auxent *) extp;
461 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
462 switch (in_class)
464 case C_FILE:
465 if (in->x_file.x_n.x_zeroes == 0)
467 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
468 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
470 else
472 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
474 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
475 goto end;
477 /* RS/6000 "csect" auxents */
478 case C_EXT:
479 case C_AIX_WEAKEXT:
480 case C_HIDEXT:
481 if (indx + 1 == numaux)
483 bfd_vma temp;
485 temp = in->x_csect.x_scnlen.l & 0xffffffff;
486 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
487 temp = in->x_csect.x_scnlen.l >> 32;
488 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
489 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
490 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
491 /* We don't have to hack bitfields in x_smtyp because it's
492 defined by shifts-and-ands, which are equivalent on all
493 byte orders. */
494 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
495 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
496 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
497 goto end;
499 break;
501 case C_STAT:
502 case C_LEAFSTAT:
503 case C_HIDDEN:
504 if (type == T_NULL)
506 goto end;
508 break;
511 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
512 || ISTAG (in_class))
514 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
515 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
516 H_PUT_8 (abfd, _AUX_FCN,
517 ext->x_auxtype.x_auxtype);
518 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
519 ext->x_sym.x_fcnary.x_fcn.x_endndx);
521 if (ISFCN (type))
523 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
524 ext->x_sym.x_fcnary.x_fcn.x_fsize);
526 else
528 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
529 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
530 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
531 ext->x_sym.x_fcnary.x_lnsz.x_size);
534 end:
536 return bfd_coff_auxesz (abfd);
539 static bfd_boolean
540 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
541 bfd *abfd;
542 struct bfd_strtab_hash *strtab;
543 struct internal_syment *sym;
544 const char *name;
546 bfd_boolean hash;
547 bfd_size_type indx;
549 hash = TRUE;
551 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
552 hash = FALSE;
554 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
556 if (indx == (bfd_size_type) -1)
557 return FALSE;
559 sym->_n._n_n._n_zeroes = 0;
560 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
562 return TRUE;
565 static bfd_boolean
566 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
567 bfd *abfd ATTRIBUTE_UNUSED;
568 struct xcoff_loader_info *ldinfo;
569 struct internal_ldsym *ldsym;
570 const char *name;
572 size_t len;
573 len = strlen (name);
575 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
577 bfd_size_type newalc;
578 char *newstrings;
580 newalc = ldinfo->string_alc * 2;
581 if (newalc == 0)
582 newalc = 32;
583 while (ldinfo->string_size + len + 3 > newalc)
584 newalc *= 2;
586 newstrings = bfd_realloc (ldinfo->strings, newalc);
587 if (newstrings == NULL)
589 ldinfo->failed = TRUE;
590 return FALSE;
592 ldinfo->string_alc = newalc;
593 ldinfo->strings = newstrings;
596 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
597 ldinfo->strings + ldinfo->string_size);
598 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
599 ldsym->_l._l_l._l_zeroes = 0;
600 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
601 ldinfo->string_size += len + 3;
603 return TRUE;
606 /* Routines to swap information in the XCOFF .loader section. If we
607 ever need to write an XCOFF loader, this stuff will need to be
608 moved to another file shared by the linker (which XCOFF calls the
609 ``binder'') and the loader. */
611 /* Swap in the ldhdr structure. */
613 static void
614 xcoff64_swap_ldhdr_in (abfd, s, dst)
615 bfd *abfd;
616 const PTR s;
617 struct internal_ldhdr *dst;
619 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
621 dst->l_version = bfd_get_32 (abfd, src->l_version);
622 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
623 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
624 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
625 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
626 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
627 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
628 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
629 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
630 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
633 /* Swap out the ldhdr structure. */
635 static void
636 xcoff64_swap_ldhdr_out (abfd, src, d)
637 bfd *abfd;
638 const struct internal_ldhdr *src;
639 PTR d;
641 struct external_ldhdr *dst = (struct external_ldhdr *) d;
643 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
644 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
645 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
646 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
647 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
648 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
649 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
650 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
651 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
652 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
655 /* Swap in the ldsym structure. */
657 static void
658 xcoff64_swap_ldsym_in (abfd, s, dst)
659 bfd *abfd;
660 const PTR s;
661 struct internal_ldsym *dst;
663 const struct external_ldsym *src = (const struct external_ldsym *) s;
664 /* XCOFF64 does not use l_zeroes like XCOFF32
665 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
666 as an offset into the loader symbol table. */
667 dst->_l._l_l._l_zeroes = 0;
668 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
669 dst->l_value = bfd_get_64 (abfd, src->l_value);
670 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
671 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
672 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
673 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
674 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
677 /* Swap out the ldsym structure. */
679 static void
680 xcoff64_swap_ldsym_out (abfd, src, d)
681 bfd *abfd;
682 const struct internal_ldsym *src;
683 PTR d;
685 struct external_ldsym *dst = (struct external_ldsym *) d;
687 bfd_put_64 (abfd, src->l_value, dst->l_value);
688 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
689 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
690 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
691 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
692 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
693 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
696 static void
697 xcoff64_swap_reloc_in (abfd, s, d)
698 bfd *abfd;
699 PTR s;
700 PTR d;
702 struct external_reloc *src = (struct external_reloc *) s;
703 struct internal_reloc *dst = (struct internal_reloc *) d;
705 memset (dst, 0, sizeof (struct internal_reloc));
707 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
708 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
709 dst->r_size = bfd_get_8 (abfd, src->r_size);
710 dst->r_type = bfd_get_8 (abfd, src->r_type);
713 static unsigned int
714 xcoff64_swap_reloc_out (abfd, s, d)
715 bfd *abfd;
716 PTR s;
717 PTR d;
719 struct internal_reloc *src = (struct internal_reloc *) s;
720 struct external_reloc *dst = (struct external_reloc *) d;
722 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
723 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
724 bfd_put_8 (abfd, src->r_type, dst->r_type);
725 bfd_put_8 (abfd, src->r_size, dst->r_size);
727 return bfd_coff_relsz (abfd);
730 /* Swap in the ldrel structure. */
732 static void
733 xcoff64_swap_ldrel_in (abfd, s, dst)
734 bfd *abfd;
735 const PTR s;
736 struct internal_ldrel *dst;
738 const struct external_ldrel *src = (const struct external_ldrel *) s;
740 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
741 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
742 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
743 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
746 /* Swap out the ldrel structure. */
748 static void
749 xcoff64_swap_ldrel_out (abfd, src, d)
750 bfd *abfd;
751 const struct internal_ldrel *src;
752 PTR d;
754 struct external_ldrel *dst = (struct external_ldrel *) d;
756 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
757 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
758 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
759 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
762 static bfd_boolean
763 xcoff64_write_object_contents (abfd)
764 bfd *abfd;
766 asection *current;
767 bfd_boolean hasrelocs = FALSE;
768 bfd_boolean haslinno = FALSE;
769 file_ptr scn_base;
770 file_ptr reloc_base;
771 file_ptr lineno_base;
772 file_ptr sym_base;
773 unsigned long reloc_size = 0;
774 unsigned long lnno_size = 0;
775 asection *text_sec = ((void *) 0);
776 asection *data_sec = ((void *) 0);
777 asection *bss_sec = ((void *) 0);
778 struct internal_filehdr internal_f;
779 struct internal_aouthdr internal_a;
781 bfd_set_error (bfd_error_system_call);
783 if (! abfd->output_has_begun)
785 if (! bfd_coff_compute_section_file_positions (abfd))
786 return FALSE;
789 /* Work out the size of the reloc and linno areas. */
790 reloc_base = obj_relocbase (abfd);
792 for (current = abfd->sections; current != NULL; current = current->next)
793 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
795 lineno_base = reloc_base + reloc_size;
797 /* Make a pass through the symbol table to count line number entries and
798 put them into the correct asections. */
799 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
801 sym_base = lineno_base + lnno_size;
803 /* Indicate in each section->line_filepos its actual file address. */
804 for (current = abfd->sections; current != NULL; current = current->next)
806 if (current->lineno_count)
808 current->line_filepos = lineno_base;
809 current->moving_line_filepos = lineno_base;
810 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
812 else
814 current->line_filepos = 0;
817 if (current->reloc_count)
819 current->rel_filepos = reloc_base;
820 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
822 else
824 current->rel_filepos = 0;
828 if ((abfd->flags & EXEC_P) != 0)
830 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
831 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
833 else
835 scn_base = bfd_coff_filhsz (abfd);
836 internal_f.f_opthdr = 0;
839 internal_f.f_nscns = 0;
841 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
842 return FALSE;
844 for (current = abfd->sections; current != NULL; current = current->next)
846 struct internal_scnhdr section;
847 struct external_scnhdr buff;
848 bfd_size_type amount;
850 internal_f.f_nscns++;
852 strncpy (section.s_name, current->name, SCNNMLEN);
854 section.s_vaddr = current->vma;
855 section.s_paddr = current->lma;
856 section.s_size = current->size;
858 /* If this section has no size or is unloadable then the scnptr
859 will be 0 too. */
860 if (current->size == 0
861 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
863 section.s_scnptr = 0;
865 else
867 section.s_scnptr = current->filepos;
870 section.s_relptr = current->rel_filepos;
871 section.s_lnnoptr = current->line_filepos;
872 section.s_nreloc = current->reloc_count;
874 section.s_nlnno = current->lineno_count;
875 if (current->reloc_count != 0)
876 hasrelocs = TRUE;
877 if (current->lineno_count != 0)
878 haslinno = TRUE;
880 section.s_flags = sec_to_styp_flags (current->name, current->flags);
882 if (!strcmp (current->name, _TEXT))
884 text_sec = current;
886 else if (!strcmp (current->name, _DATA))
888 data_sec = current;
890 else if (!strcmp (current->name, _BSS))
892 bss_sec = current;
895 amount = bfd_coff_scnhsz (abfd);
896 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
897 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
898 return FALSE;
901 internal_f.f_timdat = 0;
903 internal_f.f_flags = 0;
905 if (!hasrelocs)
906 internal_f.f_flags |= F_RELFLG;
907 if (!haslinno)
908 internal_f.f_flags |= F_LNNO;
909 if (abfd->flags & EXEC_P)
910 internal_f.f_flags |= F_EXEC;
912 /* FIXME: this is wrong for PPC_PE! */
913 if (bfd_little_endian (abfd))
914 internal_f.f_flags |= F_AR32WR;
915 else
916 internal_f.f_flags |= F_AR32W;
918 if ((abfd->flags & DYNAMIC) != 0)
919 internal_f.f_flags |= F_SHROBJ;
920 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
921 internal_f.f_flags |= F_DYNLOAD;
923 memset (&internal_a, 0, sizeof internal_a);
925 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
926 internal_a.magic = (abfd->flags & D_PAGED
927 ? RS6K_AOUTHDR_ZMAGIC
928 : (abfd->flags & WP_TEXT
929 ? RS6K_AOUTHDR_NMAGIC
930 : RS6K_AOUTHDR_OMAGIC));
932 /* FIXME: Does anybody ever set this to another value? */
933 internal_a.vstamp = 0;
935 /* Now should write relocs, strings, syms. */
936 obj_sym_filepos (abfd) = sym_base;
938 internal_f.f_symptr = 0;
939 internal_f.f_nsyms = 0;
941 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
942 backend linker, and obj_raw_syment_count is not valid until after
943 coff_write_symbols is called. */
944 if (bfd_get_symcount (abfd) != 0)
946 int firstundef;
948 if (!coff_renumber_symbols (abfd, &firstundef))
949 return FALSE;
950 coff_mangle_symbols (abfd);
951 if (! coff_write_symbols (abfd))
952 return FALSE;
953 if (! coff_write_linenumbers (abfd))
954 return FALSE;
955 if (! coff_write_relocs (abfd, firstundef))
956 return FALSE;
958 internal_f.f_symptr = sym_base;
959 internal_f.f_nsyms = bfd_get_symcount (abfd);
961 else if (obj_raw_syment_count (abfd) != 0)
963 internal_f.f_symptr = sym_base;
965 /* AIX appears to require that F_RELFLG not be set if there are
966 local symbols but no relocations. */
967 internal_f.f_flags &=~ F_RELFLG;
969 else
971 internal_f.f_flags |= F_LSYMS;
974 if (text_sec)
976 internal_a.tsize = text_sec->size;
977 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
980 if (data_sec)
982 internal_a.dsize = data_sec->size;
983 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
986 if (bss_sec)
988 internal_a.bsize = bss_sec->size;
989 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
990 internal_a.data_start = bss_sec->vma;
993 internal_a.entry = bfd_get_start_address (abfd);
994 internal_f.f_nsyms = obj_raw_syment_count (abfd);
996 if (xcoff_data (abfd)->full_aouthdr)
998 bfd_vma toc;
999 asection *loader_sec;
1001 internal_a.vstamp = 1;
1003 internal_a.o_snentry = xcoff_data (abfd)->snentry;
1004 if (internal_a.o_snentry == 0)
1005 internal_a.entry = (bfd_vma) -1;
1007 if (text_sec != NULL)
1009 internal_a.o_sntext = text_sec->target_index;
1010 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
1012 else
1014 internal_a.o_sntext = 0;
1015 internal_a.o_algntext = 0;
1018 if (data_sec != NULL)
1020 internal_a.o_sndata = data_sec->target_index;
1021 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1023 else
1025 internal_a.o_sndata = 0;
1026 internal_a.o_algndata = 0;
1029 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1030 if (loader_sec != NULL)
1031 internal_a.o_snloader = loader_sec->target_index;
1032 else
1033 internal_a.o_snloader = 0;
1034 if (bss_sec != NULL)
1035 internal_a.o_snbss = bss_sec->target_index;
1036 else
1037 internal_a.o_snbss = 0;
1039 toc = xcoff_data (abfd)->toc;
1040 internal_a.o_toc = toc;
1041 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1043 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1044 if (xcoff_data (abfd)->cputype != -1)
1045 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1046 else
1048 switch (bfd_get_arch (abfd))
1050 case bfd_arch_rs6000:
1051 internal_a.o_cputype = 4;
1052 break;
1053 case bfd_arch_powerpc:
1054 if (bfd_get_mach (abfd) == bfd_mach_ppc)
1055 internal_a.o_cputype = 3;
1056 else if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
1057 internal_a.o_cputype = 2;
1058 else
1059 internal_a.o_cputype = 1;
1060 break;
1061 default:
1062 abort ();
1065 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1066 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
1069 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
1070 return FALSE;
1073 char * buff;
1074 bfd_size_type amount = bfd_coff_filhsz (abfd);
1076 buff = bfd_malloc (amount);
1077 if (buff == NULL)
1078 return FALSE;
1080 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1081 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1083 free (buff);
1085 if (amount != bfd_coff_filhsz (abfd))
1086 return FALSE;
1089 if (abfd->flags & EXEC_P)
1091 char * buff;
1092 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1094 buff = bfd_malloc (amount);
1095 if (buff == NULL)
1096 return FALSE;
1098 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
1099 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1101 free (buff);
1103 if (amount != bfd_coff_aoutsz (abfd))
1104 return FALSE;
1107 return TRUE;
1110 static bfd_boolean
1111 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
1112 val, addend, relocation, contents)
1113 bfd *input_bfd;
1114 asection *input_section;
1115 bfd *output_bfd ATTRIBUTE_UNUSED;
1116 struct internal_reloc *rel;
1117 struct internal_syment *sym ATTRIBUTE_UNUSED;
1118 struct reloc_howto_struct *howto;
1119 bfd_vma val;
1120 bfd_vma addend;
1121 bfd_vma *relocation;
1122 bfd_byte *contents;
1124 struct xcoff_link_hash_entry *h;
1125 bfd_vma section_offset;
1127 if (0 > rel->r_symndx)
1128 return FALSE;
1130 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1131 section_offset = rel->r_vaddr - input_section->vma;
1133 /* If we see an R_BR or R_RBR reloc which is jumping to global
1134 linkage code, and it is followed by an appropriate cror nop
1135 instruction, we replace the cror with ld r2,40(r1). This
1136 restores the TOC after the glink code. Contrariwise, if the
1137 call is followed by a ld r2,40(r1), but the call is not
1138 going to global linkage code, we can replace the load with a
1139 cror. */
1140 if (NULL != h
1141 && (bfd_link_hash_defined == h->root.type
1142 || bfd_link_hash_defweak == h->root.type)
1143 && section_offset + 8 <= input_section->size)
1145 bfd_byte *pnext;
1146 unsigned long next;
1148 pnext = contents + section_offset + 4;
1149 next = bfd_get_32 (input_bfd, pnext);
1151 /* The _ptrgl function is magic. It is used by the AIX compiler to call
1152 a function through a pointer. */
1153 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
1155 if (next == 0x4def7b82 /* cror 15,15,15 */
1156 || next == 0x4ffffb82 /* cror 31,31,31 */
1157 || next == 0x60000000) /* ori r0,r0,0 */
1158 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1160 else
1162 if (next == 0xe8410028) /* ld r2,40(r1) */
1163 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1166 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
1168 /* Normally, this relocation is against a defined symbol. In the
1169 case where this is a partial link and the output section offset
1170 is greater than 2^25, the linker will return an invalid error
1171 message that the relocation has been truncated. Yes it has been
1172 truncated but no it not important. For this case, disable the
1173 overflow checking. */
1174 howto->complain_on_overflow = complain_overflow_dont;
1177 /* The original PC-relative relocation is biased by -r_vaddr, so adding
1178 the value below will give the absolute target address. */
1179 *relocation = val + addend + rel->r_vaddr;
1181 howto->src_mask &= ~3;
1182 howto->dst_mask = howto->src_mask;
1184 if (h != NULL
1185 && (h->root.type == bfd_link_hash_defined
1186 || h->root.type == bfd_link_hash_defweak)
1187 && bfd_is_abs_section (h->root.u.def.section)
1188 && section_offset + 4 <= input_section->size)
1190 bfd_byte *ptr;
1191 bfd_vma insn;
1193 /* Turn the relative branch into an absolute one by setting the
1194 AA bit. */
1195 ptr = contents + section_offset;
1196 insn = bfd_get_32 (input_bfd, ptr);
1197 insn |= 2;
1198 bfd_put_32 (input_bfd, insn, ptr);
1200 /* Make the howto absolute too. */
1201 howto->pc_relative = FALSE;
1202 howto->complain_on_overflow = complain_overflow_bitfield;
1204 else
1206 /* Use a PC-relative howto and subtract the instruction's address
1207 from the target address we calculated above. */
1208 howto->pc_relative = TRUE;
1209 *relocation -= (input_section->output_section->vma
1210 + input_section->output_offset
1211 + section_offset);
1213 return TRUE;
1216 /* This is the relocation function for the PowerPC64.
1217 See xcoff_ppc_relocation_section for more information. */
1219 bfd_boolean
1220 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1221 input_section, contents, relocs, syms,
1222 sections)
1223 bfd *output_bfd;
1224 struct bfd_link_info *info;
1225 bfd *input_bfd;
1226 asection *input_section;
1227 bfd_byte *contents;
1228 struct internal_reloc *relocs;
1229 struct internal_syment *syms;
1230 asection **sections;
1232 struct internal_reloc *rel;
1233 struct internal_reloc *relend;
1235 rel = relocs;
1236 relend = rel + input_section->reloc_count;
1237 for (; rel < relend; rel++)
1239 long symndx;
1240 struct xcoff_link_hash_entry *h;
1241 struct internal_syment *sym;
1242 bfd_vma addend;
1243 bfd_vma val;
1244 struct reloc_howto_struct howto;
1245 bfd_vma relocation;
1246 bfd_vma value_to_relocate;
1247 bfd_vma address;
1248 bfd_byte *location;
1250 /* Relocation type R_REF is a special relocation type which is
1251 merely used to prevent garbage collection from occurring for
1252 the csect including the symbol which it references. */
1253 if (rel->r_type == R_REF)
1254 continue;
1256 /* howto */
1257 howto.type = rel->r_type;
1258 howto.rightshift = 0;
1259 howto.bitsize = (rel->r_size & 0x3f) + 1;
1260 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
1261 howto.pc_relative = FALSE;
1262 howto.bitpos = 0;
1263 howto.complain_on_overflow = (rel->r_size & 0x80
1264 ? complain_overflow_signed
1265 : complain_overflow_bitfield);
1266 howto.special_function = NULL;
1267 howto.name = "internal";
1268 howto.partial_inplace = TRUE;
1269 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
1270 howto.pcrel_offset = FALSE;
1272 /* symbol */
1273 val = 0;
1274 addend = 0;
1275 h = NULL;
1276 sym = NULL;
1277 symndx = rel->r_symndx;
1279 if (-1 != symndx)
1281 asection *sec;
1283 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1284 sym = syms + symndx;
1285 addend = - sym->n_value;
1287 if (NULL == h)
1289 sec = sections[symndx];
1290 /* Hack to make sure we use the right TOC anchor value
1291 if this reloc is against the TOC anchor. */
1292 if (sec->name[3] == '0'
1293 && strcmp (sec->name, ".tc0") == 0)
1294 val = xcoff_data (output_bfd)->toc;
1295 else
1296 val = (sec->output_section->vma
1297 + sec->output_offset
1298 + sym->n_value
1299 - sec->vma);
1301 else
1303 if (info->unresolved_syms_in_objects != RM_IGNORE
1304 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
1306 if (! ((*info->callbacks->undefined_symbol)
1307 (info, h->root.root.string,
1308 input_bfd, input_section,
1309 rel->r_vaddr - input_section->vma,
1310 (info->unresolved_syms_in_objects
1311 == RM_GENERATE_ERROR))))
1312 return FALSE;
1314 if (h->root.type == bfd_link_hash_defined
1315 || h->root.type == bfd_link_hash_defweak)
1317 sec = h->root.u.def.section;
1318 val = (h->root.u.def.value
1319 + sec->output_section->vma
1320 + sec->output_offset);
1322 else if (h->root.type == bfd_link_hash_common)
1324 sec = h->root.u.c.p->section;
1325 val = (sec->output_section->vma
1326 + sec->output_offset);
1328 else
1330 BFD_ASSERT (info->relocatable
1331 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
1332 || (h->flags & XCOFF_IMPORT) != 0);
1337 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
1338 || !((*xcoff64_calculate_relocation[rel->r_type])
1339 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1340 addend, &relocation, contents)))
1341 return FALSE;
1343 /* address */
1344 address = rel->r_vaddr - input_section->vma;
1345 location = contents + address;
1347 if (address > input_section->size)
1348 abort ();
1350 /* Get the value we are going to relocate. */
1351 if (1 == howto.size)
1352 value_to_relocate = bfd_get_16 (input_bfd, location);
1353 else if (2 == howto.size)
1354 value_to_relocate = bfd_get_32 (input_bfd, location);
1355 else
1356 value_to_relocate = bfd_get_64 (input_bfd, location);
1358 /* overflow.
1360 FIXME: We may drop bits during the addition
1361 which we don't check for. We must either check at every single
1362 operation, which would be tedious, or we must do the computations
1363 in a type larger than bfd_vma, which would be inefficient. */
1365 if ((unsigned int) howto.complain_on_overflow
1366 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1367 abort ();
1369 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1370 (input_bfd, value_to_relocate, relocation, &howto)))
1372 const char *name;
1373 char buf[SYMNMLEN + 1];
1374 char reloc_type_name[10];
1376 if (symndx == -1)
1378 name = "*ABS*";
1380 else if (h != NULL)
1382 name = NULL;
1384 else
1386 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1387 if (name == NULL)
1388 name = "UNKNOWN";
1390 sprintf (reloc_type_name, "0x%02x", rel->r_type);
1392 if (! ((*info->callbacks->reloc_overflow)
1393 (info, (h ? &h->root : NULL), name, reloc_type_name,
1394 (bfd_vma) 0, input_bfd, input_section,
1395 rel->r_vaddr - input_section->vma)))
1396 return FALSE;
1399 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
1400 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1401 | (((value_to_relocate & howto.src_mask)
1402 + relocation) & howto.dst_mask));
1404 /* Put the value back in the object file. */
1405 if (1 == howto.size)
1406 bfd_put_16 (input_bfd, value_to_relocate, location);
1407 else if (2 == howto.size)
1408 bfd_put_32 (input_bfd, value_to_relocate, location);
1409 else
1410 bfd_put_64 (input_bfd, value_to_relocate, location);
1413 return TRUE;
1417 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1418 bitsize and whether they are signed or not, along with a
1419 conventional type. This table is for the types, which are used for
1420 different algorithms for putting in the reloc. Many of these
1421 relocs need special_function entries, which I have not written. */
1423 reloc_howto_type xcoff64_howto_table[] =
1425 /* Standard 64 bit relocation. */
1426 HOWTO (R_POS, /* type */
1427 0, /* rightshift */
1428 4, /* size (0 = byte, 1 = short, 2 = long) */
1429 64, /* bitsize */
1430 FALSE, /* pc_relative */
1431 0, /* bitpos */
1432 complain_overflow_bitfield, /* complain_on_overflow */
1433 0, /* special_function */
1434 "R_POS_64", /* name */
1435 TRUE, /* partial_inplace */
1436 MINUS_ONE, /* src_mask */
1437 MINUS_ONE, /* dst_mask */
1438 FALSE), /* pcrel_offset */
1440 /* 64 bit relocation, but store negative value. */
1441 HOWTO (R_NEG, /* type */
1442 0, /* rightshift */
1443 -4, /* size (0 = byte, 1 = short, 2 = long) */
1444 64, /* bitsize */
1445 FALSE, /* pc_relative */
1446 0, /* bitpos */
1447 complain_overflow_bitfield, /* complain_on_overflow */
1448 0, /* special_function */
1449 "R_NEG", /* name */
1450 TRUE, /* partial_inplace */
1451 MINUS_ONE, /* src_mask */
1452 MINUS_ONE, /* dst_mask */
1453 FALSE), /* pcrel_offset */
1455 /* 32 bit PC relative relocation. */
1456 HOWTO (R_REL, /* type */
1457 0, /* rightshift */
1458 2, /* size (0 = byte, 1 = short, 2 = long) */
1459 32, /* bitsize */
1460 TRUE, /* pc_relative */
1461 0, /* bitpos */
1462 complain_overflow_signed, /* complain_on_overflow */
1463 0, /* special_function */
1464 "R_REL", /* name */
1465 TRUE, /* partial_inplace */
1466 0xffffffff, /* src_mask */
1467 0xffffffff, /* dst_mask */
1468 FALSE), /* pcrel_offset */
1470 /* 16 bit TOC relative relocation. */
1471 HOWTO (R_TOC, /* type */
1472 0, /* rightshift */
1473 1, /* size (0 = byte, 1 = short, 2 = long) */
1474 16, /* bitsize */
1475 FALSE, /* pc_relative */
1476 0, /* bitpos */
1477 complain_overflow_bitfield, /* complain_on_overflow */
1478 0, /* special_function */
1479 "R_TOC", /* name */
1480 TRUE, /* partial_inplace */
1481 0xffff, /* src_mask */
1482 0xffff, /* dst_mask */
1483 FALSE), /* pcrel_offset */
1485 /* I don't really know what this is. */
1486 HOWTO (R_RTB, /* type */
1487 1, /* rightshift */
1488 2, /* size (0 = byte, 1 = short, 2 = long) */
1489 32, /* bitsize */
1490 FALSE, /* pc_relative */
1491 0, /* bitpos */
1492 complain_overflow_bitfield, /* complain_on_overflow */
1493 0, /* special_function */
1494 "R_RTB", /* name */
1495 TRUE, /* partial_inplace */
1496 0xffffffff, /* src_mask */
1497 0xffffffff, /* dst_mask */
1498 FALSE), /* pcrel_offset */
1500 /* External TOC relative symbol. */
1501 HOWTO (R_GL, /* type */
1502 0, /* rightshift */
1503 1, /* size (0 = byte, 1 = short, 2 = long) */
1504 16, /* bitsize */
1505 FALSE, /* pc_relative */
1506 0, /* bitpos */
1507 complain_overflow_bitfield, /* complain_on_overflow */
1508 0, /* special_function */
1509 "R_GL", /* name */
1510 TRUE, /* partial_inplace */
1511 0xffff, /* src_mask */
1512 0xffff, /* dst_mask */
1513 FALSE), /* pcrel_offset */
1515 /* Local TOC relative symbol. */
1516 HOWTO (R_TCL, /* type */
1517 0, /* rightshift */
1518 1, /* size (0 = byte, 1 = short, 2 = long) */
1519 16, /* bitsize */
1520 FALSE, /* pc_relative */
1521 0, /* bitpos */
1522 complain_overflow_bitfield, /* complain_on_overflow */
1523 0, /* special_function */
1524 "R_TCL", /* name */
1525 TRUE, /* partial_inplace */
1526 0xffff, /* src_mask */
1527 0xffff, /* dst_mask */
1528 FALSE), /* pcrel_offset */
1530 EMPTY_HOWTO (7),
1532 /* Non modifiable absolute branch. */
1533 HOWTO (R_BA, /* type */
1534 0, /* rightshift */
1535 2, /* size (0 = byte, 1 = short, 2 = long) */
1536 26, /* bitsize */
1537 FALSE, /* pc_relative */
1538 0, /* bitpos */
1539 complain_overflow_bitfield, /* complain_on_overflow */
1540 0, /* special_function */
1541 "R_BA_26", /* name */
1542 TRUE, /* partial_inplace */
1543 0x03fffffc, /* src_mask */
1544 0x03fffffc, /* dst_mask */
1545 FALSE), /* pcrel_offset */
1547 EMPTY_HOWTO (9),
1549 /* Non modifiable relative branch. */
1550 HOWTO (R_BR, /* type */
1551 0, /* rightshift */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1553 26, /* bitsize */
1554 TRUE, /* pc_relative */
1555 0, /* bitpos */
1556 complain_overflow_signed, /* complain_on_overflow */
1557 0, /* special_function */
1558 "R_BR", /* name */
1559 TRUE, /* partial_inplace */
1560 0x03fffffc, /* src_mask */
1561 0x03fffffc, /* dst_mask */
1562 FALSE), /* pcrel_offset */
1564 EMPTY_HOWTO (0xb),
1566 /* Indirect load. */
1567 HOWTO (R_RL, /* type */
1568 0, /* rightshift */
1569 1, /* size (0 = byte, 1 = short, 2 = long) */
1570 16, /* bitsize */
1571 FALSE, /* pc_relative */
1572 0, /* bitpos */
1573 complain_overflow_bitfield, /* complain_on_overflow */
1574 0, /* special_function */
1575 "R_RL", /* name */
1576 TRUE, /* partial_inplace */
1577 0xffff, /* src_mask */
1578 0xffff, /* dst_mask */
1579 FALSE), /* pcrel_offset */
1581 /* Load address. */
1582 HOWTO (R_RLA, /* type */
1583 0, /* rightshift */
1584 1, /* size (0 = byte, 1 = short, 2 = long) */
1585 16, /* bitsize */
1586 FALSE, /* pc_relative */
1587 0, /* bitpos */
1588 complain_overflow_bitfield, /* complain_on_overflow */
1589 0, /* special_function */
1590 "R_RLA", /* name */
1591 TRUE, /* partial_inplace */
1592 0xffff, /* src_mask */
1593 0xffff, /* dst_mask */
1594 FALSE), /* pcrel_offset */
1596 EMPTY_HOWTO (0xe),
1598 /* Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
1599 HOWTO (R_REF, /* type */
1600 0, /* rightshift */
1601 0, /* size (0 = byte, 1 = short, 2 = long) */
1602 1, /* bitsize */
1603 FALSE, /* pc_relative */
1604 0, /* bitpos */
1605 complain_overflow_dont, /* complain_on_overflow */
1606 0, /* special_function */
1607 "R_REF", /* name */
1608 FALSE, /* partial_inplace */
1609 0, /* src_mask */
1610 0, /* dst_mask */
1611 FALSE), /* pcrel_offset */
1613 EMPTY_HOWTO (0x10),
1614 EMPTY_HOWTO (0x11),
1616 /* TOC relative indirect load. */
1617 HOWTO (R_TRL, /* type */
1618 0, /* rightshift */
1619 1, /* size (0 = byte, 1 = short, 2 = long) */
1620 16, /* bitsize */
1621 FALSE, /* pc_relative */
1622 0, /* bitpos */
1623 complain_overflow_bitfield, /* complain_on_overflow */
1624 0, /* special_function */
1625 "R_TRL", /* name */
1626 TRUE, /* partial_inplace */
1627 0xffff, /* src_mask */
1628 0xffff, /* dst_mask */
1629 FALSE), /* pcrel_offset */
1631 /* TOC relative load address. */
1632 HOWTO (R_TRLA, /* type */
1633 0, /* rightshift */
1634 1, /* size (0 = byte, 1 = short, 2 = long) */
1635 16, /* bitsize */
1636 FALSE, /* pc_relative */
1637 0, /* bitpos */
1638 complain_overflow_bitfield, /* complain_on_overflow */
1639 0, /* special_function */
1640 "R_TRLA", /* name */
1641 TRUE, /* partial_inplace */
1642 0xffff, /* src_mask */
1643 0xffff, /* dst_mask */
1644 FALSE), /* pcrel_offset */
1646 /* Modifiable relative branch. */
1647 HOWTO (R_RRTBI, /* type */
1648 1, /* rightshift */
1649 2, /* size (0 = byte, 1 = short, 2 = long) */
1650 32, /* bitsize */
1651 FALSE, /* pc_relative */
1652 0, /* bitpos */
1653 complain_overflow_bitfield, /* complain_on_overflow */
1654 0, /* special_function */
1655 "R_RRTBI", /* name */
1656 TRUE, /* partial_inplace */
1657 0xffffffff, /* src_mask */
1658 0xffffffff, /* dst_mask */
1659 FALSE), /* pcrel_offset */
1661 /* Modifiable absolute branch. */
1662 HOWTO (R_RRTBA, /* type */
1663 1, /* rightshift */
1664 2, /* size (0 = byte, 1 = short, 2 = long) */
1665 32, /* bitsize */
1666 FALSE, /* pc_relative */
1667 0, /* bitpos */
1668 complain_overflow_bitfield, /* complain_on_overflow */
1669 0, /* special_function */
1670 "R_RRTBA", /* name */
1671 TRUE, /* partial_inplace */
1672 0xffffffff, /* src_mask */
1673 0xffffffff, /* dst_mask */
1674 FALSE), /* pcrel_offset */
1676 /* Modifiable call absolute indirect. */
1677 HOWTO (R_CAI, /* type */
1678 0, /* rightshift */
1679 1, /* size (0 = byte, 1 = short, 2 = long) */
1680 16, /* bitsize */
1681 FALSE, /* pc_relative */
1682 0, /* bitpos */
1683 complain_overflow_bitfield, /* complain_on_overflow */
1684 0, /* special_function */
1685 "R_CAI", /* name */
1686 TRUE, /* partial_inplace */
1687 0xffff, /* src_mask */
1688 0xffff, /* dst_mask */
1689 FALSE), /* pcrel_offset */
1691 /* Modifiable call relative. */
1692 HOWTO (R_CREL, /* type */
1693 0, /* rightshift */
1694 1, /* size (0 = byte, 1 = short, 2 = long) */
1695 16, /* bitsize */
1696 FALSE, /* pc_relative */
1697 0, /* bitpos */
1698 complain_overflow_bitfield, /* complain_on_overflow */
1699 0, /* special_function */
1700 "R_CREL", /* name */
1701 TRUE, /* partial_inplace */
1702 0xffff, /* src_mask */
1703 0xffff, /* dst_mask */
1704 FALSE), /* pcrel_offset */
1706 /* Modifiable branch absolute. */
1707 HOWTO (R_RBA, /* type */
1708 0, /* rightshift */
1709 2, /* size (0 = byte, 1 = short, 2 = long) */
1710 26, /* bitsize */
1711 FALSE, /* pc_relative */
1712 0, /* bitpos */
1713 complain_overflow_bitfield, /* complain_on_overflow */
1714 0, /* special_function */
1715 "R_RBA", /* name */
1716 TRUE, /* partial_inplace */
1717 0x03fffffc, /* src_mask */
1718 0x03fffffc, /* dst_mask */
1719 FALSE), /* pcrel_offset */
1721 /* Modifiable branch absolute. */
1722 HOWTO (R_RBAC, /* type */
1723 0, /* rightshift */
1724 2, /* size (0 = byte, 1 = short, 2 = long) */
1725 32, /* bitsize */
1726 FALSE, /* pc_relative */
1727 0, /* bitpos */
1728 complain_overflow_bitfield, /* complain_on_overflow */
1729 0, /* special_function */
1730 "R_RBAC", /* name */
1731 TRUE, /* partial_inplace */
1732 0xffffffff, /* src_mask */
1733 0xffffffff, /* dst_mask */
1734 FALSE), /* pcrel_offset */
1736 /* Modifiable branch relative. */
1737 HOWTO (R_RBR, /* type */
1738 0, /* rightshift */
1739 2, /* size (0 = byte, 1 = short, 2 = long) */
1740 26, /* bitsize */
1741 FALSE, /* pc_relative */
1742 0, /* bitpos */
1743 complain_overflow_signed, /* complain_on_overflow */
1744 0, /* special_function */
1745 "R_RBR_26", /* name */
1746 TRUE, /* partial_inplace */
1747 0x03fffffc, /* src_mask */
1748 0x03fffffc, /* dst_mask */
1749 FALSE), /* pcrel_offset */
1751 /* Modifiable branch absolute. */
1752 HOWTO (R_RBRC, /* type */
1753 0, /* rightshift */
1754 1, /* size (0 = byte, 1 = short, 2 = long) */
1755 16, /* bitsize */
1756 FALSE, /* pc_relative */
1757 0, /* bitpos */
1758 complain_overflow_bitfield, /* complain_on_overflow */
1759 0, /* special_function */
1760 "R_RBRC", /* name */
1761 TRUE, /* partial_inplace */
1762 0xffff, /* src_mask */
1763 0xffff, /* dst_mask */
1764 FALSE), /* pcrel_offset */
1766 HOWTO (R_POS, /* type */
1767 0, /* rightshift */
1768 2, /* size (0 = byte, 1 = short, 2 = long) */
1769 32, /* bitsize */
1770 FALSE, /* pc_relative */
1771 0, /* bitpos */
1772 complain_overflow_bitfield, /* complain_on_overflow */
1773 0, /* special_function */
1774 "R_POS_32", /* name */
1775 TRUE, /* partial_inplace */
1776 0xffffffff, /* src_mask */
1777 0xffffffff, /* dst_mask */
1778 FALSE), /* pcrel_offset */
1780 /* 16 bit Non modifiable absolute branch. */
1781 HOWTO (R_BA, /* type */
1782 0, /* rightshift */
1783 1, /* size (0 = byte, 1 = short, 2 = long) */
1784 16, /* bitsize */
1785 FALSE, /* pc_relative */
1786 0, /* bitpos */
1787 complain_overflow_bitfield, /* complain_on_overflow */
1788 0, /* special_function */
1789 "R_BA_16", /* name */
1790 TRUE, /* partial_inplace */
1791 0xfffc, /* src_mask */
1792 0xfffc, /* dst_mask */
1793 FALSE), /* pcrel_offset */
1795 /* Modifiable branch relative. */
1796 HOWTO (R_RBR, /* type */
1797 0, /* rightshift */
1798 1, /* size (0 = byte, 1 = short, 2 = long) */
1799 16, /* bitsize */
1800 FALSE, /* pc_relative */
1801 0, /* bitpos */
1802 complain_overflow_signed, /* complain_on_overflow */
1803 0, /* special_function */
1804 "R_RBR_16", /* name */
1805 TRUE, /* partial_inplace */
1806 0xffff, /* src_mask */
1807 0xffff, /* dst_mask */
1808 FALSE), /* pcrel_offset */
1810 /* Modifiable branch absolute. */
1811 HOWTO (R_RBA, /* type */
1812 0, /* rightshift */
1813 1, /* size (0 = byte, 1 = short, 2 = long) */
1814 16, /* bitsize */
1815 FALSE, /* pc_relative */
1816 0, /* bitpos */
1817 complain_overflow_bitfield, /* complain_on_overflow */
1818 0, /* special_function */
1819 "R_RBA_16", /* name */
1820 TRUE, /* partial_inplace */
1821 0xffff, /* src_mask */
1822 0xffff, /* dst_mask */
1823 FALSE), /* pcrel_offset */
1827 void
1828 xcoff64_rtype2howto (relent, internal)
1829 arelent *relent;
1830 struct internal_reloc *internal;
1832 if (internal->r_type > R_RBRC)
1833 abort ();
1835 /* Default howto layout works most of the time */
1836 relent->howto = &xcoff64_howto_table[internal->r_type];
1838 /* Special case some 16 bit reloc */
1839 if (15 == (internal->r_size & 0x3f))
1841 if (R_BA == internal->r_type)
1842 relent->howto = &xcoff64_howto_table[0x1d];
1843 else if (R_RBR == internal->r_type)
1844 relent->howto = &xcoff64_howto_table[0x1e];
1845 else if (R_RBA == internal->r_type)
1846 relent->howto = &xcoff64_howto_table[0x1f];
1848 /* Special case 32 bit */
1849 else if (31 == (internal->r_size & 0x3f))
1851 if (R_POS == internal->r_type)
1852 relent->howto = &xcoff64_howto_table[0x1c];
1855 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1856 relocation, as well as indicating whether it is signed or not.
1857 Doublecheck that the relocation information gathered from the
1858 type matches this information. The bitsize is not significant
1859 for R_REF relocs. */
1860 if (relent->howto->dst_mask != 0
1861 && (relent->howto->bitsize
1862 != ((unsigned int) internal->r_size & 0x3f) + 1))
1863 abort ();
1866 reloc_howto_type *
1867 xcoff64_reloc_type_lookup (abfd, code)
1868 bfd *abfd ATTRIBUTE_UNUSED;
1869 bfd_reloc_code_real_type code;
1871 switch (code)
1873 case BFD_RELOC_PPC_B26:
1874 return &xcoff64_howto_table[0xa];
1875 case BFD_RELOC_PPC_BA16:
1876 return &xcoff64_howto_table[0x1d];
1877 case BFD_RELOC_PPC_BA26:
1878 return &xcoff64_howto_table[8];
1879 case BFD_RELOC_PPC_TOC16:
1880 return &xcoff64_howto_table[3];
1881 case BFD_RELOC_32:
1882 case BFD_RELOC_CTOR:
1883 return &xcoff64_howto_table[0x1c];
1884 case BFD_RELOC_64:
1885 return &xcoff64_howto_table[0];
1886 case BFD_RELOC_NONE:
1887 return &xcoff64_howto_table[0xf];
1888 default:
1889 return NULL;
1893 static reloc_howto_type *
1894 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1895 const char *r_name)
1897 unsigned int i;
1899 for (i = 0;
1900 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1901 i++)
1902 if (xcoff64_howto_table[i].name != NULL
1903 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1904 return &xcoff64_howto_table[i];
1906 return NULL;
1909 /* Read in the armap of an XCOFF archive. */
1911 static bfd_boolean
1912 xcoff64_slurp_armap (abfd)
1913 bfd *abfd;
1915 file_ptr off;
1916 size_t namlen;
1917 bfd_size_type sz, amt;
1918 bfd_byte *contents, *cend;
1919 bfd_vma c, i;
1920 carsym *arsym;
1921 bfd_byte *p;
1922 file_ptr pos;
1924 /* This is for the new format. */
1925 struct xcoff_ar_hdr_big hdr;
1927 if (xcoff_ardata (abfd) == NULL)
1929 bfd_has_map (abfd) = FALSE;
1930 return TRUE;
1933 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1934 (const char **) NULL, 10);
1935 if (off == 0)
1937 bfd_has_map (abfd) = FALSE;
1938 return TRUE;
1941 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1942 return FALSE;
1944 /* The symbol table starts with a normal archive header. */
1945 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1946 != SIZEOF_AR_HDR_BIG)
1947 return FALSE;
1949 /* Skip the name (normally empty). */
1950 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1951 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1952 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1953 return FALSE;
1955 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1957 /* Read in the entire symbol table. */
1958 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1959 if (contents == NULL)
1960 return FALSE;
1961 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1962 return FALSE;
1964 /* The symbol table starts with an eight byte count. */
1965 c = H_GET_64 (abfd, contents);
1967 if (c * 8 >= sz)
1969 bfd_set_error (bfd_error_bad_value);
1970 return FALSE;
1972 amt = c;
1973 amt *= sizeof (carsym);
1974 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1975 if (bfd_ardata (abfd)->symdefs == NULL)
1976 return FALSE;
1978 /* After the count comes a list of eight byte file offsets. */
1979 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1980 i < c;
1981 ++i, ++arsym, p += 8)
1982 arsym->file_offset = H_GET_64 (abfd, p);
1984 /* After the file offsets come null terminated symbol names. */
1985 cend = contents + sz;
1986 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1987 i < c;
1988 ++i, ++arsym, p += strlen ((char *) p) + 1)
1990 if (p >= cend)
1992 bfd_set_error (bfd_error_bad_value);
1993 return FALSE;
1995 arsym->name = (char *) p;
1998 bfd_ardata (abfd)->symdef_count = c;
1999 bfd_has_map (abfd) = TRUE;
2001 return TRUE;
2005 /* See if this is an NEW XCOFF archive. */
2007 static const bfd_target *
2008 xcoff64_archive_p (abfd)
2009 bfd *abfd;
2011 struct artdata *tdata_hold;
2012 char magic[SXCOFFARMAG];
2013 /* This is the new format. */
2014 struct xcoff_ar_file_hdr_big hdr;
2015 bfd_size_type amt = SXCOFFARMAG;
2017 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2019 if (bfd_get_error () != bfd_error_system_call)
2020 bfd_set_error (bfd_error_wrong_format);
2021 return NULL;
2024 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2026 bfd_set_error (bfd_error_wrong_format);
2027 return NULL;
2030 /* Copy over the magic string. */
2031 memcpy (hdr.magic, magic, SXCOFFARMAG);
2033 /* Now read the rest of the file header. */
2034 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2035 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
2037 if (bfd_get_error () != bfd_error_system_call)
2038 bfd_set_error (bfd_error_wrong_format);
2039 return NULL;
2042 tdata_hold = bfd_ardata (abfd);
2044 amt = sizeof (struct artdata);
2045 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2046 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2047 goto error_ret_restore;
2049 /* Already cleared by bfd_zalloc above.
2050 bfd_ardata (abfd)->cache = NULL;
2051 bfd_ardata (abfd)->archive_head = NULL;
2052 bfd_ardata (abfd)->symdefs = NULL;
2053 bfd_ardata (abfd)->extended_names = NULL;
2054 bfd_ardata (abfd)->extended_names_size = 0; */
2055 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2056 (const char **) NULL,
2057 10);
2059 amt = SIZEOF_AR_FILE_HDR_BIG;
2060 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2061 if (bfd_ardata (abfd)->tdata == NULL)
2062 goto error_ret;
2064 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2066 if (! xcoff64_slurp_armap (abfd))
2068 error_ret:
2069 bfd_release (abfd, bfd_ardata (abfd));
2070 error_ret_restore:
2071 bfd_ardata (abfd) = tdata_hold;
2072 return NULL;
2075 return abfd->xvec;
2079 /* Open the next element in an XCOFF archive. */
2081 static bfd *
2082 xcoff64_openr_next_archived_file (archive, last_file)
2083 bfd *archive;
2084 bfd *last_file;
2086 bfd_vma filestart;
2088 if ((xcoff_ardata (archive) == NULL)
2089 || ! xcoff_big_format_p (archive))
2091 bfd_set_error (bfd_error_invalid_operation);
2092 return NULL;
2095 if (last_file == NULL)
2097 filestart = bfd_ardata (archive)->first_file_filepos;
2099 else
2101 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2102 (const char **) NULL, 10);
2105 if (filestart == 0
2106 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2107 (const char **) NULL, 10)
2108 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2109 (const char **) NULL, 10))
2111 bfd_set_error (bfd_error_no_more_archived_files);
2112 return NULL;
2115 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2118 /* We can't use the usual coff_sizeof_headers routine, because AIX
2119 always uses an a.out header. */
2121 static int
2122 xcoff64_sizeof_headers (bfd *abfd,
2123 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2125 int size;
2127 size = bfd_coff_filhsz (abfd);
2129 /* Don't think the small aout header can be used since some of the
2130 old elements have been reordered past the end of the old coff
2131 small aout size. */
2133 if (xcoff_data (abfd)->full_aouthdr)
2134 size += bfd_coff_aoutsz (abfd);
2136 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2137 return size;
2142 static asection *
2143 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2144 bfd *abfd;
2145 union internal_auxent *aux;
2146 const char *symbol_name;
2148 asection *return_value = NULL;
2150 /* Changes from 32 :
2151 .sv == 8, is only for 32 bit programs
2152 .ti == 12 and .tb == 13 are now reserved. */
2153 static const char *names[19] =
2155 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2156 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2157 ".td", ".sv64", ".sv3264"
2160 if ((19 >= aux->x_csect.x_smclas)
2161 && (NULL != names[aux->x_csect.x_smclas]))
2164 return_value = bfd_make_section_anyway
2165 (abfd, names[aux->x_csect.x_smclas]);
2168 else
2170 (*_bfd_error_handler)
2171 (_("%B: symbol `%s' has unrecognized smclas %d"),
2172 abfd, symbol_name, aux->x_csect.x_smclas);
2173 bfd_set_error (bfd_error_bad_value);
2176 return return_value;
2179 static bfd_boolean
2180 xcoff64_is_lineno_count_overflow (abfd, value)
2181 bfd *abfd ATTRIBUTE_UNUSED;
2182 bfd_vma value ATTRIBUTE_UNUSED;
2184 return FALSE;
2187 static bfd_boolean
2188 xcoff64_is_reloc_count_overflow (abfd, value)
2189 bfd *abfd ATTRIBUTE_UNUSED;
2190 bfd_vma value ATTRIBUTE_UNUSED;
2192 return FALSE;
2195 static bfd_vma
2196 xcoff64_loader_symbol_offset (abfd, ldhdr)
2197 bfd *abfd ATTRIBUTE_UNUSED;
2198 struct internal_ldhdr *ldhdr;
2200 return (ldhdr->l_symoff);
2203 static bfd_vma
2204 xcoff64_loader_reloc_offset (abfd, ldhdr)
2205 bfd *abfd ATTRIBUTE_UNUSED;
2206 struct internal_ldhdr *ldhdr;
2208 return (ldhdr->l_rldoff);
2211 static bfd_boolean
2212 xcoff64_bad_format_hook (abfd, filehdr)
2213 bfd * abfd;
2214 PTR filehdr;
2216 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2218 /* Check flavor first. */
2219 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2220 return FALSE;
2222 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2223 return FALSE;
2225 return TRUE;
2228 static bfd_boolean
2229 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2230 bfd *abfd;
2231 const char *init;
2232 const char *fini;
2233 bfd_boolean rtld;
2235 bfd_byte filehdr_ext[FILHSZ];
2236 bfd_byte scnhdr_ext[SCNHSZ * 3];
2237 bfd_byte syment_ext[SYMESZ * 10];
2238 bfd_byte reloc_ext[RELSZ * 3];
2239 bfd_byte *data_buffer;
2240 bfd_size_type data_buffer_size;
2241 bfd_byte *string_table, *st_tmp;
2242 bfd_size_type string_table_size;
2243 bfd_vma val;
2244 size_t initsz, finisz;
2245 struct internal_filehdr filehdr;
2246 struct internal_scnhdr text_scnhdr;
2247 struct internal_scnhdr data_scnhdr;
2248 struct internal_scnhdr bss_scnhdr;
2249 struct internal_syment syment;
2250 union internal_auxent auxent;
2251 struct internal_reloc reloc;
2253 char *text_name = ".text";
2254 char *data_name = ".data";
2255 char *bss_name = ".bss";
2256 char *rtinit_name = "__rtinit";
2257 char *rtld_name = "__rtld";
2259 if (! bfd_xcoff_rtinit_size (abfd))
2260 return FALSE;
2262 initsz = (init == NULL ? 0 : 1 + strlen (init));
2263 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2265 /* File header. */
2266 memset (filehdr_ext, 0, FILHSZ);
2267 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2268 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2269 filehdr.f_nscns = 3;
2270 filehdr.f_timdat = 0;
2271 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2272 filehdr.f_symptr = 0; /* set below */
2273 filehdr.f_opthdr = 0;
2274 filehdr.f_flags = 0;
2276 /* Section headers. */
2277 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2279 /* Text. */
2280 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2281 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2282 text_scnhdr.s_paddr = 0;
2283 text_scnhdr.s_vaddr = 0;
2284 text_scnhdr.s_size = 0;
2285 text_scnhdr.s_scnptr = 0;
2286 text_scnhdr.s_relptr = 0;
2287 text_scnhdr.s_lnnoptr = 0;
2288 text_scnhdr.s_nreloc = 0;
2289 text_scnhdr.s_nlnno = 0;
2290 text_scnhdr.s_flags = STYP_TEXT;
2292 /* Data. */
2293 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2294 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2295 data_scnhdr.s_paddr = 0;
2296 data_scnhdr.s_vaddr = 0;
2297 data_scnhdr.s_size = 0; /* set below */
2298 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2299 data_scnhdr.s_relptr = 0; /* set below */
2300 data_scnhdr.s_lnnoptr = 0;
2301 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2302 data_scnhdr.s_nlnno = 0;
2303 data_scnhdr.s_flags = STYP_DATA;
2305 /* Bss. */
2306 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2307 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2308 bss_scnhdr.s_paddr = 0; /* set below */
2309 bss_scnhdr.s_vaddr = 0; /* set below */
2310 bss_scnhdr.s_size = 0; /* set below */
2311 bss_scnhdr.s_scnptr = 0;
2312 bss_scnhdr.s_relptr = 0;
2313 bss_scnhdr.s_lnnoptr = 0;
2314 bss_scnhdr.s_nreloc = 0;
2315 bss_scnhdr.s_nlnno = 0;
2316 bss_scnhdr.s_flags = STYP_BSS;
2318 /* .data
2319 0x0000 0x00000000 : rtl
2320 0x0004 0x00000000 :
2321 0x0008 0x00000018 : offset to init, or 0
2322 0x000C 0x00000038 : offset to fini, or 0
2323 0x0010 0x00000010 : size of descriptor
2324 0x0014 0x00000000 : pad
2325 0x0018 0x00000000 : init, needs a reloc
2326 0x001C 0x00000000 :
2327 0x0020 0x00000058 : offset to init name
2328 0x0024 0x00000000 : flags, padded to a word
2329 0x0028 0x00000000 : empty init
2330 0x002C 0x00000000 :
2331 0x0030 0x00000000 :
2332 0x0034 0x00000000 :
2333 0x0038 0x00000000 : fini, needs a reloc
2334 0x003C 0x00000000 :
2335 0x0040 0x00000??? : offset to fini name
2336 0x0044 0x00000000 : flags, padded to a word
2337 0x0048 0x00000000 : empty fini
2338 0x004C 0x00000000 :
2339 0x0050 0x00000000 :
2340 0x0054 0x00000000 :
2341 0x0058 init name
2342 0x0058 + initsz fini name */
2344 data_buffer_size = 0x0058 + initsz + finisz;
2345 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2346 data_buffer = NULL;
2347 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2348 if (data_buffer == NULL)
2349 return FALSE;
2351 if (initsz)
2353 val = 0x18;
2354 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2355 val = 0x58;
2356 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2357 memcpy (&data_buffer[val], init, initsz);
2360 if (finisz)
2362 val = 0x38;
2363 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2364 val = 0x58 + initsz;
2365 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2366 memcpy (&data_buffer[val], fini, finisz);
2369 val = 0x10;
2370 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2371 data_scnhdr.s_size = data_buffer_size;
2372 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2374 /* String table. */
2375 string_table_size = 4;
2376 string_table_size += strlen (data_name) + 1;
2377 string_table_size += strlen (rtinit_name) + 1;
2378 string_table_size += initsz;
2379 string_table_size += finisz;
2380 if (rtld)
2381 string_table_size += strlen (rtld_name) + 1;
2383 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2384 if (string_table == NULL)
2385 return FALSE;
2387 val = string_table_size;
2388 bfd_put_32 (abfd, val, &string_table[0]);
2389 st_tmp = string_table + 4;
2391 /* symbols
2392 0. .data csect
2393 2. __rtinit
2394 4. init function
2395 6. fini function
2396 8. __rtld */
2397 memset (syment_ext, 0, 10 * SYMESZ);
2398 memset (reloc_ext, 0, 3 * RELSZ);
2400 /* .data csect */
2401 memset (&syment, 0, sizeof (struct internal_syment));
2402 memset (&auxent, 0, sizeof (union internal_auxent));
2404 syment._n._n_n._n_offset = st_tmp - string_table;
2405 memcpy (st_tmp, data_name, strlen (data_name));
2406 st_tmp += strlen (data_name) + 1;
2408 syment.n_scnum = 2;
2409 syment.n_sclass = C_HIDEXT;
2410 syment.n_numaux = 1;
2411 auxent.x_csect.x_scnlen.l = data_buffer_size;
2412 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2413 auxent.x_csect.x_smclas = XMC_RW;
2414 bfd_coff_swap_sym_out (abfd, &syment,
2415 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2416 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2417 syment.n_numaux,
2418 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2419 filehdr.f_nsyms += 2;
2421 /* __rtinit */
2422 memset (&syment, 0, sizeof (struct internal_syment));
2423 memset (&auxent, 0, sizeof (union internal_auxent));
2424 syment._n._n_n._n_offset = st_tmp - string_table;
2425 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2426 st_tmp += strlen (rtinit_name) + 1;
2428 syment.n_scnum = 2;
2429 syment.n_sclass = C_EXT;
2430 syment.n_numaux = 1;
2431 auxent.x_csect.x_smtyp = XTY_LD;
2432 auxent.x_csect.x_smclas = XMC_RW;
2433 bfd_coff_swap_sym_out (abfd, &syment,
2434 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2435 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2436 syment.n_numaux,
2437 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2438 filehdr.f_nsyms += 2;
2440 /* Init. */
2441 if (initsz)
2443 memset (&syment, 0, sizeof (struct internal_syment));
2444 memset (&auxent, 0, sizeof (union internal_auxent));
2446 syment._n._n_n._n_offset = st_tmp - string_table;
2447 memcpy (st_tmp, init, initsz);
2448 st_tmp += initsz;
2450 syment.n_sclass = C_EXT;
2451 syment.n_numaux = 1;
2452 bfd_coff_swap_sym_out (abfd, &syment,
2453 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2454 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2455 syment.n_numaux,
2456 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2457 /* Reloc. */
2458 memset (&reloc, 0, sizeof (struct internal_reloc));
2459 reloc.r_vaddr = 0x0018;
2460 reloc.r_symndx = filehdr.f_nsyms;
2461 reloc.r_type = R_POS;
2462 reloc.r_size = 63;
2463 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2465 filehdr.f_nsyms += 2;
2466 data_scnhdr.s_nreloc += 1;
2469 /* Finit. */
2470 if (finisz)
2472 memset (&syment, 0, sizeof (struct internal_syment));
2473 memset (&auxent, 0, sizeof (union internal_auxent));
2475 syment._n._n_n._n_offset = st_tmp - string_table;
2476 memcpy (st_tmp, fini, finisz);
2477 st_tmp += finisz;
2479 syment.n_sclass = C_EXT;
2480 syment.n_numaux = 1;
2481 bfd_coff_swap_sym_out (abfd, &syment,
2482 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2483 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2484 syment.n_numaux,
2485 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2487 /* Reloc. */
2488 memset (&reloc, 0, sizeof (struct internal_reloc));
2489 reloc.r_vaddr = 0x0038;
2490 reloc.r_symndx = filehdr.f_nsyms;
2491 reloc.r_type = R_POS;
2492 reloc.r_size = 63;
2493 bfd_coff_swap_reloc_out (abfd, &reloc,
2494 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2496 filehdr.f_nsyms += 2;
2497 data_scnhdr.s_nreloc += 1;
2500 if (rtld)
2502 memset (&syment, 0, sizeof (struct internal_syment));
2503 memset (&auxent, 0, sizeof (union internal_auxent));
2505 syment._n._n_n._n_offset = st_tmp - string_table;
2506 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2507 st_tmp += strlen (rtld_name) + 1;
2509 syment.n_sclass = C_EXT;
2510 syment.n_numaux = 1;
2511 bfd_coff_swap_sym_out (abfd, &syment,
2512 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2513 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2514 syment.n_numaux,
2515 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2517 /* Reloc. */
2518 memset (&reloc, 0, sizeof (struct internal_reloc));
2519 reloc.r_vaddr = 0x0000;
2520 reloc.r_symndx = filehdr.f_nsyms;
2521 reloc.r_type = R_POS;
2522 reloc.r_size = 63;
2523 bfd_coff_swap_reloc_out (abfd, &reloc,
2524 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2526 filehdr.f_nsyms += 2;
2527 data_scnhdr.s_nreloc += 1;
2529 bss_scnhdr.s_size = 0;
2532 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2533 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2535 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2536 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2537 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2538 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2539 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2540 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2541 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2542 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2543 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2544 bfd_bwrite (string_table, string_table_size, abfd);
2546 free (data_buffer);
2547 data_buffer = NULL;
2549 return TRUE;
2552 /* The typical dynamic reloc. */
2554 static reloc_howto_type xcoff64_dynamic_reloc =
2555 HOWTO (0, /* type */
2556 0, /* rightshift */
2557 4, /* size (0 = byte, 1 = short, 2 = long) */
2558 64, /* bitsize */
2559 FALSE, /* pc_relative */
2560 0, /* bitpos */
2561 complain_overflow_bitfield, /* complain_on_overflow */
2562 0, /* special_function */
2563 "R_POS", /* name */
2564 TRUE, /* partial_inplace */
2565 MINUS_ONE, /* src_mask */
2566 MINUS_ONE, /* dst_mask */
2567 FALSE); /* pcrel_offset */
2569 static unsigned long xcoff64_glink_code[10] =
2571 0xe9820000, /* ld r12,0(r2) */
2572 0xf8410028, /* std r2,40(r1) */
2573 0xe80c0000, /* ld r0,0(r12) */
2574 0xe84c0008, /* ld r0,8(r12) */
2575 0x7c0903a6, /* mtctr r0 */
2576 0x4e800420, /* bctr */
2577 0x00000000, /* start of traceback table */
2578 0x000ca000, /* traceback table */
2579 0x00000000, /* traceback table */
2580 0x00000018, /* ??? */
2583 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2585 { /* COFF backend, defined in libcoff.h. */
2586 _bfd_xcoff64_swap_aux_in,
2587 _bfd_xcoff64_swap_sym_in,
2588 _bfd_xcoff64_swap_lineno_in,
2589 _bfd_xcoff64_swap_aux_out,
2590 _bfd_xcoff64_swap_sym_out,
2591 _bfd_xcoff64_swap_lineno_out,
2592 xcoff64_swap_reloc_out,
2593 coff_swap_filehdr_out,
2594 coff_swap_aouthdr_out,
2595 coff_swap_scnhdr_out,
2596 FILHSZ,
2597 AOUTSZ,
2598 SCNHSZ,
2599 SYMESZ,
2600 AUXESZ,
2601 RELSZ,
2602 LINESZ,
2603 FILNMLEN,
2604 TRUE, /* _bfd_coff_long_filenames */
2605 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2606 3, /* _bfd_coff_default_section_alignment_power */
2607 TRUE, /* _bfd_coff_force_symnames_in_strings */
2608 4, /* _bfd_coff_debug_string_prefix_length */
2609 coff_swap_filehdr_in,
2610 coff_swap_aouthdr_in,
2611 coff_swap_scnhdr_in,
2612 xcoff64_swap_reloc_in,
2613 xcoff64_bad_format_hook,
2614 coff_set_arch_mach_hook,
2615 coff_mkobject_hook,
2616 styp_to_sec_flags,
2617 coff_set_alignment_hook,
2618 coff_slurp_symbol_table,
2619 symname_in_debug_hook,
2620 coff_pointerize_aux_hook,
2621 coff_print_aux,
2622 dummy_reloc16_extra_cases,
2623 dummy_reloc16_estimate,
2624 NULL, /* bfd_coff_symbol_classification */
2625 coff_compute_section_file_positions,
2626 NULL, /* _bfd_coff_start_final_link */
2627 xcoff64_ppc_relocate_section,
2628 coff_rtype_to_howto,
2629 NULL, /* _bfd_coff_adjust_symndx */
2630 _bfd_generic_link_add_one_symbol,
2631 coff_link_output_has_begun,
2632 coff_final_link_postscript,
2633 NULL /* print_pdata. */
2636 0x01EF, /* magic number */
2637 bfd_arch_powerpc,
2638 bfd_mach_ppc_620,
2640 /* Function pointers to xcoff specific swap routines. */
2641 xcoff64_swap_ldhdr_in,
2642 xcoff64_swap_ldhdr_out,
2643 xcoff64_swap_ldsym_in,
2644 xcoff64_swap_ldsym_out,
2645 xcoff64_swap_ldrel_in,
2646 xcoff64_swap_ldrel_out,
2648 /* Sizes. */
2649 LDHDRSZ,
2650 LDSYMSZ,
2651 LDRELSZ,
2652 24, /* _xcoff_function_descriptor_size */
2653 0, /* _xcoff_small_aout_header_size */
2655 /* Versions. */
2656 2, /* _xcoff_ldhdr_version */
2658 _bfd_xcoff64_put_symbol_name,
2659 _bfd_xcoff64_put_ldsymbol_name,
2660 &xcoff64_dynamic_reloc,
2661 xcoff64_create_csect_from_smclas,
2663 /* Lineno and reloc count overflow. */
2664 xcoff64_is_lineno_count_overflow,
2665 xcoff64_is_reloc_count_overflow,
2667 xcoff64_loader_symbol_offset,
2668 xcoff64_loader_reloc_offset,
2670 /* glink. */
2671 &xcoff64_glink_code[0],
2672 40, /* _xcoff_glink_size */
2674 /* rtinit. */
2675 88, /* _xcoff_rtinit_size */
2676 xcoff64_generate_rtinit,
2679 /* The transfer vector that leads the outside world to all of the above. */
2680 const bfd_target rs6000coff64_vec =
2682 "aixcoff64-rs6000",
2683 bfd_target_xcoff_flavour,
2684 BFD_ENDIAN_BIG, /* data byte order is big */
2685 BFD_ENDIAN_BIG, /* header byte order is big */
2687 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2688 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2690 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2691 0, /* leading char */
2692 '/', /* ar_pad_char */
2693 15, /* ar_max_namelen */
2695 /* data */
2696 bfd_getb64,
2697 bfd_getb_signed_64,
2698 bfd_putb64,
2699 bfd_getb32,
2700 bfd_getb_signed_32,
2701 bfd_putb32,
2702 bfd_getb16,
2703 bfd_getb_signed_16,
2704 bfd_putb16,
2706 /* hdrs */
2707 bfd_getb64,
2708 bfd_getb_signed_64,
2709 bfd_putb64,
2710 bfd_getb32,
2711 bfd_getb_signed_32,
2712 bfd_putb32,
2713 bfd_getb16,
2714 bfd_getb_signed_16,
2715 bfd_putb16,
2717 { /* bfd_check_format */
2718 _bfd_dummy_target,
2719 coff_object_p,
2720 xcoff64_archive_p,
2721 CORE_FILE_P
2724 { /* bfd_set_format */
2725 bfd_false,
2726 coff_mkobject,
2727 _bfd_generic_mkarchive,
2728 bfd_false
2731 {/* bfd_write_contents */
2732 bfd_false,
2733 xcoff64_write_object_contents,
2734 _bfd_xcoff_write_archive_contents,
2735 bfd_false
2738 /* Generic */
2739 bfd_true,
2740 bfd_true,
2741 coff_new_section_hook,
2742 _bfd_generic_get_section_contents,
2743 _bfd_generic_get_section_contents_in_window,
2745 /* Copy */
2746 _bfd_xcoff_copy_private_bfd_data,
2747 _bfd_generic_bfd_merge_private_bfd_data,
2748 _bfd_generic_init_private_section_data,
2749 _bfd_generic_bfd_copy_private_section_data,
2750 _bfd_generic_bfd_copy_private_symbol_data,
2751 _bfd_generic_bfd_copy_private_header_data,
2752 _bfd_generic_bfd_set_private_flags,
2753 _bfd_generic_bfd_print_private_bfd_data,
2755 /* Core */
2756 coff_core_file_failing_command,
2757 coff_core_file_failing_signal,
2758 coff_core_file_matches_executable_p,
2760 /* Archive */
2761 xcoff64_slurp_armap,
2762 _bfd_noarchive_slurp_extended_name_table,
2763 _bfd_noarchive_construct_extended_name_table,
2764 bfd_dont_truncate_arname,
2765 _bfd_xcoff_write_armap,
2766 _bfd_xcoff_read_ar_hdr,
2767 _bfd_generic_write_ar_hdr,
2768 xcoff64_openr_next_archived_file,
2769 _bfd_generic_get_elt_at_index,
2770 _bfd_xcoff_stat_arch_elt,
2771 bfd_true,
2773 /* Symbols */
2774 coff_get_symtab_upper_bound,
2775 coff_canonicalize_symtab,
2776 coff_make_empty_symbol,
2777 coff_print_symbol,
2778 coff_get_symbol_info,
2779 _bfd_xcoff_is_local_label_name,
2780 coff_bfd_is_target_special_symbol,
2781 coff_get_lineno,
2782 coff_find_nearest_line,
2783 _bfd_generic_find_line,
2784 coff_find_inliner_info,
2785 coff_bfd_make_debug_symbol,
2786 _bfd_generic_read_minisymbols,
2787 _bfd_generic_minisymbol_to_symbol,
2789 /* Reloc */
2790 coff_get_reloc_upper_bound,
2791 coff_canonicalize_reloc,
2792 xcoff64_reloc_type_lookup,
2793 xcoff64_reloc_name_lookup,
2795 /* Write */
2796 coff_set_arch_mach,
2797 coff_set_section_contents,
2799 /* Link */
2800 xcoff64_sizeof_headers,
2801 bfd_generic_get_relocated_section_contents,
2802 bfd_generic_relax_section,
2803 _bfd_xcoff_bfd_link_hash_table_create,
2804 _bfd_generic_link_hash_table_free,
2805 _bfd_xcoff_bfd_link_add_symbols,
2806 _bfd_generic_link_just_syms,
2807 _bfd_generic_copy_link_hash_symbol_type,
2808 _bfd_xcoff_bfd_final_link,
2809 _bfd_generic_link_split_section,
2810 bfd_generic_gc_sections,
2811 bfd_generic_merge_sections,
2812 bfd_generic_is_group_section,
2813 bfd_generic_discard_group,
2814 _bfd_generic_section_already_linked,
2815 _bfd_xcoff_define_common_symbol,
2817 /* Dynamic */
2818 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2819 _bfd_xcoff_canonicalize_dynamic_symtab,
2820 _bfd_nodynamic_get_synthetic_symtab,
2821 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2822 _bfd_xcoff_canonicalize_dynamic_reloc,
2824 /* Opposite endian version, none exists */
2825 NULL,
2827 (void *) &bfd_xcoff_backend_data,
2830 extern const bfd_target *xcoff64_core_p
2831 PARAMS ((bfd *));
2832 extern bfd_boolean xcoff64_core_file_matches_executable_p
2833 PARAMS ((bfd *, bfd *));
2834 extern char *xcoff64_core_file_failing_command
2835 PARAMS ((bfd *));
2836 extern int xcoff64_core_file_failing_signal
2837 PARAMS ((bfd *));
2839 /* AIX 5 */
2840 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2842 { /* COFF backend, defined in libcoff.h. */
2843 _bfd_xcoff64_swap_aux_in,
2844 _bfd_xcoff64_swap_sym_in,
2845 _bfd_xcoff64_swap_lineno_in,
2846 _bfd_xcoff64_swap_aux_out,
2847 _bfd_xcoff64_swap_sym_out,
2848 _bfd_xcoff64_swap_lineno_out,
2849 xcoff64_swap_reloc_out,
2850 coff_swap_filehdr_out,
2851 coff_swap_aouthdr_out,
2852 coff_swap_scnhdr_out,
2853 FILHSZ,
2854 AOUTSZ,
2855 SCNHSZ,
2856 SYMESZ,
2857 AUXESZ,
2858 RELSZ,
2859 LINESZ,
2860 FILNMLEN,
2861 TRUE, /* _bfd_coff_long_filenames */
2862 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2863 3, /* _bfd_coff_default_section_alignment_power */
2864 TRUE, /* _bfd_coff_force_symnames_in_strings */
2865 4, /* _bfd_coff_debug_string_prefix_length */
2866 coff_swap_filehdr_in,
2867 coff_swap_aouthdr_in,
2868 coff_swap_scnhdr_in,
2869 xcoff64_swap_reloc_in,
2870 xcoff64_bad_format_hook,
2871 coff_set_arch_mach_hook,
2872 coff_mkobject_hook,
2873 styp_to_sec_flags,
2874 coff_set_alignment_hook,
2875 coff_slurp_symbol_table,
2876 symname_in_debug_hook,
2877 coff_pointerize_aux_hook,
2878 coff_print_aux,
2879 dummy_reloc16_extra_cases,
2880 dummy_reloc16_estimate,
2881 NULL, /* bfd_coff_sym_is_global */
2882 coff_compute_section_file_positions,
2883 NULL, /* _bfd_coff_start_final_link */
2884 xcoff64_ppc_relocate_section,
2885 coff_rtype_to_howto,
2886 NULL, /* _bfd_coff_adjust_symndx */
2887 _bfd_generic_link_add_one_symbol,
2888 coff_link_output_has_begun,
2889 coff_final_link_postscript,
2890 NULL /* print_pdata. */
2893 U64_TOCMAGIC, /* magic number */
2894 bfd_arch_powerpc,
2895 bfd_mach_ppc_620,
2897 /* Function pointers to xcoff specific swap routines. */
2898 xcoff64_swap_ldhdr_in,
2899 xcoff64_swap_ldhdr_out,
2900 xcoff64_swap_ldsym_in,
2901 xcoff64_swap_ldsym_out,
2902 xcoff64_swap_ldrel_in,
2903 xcoff64_swap_ldrel_out,
2905 /* Sizes. */
2906 LDHDRSZ,
2907 LDSYMSZ,
2908 LDRELSZ,
2909 24, /* _xcoff_function_descriptor_size */
2910 0, /* _xcoff_small_aout_header_size */
2911 /* Versions. */
2912 2, /* _xcoff_ldhdr_version */
2914 _bfd_xcoff64_put_symbol_name,
2915 _bfd_xcoff64_put_ldsymbol_name,
2916 &xcoff64_dynamic_reloc,
2917 xcoff64_create_csect_from_smclas,
2919 /* Lineno and reloc count overflow. */
2920 xcoff64_is_lineno_count_overflow,
2921 xcoff64_is_reloc_count_overflow,
2923 xcoff64_loader_symbol_offset,
2924 xcoff64_loader_reloc_offset,
2926 /* glink. */
2927 &xcoff64_glink_code[0],
2928 40, /* _xcoff_glink_size */
2930 /* rtinit. */
2931 88, /* _xcoff_rtinit_size */
2932 xcoff64_generate_rtinit,
2935 /* The transfer vector that leads the outside world to all of the above. */
2936 const bfd_target aix5coff64_vec =
2938 "aix5coff64-rs6000",
2939 bfd_target_xcoff_flavour,
2940 BFD_ENDIAN_BIG, /* data byte order is big */
2941 BFD_ENDIAN_BIG, /* header byte order is big */
2943 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2944 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2946 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2947 0, /* leading char */
2948 '/', /* ar_pad_char */
2949 15, /* ar_max_namelen */
2951 /* data */
2952 bfd_getb64,
2953 bfd_getb_signed_64,
2954 bfd_putb64,
2955 bfd_getb32,
2956 bfd_getb_signed_32,
2957 bfd_putb32,
2958 bfd_getb16,
2959 bfd_getb_signed_16,
2960 bfd_putb16,
2962 /* hdrs */
2963 bfd_getb64,
2964 bfd_getb_signed_64,
2965 bfd_putb64,
2966 bfd_getb32,
2967 bfd_getb_signed_32,
2968 bfd_putb32,
2969 bfd_getb16,
2970 bfd_getb_signed_16,
2971 bfd_putb16,
2973 { /* bfd_check_format */
2974 _bfd_dummy_target,
2975 coff_object_p,
2976 xcoff64_archive_p,
2977 xcoff64_core_p
2980 { /* bfd_set_format */
2981 bfd_false,
2982 coff_mkobject,
2983 _bfd_generic_mkarchive,
2984 bfd_false
2987 {/* bfd_write_contents */
2988 bfd_false,
2989 xcoff64_write_object_contents,
2990 _bfd_xcoff_write_archive_contents,
2991 bfd_false
2994 /* Generic */
2995 bfd_true,
2996 bfd_true,
2997 coff_new_section_hook,
2998 _bfd_generic_get_section_contents,
2999 _bfd_generic_get_section_contents_in_window,
3001 /* Copy */
3002 _bfd_xcoff_copy_private_bfd_data,
3003 _bfd_generic_bfd_merge_private_bfd_data,
3004 _bfd_generic_init_private_section_data,
3005 _bfd_generic_bfd_copy_private_section_data,
3006 _bfd_generic_bfd_copy_private_symbol_data,
3007 _bfd_generic_bfd_copy_private_header_data,
3008 _bfd_generic_bfd_set_private_flags,
3009 _bfd_generic_bfd_print_private_bfd_data,
3011 /* Core */
3012 xcoff64_core_file_failing_command,
3013 xcoff64_core_file_failing_signal,
3014 xcoff64_core_file_matches_executable_p,
3016 /* Archive */
3017 xcoff64_slurp_armap,
3018 _bfd_noarchive_slurp_extended_name_table,
3019 _bfd_noarchive_construct_extended_name_table,
3020 bfd_dont_truncate_arname,
3021 _bfd_xcoff_write_armap,
3022 _bfd_xcoff_read_ar_hdr,
3023 _bfd_generic_write_ar_hdr,
3024 xcoff64_openr_next_archived_file,
3025 _bfd_generic_get_elt_at_index,
3026 _bfd_xcoff_stat_arch_elt,
3027 bfd_true,
3029 /* Symbols */
3030 coff_get_symtab_upper_bound,
3031 coff_canonicalize_symtab,
3032 coff_make_empty_symbol,
3033 coff_print_symbol,
3034 coff_get_symbol_info,
3035 _bfd_xcoff_is_local_label_name,
3036 coff_bfd_is_target_special_symbol,
3037 coff_get_lineno,
3038 coff_find_nearest_line,
3039 _bfd_generic_find_line,
3040 coff_find_inliner_info,
3041 coff_bfd_make_debug_symbol,
3042 _bfd_generic_read_minisymbols,
3043 _bfd_generic_minisymbol_to_symbol,
3045 /* Reloc */
3046 coff_get_reloc_upper_bound,
3047 coff_canonicalize_reloc,
3048 xcoff64_reloc_type_lookup,
3049 xcoff64_reloc_name_lookup,
3051 /* Write */
3052 coff_set_arch_mach,
3053 coff_set_section_contents,
3055 /* Link */
3056 xcoff64_sizeof_headers,
3057 bfd_generic_get_relocated_section_contents,
3058 bfd_generic_relax_section,
3059 _bfd_xcoff_bfd_link_hash_table_create,
3060 _bfd_generic_link_hash_table_free,
3061 _bfd_xcoff_bfd_link_add_symbols,
3062 _bfd_generic_link_just_syms,
3063 _bfd_generic_copy_link_hash_symbol_type,
3064 _bfd_xcoff_bfd_final_link,
3065 _bfd_generic_link_split_section,
3066 bfd_generic_gc_sections,
3067 bfd_generic_merge_sections,
3068 bfd_generic_is_group_section,
3069 bfd_generic_discard_group,
3070 _bfd_generic_section_already_linked,
3071 _bfd_xcoff_define_common_symbol,
3073 /* Dynamic */
3074 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3075 _bfd_xcoff_canonicalize_dynamic_symtab,
3076 _bfd_nodynamic_get_synthetic_symtab,
3077 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3078 _bfd_xcoff_canonicalize_dynamic_reloc,
3080 /* Opposite endian version, none exists. */
3081 NULL,
3083 (void *) & bfd_xcoff_aix5_backend_data,