Part of binutils 2.20 update
[cegcc.git] / cegcc / src / binutils / bfd / coff64-rs6000.c
blobe2020707206f4b94ab554a53df1af5a971ad16de
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
4 Written Clinton Popetz.
5 Contributed by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "bfdlink.h"
27 #include "libbfd.h"
28 #include "coff/internal.h"
29 #include "coff/xcoff.h"
30 #include "coff/rs6k64.h"
31 #include "libcoff.h"
32 #include "libxcoff.h"
34 #define GET_FILEHDR_SYMPTR H_GET_64
35 #define PUT_FILEHDR_SYMPTR H_PUT_64
36 #define GET_AOUTHDR_DATA_START H_GET_64
37 #define PUT_AOUTHDR_DATA_START H_PUT_64
38 #define GET_AOUTHDR_TEXT_START H_GET_64
39 #define PUT_AOUTHDR_TEXT_START H_PUT_64
40 #define GET_AOUTHDR_TSIZE H_GET_64
41 #define PUT_AOUTHDR_TSIZE H_PUT_64
42 #define GET_AOUTHDR_DSIZE H_GET_64
43 #define PUT_AOUTHDR_DSIZE H_PUT_64
44 #define GET_AOUTHDR_BSIZE H_GET_64
45 #define PUT_AOUTHDR_BSIZE H_PUT_64
46 #define GET_AOUTHDR_ENTRY H_GET_64
47 #define PUT_AOUTHDR_ENTRY H_PUT_64
48 #define GET_SCNHDR_PADDR H_GET_64
49 #define PUT_SCNHDR_PADDR H_PUT_64
50 #define GET_SCNHDR_VADDR H_GET_64
51 #define PUT_SCNHDR_VADDR H_PUT_64
52 #define GET_SCNHDR_SIZE H_GET_64
53 #define PUT_SCNHDR_SIZE H_PUT_64
54 #define GET_SCNHDR_SCNPTR H_GET_64
55 #define PUT_SCNHDR_SCNPTR H_PUT_64
56 #define GET_SCNHDR_RELPTR H_GET_64
57 #define PUT_SCNHDR_RELPTR H_PUT_64
58 #define GET_SCNHDR_LNNOPTR H_GET_64
59 #define PUT_SCNHDR_LNNOPTR H_PUT_64
60 #define GET_SCNHDR_NRELOC H_GET_32
61 #define MAX_SCNHDR_NRELOC 0xffffffff
62 #define PUT_SCNHDR_NRELOC H_PUT_32
63 #define GET_SCNHDR_NLNNO H_GET_32
64 #define MAX_SCNHDR_NLNNO 0xffffffff
65 #define PUT_SCNHDR_NLNNO H_PUT_32
66 #define GET_RELOC_VADDR H_GET_64
67 #define PUT_RELOC_VADDR H_PUT_64
69 #define COFF_FORCE_SYMBOLS_IN_STRINGS
70 #define COFF_DEBUG_STRING_WIDE_PREFIX
73 #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
74 do \
75 { \
76 memset (((SCNHDR *) EXT)->s_pad, 0, \
77 sizeof (((SCNHDR *) EXT)->s_pad)); \
78 } \
79 while (0)
81 #define NO_COFF_LINENOS
83 #define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
84 #define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
86 static void _bfd_xcoff64_swap_lineno_in
87 PARAMS ((bfd *, PTR, PTR));
88 static unsigned int _bfd_xcoff64_swap_lineno_out
89 PARAMS ((bfd *, PTR, PTR));
90 static bfd_boolean _bfd_xcoff64_put_symbol_name
91 PARAMS ((bfd *, struct bfd_strtab_hash *, struct internal_syment *,
92 const char *));
93 static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
94 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
95 const char *));
96 static void _bfd_xcoff64_swap_sym_in
97 PARAMS ((bfd *, PTR, PTR));
98 static unsigned int _bfd_xcoff64_swap_sym_out
99 PARAMS ((bfd *, PTR, PTR));
100 static void _bfd_xcoff64_swap_aux_in
101 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
102 static unsigned int _bfd_xcoff64_swap_aux_out
103 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
104 static void xcoff64_swap_reloc_in
105 PARAMS ((bfd *, PTR, PTR));
106 static unsigned int xcoff64_swap_reloc_out
107 PARAMS ((bfd *, PTR, PTR));
108 extern bfd_boolean _bfd_xcoff_mkobject
109 PARAMS ((bfd *));
110 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
111 PARAMS ((bfd *, bfd *));
112 extern bfd_boolean _bfd_xcoff_is_local_label_name
113 PARAMS ((bfd *, const char *));
114 extern void xcoff64_rtype2howto
115 PARAMS ((arelent *, struct internal_reloc *));
116 extern reloc_howto_type * xcoff64_reloc_type_lookup
117 PARAMS ((bfd *, bfd_reloc_code_real_type));
118 extern bfd_boolean _bfd_xcoff_slurp_armap
119 PARAMS ((bfd *));
120 extern PTR _bfd_xcoff_read_ar_hdr
121 PARAMS ((bfd *));
122 extern bfd *_bfd_xcoff_openr_next_archived_file
123 PARAMS ((bfd *, bfd *));
124 extern int _bfd_xcoff_stat_arch_elt
125 PARAMS ((bfd *, struct stat *));
126 extern bfd_boolean _bfd_xcoff_write_armap
127 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
128 extern bfd_boolean _bfd_xcoff_write_archive_contents
129 PARAMS ((bfd *));
130 extern int _bfd_xcoff_sizeof_headers
131 PARAMS ((bfd *, struct bfd_link_info *));
132 extern void _bfd_xcoff_swap_sym_in
133 PARAMS ((bfd *, PTR, PTR));
134 extern unsigned int _bfd_xcoff_swap_sym_out
135 PARAMS ((bfd *, PTR, PTR));
136 extern void _bfd_xcoff_swap_aux_in
137 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
138 extern unsigned int _bfd_xcoff_swap_aux_out
139 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
140 static void xcoff64_swap_ldhdr_in
141 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
142 static void xcoff64_swap_ldhdr_out
143 PARAMS ((bfd *, const struct internal_ldhdr *, PTR d));
144 static void xcoff64_swap_ldsym_in
145 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
146 static void xcoff64_swap_ldsym_out
147 PARAMS ((bfd *, const struct internal_ldsym *, PTR d));
148 static void xcoff64_swap_ldrel_in
149 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
150 static void xcoff64_swap_ldrel_out
151 PARAMS ((bfd *, const struct internal_ldrel *, PTR d));
152 static bfd_boolean xcoff64_write_object_contents
153 PARAMS ((bfd *));
154 static bfd_boolean xcoff64_ppc_relocate_section
155 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
156 struct internal_reloc *, struct internal_syment *,
157 asection **));
158 static bfd_boolean xcoff64_slurp_armap
159 PARAMS ((bfd *));
160 static const bfd_target *xcoff64_archive_p
161 PARAMS ((bfd *));
162 static bfd *xcoff64_openr_next_archived_file
163 PARAMS ((bfd *, bfd *));
164 static int xcoff64_sizeof_headers
165 PARAMS ((bfd *, struct bfd_link_info *));
166 static asection *xcoff64_create_csect_from_smclas
167 PARAMS ((bfd *, union internal_auxent *, const char *));
168 static bfd_boolean xcoff64_is_lineno_count_overflow
169 PARAMS ((bfd *, bfd_vma));
170 static bfd_boolean xcoff64_is_reloc_count_overflow
171 PARAMS ((bfd *, bfd_vma));
172 static bfd_vma xcoff64_loader_symbol_offset
173 PARAMS ((bfd *, struct internal_ldhdr *));
174 static bfd_vma xcoff64_loader_reloc_offset
175 PARAMS ((bfd *, struct internal_ldhdr *));
176 static bfd_boolean xcoff64_generate_rtinit
177 PARAMS ((bfd *, const char *, const char *, bfd_boolean));
178 static bfd_boolean xcoff64_bad_format_hook
179 PARAMS ((bfd *, PTR ));
181 /* Relocation functions */
182 static bfd_boolean xcoff64_reloc_type_br
183 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
185 bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
186 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
188 xcoff_reloc_type_pos, /* R_POS (0x00) */
189 xcoff_reloc_type_neg, /* R_NEG (0x01) */
190 xcoff_reloc_type_rel, /* R_REL (0x02) */
191 xcoff_reloc_type_toc, /* R_TOC (0x03) */
192 xcoff_reloc_type_fail, /* R_RTB (0x04) */
193 xcoff_reloc_type_toc, /* R_GL (0x05) */
194 xcoff_reloc_type_toc, /* R_TCL (0x06) */
195 xcoff_reloc_type_fail, /* (0x07) */
196 xcoff_reloc_type_ba, /* R_BA (0x08) */
197 xcoff_reloc_type_fail, /* (0x09) */
198 xcoff64_reloc_type_br, /* R_BR (0x0a) */
199 xcoff_reloc_type_fail, /* (0x0b) */
200 xcoff_reloc_type_pos, /* R_RL (0x0c) */
201 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
202 xcoff_reloc_type_fail, /* (0x0e) */
203 xcoff_reloc_type_noop, /* R_REF (0x0f) */
204 xcoff_reloc_type_fail, /* (0x10) */
205 xcoff_reloc_type_fail, /* (0x11) */
206 xcoff_reloc_type_toc, /* R_TRL (0x12) */
207 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
208 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
209 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
210 xcoff_reloc_type_ba, /* R_CAI (0x16) */
211 xcoff_reloc_type_crel, /* R_CREL (0x17) */
212 xcoff_reloc_type_ba, /* R_RBA (0x18) */
213 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
214 xcoff64_reloc_type_br, /* R_RBR (0x1a) */
215 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
218 /* coffcode.h needs these to be defined. */
219 /* Internalcoff.h and coffcode.h modify themselves based on these flags. */
220 #define XCOFF64
221 #define RS6000COFF_C 1
223 #define SELECT_RELOC(internal, howto) \
225 internal.r_type = howto->type; \
226 internal.r_size = \
227 ((howto->complain_on_overflow == complain_overflow_signed \
228 ? 0x80 \
229 : 0) \
230 | (howto->bitsize - 1)); \
233 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
234 #define COFF_LONG_FILENAMES
235 #define NO_COFF_SYMBOLS
236 #define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
237 #define coff_mkobject _bfd_xcoff_mkobject
238 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
239 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
240 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
241 #define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
242 #ifdef AIX_CORE
243 extern const bfd_target * rs6000coff_core_p
244 PARAMS ((bfd *abfd));
245 extern bfd_boolean rs6000coff_core_file_matches_executable_p
246 PARAMS ((bfd *cbfd, bfd *ebfd));
247 extern char *rs6000coff_core_file_failing_command
248 PARAMS ((bfd *abfd));
249 extern int rs6000coff_core_file_failing_signal
250 PARAMS ((bfd *abfd));
251 #define CORE_FILE_P rs6000coff_core_p
252 #define coff_core_file_failing_command \
253 rs6000coff_core_file_failing_command
254 #define coff_core_file_failing_signal \
255 rs6000coff_core_file_failing_signal
256 #define coff_core_file_matches_executable_p \
257 rs6000coff_core_file_matches_executable_p
258 #else
259 #define CORE_FILE_P _bfd_dummy_target
260 #define coff_core_file_failing_command \
261 _bfd_nocore_core_file_failing_command
262 #define coff_core_file_failing_signal \
263 _bfd_nocore_core_file_failing_signal
264 #define coff_core_file_matches_executable_p \
265 _bfd_nocore_core_file_matches_executable_p
266 #endif
267 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
268 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
269 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
270 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
271 #define coff_swap_reloc_in xcoff64_swap_reloc_in
272 #define coff_swap_reloc_out xcoff64_swap_reloc_out
273 #define NO_COFF_RELOCS
275 #ifndef bfd_pe_print_pdata
276 #define bfd_pe_print_pdata NULL
277 #endif
279 #include "coffcode.h"
281 /* For XCOFF64, the effective width of symndx changes depending on
282 whether we are the first entry. Sigh. */
283 static void
284 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
285 bfd *abfd;
286 PTR ext1;
287 PTR in1;
289 LINENO *ext = (LINENO *) ext1;
290 struct internal_lineno *in = (struct internal_lineno *) in1;
292 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
293 if (in->l_lnno == 0)
294 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
295 else
296 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
299 static unsigned int
300 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
301 bfd *abfd;
302 PTR inp;
303 PTR outp;
305 struct internal_lineno *in = (struct internal_lineno *) inp;
306 struct external_lineno *ext = (struct external_lineno *) outp;
308 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
309 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
311 if (in->l_lnno == 0)
312 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
313 else
314 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
316 return bfd_coff_linesz (abfd);
319 static void
320 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
321 bfd *abfd;
322 PTR ext1;
323 PTR in1;
325 struct external_syment *ext = (struct external_syment *) ext1;
326 struct internal_syment *in = (struct internal_syment *) in1;
328 in->_n._n_n._n_zeroes = 0;
329 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
330 in->n_value = H_GET_64 (abfd, ext->e_value);
331 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
332 in->n_type = H_GET_16 (abfd, ext->e_type);
333 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
334 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
337 static unsigned int
338 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
339 bfd *abfd;
340 PTR inp;
341 PTR extp;
343 struct internal_syment *in = (struct internal_syment *) inp;
344 struct external_syment *ext = (struct external_syment *) extp;
346 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
347 H_PUT_64 (abfd, in->n_value, ext->e_value);
348 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
349 H_PUT_16 (abfd, in->n_type, ext->e_type);
350 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
351 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
352 return bfd_coff_symesz (abfd);
355 static void
356 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, in_class, indx, numaux, in1)
357 bfd *abfd;
358 PTR ext1;
359 int type;
360 int in_class;
361 int indx;
362 int numaux;
363 PTR in1;
365 union external_auxent *ext = (union external_auxent *) ext1;
366 union internal_auxent *in = (union internal_auxent *) in1;
368 switch (in_class)
370 case C_FILE:
371 if (ext->x_file.x_n.x_zeroes[0] == 0)
373 in->x_file.x_n.x_zeroes = 0;
374 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
376 else
378 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
380 goto end;
382 /* RS/6000 "csect" auxents */
383 case C_EXT:
384 case C_AIX_WEAKEXT:
385 case C_HIDEXT:
386 if (indx + 1 == numaux)
388 bfd_signed_vma h = 0;
389 bfd_vma l = 0;
391 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
392 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
394 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
396 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
397 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
398 /* We don't have to hack bitfields in x_smtyp because it's
399 defined by shifts-and-ands, which are equivalent on all
400 byte orders. */
401 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
402 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
403 goto end;
405 break;
407 case C_STAT:
408 case C_LEAFSTAT:
409 case C_HIDDEN:
410 if (type == T_NULL)
412 /* PE defines some extra fields; we zero them out for
413 safety. */
414 in->x_scn.x_checksum = 0;
415 in->x_scn.x_associated = 0;
416 in->x_scn.x_comdat = 0;
418 goto end;
420 break;
423 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
424 || ISTAG (in_class))
426 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
427 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
428 in->x_sym.x_fcnary.x_fcn.x_endndx.l
429 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
431 if (ISFCN (type))
433 in->x_sym.x_misc.x_fsize
434 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
436 else
438 in->x_sym.x_misc.x_lnsz.x_lnno
439 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
440 in->x_sym.x_misc.x_lnsz.x_size
441 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
444 end: ;
447 static unsigned int
448 _bfd_xcoff64_swap_aux_out (abfd, inp, type, in_class, indx, numaux, extp)
449 bfd *abfd;
450 PTR inp;
451 int type;
452 int in_class;
453 int indx ATTRIBUTE_UNUSED;
454 int numaux ATTRIBUTE_UNUSED;
455 PTR extp;
457 union internal_auxent *in = (union internal_auxent *) inp;
458 union external_auxent *ext = (union external_auxent *) extp;
460 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
461 switch (in_class)
463 case C_FILE:
464 if (in->x_file.x_n.x_zeroes == 0)
466 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
467 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
469 else
471 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
473 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
474 goto end;
476 /* RS/6000 "csect" auxents */
477 case C_EXT:
478 case C_AIX_WEAKEXT:
479 case C_HIDEXT:
480 if (indx + 1 == numaux)
482 bfd_vma temp;
484 temp = in->x_csect.x_scnlen.l & 0xffffffff;
485 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
486 temp = in->x_csect.x_scnlen.l >> 32;
487 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
488 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
489 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
490 /* We don't have to hack bitfields in x_smtyp because it's
491 defined by shifts-and-ands, which are equivalent on all
492 byte orders. */
493 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
494 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
495 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
496 goto end;
498 break;
500 case C_STAT:
501 case C_LEAFSTAT:
502 case C_HIDDEN:
503 if (type == T_NULL)
505 goto end;
507 break;
510 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
511 || ISTAG (in_class))
513 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
514 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
515 H_PUT_8 (abfd, _AUX_FCN,
516 ext->x_auxtype.x_auxtype);
517 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
518 ext->x_sym.x_fcnary.x_fcn.x_endndx);
520 if (ISFCN (type))
522 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
523 ext->x_sym.x_fcnary.x_fcn.x_fsize);
525 else
527 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
528 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
529 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
530 ext->x_sym.x_fcnary.x_lnsz.x_size);
533 end:
535 return bfd_coff_auxesz (abfd);
538 static bfd_boolean
539 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
540 bfd *abfd;
541 struct bfd_strtab_hash *strtab;
542 struct internal_syment *sym;
543 const char *name;
545 bfd_boolean hash;
546 bfd_size_type indx;
548 hash = TRUE;
550 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
551 hash = FALSE;
553 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
555 if (indx == (bfd_size_type) -1)
556 return FALSE;
558 sym->_n._n_n._n_zeroes = 0;
559 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
561 return TRUE;
564 static bfd_boolean
565 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
566 bfd *abfd ATTRIBUTE_UNUSED;
567 struct xcoff_loader_info *ldinfo;
568 struct internal_ldsym *ldsym;
569 const char *name;
571 size_t len;
572 len = strlen (name);
574 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
576 bfd_size_type newalc;
577 char *newstrings;
579 newalc = ldinfo->string_alc * 2;
580 if (newalc == 0)
581 newalc = 32;
582 while (ldinfo->string_size + len + 3 > newalc)
583 newalc *= 2;
585 newstrings = bfd_realloc (ldinfo->strings, newalc);
586 if (newstrings == NULL)
588 ldinfo->failed = TRUE;
589 return FALSE;
591 ldinfo->string_alc = newalc;
592 ldinfo->strings = newstrings;
595 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
596 ldinfo->strings + ldinfo->string_size);
597 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
598 ldsym->_l._l_l._l_zeroes = 0;
599 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
600 ldinfo->string_size += len + 3;
602 return TRUE;
605 /* Routines to swap information in the XCOFF .loader section. If we
606 ever need to write an XCOFF loader, this stuff will need to be
607 moved to another file shared by the linker (which XCOFF calls the
608 ``binder'') and the loader. */
610 /* Swap in the ldhdr structure. */
612 static void
613 xcoff64_swap_ldhdr_in (abfd, s, dst)
614 bfd *abfd;
615 const PTR s;
616 struct internal_ldhdr *dst;
618 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
620 dst->l_version = bfd_get_32 (abfd, src->l_version);
621 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
622 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
623 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
624 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
625 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
626 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
627 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
628 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
629 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
632 /* Swap out the ldhdr structure. */
634 static void
635 xcoff64_swap_ldhdr_out (abfd, src, d)
636 bfd *abfd;
637 const struct internal_ldhdr *src;
638 PTR d;
640 struct external_ldhdr *dst = (struct external_ldhdr *) d;
642 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
643 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
644 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
645 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
646 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
647 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
648 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
649 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
650 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
651 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
654 /* Swap in the ldsym structure. */
656 static void
657 xcoff64_swap_ldsym_in (abfd, s, dst)
658 bfd *abfd;
659 const PTR s;
660 struct internal_ldsym *dst;
662 const struct external_ldsym *src = (const struct external_ldsym *) s;
663 /* XCOFF64 does not use l_zeroes like XCOFF32
664 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
665 as an offset into the loader symbol table. */
666 dst->_l._l_l._l_zeroes = 0;
667 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
668 dst->l_value = bfd_get_64 (abfd, src->l_value);
669 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
670 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
671 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
672 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
673 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
676 /* Swap out the ldsym structure. */
678 static void
679 xcoff64_swap_ldsym_out (abfd, src, d)
680 bfd *abfd;
681 const struct internal_ldsym *src;
682 PTR d;
684 struct external_ldsym *dst = (struct external_ldsym *) d;
686 bfd_put_64 (abfd, src->l_value, dst->l_value);
687 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
688 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
689 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
690 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
691 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
692 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
695 static void
696 xcoff64_swap_reloc_in (abfd, s, d)
697 bfd *abfd;
698 PTR s;
699 PTR d;
701 struct external_reloc *src = (struct external_reloc *) s;
702 struct internal_reloc *dst = (struct internal_reloc *) d;
704 memset (dst, 0, sizeof (struct internal_reloc));
706 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
707 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
708 dst->r_size = bfd_get_8 (abfd, src->r_size);
709 dst->r_type = bfd_get_8 (abfd, src->r_type);
712 static unsigned int
713 xcoff64_swap_reloc_out (abfd, s, d)
714 bfd *abfd;
715 PTR s;
716 PTR d;
718 struct internal_reloc *src = (struct internal_reloc *) s;
719 struct external_reloc *dst = (struct external_reloc *) d;
721 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
722 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
723 bfd_put_8 (abfd, src->r_type, dst->r_type);
724 bfd_put_8 (abfd, src->r_size, dst->r_size);
726 return bfd_coff_relsz (abfd);
729 /* Swap in the ldrel structure. */
731 static void
732 xcoff64_swap_ldrel_in (abfd, s, dst)
733 bfd *abfd;
734 const PTR s;
735 struct internal_ldrel *dst;
737 const struct external_ldrel *src = (const struct external_ldrel *) s;
739 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
740 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
741 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
742 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
745 /* Swap out the ldrel structure. */
747 static void
748 xcoff64_swap_ldrel_out (abfd, src, d)
749 bfd *abfd;
750 const struct internal_ldrel *src;
751 PTR d;
753 struct external_ldrel *dst = (struct external_ldrel *) d;
755 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
756 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
757 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
758 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
761 static bfd_boolean
762 xcoff64_write_object_contents (abfd)
763 bfd *abfd;
765 asection *current;
766 bfd_boolean hasrelocs = FALSE;
767 bfd_boolean haslinno = FALSE;
768 file_ptr scn_base;
769 file_ptr reloc_base;
770 file_ptr lineno_base;
771 file_ptr sym_base;
772 unsigned long reloc_size = 0;
773 unsigned long lnno_size = 0;
774 asection *text_sec = ((void *) 0);
775 asection *data_sec = ((void *) 0);
776 asection *bss_sec = ((void *) 0);
777 struct internal_filehdr internal_f;
778 struct internal_aouthdr internal_a;
780 bfd_set_error (bfd_error_system_call);
782 if (! abfd->output_has_begun)
784 if (! bfd_coff_compute_section_file_positions (abfd))
785 return FALSE;
788 /* Work out the size of the reloc and linno areas. */
789 reloc_base = obj_relocbase (abfd);
791 for (current = abfd->sections; current != NULL; current = current->next)
792 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
794 lineno_base = reloc_base + reloc_size;
796 /* Make a pass through the symbol table to count line number entries and
797 put them into the correct asections. */
798 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
800 sym_base = lineno_base + lnno_size;
802 /* Indicate in each section->line_filepos its actual file address. */
803 for (current = abfd->sections; current != NULL; current = current->next)
805 if (current->lineno_count)
807 current->line_filepos = lineno_base;
808 current->moving_line_filepos = lineno_base;
809 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
811 else
813 current->line_filepos = 0;
816 if (current->reloc_count)
818 current->rel_filepos = reloc_base;
819 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
821 else
823 current->rel_filepos = 0;
827 if ((abfd->flags & EXEC_P) != 0)
829 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
830 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
832 else
834 scn_base = bfd_coff_filhsz (abfd);
835 internal_f.f_opthdr = 0;
838 internal_f.f_nscns = 0;
840 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
841 return FALSE;
843 for (current = abfd->sections; current != NULL; current = current->next)
845 struct internal_scnhdr section;
846 struct external_scnhdr buff;
847 bfd_size_type amount;
849 internal_f.f_nscns++;
851 strncpy (section.s_name, current->name, SCNNMLEN);
853 section.s_vaddr = current->vma;
854 section.s_paddr = current->lma;
855 section.s_size = current->size;
857 /* If this section has no size or is unloadable then the scnptr
858 will be 0 too. */
859 if (current->size == 0
860 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
862 section.s_scnptr = 0;
864 else
866 section.s_scnptr = current->filepos;
869 section.s_relptr = current->rel_filepos;
870 section.s_lnnoptr = current->line_filepos;
871 section.s_nreloc = current->reloc_count;
873 section.s_nlnno = current->lineno_count;
874 if (current->reloc_count != 0)
875 hasrelocs = TRUE;
876 if (current->lineno_count != 0)
877 haslinno = TRUE;
879 section.s_flags = sec_to_styp_flags (current->name, current->flags);
881 if (!strcmp (current->name, _TEXT))
883 text_sec = current;
885 else if (!strcmp (current->name, _DATA))
887 data_sec = current;
889 else if (!strcmp (current->name, _BSS))
891 bss_sec = current;
894 amount = bfd_coff_scnhsz (abfd);
895 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
896 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
897 return FALSE;
900 internal_f.f_timdat = 0;
902 internal_f.f_flags = 0;
904 if (!hasrelocs)
905 internal_f.f_flags |= F_RELFLG;
906 if (!haslinno)
907 internal_f.f_flags |= F_LNNO;
908 if (abfd->flags & EXEC_P)
909 internal_f.f_flags |= F_EXEC;
911 /* FIXME: this is wrong for PPC_PE! */
912 if (bfd_little_endian (abfd))
913 internal_f.f_flags |= F_AR32WR;
914 else
915 internal_f.f_flags |= F_AR32W;
917 if ((abfd->flags & DYNAMIC) != 0)
918 internal_f.f_flags |= F_SHROBJ;
919 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
920 internal_f.f_flags |= F_DYNLOAD;
922 memset (&internal_a, 0, sizeof internal_a);
924 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
925 internal_a.magic = (abfd->flags & D_PAGED
926 ? RS6K_AOUTHDR_ZMAGIC
927 : (abfd->flags & WP_TEXT
928 ? RS6K_AOUTHDR_NMAGIC
929 : RS6K_AOUTHDR_OMAGIC));
931 /* FIXME: Does anybody ever set this to another value? */
932 internal_a.vstamp = 0;
934 /* Now should write relocs, strings, syms. */
935 obj_sym_filepos (abfd) = sym_base;
937 internal_f.f_symptr = 0;
938 internal_f.f_nsyms = 0;
940 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
941 backend linker, and obj_raw_syment_count is not valid until after
942 coff_write_symbols is called. */
943 if (bfd_get_symcount (abfd) != 0)
945 int firstundef;
947 if (!coff_renumber_symbols (abfd, &firstundef))
948 return FALSE;
949 coff_mangle_symbols (abfd);
950 if (! coff_write_symbols (abfd))
951 return FALSE;
952 if (! coff_write_linenumbers (abfd))
953 return FALSE;
954 if (! coff_write_relocs (abfd, firstundef))
955 return FALSE;
957 internal_f.f_symptr = sym_base;
958 internal_f.f_nsyms = bfd_get_symcount (abfd);
960 else if (obj_raw_syment_count (abfd) != 0)
962 internal_f.f_symptr = sym_base;
964 /* AIX appears to require that F_RELFLG not be set if there are
965 local symbols but no relocations. */
966 internal_f.f_flags &=~ F_RELFLG;
968 else
970 internal_f.f_flags |= F_LSYMS;
973 if (text_sec)
975 internal_a.tsize = text_sec->size;
976 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
979 if (data_sec)
981 internal_a.dsize = data_sec->size;
982 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
985 if (bss_sec)
987 internal_a.bsize = bss_sec->size;
988 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
989 internal_a.data_start = bss_sec->vma;
992 internal_a.entry = bfd_get_start_address (abfd);
993 internal_f.f_nsyms = obj_raw_syment_count (abfd);
995 if (xcoff_data (abfd)->full_aouthdr)
997 bfd_vma toc;
998 asection *loader_sec;
1000 internal_a.vstamp = 1;
1002 internal_a.o_snentry = xcoff_data (abfd)->snentry;
1003 if (internal_a.o_snentry == 0)
1004 internal_a.entry = (bfd_vma) -1;
1006 if (text_sec != NULL)
1008 internal_a.o_sntext = text_sec->target_index;
1009 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
1011 else
1013 internal_a.o_sntext = 0;
1014 internal_a.o_algntext = 0;
1017 if (data_sec != NULL)
1019 internal_a.o_sndata = data_sec->target_index;
1020 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1022 else
1024 internal_a.o_sndata = 0;
1025 internal_a.o_algndata = 0;
1028 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1029 if (loader_sec != NULL)
1030 internal_a.o_snloader = loader_sec->target_index;
1031 else
1032 internal_a.o_snloader = 0;
1033 if (bss_sec != NULL)
1034 internal_a.o_snbss = bss_sec->target_index;
1035 else
1036 internal_a.o_snbss = 0;
1038 toc = xcoff_data (abfd)->toc;
1039 internal_a.o_toc = toc;
1040 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1042 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1043 if (xcoff_data (abfd)->cputype != -1)
1044 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1045 else
1047 switch (bfd_get_arch (abfd))
1049 case bfd_arch_rs6000:
1050 internal_a.o_cputype = 4;
1051 break;
1052 case bfd_arch_powerpc:
1053 if (bfd_get_mach (abfd) == bfd_mach_ppc)
1054 internal_a.o_cputype = 3;
1055 else if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
1056 internal_a.o_cputype = 2;
1057 else
1058 internal_a.o_cputype = 1;
1059 break;
1060 default:
1061 abort ();
1064 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1065 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
1068 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
1069 return FALSE;
1072 char * buff;
1073 bfd_size_type amount = bfd_coff_filhsz (abfd);
1075 buff = bfd_malloc (amount);
1076 if (buff == NULL)
1077 return FALSE;
1079 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1080 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1082 free (buff);
1084 if (amount != bfd_coff_filhsz (abfd))
1085 return FALSE;
1088 if (abfd->flags & EXEC_P)
1090 char * buff;
1091 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1093 buff = bfd_malloc (amount);
1094 if (buff == NULL)
1095 return FALSE;
1097 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
1098 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1100 free (buff);
1102 if (amount != bfd_coff_aoutsz (abfd))
1103 return FALSE;
1106 return TRUE;
1109 static bfd_boolean
1110 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
1111 val, addend, relocation, contents)
1112 bfd *input_bfd;
1113 asection *input_section;
1114 bfd *output_bfd ATTRIBUTE_UNUSED;
1115 struct internal_reloc *rel;
1116 struct internal_syment *sym ATTRIBUTE_UNUSED;
1117 struct reloc_howto_struct *howto;
1118 bfd_vma val;
1119 bfd_vma addend;
1120 bfd_vma *relocation;
1121 bfd_byte *contents;
1123 struct xcoff_link_hash_entry *h;
1124 bfd_vma section_offset;
1126 if (0 > rel->r_symndx)
1127 return FALSE;
1129 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1130 section_offset = rel->r_vaddr - input_section->vma;
1132 /* If we see an R_BR or R_RBR reloc which is jumping to global
1133 linkage code, and it is followed by an appropriate cror nop
1134 instruction, we replace the cror with ld r2,40(r1). This
1135 restores the TOC after the glink code. Contrariwise, if the
1136 call is followed by a ld r2,40(r1), but the call is not
1137 going to global linkage code, we can replace the load with a
1138 cror. */
1139 if (NULL != h
1140 && (bfd_link_hash_defined == h->root.type
1141 || bfd_link_hash_defweak == h->root.type)
1142 && section_offset + 8 <= input_section->size)
1144 bfd_byte *pnext;
1145 unsigned long next;
1147 pnext = contents + section_offset + 4;
1148 next = bfd_get_32 (input_bfd, pnext);
1150 /* The _ptrgl function is magic. It is used by the AIX compiler to call
1151 a function through a pointer. */
1152 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
1154 if (next == 0x4def7b82 /* cror 15,15,15 */
1155 || next == 0x4ffffb82 /* cror 31,31,31 */
1156 || next == 0x60000000) /* ori r0,r0,0 */
1157 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1159 else
1161 if (next == 0xe8410028) /* ld r2,40(r1) */
1162 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1165 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
1167 /* Normally, this relocation is against a defined symbol. In the
1168 case where this is a partial link and the output section offset
1169 is greater than 2^25, the linker will return an invalid error
1170 message that the relocation has been truncated. Yes it has been
1171 truncated but no it not important. For this case, disable the
1172 overflow checking. */
1173 howto->complain_on_overflow = complain_overflow_dont;
1176 /* The original PC-relative relocation is biased by -r_vaddr, so adding
1177 the value below will give the absolute target address. */
1178 *relocation = val + addend + rel->r_vaddr;
1180 howto->src_mask &= ~3;
1181 howto->dst_mask = howto->src_mask;
1183 if (h != NULL
1184 && (h->root.type == bfd_link_hash_defined
1185 || h->root.type == bfd_link_hash_defweak)
1186 && bfd_is_abs_section (h->root.u.def.section)
1187 && section_offset + 4 <= input_section->size)
1189 bfd_byte *ptr;
1190 bfd_vma insn;
1192 /* Turn the relative branch into an absolute one by setting the
1193 AA bit. */
1194 ptr = contents + section_offset;
1195 insn = bfd_get_32 (input_bfd, ptr);
1196 insn |= 2;
1197 bfd_put_32 (input_bfd, insn, ptr);
1199 /* Make the howto absolute too. */
1200 howto->pc_relative = FALSE;
1201 howto->complain_on_overflow = complain_overflow_bitfield;
1203 else
1205 /* Use a PC-relative howto and subtract the instruction's address
1206 from the target address we calculated above. */
1207 howto->pc_relative = TRUE;
1208 *relocation -= (input_section->output_section->vma
1209 + input_section->output_offset
1210 + section_offset);
1212 return TRUE;
1215 /* This is the relocation function for the PowerPC64.
1216 See xcoff_ppc_relocation_section for more information. */
1218 bfd_boolean
1219 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1220 input_section, contents, relocs, syms,
1221 sections)
1222 bfd *output_bfd;
1223 struct bfd_link_info *info;
1224 bfd *input_bfd;
1225 asection *input_section;
1226 bfd_byte *contents;
1227 struct internal_reloc *relocs;
1228 struct internal_syment *syms;
1229 asection **sections;
1231 struct internal_reloc *rel;
1232 struct internal_reloc *relend;
1234 rel = relocs;
1235 relend = rel + input_section->reloc_count;
1236 for (; rel < relend; rel++)
1238 long symndx;
1239 struct xcoff_link_hash_entry *h;
1240 struct internal_syment *sym;
1241 bfd_vma addend;
1242 bfd_vma val;
1243 struct reloc_howto_struct howto;
1244 bfd_vma relocation;
1245 bfd_vma value_to_relocate;
1246 bfd_vma address;
1247 bfd_byte *location;
1249 /* Relocation type R_REF is a special relocation type which is
1250 merely used to prevent garbage collection from occurring for
1251 the csect including the symbol which it references. */
1252 if (rel->r_type == R_REF)
1253 continue;
1255 /* howto */
1256 howto.type = rel->r_type;
1257 howto.rightshift = 0;
1258 howto.bitsize = (rel->r_size & 0x3f) + 1;
1259 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
1260 howto.pc_relative = FALSE;
1261 howto.bitpos = 0;
1262 howto.complain_on_overflow = (rel->r_size & 0x80
1263 ? complain_overflow_signed
1264 : complain_overflow_bitfield);
1265 howto.special_function = NULL;
1266 howto.name = "internal";
1267 howto.partial_inplace = TRUE;
1268 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
1269 howto.pcrel_offset = FALSE;
1271 /* symbol */
1272 val = 0;
1273 addend = 0;
1274 h = NULL;
1275 sym = NULL;
1276 symndx = rel->r_symndx;
1278 if (-1 != symndx)
1280 asection *sec;
1282 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1283 sym = syms + symndx;
1284 addend = - sym->n_value;
1286 if (NULL == h)
1288 sec = sections[symndx];
1289 /* Hack to make sure we use the right TOC anchor value
1290 if this reloc is against the TOC anchor. */
1291 if (sec->name[3] == '0'
1292 && strcmp (sec->name, ".tc0") == 0)
1293 val = xcoff_data (output_bfd)->toc;
1294 else
1295 val = (sec->output_section->vma
1296 + sec->output_offset
1297 + sym->n_value
1298 - sec->vma);
1300 else
1302 if (info->unresolved_syms_in_objects != RM_IGNORE
1303 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
1305 if (! ((*info->callbacks->undefined_symbol)
1306 (info, h->root.root.string,
1307 input_bfd, input_section,
1308 rel->r_vaddr - input_section->vma,
1309 (info->unresolved_syms_in_objects
1310 == RM_GENERATE_ERROR))))
1311 return FALSE;
1313 if (h->root.type == bfd_link_hash_defined
1314 || h->root.type == bfd_link_hash_defweak)
1316 sec = h->root.u.def.section;
1317 val = (h->root.u.def.value
1318 + sec->output_section->vma
1319 + sec->output_offset);
1321 else if (h->root.type == bfd_link_hash_common)
1323 sec = h->root.u.c.p->section;
1324 val = (sec->output_section->vma
1325 + sec->output_offset);
1327 else
1329 BFD_ASSERT (info->relocatable
1330 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
1331 || (h->flags & XCOFF_IMPORT) != 0);
1336 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
1337 || !((*xcoff64_calculate_relocation[rel->r_type])
1338 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1339 addend, &relocation, contents)))
1340 return FALSE;
1342 /* address */
1343 address = rel->r_vaddr - input_section->vma;
1344 location = contents + address;
1346 if (address > input_section->size)
1347 abort ();
1349 /* Get the value we are going to relocate. */
1350 if (1 == howto.size)
1351 value_to_relocate = bfd_get_16 (input_bfd, location);
1352 else if (2 == howto.size)
1353 value_to_relocate = bfd_get_32 (input_bfd, location);
1354 else
1355 value_to_relocate = bfd_get_64 (input_bfd, location);
1357 /* overflow.
1359 FIXME: We may drop bits during the addition
1360 which we don't check for. We must either check at every single
1361 operation, which would be tedious, or we must do the computations
1362 in a type larger than bfd_vma, which would be inefficient. */
1364 if ((unsigned int) howto.complain_on_overflow
1365 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1366 abort ();
1368 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1369 (input_bfd, value_to_relocate, relocation, &howto)))
1371 const char *name;
1372 char buf[SYMNMLEN + 1];
1373 char reloc_type_name[10];
1375 if (symndx == -1)
1377 name = "*ABS*";
1379 else if (h != NULL)
1381 name = NULL;
1383 else
1385 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1386 if (name == NULL)
1387 name = "UNKNOWN";
1389 sprintf (reloc_type_name, "0x%02x", rel->r_type);
1391 if (! ((*info->callbacks->reloc_overflow)
1392 (info, (h ? &h->root : NULL), name, reloc_type_name,
1393 (bfd_vma) 0, input_bfd, input_section,
1394 rel->r_vaddr - input_section->vma)))
1395 return FALSE;
1398 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
1399 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1400 | (((value_to_relocate & howto.src_mask)
1401 + relocation) & howto.dst_mask));
1403 /* Put the value back in the object file. */
1404 if (1 == howto.size)
1405 bfd_put_16 (input_bfd, value_to_relocate, location);
1406 else if (2 == howto.size)
1407 bfd_put_32 (input_bfd, value_to_relocate, location);
1408 else
1409 bfd_put_64 (input_bfd, value_to_relocate, location);
1412 return TRUE;
1416 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1417 bitsize and whether they are signed or not, along with a
1418 conventional type. This table is for the types, which are used for
1419 different algorithms for putting in the reloc. Many of these
1420 relocs need special_function entries, which I have not written. */
1422 reloc_howto_type xcoff64_howto_table[] =
1424 /* Standard 64 bit relocation. */
1425 HOWTO (R_POS, /* type */
1426 0, /* rightshift */
1427 4, /* size (0 = byte, 1 = short, 2 = long) */
1428 64, /* bitsize */
1429 FALSE, /* pc_relative */
1430 0, /* bitpos */
1431 complain_overflow_bitfield, /* complain_on_overflow */
1432 0, /* special_function */
1433 "R_POS_64", /* name */
1434 TRUE, /* partial_inplace */
1435 MINUS_ONE, /* src_mask */
1436 MINUS_ONE, /* dst_mask */
1437 FALSE), /* pcrel_offset */
1439 /* 64 bit relocation, but store negative value. */
1440 HOWTO (R_NEG, /* type */
1441 0, /* rightshift */
1442 -4, /* size (0 = byte, 1 = short, 2 = long) */
1443 64, /* bitsize */
1444 FALSE, /* pc_relative */
1445 0, /* bitpos */
1446 complain_overflow_bitfield, /* complain_on_overflow */
1447 0, /* special_function */
1448 "R_NEG", /* name */
1449 TRUE, /* partial_inplace */
1450 MINUS_ONE, /* src_mask */
1451 MINUS_ONE, /* dst_mask */
1452 FALSE), /* pcrel_offset */
1454 /* 32 bit PC relative relocation. */
1455 HOWTO (R_REL, /* type */
1456 0, /* rightshift */
1457 2, /* size (0 = byte, 1 = short, 2 = long) */
1458 32, /* bitsize */
1459 TRUE, /* pc_relative */
1460 0, /* bitpos */
1461 complain_overflow_signed, /* complain_on_overflow */
1462 0, /* special_function */
1463 "R_REL", /* name */
1464 TRUE, /* partial_inplace */
1465 0xffffffff, /* src_mask */
1466 0xffffffff, /* dst_mask */
1467 FALSE), /* pcrel_offset */
1469 /* 16 bit TOC relative relocation. */
1470 HOWTO (R_TOC, /* type */
1471 0, /* rightshift */
1472 1, /* size (0 = byte, 1 = short, 2 = long) */
1473 16, /* bitsize */
1474 FALSE, /* pc_relative */
1475 0, /* bitpos */
1476 complain_overflow_bitfield, /* complain_on_overflow */
1477 0, /* special_function */
1478 "R_TOC", /* name */
1479 TRUE, /* partial_inplace */
1480 0xffff, /* src_mask */
1481 0xffff, /* dst_mask */
1482 FALSE), /* pcrel_offset */
1484 /* I don't really know what this is. */
1485 HOWTO (R_RTB, /* type */
1486 1, /* rightshift */
1487 2, /* size (0 = byte, 1 = short, 2 = long) */
1488 32, /* bitsize */
1489 FALSE, /* pc_relative */
1490 0, /* bitpos */
1491 complain_overflow_bitfield, /* complain_on_overflow */
1492 0, /* special_function */
1493 "R_RTB", /* name */
1494 TRUE, /* partial_inplace */
1495 0xffffffff, /* src_mask */
1496 0xffffffff, /* dst_mask */
1497 FALSE), /* pcrel_offset */
1499 /* External TOC relative symbol. */
1500 HOWTO (R_GL, /* type */
1501 0, /* rightshift */
1502 1, /* size (0 = byte, 1 = short, 2 = long) */
1503 16, /* bitsize */
1504 FALSE, /* pc_relative */
1505 0, /* bitpos */
1506 complain_overflow_bitfield, /* complain_on_overflow */
1507 0, /* special_function */
1508 "R_GL", /* name */
1509 TRUE, /* partial_inplace */
1510 0xffff, /* src_mask */
1511 0xffff, /* dst_mask */
1512 FALSE), /* pcrel_offset */
1514 /* Local TOC relative symbol. */
1515 HOWTO (R_TCL, /* type */
1516 0, /* rightshift */
1517 1, /* size (0 = byte, 1 = short, 2 = long) */
1518 16, /* bitsize */
1519 FALSE, /* pc_relative */
1520 0, /* bitpos */
1521 complain_overflow_bitfield, /* complain_on_overflow */
1522 0, /* special_function */
1523 "R_TCL", /* name */
1524 TRUE, /* partial_inplace */
1525 0xffff, /* src_mask */
1526 0xffff, /* dst_mask */
1527 FALSE), /* pcrel_offset */
1529 EMPTY_HOWTO (7),
1531 /* Non modifiable absolute branch. */
1532 HOWTO (R_BA, /* type */
1533 0, /* rightshift */
1534 2, /* size (0 = byte, 1 = short, 2 = long) */
1535 26, /* bitsize */
1536 FALSE, /* pc_relative */
1537 0, /* bitpos */
1538 complain_overflow_bitfield, /* complain_on_overflow */
1539 0, /* special_function */
1540 "R_BA_26", /* name */
1541 TRUE, /* partial_inplace */
1542 0x03fffffc, /* src_mask */
1543 0x03fffffc, /* dst_mask */
1544 FALSE), /* pcrel_offset */
1546 EMPTY_HOWTO (9),
1548 /* Non modifiable relative branch. */
1549 HOWTO (R_BR, /* type */
1550 0, /* rightshift */
1551 2, /* size (0 = byte, 1 = short, 2 = long) */
1552 26, /* bitsize */
1553 TRUE, /* pc_relative */
1554 0, /* bitpos */
1555 complain_overflow_signed, /* complain_on_overflow */
1556 0, /* special_function */
1557 "R_BR", /* name */
1558 TRUE, /* partial_inplace */
1559 0x03fffffc, /* src_mask */
1560 0x03fffffc, /* dst_mask */
1561 FALSE), /* pcrel_offset */
1563 EMPTY_HOWTO (0xb),
1565 /* Indirect load. */
1566 HOWTO (R_RL, /* type */
1567 0, /* rightshift */
1568 1, /* size (0 = byte, 1 = short, 2 = long) */
1569 16, /* bitsize */
1570 FALSE, /* pc_relative */
1571 0, /* bitpos */
1572 complain_overflow_bitfield, /* complain_on_overflow */
1573 0, /* special_function */
1574 "R_RL", /* name */
1575 TRUE, /* partial_inplace */
1576 0xffff, /* src_mask */
1577 0xffff, /* dst_mask */
1578 FALSE), /* pcrel_offset */
1580 /* Load address. */
1581 HOWTO (R_RLA, /* type */
1582 0, /* rightshift */
1583 1, /* size (0 = byte, 1 = short, 2 = long) */
1584 16, /* bitsize */
1585 FALSE, /* pc_relative */
1586 0, /* bitpos */
1587 complain_overflow_bitfield, /* complain_on_overflow */
1588 0, /* special_function */
1589 "R_RLA", /* name */
1590 TRUE, /* partial_inplace */
1591 0xffff, /* src_mask */
1592 0xffff, /* dst_mask */
1593 FALSE), /* pcrel_offset */
1595 EMPTY_HOWTO (0xe),
1597 /* Non-relocating reference. */
1598 HOWTO (R_REF, /* type */
1599 0, /* rightshift */
1600 2, /* size (0 = byte, 1 = short, 2 = long) */
1601 32, /* bitsize */
1602 FALSE, /* pc_relative */
1603 0, /* bitpos */
1604 complain_overflow_dont, /* complain_on_overflow */
1605 0, /* special_function */
1606 "R_REF", /* name */
1607 FALSE, /* partial_inplace */
1608 0, /* src_mask */
1609 0, /* dst_mask */
1610 FALSE), /* pcrel_offset */
1612 EMPTY_HOWTO (0x10),
1613 EMPTY_HOWTO (0x11),
1615 /* TOC relative indirect load. */
1616 HOWTO (R_TRL, /* type */
1617 0, /* rightshift */
1618 1, /* size (0 = byte, 1 = short, 2 = long) */
1619 16, /* bitsize */
1620 FALSE, /* pc_relative */
1621 0, /* bitpos */
1622 complain_overflow_bitfield, /* complain_on_overflow */
1623 0, /* special_function */
1624 "R_TRL", /* name */
1625 TRUE, /* partial_inplace */
1626 0xffff, /* src_mask */
1627 0xffff, /* dst_mask */
1628 FALSE), /* pcrel_offset */
1630 /* TOC relative load address. */
1631 HOWTO (R_TRLA, /* type */
1632 0, /* rightshift */
1633 1, /* size (0 = byte, 1 = short, 2 = long) */
1634 16, /* bitsize */
1635 FALSE, /* pc_relative */
1636 0, /* bitpos */
1637 complain_overflow_bitfield, /* complain_on_overflow */
1638 0, /* special_function */
1639 "R_TRLA", /* name */
1640 TRUE, /* partial_inplace */
1641 0xffff, /* src_mask */
1642 0xffff, /* dst_mask */
1643 FALSE), /* pcrel_offset */
1645 /* Modifiable relative branch. */
1646 HOWTO (R_RRTBI, /* type */
1647 1, /* rightshift */
1648 2, /* size (0 = byte, 1 = short, 2 = long) */
1649 32, /* bitsize */
1650 FALSE, /* pc_relative */
1651 0, /* bitpos */
1652 complain_overflow_bitfield, /* complain_on_overflow */
1653 0, /* special_function */
1654 "R_RRTBI", /* name */
1655 TRUE, /* partial_inplace */
1656 0xffffffff, /* src_mask */
1657 0xffffffff, /* dst_mask */
1658 FALSE), /* pcrel_offset */
1660 /* Modifiable absolute branch. */
1661 HOWTO (R_RRTBA, /* type */
1662 1, /* rightshift */
1663 2, /* size (0 = byte, 1 = short, 2 = long) */
1664 32, /* bitsize */
1665 FALSE, /* pc_relative */
1666 0, /* bitpos */
1667 complain_overflow_bitfield, /* complain_on_overflow */
1668 0, /* special_function */
1669 "R_RRTBA", /* name */
1670 TRUE, /* partial_inplace */
1671 0xffffffff, /* src_mask */
1672 0xffffffff, /* dst_mask */
1673 FALSE), /* pcrel_offset */
1675 /* Modifiable call absolute indirect. */
1676 HOWTO (R_CAI, /* type */
1677 0, /* rightshift */
1678 1, /* size (0 = byte, 1 = short, 2 = long) */
1679 16, /* bitsize */
1680 FALSE, /* pc_relative */
1681 0, /* bitpos */
1682 complain_overflow_bitfield, /* complain_on_overflow */
1683 0, /* special_function */
1684 "R_CAI", /* name */
1685 TRUE, /* partial_inplace */
1686 0xffff, /* src_mask */
1687 0xffff, /* dst_mask */
1688 FALSE), /* pcrel_offset */
1690 /* Modifiable call relative. */
1691 HOWTO (R_CREL, /* type */
1692 0, /* rightshift */
1693 1, /* size (0 = byte, 1 = short, 2 = long) */
1694 16, /* bitsize */
1695 FALSE, /* pc_relative */
1696 0, /* bitpos */
1697 complain_overflow_bitfield, /* complain_on_overflow */
1698 0, /* special_function */
1699 "R_CREL", /* name */
1700 TRUE, /* partial_inplace */
1701 0xffff, /* src_mask */
1702 0xffff, /* dst_mask */
1703 FALSE), /* pcrel_offset */
1705 /* Modifiable branch absolute. */
1706 HOWTO (R_RBA, /* type */
1707 0, /* rightshift */
1708 2, /* size (0 = byte, 1 = short, 2 = long) */
1709 26, /* bitsize */
1710 FALSE, /* pc_relative */
1711 0, /* bitpos */
1712 complain_overflow_bitfield, /* complain_on_overflow */
1713 0, /* special_function */
1714 "R_RBA", /* name */
1715 TRUE, /* partial_inplace */
1716 0x03fffffc, /* src_mask */
1717 0x03fffffc, /* dst_mask */
1718 FALSE), /* pcrel_offset */
1720 /* Modifiable branch absolute. */
1721 HOWTO (R_RBAC, /* type */
1722 0, /* rightshift */
1723 2, /* size (0 = byte, 1 = short, 2 = long) */
1724 32, /* bitsize */
1725 FALSE, /* pc_relative */
1726 0, /* bitpos */
1727 complain_overflow_bitfield, /* complain_on_overflow */
1728 0, /* special_function */
1729 "R_RBAC", /* name */
1730 TRUE, /* partial_inplace */
1731 0xffffffff, /* src_mask */
1732 0xffffffff, /* dst_mask */
1733 FALSE), /* pcrel_offset */
1735 /* Modifiable branch relative. */
1736 HOWTO (R_RBR, /* type */
1737 0, /* rightshift */
1738 2, /* size (0 = byte, 1 = short, 2 = long) */
1739 26, /* bitsize */
1740 FALSE, /* pc_relative */
1741 0, /* bitpos */
1742 complain_overflow_signed, /* complain_on_overflow */
1743 0, /* special_function */
1744 "R_RBR_26", /* name */
1745 TRUE, /* partial_inplace */
1746 0x03fffffc, /* src_mask */
1747 0x03fffffc, /* dst_mask */
1748 FALSE), /* pcrel_offset */
1750 /* Modifiable branch absolute. */
1751 HOWTO (R_RBRC, /* type */
1752 0, /* rightshift */
1753 1, /* size (0 = byte, 1 = short, 2 = long) */
1754 16, /* bitsize */
1755 FALSE, /* pc_relative */
1756 0, /* bitpos */
1757 complain_overflow_bitfield, /* complain_on_overflow */
1758 0, /* special_function */
1759 "R_RBRC", /* name */
1760 TRUE, /* partial_inplace */
1761 0xffff, /* src_mask */
1762 0xffff, /* dst_mask */
1763 FALSE), /* pcrel_offset */
1765 HOWTO (R_POS, /* type */
1766 0, /* rightshift */
1767 2, /* size (0 = byte, 1 = short, 2 = long) */
1768 32, /* bitsize */
1769 FALSE, /* pc_relative */
1770 0, /* bitpos */
1771 complain_overflow_bitfield, /* complain_on_overflow */
1772 0, /* special_function */
1773 "R_POS_32", /* name */
1774 TRUE, /* partial_inplace */
1775 0xffffffff, /* src_mask */
1776 0xffffffff, /* dst_mask */
1777 FALSE), /* pcrel_offset */
1779 /* 16 bit Non modifiable absolute branch. */
1780 HOWTO (R_BA, /* type */
1781 0, /* rightshift */
1782 1, /* size (0 = byte, 1 = short, 2 = long) */
1783 16, /* bitsize */
1784 FALSE, /* pc_relative */
1785 0, /* bitpos */
1786 complain_overflow_bitfield, /* complain_on_overflow */
1787 0, /* special_function */
1788 "R_BA_16", /* name */
1789 TRUE, /* partial_inplace */
1790 0xfffc, /* src_mask */
1791 0xfffc, /* dst_mask */
1792 FALSE), /* pcrel_offset */
1794 /* Modifiable branch relative. */
1795 HOWTO (R_RBR, /* type */
1796 0, /* rightshift */
1797 1, /* size (0 = byte, 1 = short, 2 = long) */
1798 16, /* bitsize */
1799 FALSE, /* pc_relative */
1800 0, /* bitpos */
1801 complain_overflow_signed, /* complain_on_overflow */
1802 0, /* special_function */
1803 "R_RBR_16", /* name */
1804 TRUE, /* partial_inplace */
1805 0xffff, /* src_mask */
1806 0xffff, /* dst_mask */
1807 FALSE), /* pcrel_offset */
1809 /* Modifiable branch absolute. */
1810 HOWTO (R_RBA, /* type */
1811 0, /* rightshift */
1812 1, /* size (0 = byte, 1 = short, 2 = long) */
1813 16, /* bitsize */
1814 FALSE, /* pc_relative */
1815 0, /* bitpos */
1816 complain_overflow_bitfield, /* complain_on_overflow */
1817 0, /* special_function */
1818 "R_RBA_16", /* name */
1819 TRUE, /* partial_inplace */
1820 0xffff, /* src_mask */
1821 0xffff, /* dst_mask */
1822 FALSE), /* pcrel_offset */
1826 void
1827 xcoff64_rtype2howto (relent, internal)
1828 arelent *relent;
1829 struct internal_reloc *internal;
1831 if (internal->r_type > R_RBRC)
1832 abort ();
1834 /* Default howto layout works most of the time */
1835 relent->howto = &xcoff64_howto_table[internal->r_type];
1837 /* Special case some 16 bit reloc */
1838 if (15 == (internal->r_size & 0x3f))
1840 if (R_BA == internal->r_type)
1841 relent->howto = &xcoff64_howto_table[0x1d];
1842 else if (R_RBR == internal->r_type)
1843 relent->howto = &xcoff64_howto_table[0x1e];
1844 else if (R_RBA == internal->r_type)
1845 relent->howto = &xcoff64_howto_table[0x1f];
1847 /* Special case 32 bit */
1848 else if (31 == (internal->r_size & 0x3f))
1850 if (R_POS == internal->r_type)
1851 relent->howto = &xcoff64_howto_table[0x1c];
1854 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1855 relocation, as well as indicating whether it is signed or not.
1856 Doublecheck that the relocation information gathered from the
1857 type matches this information. The bitsize is not significant
1858 for R_REF relocs. */
1859 if (relent->howto->dst_mask != 0
1860 && (relent->howto->bitsize
1861 != ((unsigned int) internal->r_size & 0x3f) + 1))
1862 abort ();
1865 reloc_howto_type *
1866 xcoff64_reloc_type_lookup (abfd, code)
1867 bfd *abfd ATTRIBUTE_UNUSED;
1868 bfd_reloc_code_real_type code;
1870 switch (code)
1872 case BFD_RELOC_PPC_B26:
1873 return &xcoff64_howto_table[0xa];
1874 case BFD_RELOC_PPC_BA16:
1875 return &xcoff64_howto_table[0x1d];
1876 case BFD_RELOC_PPC_BA26:
1877 return &xcoff64_howto_table[8];
1878 case BFD_RELOC_PPC_TOC16:
1879 return &xcoff64_howto_table[3];
1880 case BFD_RELOC_32:
1881 case BFD_RELOC_CTOR:
1882 return &xcoff64_howto_table[0x1c];
1883 case BFD_RELOC_64:
1884 return &xcoff64_howto_table[0];
1885 default:
1886 return NULL;
1890 static reloc_howto_type *
1891 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1892 const char *r_name)
1894 unsigned int i;
1896 for (i = 0;
1897 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1898 i++)
1899 if (xcoff64_howto_table[i].name != NULL
1900 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1901 return &xcoff64_howto_table[i];
1903 return NULL;
1906 /* Read in the armap of an XCOFF archive. */
1908 static bfd_boolean
1909 xcoff64_slurp_armap (abfd)
1910 bfd *abfd;
1912 file_ptr off;
1913 size_t namlen;
1914 bfd_size_type sz, amt;
1915 bfd_byte *contents, *cend;
1916 bfd_vma c, i;
1917 carsym *arsym;
1918 bfd_byte *p;
1919 file_ptr pos;
1921 /* This is for the new format. */
1922 struct xcoff_ar_hdr_big hdr;
1924 if (xcoff_ardata (abfd) == NULL)
1926 bfd_has_map (abfd) = FALSE;
1927 return TRUE;
1930 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1931 (const char **) NULL, 10);
1932 if (off == 0)
1934 bfd_has_map (abfd) = FALSE;
1935 return TRUE;
1938 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1939 return FALSE;
1941 /* The symbol table starts with a normal archive header. */
1942 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1943 != SIZEOF_AR_HDR_BIG)
1944 return FALSE;
1946 /* Skip the name (normally empty). */
1947 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1948 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1949 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1950 return FALSE;
1952 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1954 /* Read in the entire symbol table. */
1955 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1956 if (contents == NULL)
1957 return FALSE;
1958 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1959 return FALSE;
1961 /* The symbol table starts with an eight byte count. */
1962 c = H_GET_64 (abfd, contents);
1964 if (c * 8 >= sz)
1966 bfd_set_error (bfd_error_bad_value);
1967 return FALSE;
1969 amt = c;
1970 amt *= sizeof (carsym);
1971 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1972 if (bfd_ardata (abfd)->symdefs == NULL)
1973 return FALSE;
1975 /* After the count comes a list of eight byte file offsets. */
1976 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1977 i < c;
1978 ++i, ++arsym, p += 8)
1979 arsym->file_offset = H_GET_64 (abfd, p);
1981 /* After the file offsets come null terminated symbol names. */
1982 cend = contents + sz;
1983 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1984 i < c;
1985 ++i, ++arsym, p += strlen ((char *) p) + 1)
1987 if (p >= cend)
1989 bfd_set_error (bfd_error_bad_value);
1990 return FALSE;
1992 arsym->name = (char *) p;
1995 bfd_ardata (abfd)->symdef_count = c;
1996 bfd_has_map (abfd) = TRUE;
1998 return TRUE;
2002 /* See if this is an NEW XCOFF archive. */
2004 static const bfd_target *
2005 xcoff64_archive_p (abfd)
2006 bfd *abfd;
2008 struct artdata *tdata_hold;
2009 char magic[SXCOFFARMAG];
2010 /* This is the new format. */
2011 struct xcoff_ar_file_hdr_big hdr;
2012 bfd_size_type amt = SXCOFFARMAG;
2014 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2016 if (bfd_get_error () != bfd_error_system_call)
2017 bfd_set_error (bfd_error_wrong_format);
2018 return NULL;
2021 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2023 bfd_set_error (bfd_error_wrong_format);
2024 return NULL;
2027 /* Copy over the magic string. */
2028 memcpy (hdr.magic, magic, SXCOFFARMAG);
2030 /* Now read the rest of the file header. */
2031 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2032 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
2034 if (bfd_get_error () != bfd_error_system_call)
2035 bfd_set_error (bfd_error_wrong_format);
2036 return NULL;
2039 tdata_hold = bfd_ardata (abfd);
2041 amt = sizeof (struct artdata);
2042 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2043 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2044 goto error_ret_restore;
2046 /* Already cleared by bfd_zalloc above.
2047 bfd_ardata (abfd)->cache = NULL;
2048 bfd_ardata (abfd)->archive_head = NULL;
2049 bfd_ardata (abfd)->symdefs = NULL;
2050 bfd_ardata (abfd)->extended_names = NULL;
2051 bfd_ardata (abfd)->extended_names_size = 0; */
2052 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2053 (const char **) NULL,
2054 10);
2056 amt = SIZEOF_AR_FILE_HDR_BIG;
2057 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2058 if (bfd_ardata (abfd)->tdata == NULL)
2059 goto error_ret;
2061 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2063 if (! xcoff64_slurp_armap (abfd))
2065 error_ret:
2066 bfd_release (abfd, bfd_ardata (abfd));
2067 error_ret_restore:
2068 bfd_ardata (abfd) = tdata_hold;
2069 return NULL;
2072 return abfd->xvec;
2076 /* Open the next element in an XCOFF archive. */
2078 static bfd *
2079 xcoff64_openr_next_archived_file (archive, last_file)
2080 bfd *archive;
2081 bfd *last_file;
2083 bfd_vma filestart;
2085 if ((xcoff_ardata (archive) == NULL)
2086 || ! xcoff_big_format_p (archive))
2088 bfd_set_error (bfd_error_invalid_operation);
2089 return NULL;
2092 if (last_file == NULL)
2094 filestart = bfd_ardata (archive)->first_file_filepos;
2096 else
2098 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2099 (const char **) NULL, 10);
2102 if (filestart == 0
2103 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2104 (const char **) NULL, 10)
2105 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2106 (const char **) NULL, 10))
2108 bfd_set_error (bfd_error_no_more_archived_files);
2109 return NULL;
2112 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2115 /* We can't use the usual coff_sizeof_headers routine, because AIX
2116 always uses an a.out header. */
2118 static int
2119 xcoff64_sizeof_headers (bfd *abfd,
2120 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2122 int size;
2124 size = bfd_coff_filhsz (abfd);
2126 /* Don't think the small aout header can be used since some of the
2127 old elements have been reordered past the end of the old coff
2128 small aout size. */
2130 if (xcoff_data (abfd)->full_aouthdr)
2131 size += bfd_coff_aoutsz (abfd);
2133 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2134 return size;
2139 static asection *
2140 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2141 bfd *abfd;
2142 union internal_auxent *aux;
2143 const char *symbol_name;
2145 asection *return_value = NULL;
2147 /* Changes from 32 :
2148 .sv == 8, is only for 32 bit programs
2149 .ti == 12 and .tb == 13 are now reserved. */
2150 static const char *names[19] =
2152 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2153 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2154 ".td", ".sv64", ".sv3264"
2157 if ((19 >= aux->x_csect.x_smclas)
2158 && (NULL != names[aux->x_csect.x_smclas]))
2161 return_value = bfd_make_section_anyway
2162 (abfd, names[aux->x_csect.x_smclas]);
2165 else
2167 (*_bfd_error_handler)
2168 (_("%B: symbol `%s' has unrecognized smclas %d"),
2169 abfd, symbol_name, aux->x_csect.x_smclas);
2170 bfd_set_error (bfd_error_bad_value);
2173 return return_value;
2176 static bfd_boolean
2177 xcoff64_is_lineno_count_overflow (abfd, value)
2178 bfd *abfd ATTRIBUTE_UNUSED;
2179 bfd_vma value ATTRIBUTE_UNUSED;
2181 return FALSE;
2184 static bfd_boolean
2185 xcoff64_is_reloc_count_overflow (abfd, value)
2186 bfd *abfd ATTRIBUTE_UNUSED;
2187 bfd_vma value ATTRIBUTE_UNUSED;
2189 return FALSE;
2192 static bfd_vma
2193 xcoff64_loader_symbol_offset (abfd, ldhdr)
2194 bfd *abfd ATTRIBUTE_UNUSED;
2195 struct internal_ldhdr *ldhdr;
2197 return (ldhdr->l_symoff);
2200 static bfd_vma
2201 xcoff64_loader_reloc_offset (abfd, ldhdr)
2202 bfd *abfd ATTRIBUTE_UNUSED;
2203 struct internal_ldhdr *ldhdr;
2205 return (ldhdr->l_rldoff);
2208 static bfd_boolean
2209 xcoff64_bad_format_hook (abfd, filehdr)
2210 bfd * abfd;
2211 PTR filehdr;
2213 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2215 /* Check flavor first. */
2216 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2217 return FALSE;
2219 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2220 return FALSE;
2222 return TRUE;
2225 static bfd_boolean
2226 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2227 bfd *abfd;
2228 const char *init;
2229 const char *fini;
2230 bfd_boolean rtld;
2232 bfd_byte filehdr_ext[FILHSZ];
2233 bfd_byte scnhdr_ext[SCNHSZ * 3];
2234 bfd_byte syment_ext[SYMESZ * 10];
2235 bfd_byte reloc_ext[RELSZ * 3];
2236 bfd_byte *data_buffer;
2237 bfd_size_type data_buffer_size;
2238 bfd_byte *string_table, *st_tmp;
2239 bfd_size_type string_table_size;
2240 bfd_vma val;
2241 size_t initsz, finisz;
2242 struct internal_filehdr filehdr;
2243 struct internal_scnhdr text_scnhdr;
2244 struct internal_scnhdr data_scnhdr;
2245 struct internal_scnhdr bss_scnhdr;
2246 struct internal_syment syment;
2247 union internal_auxent auxent;
2248 struct internal_reloc reloc;
2250 char *text_name = ".text";
2251 char *data_name = ".data";
2252 char *bss_name = ".bss";
2253 char *rtinit_name = "__rtinit";
2254 char *rtld_name = "__rtld";
2256 if (! bfd_xcoff_rtinit_size (abfd))
2257 return FALSE;
2259 initsz = (init == NULL ? 0 : 1 + strlen (init));
2260 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2262 /* File header. */
2263 memset (filehdr_ext, 0, FILHSZ);
2264 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2265 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2266 filehdr.f_nscns = 3;
2267 filehdr.f_timdat = 0;
2268 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2269 filehdr.f_symptr = 0; /* set below */
2270 filehdr.f_opthdr = 0;
2271 filehdr.f_flags = 0;
2273 /* Section headers. */
2274 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2276 /* Text. */
2277 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2278 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2279 text_scnhdr.s_paddr = 0;
2280 text_scnhdr.s_vaddr = 0;
2281 text_scnhdr.s_size = 0;
2282 text_scnhdr.s_scnptr = 0;
2283 text_scnhdr.s_relptr = 0;
2284 text_scnhdr.s_lnnoptr = 0;
2285 text_scnhdr.s_nreloc = 0;
2286 text_scnhdr.s_nlnno = 0;
2287 text_scnhdr.s_flags = STYP_TEXT;
2289 /* Data. */
2290 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2291 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2292 data_scnhdr.s_paddr = 0;
2293 data_scnhdr.s_vaddr = 0;
2294 data_scnhdr.s_size = 0; /* set below */
2295 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2296 data_scnhdr.s_relptr = 0; /* set below */
2297 data_scnhdr.s_lnnoptr = 0;
2298 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2299 data_scnhdr.s_nlnno = 0;
2300 data_scnhdr.s_flags = STYP_DATA;
2302 /* Bss. */
2303 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2304 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2305 bss_scnhdr.s_paddr = 0; /* set below */
2306 bss_scnhdr.s_vaddr = 0; /* set below */
2307 bss_scnhdr.s_size = 0; /* set below */
2308 bss_scnhdr.s_scnptr = 0;
2309 bss_scnhdr.s_relptr = 0;
2310 bss_scnhdr.s_lnnoptr = 0;
2311 bss_scnhdr.s_nreloc = 0;
2312 bss_scnhdr.s_nlnno = 0;
2313 bss_scnhdr.s_flags = STYP_BSS;
2315 /* .data
2316 0x0000 0x00000000 : rtl
2317 0x0004 0x00000000 :
2318 0x0008 0x00000018 : offset to init, or 0
2319 0x000C 0x00000038 : offset to fini, or 0
2320 0x0010 0x00000010 : size of descriptor
2321 0x0014 0x00000000 : pad
2322 0x0018 0x00000000 : init, needs a reloc
2323 0x001C 0x00000000 :
2324 0x0020 0x00000058 : offset to init name
2325 0x0024 0x00000000 : flags, padded to a word
2326 0x0028 0x00000000 : empty init
2327 0x002C 0x00000000 :
2328 0x0030 0x00000000 :
2329 0x0034 0x00000000 :
2330 0x0038 0x00000000 : fini, needs a reloc
2331 0x003C 0x00000000 :
2332 0x0040 0x00000??? : offset to fini name
2333 0x0044 0x00000000 : flags, padded to a word
2334 0x0048 0x00000000 : empty fini
2335 0x004C 0x00000000 :
2336 0x0050 0x00000000 :
2337 0x0054 0x00000000 :
2338 0x0058 init name
2339 0x0058 + initsz fini name */
2341 data_buffer_size = 0x0058 + initsz + finisz;
2342 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2343 data_buffer = NULL;
2344 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2345 if (data_buffer == NULL)
2346 return FALSE;
2348 if (initsz)
2350 val = 0x18;
2351 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2352 val = 0x58;
2353 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2354 memcpy (&data_buffer[val], init, initsz);
2357 if (finisz)
2359 val = 0x38;
2360 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2361 val = 0x58 + initsz;
2362 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2363 memcpy (&data_buffer[val], fini, finisz);
2366 val = 0x10;
2367 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2368 data_scnhdr.s_size = data_buffer_size;
2369 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2371 /* String table. */
2372 string_table_size = 4;
2373 string_table_size += strlen (data_name) + 1;
2374 string_table_size += strlen (rtinit_name) + 1;
2375 string_table_size += initsz;
2376 string_table_size += finisz;
2377 if (rtld)
2378 string_table_size += strlen (rtld_name) + 1;
2380 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2381 if (string_table == NULL)
2382 return FALSE;
2384 val = string_table_size;
2385 bfd_put_32 (abfd, val, &string_table[0]);
2386 st_tmp = string_table + 4;
2388 /* symbols
2389 0. .data csect
2390 2. __rtinit
2391 4. init function
2392 6. fini function
2393 8. __rtld */
2394 memset (syment_ext, 0, 10 * SYMESZ);
2395 memset (reloc_ext, 0, 3 * RELSZ);
2397 /* .data csect */
2398 memset (&syment, 0, sizeof (struct internal_syment));
2399 memset (&auxent, 0, sizeof (union internal_auxent));
2401 syment._n._n_n._n_offset = st_tmp - string_table;
2402 memcpy (st_tmp, data_name, strlen (data_name));
2403 st_tmp += strlen (data_name) + 1;
2405 syment.n_scnum = 2;
2406 syment.n_sclass = C_HIDEXT;
2407 syment.n_numaux = 1;
2408 auxent.x_csect.x_scnlen.l = data_buffer_size;
2409 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2410 auxent.x_csect.x_smclas = XMC_RW;
2411 bfd_coff_swap_sym_out (abfd, &syment,
2412 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2413 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2414 syment.n_numaux,
2415 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2416 filehdr.f_nsyms += 2;
2418 /* __rtinit */
2419 memset (&syment, 0, sizeof (struct internal_syment));
2420 memset (&auxent, 0, sizeof (union internal_auxent));
2421 syment._n._n_n._n_offset = st_tmp - string_table;
2422 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2423 st_tmp += strlen (rtinit_name) + 1;
2425 syment.n_scnum = 2;
2426 syment.n_sclass = C_EXT;
2427 syment.n_numaux = 1;
2428 auxent.x_csect.x_smtyp = XTY_LD;
2429 auxent.x_csect.x_smclas = XMC_RW;
2430 bfd_coff_swap_sym_out (abfd, &syment,
2431 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2432 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2433 syment.n_numaux,
2434 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2435 filehdr.f_nsyms += 2;
2437 /* Init. */
2438 if (initsz)
2440 memset (&syment, 0, sizeof (struct internal_syment));
2441 memset (&auxent, 0, sizeof (union internal_auxent));
2443 syment._n._n_n._n_offset = st_tmp - string_table;
2444 memcpy (st_tmp, init, initsz);
2445 st_tmp += initsz;
2447 syment.n_sclass = C_EXT;
2448 syment.n_numaux = 1;
2449 bfd_coff_swap_sym_out (abfd, &syment,
2450 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2451 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2452 syment.n_numaux,
2453 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2454 /* Reloc. */
2455 memset (&reloc, 0, sizeof (struct internal_reloc));
2456 reloc.r_vaddr = 0x0018;
2457 reloc.r_symndx = filehdr.f_nsyms;
2458 reloc.r_type = R_POS;
2459 reloc.r_size = 63;
2460 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2462 filehdr.f_nsyms += 2;
2463 data_scnhdr.s_nreloc += 1;
2466 /* Finit. */
2467 if (finisz)
2469 memset (&syment, 0, sizeof (struct internal_syment));
2470 memset (&auxent, 0, sizeof (union internal_auxent));
2472 syment._n._n_n._n_offset = st_tmp - string_table;
2473 memcpy (st_tmp, fini, finisz);
2474 st_tmp += finisz;
2476 syment.n_sclass = C_EXT;
2477 syment.n_numaux = 1;
2478 bfd_coff_swap_sym_out (abfd, &syment,
2479 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2480 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2481 syment.n_numaux,
2482 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2484 /* Reloc. */
2485 memset (&reloc, 0, sizeof (struct internal_reloc));
2486 reloc.r_vaddr = 0x0038;
2487 reloc.r_symndx = filehdr.f_nsyms;
2488 reloc.r_type = R_POS;
2489 reloc.r_size = 63;
2490 bfd_coff_swap_reloc_out (abfd, &reloc,
2491 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2493 filehdr.f_nsyms += 2;
2494 data_scnhdr.s_nreloc += 1;
2497 if (rtld)
2499 memset (&syment, 0, sizeof (struct internal_syment));
2500 memset (&auxent, 0, sizeof (union internal_auxent));
2502 syment._n._n_n._n_offset = st_tmp - string_table;
2503 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2504 st_tmp += strlen (rtld_name) + 1;
2506 syment.n_sclass = C_EXT;
2507 syment.n_numaux = 1;
2508 bfd_coff_swap_sym_out (abfd, &syment,
2509 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2510 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2511 syment.n_numaux,
2512 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2514 /* Reloc. */
2515 memset (&reloc, 0, sizeof (struct internal_reloc));
2516 reloc.r_vaddr = 0x0000;
2517 reloc.r_symndx = filehdr.f_nsyms;
2518 reloc.r_type = R_POS;
2519 reloc.r_size = 63;
2520 bfd_coff_swap_reloc_out (abfd, &reloc,
2521 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2523 filehdr.f_nsyms += 2;
2524 data_scnhdr.s_nreloc += 1;
2526 bss_scnhdr.s_size = 0;
2529 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2530 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2532 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2533 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2534 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2535 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2536 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2537 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2538 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2539 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2540 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2541 bfd_bwrite (string_table, string_table_size, abfd);
2543 free (data_buffer);
2544 data_buffer = NULL;
2546 return TRUE;
2549 /* The typical dynamic reloc. */
2551 static reloc_howto_type xcoff64_dynamic_reloc =
2552 HOWTO (0, /* type */
2553 0, /* rightshift */
2554 4, /* size (0 = byte, 1 = short, 2 = long) */
2555 64, /* bitsize */
2556 FALSE, /* pc_relative */
2557 0, /* bitpos */
2558 complain_overflow_bitfield, /* complain_on_overflow */
2559 0, /* special_function */
2560 "R_POS", /* name */
2561 TRUE, /* partial_inplace */
2562 MINUS_ONE, /* src_mask */
2563 MINUS_ONE, /* dst_mask */
2564 FALSE); /* pcrel_offset */
2566 static unsigned long xcoff64_glink_code[10] =
2568 0xe9820000, /* ld r12,0(r2) */
2569 0xf8410028, /* std r2,40(r1) */
2570 0xe80c0000, /* ld r0,0(r12) */
2571 0xe84c0008, /* ld r0,8(r12) */
2572 0x7c0903a6, /* mtctr r0 */
2573 0x4e800420, /* bctr */
2574 0x00000000, /* start of traceback table */
2575 0x000ca000, /* traceback table */
2576 0x00000000, /* traceback table */
2577 0x00000018, /* ??? */
2580 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2582 { /* COFF backend, defined in libcoff.h. */
2583 _bfd_xcoff64_swap_aux_in,
2584 _bfd_xcoff64_swap_sym_in,
2585 _bfd_xcoff64_swap_lineno_in,
2586 _bfd_xcoff64_swap_aux_out,
2587 _bfd_xcoff64_swap_sym_out,
2588 _bfd_xcoff64_swap_lineno_out,
2589 xcoff64_swap_reloc_out,
2590 coff_swap_filehdr_out,
2591 coff_swap_aouthdr_out,
2592 coff_swap_scnhdr_out,
2593 FILHSZ,
2594 AOUTSZ,
2595 SCNHSZ,
2596 SYMESZ,
2597 AUXESZ,
2598 RELSZ,
2599 LINESZ,
2600 FILNMLEN,
2601 TRUE, /* _bfd_coff_long_filenames */
2602 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2603 3, /* _bfd_coff_default_section_alignment_power */
2604 TRUE, /* _bfd_coff_force_symnames_in_strings */
2605 4, /* _bfd_coff_debug_string_prefix_length */
2606 coff_swap_filehdr_in,
2607 coff_swap_aouthdr_in,
2608 coff_swap_scnhdr_in,
2609 xcoff64_swap_reloc_in,
2610 xcoff64_bad_format_hook,
2611 coff_set_arch_mach_hook,
2612 coff_mkobject_hook,
2613 styp_to_sec_flags,
2614 coff_set_alignment_hook,
2615 coff_slurp_symbol_table,
2616 symname_in_debug_hook,
2617 coff_pointerize_aux_hook,
2618 coff_print_aux,
2619 dummy_reloc16_extra_cases,
2620 dummy_reloc16_estimate,
2621 NULL, /* bfd_coff_symbol_classification */
2622 coff_compute_section_file_positions,
2623 NULL, /* _bfd_coff_start_final_link */
2624 xcoff64_ppc_relocate_section,
2625 coff_rtype_to_howto,
2626 NULL, /* _bfd_coff_adjust_symndx */
2627 _bfd_generic_link_add_one_symbol,
2628 coff_link_output_has_begun,
2629 coff_final_link_postscript,
2630 NULL /* print_pdata. */
2633 0x01EF, /* magic number */
2634 bfd_arch_powerpc,
2635 bfd_mach_ppc_620,
2637 /* Function pointers to xcoff specific swap routines. */
2638 xcoff64_swap_ldhdr_in,
2639 xcoff64_swap_ldhdr_out,
2640 xcoff64_swap_ldsym_in,
2641 xcoff64_swap_ldsym_out,
2642 xcoff64_swap_ldrel_in,
2643 xcoff64_swap_ldrel_out,
2645 /* Sizes. */
2646 LDHDRSZ,
2647 LDSYMSZ,
2648 LDRELSZ,
2649 24, /* _xcoff_function_descriptor_size */
2650 0, /* _xcoff_small_aout_header_size */
2652 /* Versions. */
2653 2, /* _xcoff_ldhdr_version */
2655 _bfd_xcoff64_put_symbol_name,
2656 _bfd_xcoff64_put_ldsymbol_name,
2657 &xcoff64_dynamic_reloc,
2658 xcoff64_create_csect_from_smclas,
2660 /* Lineno and reloc count overflow. */
2661 xcoff64_is_lineno_count_overflow,
2662 xcoff64_is_reloc_count_overflow,
2664 xcoff64_loader_symbol_offset,
2665 xcoff64_loader_reloc_offset,
2667 /* glink. */
2668 &xcoff64_glink_code[0],
2669 40, /* _xcoff_glink_size */
2671 /* rtinit. */
2672 88, /* _xcoff_rtinit_size */
2673 xcoff64_generate_rtinit,
2676 /* The transfer vector that leads the outside world to all of the above. */
2677 const bfd_target rs6000coff64_vec =
2679 "aixcoff64-rs6000",
2680 bfd_target_xcoff_flavour,
2681 BFD_ENDIAN_BIG, /* data byte order is big */
2682 BFD_ENDIAN_BIG, /* header byte order is big */
2684 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2685 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2687 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2688 0, /* leading char */
2689 '/', /* ar_pad_char */
2690 15, /* ar_max_namelen */
2692 /* data */
2693 bfd_getb64,
2694 bfd_getb_signed_64,
2695 bfd_putb64,
2696 bfd_getb32,
2697 bfd_getb_signed_32,
2698 bfd_putb32,
2699 bfd_getb16,
2700 bfd_getb_signed_16,
2701 bfd_putb16,
2703 /* hdrs */
2704 bfd_getb64,
2705 bfd_getb_signed_64,
2706 bfd_putb64,
2707 bfd_getb32,
2708 bfd_getb_signed_32,
2709 bfd_putb32,
2710 bfd_getb16,
2711 bfd_getb_signed_16,
2712 bfd_putb16,
2714 { /* bfd_check_format */
2715 _bfd_dummy_target,
2716 coff_object_p,
2717 xcoff64_archive_p,
2718 CORE_FILE_P
2721 { /* bfd_set_format */
2722 bfd_false,
2723 coff_mkobject,
2724 _bfd_generic_mkarchive,
2725 bfd_false
2728 {/* bfd_write_contents */
2729 bfd_false,
2730 xcoff64_write_object_contents,
2731 _bfd_xcoff_write_archive_contents,
2732 bfd_false
2735 /* Generic */
2736 bfd_true,
2737 bfd_true,
2738 coff_new_section_hook,
2739 _bfd_generic_get_section_contents,
2740 _bfd_generic_get_section_contents_in_window,
2742 /* Copy */
2743 _bfd_xcoff_copy_private_bfd_data,
2744 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2745 _bfd_generic_init_private_section_data,
2746 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2747 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2748 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2749 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2750 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
2752 /* Core */
2753 coff_core_file_failing_command,
2754 coff_core_file_failing_signal,
2755 coff_core_file_matches_executable_p,
2757 /* Archive */
2758 xcoff64_slurp_armap,
2759 bfd_false,
2760 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2761 bfd_dont_truncate_arname,
2762 _bfd_xcoff_write_armap,
2763 _bfd_xcoff_read_ar_hdr,
2764 xcoff64_openr_next_archived_file,
2765 _bfd_generic_get_elt_at_index,
2766 _bfd_xcoff_stat_arch_elt,
2767 bfd_true,
2769 /* Symbols */
2770 coff_get_symtab_upper_bound,
2771 coff_canonicalize_symtab,
2772 coff_make_empty_symbol,
2773 coff_print_symbol,
2774 coff_get_symbol_info,
2775 _bfd_xcoff_is_local_label_name,
2776 coff_bfd_is_target_special_symbol,
2777 coff_get_lineno,
2778 coff_find_nearest_line,
2779 _bfd_generic_find_line,
2780 coff_find_inliner_info,
2781 coff_bfd_make_debug_symbol,
2782 _bfd_generic_read_minisymbols,
2783 _bfd_generic_minisymbol_to_symbol,
2785 /* Reloc */
2786 coff_get_reloc_upper_bound,
2787 coff_canonicalize_reloc,
2788 xcoff64_reloc_type_lookup,
2789 xcoff64_reloc_name_lookup,
2791 /* Write */
2792 coff_set_arch_mach,
2793 coff_set_section_contents,
2795 /* Link */
2796 xcoff64_sizeof_headers,
2797 bfd_generic_get_relocated_section_contents,
2798 bfd_generic_relax_section,
2799 _bfd_xcoff_bfd_link_hash_table_create,
2800 _bfd_generic_link_hash_table_free,
2801 _bfd_xcoff_bfd_link_add_symbols,
2802 _bfd_generic_link_just_syms,
2803 _bfd_xcoff_bfd_final_link,
2804 _bfd_generic_link_split_section,
2805 bfd_generic_gc_sections,
2806 bfd_generic_merge_sections,
2807 bfd_generic_is_group_section,
2808 bfd_generic_discard_group,
2809 _bfd_generic_section_already_linked,
2810 _bfd_xcoff_define_common_symbol,
2812 /* Dynamic */
2813 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2814 _bfd_xcoff_canonicalize_dynamic_symtab,
2815 _bfd_nodynamic_get_synthetic_symtab,
2816 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2817 _bfd_xcoff_canonicalize_dynamic_reloc,
2819 /* Opposite endian version, none exists */
2820 NULL,
2822 (void *) &bfd_xcoff_backend_data,
2825 extern const bfd_target *xcoff64_core_p
2826 PARAMS ((bfd *));
2827 extern bfd_boolean xcoff64_core_file_matches_executable_p
2828 PARAMS ((bfd *, bfd *));
2829 extern char *xcoff64_core_file_failing_command
2830 PARAMS ((bfd *));
2831 extern int xcoff64_core_file_failing_signal
2832 PARAMS ((bfd *));
2834 /* AIX 5 */
2835 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2837 { /* COFF backend, defined in libcoff.h. */
2838 _bfd_xcoff64_swap_aux_in,
2839 _bfd_xcoff64_swap_sym_in,
2840 _bfd_xcoff64_swap_lineno_in,
2841 _bfd_xcoff64_swap_aux_out,
2842 _bfd_xcoff64_swap_sym_out,
2843 _bfd_xcoff64_swap_lineno_out,
2844 xcoff64_swap_reloc_out,
2845 coff_swap_filehdr_out,
2846 coff_swap_aouthdr_out,
2847 coff_swap_scnhdr_out,
2848 FILHSZ,
2849 AOUTSZ,
2850 SCNHSZ,
2851 SYMESZ,
2852 AUXESZ,
2853 RELSZ,
2854 LINESZ,
2855 FILNMLEN,
2856 TRUE, /* _bfd_coff_long_filenames */
2857 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2858 3, /* _bfd_coff_default_section_alignment_power */
2859 TRUE, /* _bfd_coff_force_symnames_in_strings */
2860 4, /* _bfd_coff_debug_string_prefix_length */
2861 coff_swap_filehdr_in,
2862 coff_swap_aouthdr_in,
2863 coff_swap_scnhdr_in,
2864 xcoff64_swap_reloc_in,
2865 xcoff64_bad_format_hook,
2866 coff_set_arch_mach_hook,
2867 coff_mkobject_hook,
2868 styp_to_sec_flags,
2869 coff_set_alignment_hook,
2870 coff_slurp_symbol_table,
2871 symname_in_debug_hook,
2872 coff_pointerize_aux_hook,
2873 coff_print_aux,
2874 dummy_reloc16_extra_cases,
2875 dummy_reloc16_estimate,
2876 NULL, /* bfd_coff_sym_is_global */
2877 coff_compute_section_file_positions,
2878 NULL, /* _bfd_coff_start_final_link */
2879 xcoff64_ppc_relocate_section,
2880 coff_rtype_to_howto,
2881 NULL, /* _bfd_coff_adjust_symndx */
2882 _bfd_generic_link_add_one_symbol,
2883 coff_link_output_has_begun,
2884 coff_final_link_postscript,
2885 NULL /* print_pdata. */
2888 U64_TOCMAGIC, /* magic number */
2889 bfd_arch_powerpc,
2890 bfd_mach_ppc_620,
2892 /* Function pointers to xcoff specific swap routines. */
2893 xcoff64_swap_ldhdr_in,
2894 xcoff64_swap_ldhdr_out,
2895 xcoff64_swap_ldsym_in,
2896 xcoff64_swap_ldsym_out,
2897 xcoff64_swap_ldrel_in,
2898 xcoff64_swap_ldrel_out,
2900 /* Sizes. */
2901 LDHDRSZ,
2902 LDSYMSZ,
2903 LDRELSZ,
2904 24, /* _xcoff_function_descriptor_size */
2905 0, /* _xcoff_small_aout_header_size */
2906 /* Versions. */
2907 2, /* _xcoff_ldhdr_version */
2909 _bfd_xcoff64_put_symbol_name,
2910 _bfd_xcoff64_put_ldsymbol_name,
2911 &xcoff64_dynamic_reloc,
2912 xcoff64_create_csect_from_smclas,
2914 /* Lineno and reloc count overflow. */
2915 xcoff64_is_lineno_count_overflow,
2916 xcoff64_is_reloc_count_overflow,
2918 xcoff64_loader_symbol_offset,
2919 xcoff64_loader_reloc_offset,
2921 /* glink. */
2922 &xcoff64_glink_code[0],
2923 40, /* _xcoff_glink_size */
2925 /* rtinit. */
2926 88, /* _xcoff_rtinit_size */
2927 xcoff64_generate_rtinit,
2930 /* The transfer vector that leads the outside world to all of the above. */
2931 const bfd_target aix5coff64_vec =
2933 "aix5coff64-rs6000",
2934 bfd_target_xcoff_flavour,
2935 BFD_ENDIAN_BIG, /* data byte order is big */
2936 BFD_ENDIAN_BIG, /* header byte order is big */
2938 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2939 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2941 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2942 0, /* leading char */
2943 '/', /* ar_pad_char */
2944 15, /* ar_max_namelen */
2946 /* data */
2947 bfd_getb64,
2948 bfd_getb_signed_64,
2949 bfd_putb64,
2950 bfd_getb32,
2951 bfd_getb_signed_32,
2952 bfd_putb32,
2953 bfd_getb16,
2954 bfd_getb_signed_16,
2955 bfd_putb16,
2957 /* hdrs */
2958 bfd_getb64,
2959 bfd_getb_signed_64,
2960 bfd_putb64,
2961 bfd_getb32,
2962 bfd_getb_signed_32,
2963 bfd_putb32,
2964 bfd_getb16,
2965 bfd_getb_signed_16,
2966 bfd_putb16,
2968 { /* bfd_check_format */
2969 _bfd_dummy_target,
2970 coff_object_p,
2971 xcoff64_archive_p,
2972 xcoff64_core_p
2975 { /* bfd_set_format */
2976 bfd_false,
2977 coff_mkobject,
2978 _bfd_generic_mkarchive,
2979 bfd_false
2982 {/* bfd_write_contents */
2983 bfd_false,
2984 xcoff64_write_object_contents,
2985 _bfd_xcoff_write_archive_contents,
2986 bfd_false
2989 /* Generic */
2990 bfd_true,
2991 bfd_true,
2992 coff_new_section_hook,
2993 _bfd_generic_get_section_contents,
2994 _bfd_generic_get_section_contents_in_window,
2996 /* Copy */
2997 _bfd_xcoff_copy_private_bfd_data,
2998 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2999 _bfd_generic_init_private_section_data,
3000 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
3001 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
3002 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
3003 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
3004 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
3006 /* Core */
3007 xcoff64_core_file_failing_command,
3008 xcoff64_core_file_failing_signal,
3009 xcoff64_core_file_matches_executable_p,
3011 /* Archive */
3012 xcoff64_slurp_armap,
3013 bfd_false,
3014 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
3015 bfd_dont_truncate_arname,
3016 _bfd_xcoff_write_armap,
3017 _bfd_xcoff_read_ar_hdr,
3018 xcoff64_openr_next_archived_file,
3019 _bfd_generic_get_elt_at_index,
3020 _bfd_xcoff_stat_arch_elt,
3021 bfd_true,
3023 /* Symbols */
3024 coff_get_symtab_upper_bound,
3025 coff_canonicalize_symtab,
3026 coff_make_empty_symbol,
3027 coff_print_symbol,
3028 coff_get_symbol_info,
3029 _bfd_xcoff_is_local_label_name,
3030 coff_bfd_is_target_special_symbol,
3031 coff_get_lineno,
3032 coff_find_nearest_line,
3033 _bfd_generic_find_line,
3034 coff_find_inliner_info,
3035 coff_bfd_make_debug_symbol,
3036 _bfd_generic_read_minisymbols,
3037 _bfd_generic_minisymbol_to_symbol,
3039 /* Reloc */
3040 coff_get_reloc_upper_bound,
3041 coff_canonicalize_reloc,
3042 xcoff64_reloc_type_lookup,
3043 xcoff64_reloc_name_lookup,
3045 /* Write */
3046 coff_set_arch_mach,
3047 coff_set_section_contents,
3049 /* Link */
3050 xcoff64_sizeof_headers,
3051 bfd_generic_get_relocated_section_contents,
3052 bfd_generic_relax_section,
3053 _bfd_xcoff_bfd_link_hash_table_create,
3054 _bfd_generic_link_hash_table_free,
3055 _bfd_xcoff_bfd_link_add_symbols,
3056 _bfd_generic_link_just_syms,
3057 _bfd_xcoff_bfd_final_link,
3058 _bfd_generic_link_split_section,
3059 bfd_generic_gc_sections,
3060 bfd_generic_merge_sections,
3061 bfd_generic_is_group_section,
3062 bfd_generic_discard_group,
3063 _bfd_generic_section_already_linked,
3064 _bfd_xcoff_define_common_symbol,
3066 /* Dynamic */
3067 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3068 _bfd_xcoff_canonicalize_dynamic_symtab,
3069 _bfd_nodynamic_get_synthetic_symtab,
3070 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3071 _bfd_xcoff_canonicalize_dynamic_reloc,
3073 /* Opposite endian version, none exists. */
3074 NULL,
3076 (void *) & bfd_xcoff_aix5_backend_data,