PR 11225
[binutils.git] / bfd / coff64-rs6000.c
blob7668e7ab909df86e755944892da805702c090952
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. Bitsize is 1 so that r_rsize is 0. */
1598 HOWTO (R_REF, /* type */
1599 0, /* rightshift */
1600 0, /* size (0 = byte, 1 = short, 2 = long) */
1601 1, /* 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 case BFD_RELOC_NONE:
1886 return &xcoff64_howto_table[0xf];
1887 default:
1888 return NULL;
1892 static reloc_howto_type *
1893 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1894 const char *r_name)
1896 unsigned int i;
1898 for (i = 0;
1899 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1900 i++)
1901 if (xcoff64_howto_table[i].name != NULL
1902 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1903 return &xcoff64_howto_table[i];
1905 return NULL;
1908 /* Read in the armap of an XCOFF archive. */
1910 static bfd_boolean
1911 xcoff64_slurp_armap (abfd)
1912 bfd *abfd;
1914 file_ptr off;
1915 size_t namlen;
1916 bfd_size_type sz, amt;
1917 bfd_byte *contents, *cend;
1918 bfd_vma c, i;
1919 carsym *arsym;
1920 bfd_byte *p;
1921 file_ptr pos;
1923 /* This is for the new format. */
1924 struct xcoff_ar_hdr_big hdr;
1926 if (xcoff_ardata (abfd) == NULL)
1928 bfd_has_map (abfd) = FALSE;
1929 return TRUE;
1932 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1933 (const char **) NULL, 10);
1934 if (off == 0)
1936 bfd_has_map (abfd) = FALSE;
1937 return TRUE;
1940 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1941 return FALSE;
1943 /* The symbol table starts with a normal archive header. */
1944 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1945 != SIZEOF_AR_HDR_BIG)
1946 return FALSE;
1948 /* Skip the name (normally empty). */
1949 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1950 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1951 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1952 return FALSE;
1954 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1956 /* Read in the entire symbol table. */
1957 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1958 if (contents == NULL)
1959 return FALSE;
1960 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1961 return FALSE;
1963 /* The symbol table starts with an eight byte count. */
1964 c = H_GET_64 (abfd, contents);
1966 if (c * 8 >= sz)
1968 bfd_set_error (bfd_error_bad_value);
1969 return FALSE;
1971 amt = c;
1972 amt *= sizeof (carsym);
1973 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1974 if (bfd_ardata (abfd)->symdefs == NULL)
1975 return FALSE;
1977 /* After the count comes a list of eight byte file offsets. */
1978 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1979 i < c;
1980 ++i, ++arsym, p += 8)
1981 arsym->file_offset = H_GET_64 (abfd, p);
1983 /* After the file offsets come null terminated symbol names. */
1984 cend = contents + sz;
1985 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1986 i < c;
1987 ++i, ++arsym, p += strlen ((char *) p) + 1)
1989 if (p >= cend)
1991 bfd_set_error (bfd_error_bad_value);
1992 return FALSE;
1994 arsym->name = (char *) p;
1997 bfd_ardata (abfd)->symdef_count = c;
1998 bfd_has_map (abfd) = TRUE;
2000 return TRUE;
2004 /* See if this is an NEW XCOFF archive. */
2006 static const bfd_target *
2007 xcoff64_archive_p (abfd)
2008 bfd *abfd;
2010 struct artdata *tdata_hold;
2011 char magic[SXCOFFARMAG];
2012 /* This is the new format. */
2013 struct xcoff_ar_file_hdr_big hdr;
2014 bfd_size_type amt = SXCOFFARMAG;
2016 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2018 if (bfd_get_error () != bfd_error_system_call)
2019 bfd_set_error (bfd_error_wrong_format);
2020 return NULL;
2023 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2025 bfd_set_error (bfd_error_wrong_format);
2026 return NULL;
2029 /* Copy over the magic string. */
2030 memcpy (hdr.magic, magic, SXCOFFARMAG);
2032 /* Now read the rest of the file header. */
2033 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2034 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
2036 if (bfd_get_error () != bfd_error_system_call)
2037 bfd_set_error (bfd_error_wrong_format);
2038 return NULL;
2041 tdata_hold = bfd_ardata (abfd);
2043 amt = sizeof (struct artdata);
2044 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2045 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2046 goto error_ret_restore;
2048 /* Already cleared by bfd_zalloc above.
2049 bfd_ardata (abfd)->cache = NULL;
2050 bfd_ardata (abfd)->archive_head = NULL;
2051 bfd_ardata (abfd)->symdefs = NULL;
2052 bfd_ardata (abfd)->extended_names = NULL;
2053 bfd_ardata (abfd)->extended_names_size = 0; */
2054 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2055 (const char **) NULL,
2056 10);
2058 amt = SIZEOF_AR_FILE_HDR_BIG;
2059 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2060 if (bfd_ardata (abfd)->tdata == NULL)
2061 goto error_ret;
2063 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2065 if (! xcoff64_slurp_armap (abfd))
2067 error_ret:
2068 bfd_release (abfd, bfd_ardata (abfd));
2069 error_ret_restore:
2070 bfd_ardata (abfd) = tdata_hold;
2071 return NULL;
2074 return abfd->xvec;
2078 /* Open the next element in an XCOFF archive. */
2080 static bfd *
2081 xcoff64_openr_next_archived_file (archive, last_file)
2082 bfd *archive;
2083 bfd *last_file;
2085 bfd_vma filestart;
2087 if ((xcoff_ardata (archive) == NULL)
2088 || ! xcoff_big_format_p (archive))
2090 bfd_set_error (bfd_error_invalid_operation);
2091 return NULL;
2094 if (last_file == NULL)
2096 filestart = bfd_ardata (archive)->first_file_filepos;
2098 else
2100 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2101 (const char **) NULL, 10);
2104 if (filestart == 0
2105 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2106 (const char **) NULL, 10)
2107 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2108 (const char **) NULL, 10))
2110 bfd_set_error (bfd_error_no_more_archived_files);
2111 return NULL;
2114 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2117 /* We can't use the usual coff_sizeof_headers routine, because AIX
2118 always uses an a.out header. */
2120 static int
2121 xcoff64_sizeof_headers (bfd *abfd,
2122 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2124 int size;
2126 size = bfd_coff_filhsz (abfd);
2128 /* Don't think the small aout header can be used since some of the
2129 old elements have been reordered past the end of the old coff
2130 small aout size. */
2132 if (xcoff_data (abfd)->full_aouthdr)
2133 size += bfd_coff_aoutsz (abfd);
2135 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2136 return size;
2141 static asection *
2142 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2143 bfd *abfd;
2144 union internal_auxent *aux;
2145 const char *symbol_name;
2147 asection *return_value = NULL;
2149 /* Changes from 32 :
2150 .sv == 8, is only for 32 bit programs
2151 .ti == 12 and .tb == 13 are now reserved. */
2152 static const char *names[19] =
2154 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2155 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2156 ".td", ".sv64", ".sv3264"
2159 if ((19 >= aux->x_csect.x_smclas)
2160 && (NULL != names[aux->x_csect.x_smclas]))
2163 return_value = bfd_make_section_anyway
2164 (abfd, names[aux->x_csect.x_smclas]);
2167 else
2169 (*_bfd_error_handler)
2170 (_("%B: symbol `%s' has unrecognized smclas %d"),
2171 abfd, symbol_name, aux->x_csect.x_smclas);
2172 bfd_set_error (bfd_error_bad_value);
2175 return return_value;
2178 static bfd_boolean
2179 xcoff64_is_lineno_count_overflow (abfd, value)
2180 bfd *abfd ATTRIBUTE_UNUSED;
2181 bfd_vma value ATTRIBUTE_UNUSED;
2183 return FALSE;
2186 static bfd_boolean
2187 xcoff64_is_reloc_count_overflow (abfd, value)
2188 bfd *abfd ATTRIBUTE_UNUSED;
2189 bfd_vma value ATTRIBUTE_UNUSED;
2191 return FALSE;
2194 static bfd_vma
2195 xcoff64_loader_symbol_offset (abfd, ldhdr)
2196 bfd *abfd ATTRIBUTE_UNUSED;
2197 struct internal_ldhdr *ldhdr;
2199 return (ldhdr->l_symoff);
2202 static bfd_vma
2203 xcoff64_loader_reloc_offset (abfd, ldhdr)
2204 bfd *abfd ATTRIBUTE_UNUSED;
2205 struct internal_ldhdr *ldhdr;
2207 return (ldhdr->l_rldoff);
2210 static bfd_boolean
2211 xcoff64_bad_format_hook (abfd, filehdr)
2212 bfd * abfd;
2213 PTR filehdr;
2215 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2217 /* Check flavor first. */
2218 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2219 return FALSE;
2221 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2222 return FALSE;
2224 return TRUE;
2227 static bfd_boolean
2228 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2229 bfd *abfd;
2230 const char *init;
2231 const char *fini;
2232 bfd_boolean rtld;
2234 bfd_byte filehdr_ext[FILHSZ];
2235 bfd_byte scnhdr_ext[SCNHSZ * 3];
2236 bfd_byte syment_ext[SYMESZ * 10];
2237 bfd_byte reloc_ext[RELSZ * 3];
2238 bfd_byte *data_buffer;
2239 bfd_size_type data_buffer_size;
2240 bfd_byte *string_table, *st_tmp;
2241 bfd_size_type string_table_size;
2242 bfd_vma val;
2243 size_t initsz, finisz;
2244 struct internal_filehdr filehdr;
2245 struct internal_scnhdr text_scnhdr;
2246 struct internal_scnhdr data_scnhdr;
2247 struct internal_scnhdr bss_scnhdr;
2248 struct internal_syment syment;
2249 union internal_auxent auxent;
2250 struct internal_reloc reloc;
2252 char *text_name = ".text";
2253 char *data_name = ".data";
2254 char *bss_name = ".bss";
2255 char *rtinit_name = "__rtinit";
2256 char *rtld_name = "__rtld";
2258 if (! bfd_xcoff_rtinit_size (abfd))
2259 return FALSE;
2261 initsz = (init == NULL ? 0 : 1 + strlen (init));
2262 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2264 /* File header. */
2265 memset (filehdr_ext, 0, FILHSZ);
2266 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2267 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2268 filehdr.f_nscns = 3;
2269 filehdr.f_timdat = 0;
2270 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2271 filehdr.f_symptr = 0; /* set below */
2272 filehdr.f_opthdr = 0;
2273 filehdr.f_flags = 0;
2275 /* Section headers. */
2276 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2278 /* Text. */
2279 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2280 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2281 text_scnhdr.s_paddr = 0;
2282 text_scnhdr.s_vaddr = 0;
2283 text_scnhdr.s_size = 0;
2284 text_scnhdr.s_scnptr = 0;
2285 text_scnhdr.s_relptr = 0;
2286 text_scnhdr.s_lnnoptr = 0;
2287 text_scnhdr.s_nreloc = 0;
2288 text_scnhdr.s_nlnno = 0;
2289 text_scnhdr.s_flags = STYP_TEXT;
2291 /* Data. */
2292 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2293 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2294 data_scnhdr.s_paddr = 0;
2295 data_scnhdr.s_vaddr = 0;
2296 data_scnhdr.s_size = 0; /* set below */
2297 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2298 data_scnhdr.s_relptr = 0; /* set below */
2299 data_scnhdr.s_lnnoptr = 0;
2300 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2301 data_scnhdr.s_nlnno = 0;
2302 data_scnhdr.s_flags = STYP_DATA;
2304 /* Bss. */
2305 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2306 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2307 bss_scnhdr.s_paddr = 0; /* set below */
2308 bss_scnhdr.s_vaddr = 0; /* set below */
2309 bss_scnhdr.s_size = 0; /* set below */
2310 bss_scnhdr.s_scnptr = 0;
2311 bss_scnhdr.s_relptr = 0;
2312 bss_scnhdr.s_lnnoptr = 0;
2313 bss_scnhdr.s_nreloc = 0;
2314 bss_scnhdr.s_nlnno = 0;
2315 bss_scnhdr.s_flags = STYP_BSS;
2317 /* .data
2318 0x0000 0x00000000 : rtl
2319 0x0004 0x00000000 :
2320 0x0008 0x00000018 : offset to init, or 0
2321 0x000C 0x00000038 : offset to fini, or 0
2322 0x0010 0x00000010 : size of descriptor
2323 0x0014 0x00000000 : pad
2324 0x0018 0x00000000 : init, needs a reloc
2325 0x001C 0x00000000 :
2326 0x0020 0x00000058 : offset to init name
2327 0x0024 0x00000000 : flags, padded to a word
2328 0x0028 0x00000000 : empty init
2329 0x002C 0x00000000 :
2330 0x0030 0x00000000 :
2331 0x0034 0x00000000 :
2332 0x0038 0x00000000 : fini, needs a reloc
2333 0x003C 0x00000000 :
2334 0x0040 0x00000??? : offset to fini name
2335 0x0044 0x00000000 : flags, padded to a word
2336 0x0048 0x00000000 : empty fini
2337 0x004C 0x00000000 :
2338 0x0050 0x00000000 :
2339 0x0054 0x00000000 :
2340 0x0058 init name
2341 0x0058 + initsz fini name */
2343 data_buffer_size = 0x0058 + initsz + finisz;
2344 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2345 data_buffer = NULL;
2346 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2347 if (data_buffer == NULL)
2348 return FALSE;
2350 if (initsz)
2352 val = 0x18;
2353 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2354 val = 0x58;
2355 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2356 memcpy (&data_buffer[val], init, initsz);
2359 if (finisz)
2361 val = 0x38;
2362 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2363 val = 0x58 + initsz;
2364 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2365 memcpy (&data_buffer[val], fini, finisz);
2368 val = 0x10;
2369 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2370 data_scnhdr.s_size = data_buffer_size;
2371 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2373 /* String table. */
2374 string_table_size = 4;
2375 string_table_size += strlen (data_name) + 1;
2376 string_table_size += strlen (rtinit_name) + 1;
2377 string_table_size += initsz;
2378 string_table_size += finisz;
2379 if (rtld)
2380 string_table_size += strlen (rtld_name) + 1;
2382 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2383 if (string_table == NULL)
2384 return FALSE;
2386 val = string_table_size;
2387 bfd_put_32 (abfd, val, &string_table[0]);
2388 st_tmp = string_table + 4;
2390 /* symbols
2391 0. .data csect
2392 2. __rtinit
2393 4. init function
2394 6. fini function
2395 8. __rtld */
2396 memset (syment_ext, 0, 10 * SYMESZ);
2397 memset (reloc_ext, 0, 3 * RELSZ);
2399 /* .data csect */
2400 memset (&syment, 0, sizeof (struct internal_syment));
2401 memset (&auxent, 0, sizeof (union internal_auxent));
2403 syment._n._n_n._n_offset = st_tmp - string_table;
2404 memcpy (st_tmp, data_name, strlen (data_name));
2405 st_tmp += strlen (data_name) + 1;
2407 syment.n_scnum = 2;
2408 syment.n_sclass = C_HIDEXT;
2409 syment.n_numaux = 1;
2410 auxent.x_csect.x_scnlen.l = data_buffer_size;
2411 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2412 auxent.x_csect.x_smclas = XMC_RW;
2413 bfd_coff_swap_sym_out (abfd, &syment,
2414 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2415 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2416 syment.n_numaux,
2417 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2418 filehdr.f_nsyms += 2;
2420 /* __rtinit */
2421 memset (&syment, 0, sizeof (struct internal_syment));
2422 memset (&auxent, 0, sizeof (union internal_auxent));
2423 syment._n._n_n._n_offset = st_tmp - string_table;
2424 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2425 st_tmp += strlen (rtinit_name) + 1;
2427 syment.n_scnum = 2;
2428 syment.n_sclass = C_EXT;
2429 syment.n_numaux = 1;
2430 auxent.x_csect.x_smtyp = XTY_LD;
2431 auxent.x_csect.x_smclas = XMC_RW;
2432 bfd_coff_swap_sym_out (abfd, &syment,
2433 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2434 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2435 syment.n_numaux,
2436 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2437 filehdr.f_nsyms += 2;
2439 /* Init. */
2440 if (initsz)
2442 memset (&syment, 0, sizeof (struct internal_syment));
2443 memset (&auxent, 0, sizeof (union internal_auxent));
2445 syment._n._n_n._n_offset = st_tmp - string_table;
2446 memcpy (st_tmp, init, initsz);
2447 st_tmp += initsz;
2449 syment.n_sclass = C_EXT;
2450 syment.n_numaux = 1;
2451 bfd_coff_swap_sym_out (abfd, &syment,
2452 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2453 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2454 syment.n_numaux,
2455 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2456 /* Reloc. */
2457 memset (&reloc, 0, sizeof (struct internal_reloc));
2458 reloc.r_vaddr = 0x0018;
2459 reloc.r_symndx = filehdr.f_nsyms;
2460 reloc.r_type = R_POS;
2461 reloc.r_size = 63;
2462 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2464 filehdr.f_nsyms += 2;
2465 data_scnhdr.s_nreloc += 1;
2468 /* Finit. */
2469 if (finisz)
2471 memset (&syment, 0, sizeof (struct internal_syment));
2472 memset (&auxent, 0, sizeof (union internal_auxent));
2474 syment._n._n_n._n_offset = st_tmp - string_table;
2475 memcpy (st_tmp, fini, finisz);
2476 st_tmp += finisz;
2478 syment.n_sclass = C_EXT;
2479 syment.n_numaux = 1;
2480 bfd_coff_swap_sym_out (abfd, &syment,
2481 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2482 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2483 syment.n_numaux,
2484 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2486 /* Reloc. */
2487 memset (&reloc, 0, sizeof (struct internal_reloc));
2488 reloc.r_vaddr = 0x0038;
2489 reloc.r_symndx = filehdr.f_nsyms;
2490 reloc.r_type = R_POS;
2491 reloc.r_size = 63;
2492 bfd_coff_swap_reloc_out (abfd, &reloc,
2493 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2495 filehdr.f_nsyms += 2;
2496 data_scnhdr.s_nreloc += 1;
2499 if (rtld)
2501 memset (&syment, 0, sizeof (struct internal_syment));
2502 memset (&auxent, 0, sizeof (union internal_auxent));
2504 syment._n._n_n._n_offset = st_tmp - string_table;
2505 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2506 st_tmp += strlen (rtld_name) + 1;
2508 syment.n_sclass = C_EXT;
2509 syment.n_numaux = 1;
2510 bfd_coff_swap_sym_out (abfd, &syment,
2511 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2512 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2513 syment.n_numaux,
2514 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2516 /* Reloc. */
2517 memset (&reloc, 0, sizeof (struct internal_reloc));
2518 reloc.r_vaddr = 0x0000;
2519 reloc.r_symndx = filehdr.f_nsyms;
2520 reloc.r_type = R_POS;
2521 reloc.r_size = 63;
2522 bfd_coff_swap_reloc_out (abfd, &reloc,
2523 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2525 filehdr.f_nsyms += 2;
2526 data_scnhdr.s_nreloc += 1;
2528 bss_scnhdr.s_size = 0;
2531 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2532 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2534 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2535 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2536 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2537 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2538 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2539 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2540 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2541 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2542 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2543 bfd_bwrite (string_table, string_table_size, abfd);
2545 free (data_buffer);
2546 data_buffer = NULL;
2548 return TRUE;
2551 /* The typical dynamic reloc. */
2553 static reloc_howto_type xcoff64_dynamic_reloc =
2554 HOWTO (0, /* type */
2555 0, /* rightshift */
2556 4, /* size (0 = byte, 1 = short, 2 = long) */
2557 64, /* bitsize */
2558 FALSE, /* pc_relative */
2559 0, /* bitpos */
2560 complain_overflow_bitfield, /* complain_on_overflow */
2561 0, /* special_function */
2562 "R_POS", /* name */
2563 TRUE, /* partial_inplace */
2564 MINUS_ONE, /* src_mask */
2565 MINUS_ONE, /* dst_mask */
2566 FALSE); /* pcrel_offset */
2568 static unsigned long xcoff64_glink_code[10] =
2570 0xe9820000, /* ld r12,0(r2) */
2571 0xf8410028, /* std r2,40(r1) */
2572 0xe80c0000, /* ld r0,0(r12) */
2573 0xe84c0008, /* ld r0,8(r12) */
2574 0x7c0903a6, /* mtctr r0 */
2575 0x4e800420, /* bctr */
2576 0x00000000, /* start of traceback table */
2577 0x000ca000, /* traceback table */
2578 0x00000000, /* traceback table */
2579 0x00000018, /* ??? */
2582 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2584 { /* COFF backend, defined in libcoff.h. */
2585 _bfd_xcoff64_swap_aux_in,
2586 _bfd_xcoff64_swap_sym_in,
2587 _bfd_xcoff64_swap_lineno_in,
2588 _bfd_xcoff64_swap_aux_out,
2589 _bfd_xcoff64_swap_sym_out,
2590 _bfd_xcoff64_swap_lineno_out,
2591 xcoff64_swap_reloc_out,
2592 coff_swap_filehdr_out,
2593 coff_swap_aouthdr_out,
2594 coff_swap_scnhdr_out,
2595 FILHSZ,
2596 AOUTSZ,
2597 SCNHSZ,
2598 SYMESZ,
2599 AUXESZ,
2600 RELSZ,
2601 LINESZ,
2602 FILNMLEN,
2603 TRUE, /* _bfd_coff_long_filenames */
2604 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2605 3, /* _bfd_coff_default_section_alignment_power */
2606 TRUE, /* _bfd_coff_force_symnames_in_strings */
2607 4, /* _bfd_coff_debug_string_prefix_length */
2608 coff_swap_filehdr_in,
2609 coff_swap_aouthdr_in,
2610 coff_swap_scnhdr_in,
2611 xcoff64_swap_reloc_in,
2612 xcoff64_bad_format_hook,
2613 coff_set_arch_mach_hook,
2614 coff_mkobject_hook,
2615 styp_to_sec_flags,
2616 coff_set_alignment_hook,
2617 coff_slurp_symbol_table,
2618 symname_in_debug_hook,
2619 coff_pointerize_aux_hook,
2620 coff_print_aux,
2621 dummy_reloc16_extra_cases,
2622 dummy_reloc16_estimate,
2623 NULL, /* bfd_coff_symbol_classification */
2624 coff_compute_section_file_positions,
2625 NULL, /* _bfd_coff_start_final_link */
2626 xcoff64_ppc_relocate_section,
2627 coff_rtype_to_howto,
2628 NULL, /* _bfd_coff_adjust_symndx */
2629 _bfd_generic_link_add_one_symbol,
2630 coff_link_output_has_begun,
2631 coff_final_link_postscript,
2632 NULL /* print_pdata. */
2635 0x01EF, /* magic number */
2636 bfd_arch_powerpc,
2637 bfd_mach_ppc_620,
2639 /* Function pointers to xcoff specific swap routines. */
2640 xcoff64_swap_ldhdr_in,
2641 xcoff64_swap_ldhdr_out,
2642 xcoff64_swap_ldsym_in,
2643 xcoff64_swap_ldsym_out,
2644 xcoff64_swap_ldrel_in,
2645 xcoff64_swap_ldrel_out,
2647 /* Sizes. */
2648 LDHDRSZ,
2649 LDSYMSZ,
2650 LDRELSZ,
2651 24, /* _xcoff_function_descriptor_size */
2652 0, /* _xcoff_small_aout_header_size */
2654 /* Versions. */
2655 2, /* _xcoff_ldhdr_version */
2657 _bfd_xcoff64_put_symbol_name,
2658 _bfd_xcoff64_put_ldsymbol_name,
2659 &xcoff64_dynamic_reloc,
2660 xcoff64_create_csect_from_smclas,
2662 /* Lineno and reloc count overflow. */
2663 xcoff64_is_lineno_count_overflow,
2664 xcoff64_is_reloc_count_overflow,
2666 xcoff64_loader_symbol_offset,
2667 xcoff64_loader_reloc_offset,
2669 /* glink. */
2670 &xcoff64_glink_code[0],
2671 40, /* _xcoff_glink_size */
2673 /* rtinit. */
2674 88, /* _xcoff_rtinit_size */
2675 xcoff64_generate_rtinit,
2678 /* The transfer vector that leads the outside world to all of the above. */
2679 const bfd_target rs6000coff64_vec =
2681 "aixcoff64-rs6000",
2682 bfd_target_xcoff_flavour,
2683 BFD_ENDIAN_BIG, /* data byte order is big */
2684 BFD_ENDIAN_BIG, /* header byte order is big */
2686 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2687 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2689 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2690 0, /* leading char */
2691 '/', /* ar_pad_char */
2692 15, /* ar_max_namelen */
2694 /* data */
2695 bfd_getb64,
2696 bfd_getb_signed_64,
2697 bfd_putb64,
2698 bfd_getb32,
2699 bfd_getb_signed_32,
2700 bfd_putb32,
2701 bfd_getb16,
2702 bfd_getb_signed_16,
2703 bfd_putb16,
2705 /* hdrs */
2706 bfd_getb64,
2707 bfd_getb_signed_64,
2708 bfd_putb64,
2709 bfd_getb32,
2710 bfd_getb_signed_32,
2711 bfd_putb32,
2712 bfd_getb16,
2713 bfd_getb_signed_16,
2714 bfd_putb16,
2716 { /* bfd_check_format */
2717 _bfd_dummy_target,
2718 coff_object_p,
2719 xcoff64_archive_p,
2720 CORE_FILE_P
2723 { /* bfd_set_format */
2724 bfd_false,
2725 coff_mkobject,
2726 _bfd_generic_mkarchive,
2727 bfd_false
2730 {/* bfd_write_contents */
2731 bfd_false,
2732 xcoff64_write_object_contents,
2733 _bfd_xcoff_write_archive_contents,
2734 bfd_false
2737 /* Generic */
2738 bfd_true,
2739 bfd_true,
2740 coff_new_section_hook,
2741 _bfd_generic_get_section_contents,
2742 _bfd_generic_get_section_contents_in_window,
2744 /* Copy */
2745 _bfd_xcoff_copy_private_bfd_data,
2746 _bfd_generic_bfd_merge_private_bfd_data,
2747 _bfd_generic_init_private_section_data,
2748 _bfd_generic_bfd_copy_private_section_data,
2749 _bfd_generic_bfd_copy_private_symbol_data,
2750 _bfd_generic_bfd_copy_private_header_data,
2751 _bfd_generic_bfd_set_private_flags,
2752 _bfd_generic_bfd_print_private_bfd_data,
2754 /* Core */
2755 coff_core_file_failing_command,
2756 coff_core_file_failing_signal,
2757 coff_core_file_matches_executable_p,
2759 /* Archive */
2760 xcoff64_slurp_armap,
2761 _bfd_noarchive_slurp_extended_name_table,
2762 _bfd_noarchive_construct_extended_name_table,
2763 bfd_dont_truncate_arname,
2764 _bfd_xcoff_write_armap,
2765 _bfd_xcoff_read_ar_hdr,
2766 _bfd_generic_write_ar_hdr,
2767 xcoff64_openr_next_archived_file,
2768 _bfd_generic_get_elt_at_index,
2769 _bfd_xcoff_stat_arch_elt,
2770 bfd_true,
2772 /* Symbols */
2773 coff_get_symtab_upper_bound,
2774 coff_canonicalize_symtab,
2775 coff_make_empty_symbol,
2776 coff_print_symbol,
2777 coff_get_symbol_info,
2778 _bfd_xcoff_is_local_label_name,
2779 coff_bfd_is_target_special_symbol,
2780 coff_get_lineno,
2781 coff_find_nearest_line,
2782 _bfd_generic_find_line,
2783 coff_find_inliner_info,
2784 coff_bfd_make_debug_symbol,
2785 _bfd_generic_read_minisymbols,
2786 _bfd_generic_minisymbol_to_symbol,
2788 /* Reloc */
2789 coff_get_reloc_upper_bound,
2790 coff_canonicalize_reloc,
2791 xcoff64_reloc_type_lookup,
2792 xcoff64_reloc_name_lookup,
2794 /* Write */
2795 coff_set_arch_mach,
2796 coff_set_section_contents,
2798 /* Link */
2799 xcoff64_sizeof_headers,
2800 bfd_generic_get_relocated_section_contents,
2801 bfd_generic_relax_section,
2802 _bfd_xcoff_bfd_link_hash_table_create,
2803 _bfd_generic_link_hash_table_free,
2804 _bfd_xcoff_bfd_link_add_symbols,
2805 _bfd_generic_link_just_syms,
2806 _bfd_generic_copy_link_hash_symbol_type,
2807 _bfd_xcoff_bfd_final_link,
2808 _bfd_generic_link_split_section,
2809 bfd_generic_gc_sections,
2810 bfd_generic_merge_sections,
2811 bfd_generic_is_group_section,
2812 bfd_generic_discard_group,
2813 _bfd_generic_section_already_linked,
2814 _bfd_xcoff_define_common_symbol,
2816 /* Dynamic */
2817 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2818 _bfd_xcoff_canonicalize_dynamic_symtab,
2819 _bfd_nodynamic_get_synthetic_symtab,
2820 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2821 _bfd_xcoff_canonicalize_dynamic_reloc,
2823 /* Opposite endian version, none exists */
2824 NULL,
2826 (void *) &bfd_xcoff_backend_data,
2829 extern const bfd_target *xcoff64_core_p
2830 PARAMS ((bfd *));
2831 extern bfd_boolean xcoff64_core_file_matches_executable_p
2832 PARAMS ((bfd *, bfd *));
2833 extern char *xcoff64_core_file_failing_command
2834 PARAMS ((bfd *));
2835 extern int xcoff64_core_file_failing_signal
2836 PARAMS ((bfd *));
2838 /* AIX 5 */
2839 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2841 { /* COFF backend, defined in libcoff.h. */
2842 _bfd_xcoff64_swap_aux_in,
2843 _bfd_xcoff64_swap_sym_in,
2844 _bfd_xcoff64_swap_lineno_in,
2845 _bfd_xcoff64_swap_aux_out,
2846 _bfd_xcoff64_swap_sym_out,
2847 _bfd_xcoff64_swap_lineno_out,
2848 xcoff64_swap_reloc_out,
2849 coff_swap_filehdr_out,
2850 coff_swap_aouthdr_out,
2851 coff_swap_scnhdr_out,
2852 FILHSZ,
2853 AOUTSZ,
2854 SCNHSZ,
2855 SYMESZ,
2856 AUXESZ,
2857 RELSZ,
2858 LINESZ,
2859 FILNMLEN,
2860 TRUE, /* _bfd_coff_long_filenames */
2861 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2862 3, /* _bfd_coff_default_section_alignment_power */
2863 TRUE, /* _bfd_coff_force_symnames_in_strings */
2864 4, /* _bfd_coff_debug_string_prefix_length */
2865 coff_swap_filehdr_in,
2866 coff_swap_aouthdr_in,
2867 coff_swap_scnhdr_in,
2868 xcoff64_swap_reloc_in,
2869 xcoff64_bad_format_hook,
2870 coff_set_arch_mach_hook,
2871 coff_mkobject_hook,
2872 styp_to_sec_flags,
2873 coff_set_alignment_hook,
2874 coff_slurp_symbol_table,
2875 symname_in_debug_hook,
2876 coff_pointerize_aux_hook,
2877 coff_print_aux,
2878 dummy_reloc16_extra_cases,
2879 dummy_reloc16_estimate,
2880 NULL, /* bfd_coff_sym_is_global */
2881 coff_compute_section_file_positions,
2882 NULL, /* _bfd_coff_start_final_link */
2883 xcoff64_ppc_relocate_section,
2884 coff_rtype_to_howto,
2885 NULL, /* _bfd_coff_adjust_symndx */
2886 _bfd_generic_link_add_one_symbol,
2887 coff_link_output_has_begun,
2888 coff_final_link_postscript,
2889 NULL /* print_pdata. */
2892 U64_TOCMAGIC, /* magic number */
2893 bfd_arch_powerpc,
2894 bfd_mach_ppc_620,
2896 /* Function pointers to xcoff specific swap routines. */
2897 xcoff64_swap_ldhdr_in,
2898 xcoff64_swap_ldhdr_out,
2899 xcoff64_swap_ldsym_in,
2900 xcoff64_swap_ldsym_out,
2901 xcoff64_swap_ldrel_in,
2902 xcoff64_swap_ldrel_out,
2904 /* Sizes. */
2905 LDHDRSZ,
2906 LDSYMSZ,
2907 LDRELSZ,
2908 24, /* _xcoff_function_descriptor_size */
2909 0, /* _xcoff_small_aout_header_size */
2910 /* Versions. */
2911 2, /* _xcoff_ldhdr_version */
2913 _bfd_xcoff64_put_symbol_name,
2914 _bfd_xcoff64_put_ldsymbol_name,
2915 &xcoff64_dynamic_reloc,
2916 xcoff64_create_csect_from_smclas,
2918 /* Lineno and reloc count overflow. */
2919 xcoff64_is_lineno_count_overflow,
2920 xcoff64_is_reloc_count_overflow,
2922 xcoff64_loader_symbol_offset,
2923 xcoff64_loader_reloc_offset,
2925 /* glink. */
2926 &xcoff64_glink_code[0],
2927 40, /* _xcoff_glink_size */
2929 /* rtinit. */
2930 88, /* _xcoff_rtinit_size */
2931 xcoff64_generate_rtinit,
2934 /* The transfer vector that leads the outside world to all of the above. */
2935 const bfd_target aix5coff64_vec =
2937 "aix5coff64-rs6000",
2938 bfd_target_xcoff_flavour,
2939 BFD_ENDIAN_BIG, /* data byte order is big */
2940 BFD_ENDIAN_BIG, /* header byte order is big */
2942 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2943 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2945 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2946 0, /* leading char */
2947 '/', /* ar_pad_char */
2948 15, /* ar_max_namelen */
2950 /* data */
2951 bfd_getb64,
2952 bfd_getb_signed_64,
2953 bfd_putb64,
2954 bfd_getb32,
2955 bfd_getb_signed_32,
2956 bfd_putb32,
2957 bfd_getb16,
2958 bfd_getb_signed_16,
2959 bfd_putb16,
2961 /* hdrs */
2962 bfd_getb64,
2963 bfd_getb_signed_64,
2964 bfd_putb64,
2965 bfd_getb32,
2966 bfd_getb_signed_32,
2967 bfd_putb32,
2968 bfd_getb16,
2969 bfd_getb_signed_16,
2970 bfd_putb16,
2972 { /* bfd_check_format */
2973 _bfd_dummy_target,
2974 coff_object_p,
2975 xcoff64_archive_p,
2976 xcoff64_core_p
2979 { /* bfd_set_format */
2980 bfd_false,
2981 coff_mkobject,
2982 _bfd_generic_mkarchive,
2983 bfd_false
2986 {/* bfd_write_contents */
2987 bfd_false,
2988 xcoff64_write_object_contents,
2989 _bfd_xcoff_write_archive_contents,
2990 bfd_false
2993 /* Generic */
2994 bfd_true,
2995 bfd_true,
2996 coff_new_section_hook,
2997 _bfd_generic_get_section_contents,
2998 _bfd_generic_get_section_contents_in_window,
3000 /* Copy */
3001 _bfd_xcoff_copy_private_bfd_data,
3002 _bfd_generic_bfd_merge_private_bfd_data,
3003 _bfd_generic_init_private_section_data,
3004 _bfd_generic_bfd_copy_private_section_data,
3005 _bfd_generic_bfd_copy_private_symbol_data,
3006 _bfd_generic_bfd_copy_private_header_data,
3007 _bfd_generic_bfd_set_private_flags,
3008 _bfd_generic_bfd_print_private_bfd_data,
3010 /* Core */
3011 xcoff64_core_file_failing_command,
3012 xcoff64_core_file_failing_signal,
3013 xcoff64_core_file_matches_executable_p,
3015 /* Archive */
3016 xcoff64_slurp_armap,
3017 _bfd_noarchive_slurp_extended_name_table,
3018 _bfd_noarchive_construct_extended_name_table,
3019 bfd_dont_truncate_arname,
3020 _bfd_xcoff_write_armap,
3021 _bfd_xcoff_read_ar_hdr,
3022 _bfd_generic_write_ar_hdr,
3023 xcoff64_openr_next_archived_file,
3024 _bfd_generic_get_elt_at_index,
3025 _bfd_xcoff_stat_arch_elt,
3026 bfd_true,
3028 /* Symbols */
3029 coff_get_symtab_upper_bound,
3030 coff_canonicalize_symtab,
3031 coff_make_empty_symbol,
3032 coff_print_symbol,
3033 coff_get_symbol_info,
3034 _bfd_xcoff_is_local_label_name,
3035 coff_bfd_is_target_special_symbol,
3036 coff_get_lineno,
3037 coff_find_nearest_line,
3038 _bfd_generic_find_line,
3039 coff_find_inliner_info,
3040 coff_bfd_make_debug_symbol,
3041 _bfd_generic_read_minisymbols,
3042 _bfd_generic_minisymbol_to_symbol,
3044 /* Reloc */
3045 coff_get_reloc_upper_bound,
3046 coff_canonicalize_reloc,
3047 xcoff64_reloc_type_lookup,
3048 xcoff64_reloc_name_lookup,
3050 /* Write */
3051 coff_set_arch_mach,
3052 coff_set_section_contents,
3054 /* Link */
3055 xcoff64_sizeof_headers,
3056 bfd_generic_get_relocated_section_contents,
3057 bfd_generic_relax_section,
3058 _bfd_xcoff_bfd_link_hash_table_create,
3059 _bfd_generic_link_hash_table_free,
3060 _bfd_xcoff_bfd_link_add_symbols,
3061 _bfd_generic_link_just_syms,
3062 _bfd_generic_copy_link_hash_symbol_type,
3063 _bfd_xcoff_bfd_final_link,
3064 _bfd_generic_link_split_section,
3065 bfd_generic_gc_sections,
3066 bfd_generic_merge_sections,
3067 bfd_generic_is_group_section,
3068 bfd_generic_discard_group,
3069 _bfd_generic_section_already_linked,
3070 _bfd_xcoff_define_common_symbol,
3072 /* Dynamic */
3073 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3074 _bfd_xcoff_canonicalize_dynamic_symtab,
3075 _bfd_nodynamic_get_synthetic_symtab,
3076 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3077 _bfd_xcoff_canonicalize_dynamic_reloc,
3079 /* Opposite endian version, none exists. */
3080 NULL,
3082 (void *) & bfd_xcoff_aix5_backend_data,