2008-01-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
[binutils.git] / bfd / coff64-rs6000.c
blob0c5a3dd39637f0a61e7cf19cddd8e52c6a319e06
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
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 #include "coffcode.h"
277 /* For XCOFF64, the effective width of symndx changes depending on
278 whether we are the first entry. Sigh. */
279 static void
280 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
281 bfd *abfd;
282 PTR ext1;
283 PTR in1;
285 LINENO *ext = (LINENO *) ext1;
286 struct internal_lineno *in = (struct internal_lineno *) in1;
288 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
289 if (in->l_lnno == 0)
290 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
291 else
292 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
295 static unsigned int
296 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
297 bfd *abfd;
298 PTR inp;
299 PTR outp;
301 struct internal_lineno *in = (struct internal_lineno *) inp;
302 struct external_lineno *ext = (struct external_lineno *) outp;
304 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
305 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
307 if (in->l_lnno == 0)
308 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
309 else
310 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
312 return bfd_coff_linesz (abfd);
315 static void
316 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
317 bfd *abfd;
318 PTR ext1;
319 PTR in1;
321 struct external_syment *ext = (struct external_syment *) ext1;
322 struct internal_syment *in = (struct internal_syment *) in1;
324 in->_n._n_n._n_zeroes = 0;
325 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
326 in->n_value = H_GET_64 (abfd, ext->e_value);
327 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
328 in->n_type = H_GET_16 (abfd, ext->e_type);
329 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
330 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
333 static unsigned int
334 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
335 bfd *abfd;
336 PTR inp;
337 PTR extp;
339 struct internal_syment *in = (struct internal_syment *) inp;
340 struct external_syment *ext = (struct external_syment *) extp;
342 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
343 H_PUT_64 (abfd, in->n_value, ext->e_value);
344 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
345 H_PUT_16 (abfd, in->n_type, ext->e_type);
346 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
347 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
348 return bfd_coff_symesz (abfd);
351 static void
352 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
353 bfd *abfd;
354 PTR ext1;
355 int type;
356 int class;
357 int indx;
358 int numaux;
359 PTR in1;
361 union external_auxent *ext = (union external_auxent *) ext1;
362 union internal_auxent *in = (union internal_auxent *) in1;
364 switch (class)
366 case C_FILE:
367 if (ext->x_file.x_n.x_zeroes[0] == 0)
369 in->x_file.x_n.x_zeroes = 0;
370 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
372 else
374 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
376 goto end;
378 /* RS/6000 "csect" auxents */
379 case C_EXT:
380 case C_HIDEXT:
381 if (indx + 1 == numaux)
383 bfd_signed_vma h = 0;
384 bfd_vma l = 0;
386 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
387 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
389 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
391 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
392 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
393 /* We don't have to hack bitfields in x_smtyp because it's
394 defined by shifts-and-ands, which are equivalent on all
395 byte orders. */
396 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
397 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
398 goto end;
400 break;
402 case C_STAT:
403 case C_LEAFSTAT:
404 case C_HIDDEN:
405 if (type == T_NULL)
407 /* PE defines some extra fields; we zero them out for
408 safety. */
409 in->x_scn.x_checksum = 0;
410 in->x_scn.x_associated = 0;
411 in->x_scn.x_comdat = 0;
413 goto end;
415 break;
418 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
420 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
421 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
422 in->x_sym.x_fcnary.x_fcn.x_endndx.l
423 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
425 if (ISFCN (type))
427 in->x_sym.x_misc.x_fsize
428 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
430 else
432 in->x_sym.x_misc.x_lnsz.x_lnno
433 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
434 in->x_sym.x_misc.x_lnsz.x_size
435 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
438 end: ;
441 static unsigned int
442 _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
443 bfd *abfd;
444 PTR inp;
445 int type;
446 int class;
447 int indx ATTRIBUTE_UNUSED;
448 int numaux ATTRIBUTE_UNUSED;
449 PTR extp;
451 union internal_auxent *in = (union internal_auxent *) inp;
452 union external_auxent *ext = (union external_auxent *) extp;
454 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
455 switch (class)
457 case C_FILE:
458 if (in->x_file.x_n.x_zeroes == 0)
460 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
461 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
463 else
465 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
467 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
468 goto end;
470 /* RS/6000 "csect" auxents */
471 case C_EXT:
472 case C_HIDEXT:
473 if (indx + 1 == numaux)
475 bfd_vma temp;
477 temp = in->x_csect.x_scnlen.l & 0xffffffff;
478 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
479 temp = in->x_csect.x_scnlen.l >> 32;
480 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
481 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
482 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
483 /* We don't have to hack bitfields in x_smtyp because it's
484 defined by shifts-and-ands, which are equivalent on all
485 byte orders. */
486 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
487 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
488 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
489 goto end;
491 break;
493 case C_STAT:
494 case C_LEAFSTAT:
495 case C_HIDDEN:
496 if (type == T_NULL)
498 goto end;
500 break;
503 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
505 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
506 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
507 H_PUT_8 (abfd, _AUX_FCN,
508 ext->x_auxtype.x_auxtype);
509 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
510 ext->x_sym.x_fcnary.x_fcn.x_endndx);
512 if (ISFCN (type))
514 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
515 ext->x_sym.x_fcnary.x_fcn.x_fsize);
517 else
519 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
520 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
521 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
522 ext->x_sym.x_fcnary.x_lnsz.x_size);
525 end:
527 return bfd_coff_auxesz (abfd);
530 static bfd_boolean
531 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
532 bfd *abfd;
533 struct bfd_strtab_hash *strtab;
534 struct internal_syment *sym;
535 const char *name;
537 bfd_boolean hash;
538 bfd_size_type indx;
540 hash = TRUE;
542 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
543 hash = FALSE;
545 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
547 if (indx == (bfd_size_type) -1)
548 return FALSE;
550 sym->_n._n_n._n_zeroes = 0;
551 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
553 return TRUE;
556 static bfd_boolean
557 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
558 bfd *abfd ATTRIBUTE_UNUSED;
559 struct xcoff_loader_info *ldinfo;
560 struct internal_ldsym *ldsym;
561 const char *name;
563 size_t len;
564 len = strlen (name);
566 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
568 bfd_size_type newalc;
569 char *newstrings;
571 newalc = ldinfo->string_alc * 2;
572 if (newalc == 0)
573 newalc = 32;
574 while (ldinfo->string_size + len + 3 > newalc)
575 newalc *= 2;
577 newstrings = bfd_realloc (ldinfo->strings, newalc);
578 if (newstrings == NULL)
580 ldinfo->failed = TRUE;
581 return FALSE;
583 ldinfo->string_alc = newalc;
584 ldinfo->strings = newstrings;
587 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
588 ldinfo->strings + ldinfo->string_size);
589 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
590 ldsym->_l._l_l._l_zeroes = 0;
591 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
592 ldinfo->string_size += len + 3;
594 return TRUE;
597 /* Routines to swap information in the XCOFF .loader section. If we
598 ever need to write an XCOFF loader, this stuff will need to be
599 moved to another file shared by the linker (which XCOFF calls the
600 ``binder'') and the loader. */
602 /* Swap in the ldhdr structure. */
604 static void
605 xcoff64_swap_ldhdr_in (abfd, s, dst)
606 bfd *abfd;
607 const PTR s;
608 struct internal_ldhdr *dst;
610 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
612 dst->l_version = bfd_get_32 (abfd, src->l_version);
613 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
614 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
615 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
616 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
617 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
618 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
619 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
620 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
621 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
624 /* Swap out the ldhdr structure. */
626 static void
627 xcoff64_swap_ldhdr_out (abfd, src, d)
628 bfd *abfd;
629 const struct internal_ldhdr *src;
630 PTR d;
632 struct external_ldhdr *dst = (struct external_ldhdr *) d;
634 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
635 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
636 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
637 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
638 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
639 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
640 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
641 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
642 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
643 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
646 /* Swap in the ldsym structure. */
648 static void
649 xcoff64_swap_ldsym_in (abfd, s, dst)
650 bfd *abfd;
651 const PTR s;
652 struct internal_ldsym *dst;
654 const struct external_ldsym *src = (const struct external_ldsym *) s;
655 /* XCOFF64 does not use l_zeroes like XCOFF32
656 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
657 as an offset into the loader symbol table. */
658 dst->_l._l_l._l_zeroes = 0;
659 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
660 dst->l_value = bfd_get_64 (abfd, src->l_value);
661 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
662 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
663 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
664 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
665 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
668 /* Swap out the ldsym structure. */
670 static void
671 xcoff64_swap_ldsym_out (abfd, src, d)
672 bfd *abfd;
673 const struct internal_ldsym *src;
674 PTR d;
676 struct external_ldsym *dst = (struct external_ldsym *) d;
678 bfd_put_64 (abfd, src->l_value, dst->l_value);
679 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
680 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
681 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
682 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
683 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
684 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
687 static void
688 xcoff64_swap_reloc_in (abfd, s, d)
689 bfd *abfd;
690 PTR s;
691 PTR d;
693 struct external_reloc *src = (struct external_reloc *) s;
694 struct internal_reloc *dst = (struct internal_reloc *) d;
696 memset (dst, 0, sizeof (struct internal_reloc));
698 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
699 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
700 dst->r_size = bfd_get_8 (abfd, src->r_size);
701 dst->r_type = bfd_get_8 (abfd, src->r_type);
704 static unsigned int
705 xcoff64_swap_reloc_out (abfd, s, d)
706 bfd *abfd;
707 PTR s;
708 PTR d;
710 struct internal_reloc *src = (struct internal_reloc *) s;
711 struct external_reloc *dst = (struct external_reloc *) d;
713 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
714 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
715 bfd_put_8 (abfd, src->r_type, dst->r_type);
716 bfd_put_8 (abfd, src->r_size, dst->r_size);
718 return bfd_coff_relsz (abfd);
721 /* Swap in the ldrel structure. */
723 static void
724 xcoff64_swap_ldrel_in (abfd, s, dst)
725 bfd *abfd;
726 const PTR s;
727 struct internal_ldrel *dst;
729 const struct external_ldrel *src = (const struct external_ldrel *) s;
731 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
732 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
733 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
734 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
737 /* Swap out the ldrel structure. */
739 static void
740 xcoff64_swap_ldrel_out (abfd, src, d)
741 bfd *abfd;
742 const struct internal_ldrel *src;
743 PTR d;
745 struct external_ldrel *dst = (struct external_ldrel *) d;
747 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
748 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
749 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
750 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
753 static bfd_boolean
754 xcoff64_write_object_contents (abfd)
755 bfd *abfd;
757 asection *current;
758 bfd_boolean hasrelocs = FALSE;
759 bfd_boolean haslinno = FALSE;
760 file_ptr scn_base;
761 file_ptr reloc_base;
762 file_ptr lineno_base;
763 file_ptr sym_base;
764 unsigned long reloc_size = 0;
765 unsigned long lnno_size = 0;
766 bfd_boolean long_section_names;
767 asection *text_sec = ((void *) 0);
768 asection *data_sec = ((void *) 0);
769 asection *bss_sec = ((void *) 0);
770 struct internal_filehdr internal_f;
771 struct internal_aouthdr internal_a;
773 bfd_set_error (bfd_error_system_call);
775 if (! abfd->output_has_begun)
777 if (! bfd_coff_compute_section_file_positions (abfd))
778 return FALSE;
781 /* Work out the size of the reloc and linno areas. */
782 reloc_base = obj_relocbase (abfd);
784 for (current = abfd->sections; current != NULL; current = current->next)
785 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
787 lineno_base = reloc_base + reloc_size;
789 /* Make a pass through the symbol table to count line number entries and
790 put them into the correct asections. */
791 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
793 sym_base = lineno_base + lnno_size;
795 /* Indicate in each section->line_filepos its actual file address. */
796 for (current = abfd->sections; current != NULL; current = current->next)
798 if (current->lineno_count)
800 current->line_filepos = lineno_base;
801 current->moving_line_filepos = lineno_base;
802 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
804 else
806 current->line_filepos = 0;
809 if (current->reloc_count)
811 current->rel_filepos = reloc_base;
812 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
814 else
816 current->rel_filepos = 0;
820 if ((abfd->flags & EXEC_P) != 0)
822 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
823 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
825 else
827 scn_base = bfd_coff_filhsz (abfd);
828 internal_f.f_opthdr = 0;
831 internal_f.f_nscns = 0;
833 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
834 return FALSE;
836 long_section_names = FALSE;
837 for (current = abfd->sections; current != NULL; current = current->next)
839 struct internal_scnhdr section;
840 struct external_scnhdr buff;
841 bfd_size_type amount;
843 internal_f.f_nscns++;
845 strncpy (section.s_name, current->name, SCNNMLEN);
847 section.s_vaddr = current->vma;
848 section.s_paddr = current->lma;
849 section.s_size = current->size;
851 /* If this section has no size or is unloadable then the scnptr
852 will be 0 too. */
853 if (current->size == 0
854 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
856 section.s_scnptr = 0;
858 else
860 section.s_scnptr = current->filepos;
863 section.s_relptr = current->rel_filepos;
864 section.s_lnnoptr = current->line_filepos;
865 section.s_nreloc = current->reloc_count;
867 section.s_nlnno = current->lineno_count;
868 if (current->reloc_count != 0)
869 hasrelocs = TRUE;
870 if (current->lineno_count != 0)
871 haslinno = TRUE;
873 section.s_flags = sec_to_styp_flags (current->name, current->flags);
875 if (!strcmp (current->name, _TEXT))
877 text_sec = current;
879 else if (!strcmp (current->name, _DATA))
881 data_sec = current;
883 else if (!strcmp (current->name, _BSS))
885 bss_sec = current;
888 amount = bfd_coff_scnhsz (abfd);
889 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
890 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
891 return FALSE;
894 internal_f.f_timdat = 0;
896 internal_f.f_flags = 0;
898 if (!hasrelocs)
899 internal_f.f_flags |= F_RELFLG;
900 if (!haslinno)
901 internal_f.f_flags |= F_LNNO;
902 if (abfd->flags & EXEC_P)
903 internal_f.f_flags |= F_EXEC;
905 /* FIXME: this is wrong for PPC_PE! */
906 if (bfd_little_endian (abfd))
907 internal_f.f_flags |= F_AR32WR;
908 else
909 internal_f.f_flags |= F_AR32W;
911 if ((abfd->flags & DYNAMIC) != 0)
912 internal_f.f_flags |= F_SHROBJ;
913 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
914 internal_f.f_flags |= F_DYNLOAD;
916 memset (&internal_a, 0, sizeof internal_a);
918 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
919 internal_a.magic = (abfd->flags & D_PAGED
920 ? RS6K_AOUTHDR_ZMAGIC
921 : (abfd->flags & WP_TEXT
922 ? RS6K_AOUTHDR_NMAGIC
923 : RS6K_AOUTHDR_OMAGIC));
925 /* FIXME: Does anybody ever set this to another value? */
926 internal_a.vstamp = 0;
928 /* Now should write relocs, strings, syms. */
929 obj_sym_filepos (abfd) = sym_base;
931 internal_f.f_symptr = 0;
932 internal_f.f_nsyms = 0;
934 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
935 backend linker, and obj_raw_syment_count is not valid until after
936 coff_write_symbols is called. */
937 if (bfd_get_symcount (abfd) != 0)
939 int firstundef;
941 if (!coff_renumber_symbols (abfd, &firstundef))
942 return FALSE;
943 coff_mangle_symbols (abfd);
944 if (! coff_write_symbols (abfd))
945 return FALSE;
946 if (! coff_write_linenumbers (abfd))
947 return FALSE;
948 if (! coff_write_relocs (abfd, firstundef))
949 return FALSE;
951 internal_f.f_symptr = sym_base;
952 internal_f.f_nsyms = bfd_get_symcount (abfd);
954 else if (obj_raw_syment_count (abfd) != 0)
956 internal_f.f_symptr = sym_base;
958 /* AIX appears to require that F_RELFLG not be set if there are
959 local symbols but no relocations. */
960 internal_f.f_flags &=~ F_RELFLG;
962 else
964 internal_f.f_flags |= F_LSYMS;
967 if (text_sec)
969 internal_a.tsize = text_sec->size;
970 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
973 if (data_sec)
975 internal_a.dsize = data_sec->size;
976 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
979 if (bss_sec)
981 internal_a.bsize = bss_sec->size;
982 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
983 internal_a.data_start = bss_sec->vma;
986 internal_a.entry = bfd_get_start_address (abfd);
987 internal_f.f_nsyms = obj_raw_syment_count (abfd);
989 if (xcoff_data (abfd)->full_aouthdr)
991 bfd_vma toc;
992 asection *loader_sec;
994 internal_a.vstamp = 1;
996 internal_a.o_snentry = xcoff_data (abfd)->snentry;
997 if (internal_a.o_snentry == 0)
998 internal_a.entry = (bfd_vma) -1;
1000 if (text_sec != NULL)
1002 internal_a.o_sntext = text_sec->target_index;
1003 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
1005 else
1007 internal_a.o_sntext = 0;
1008 internal_a.o_algntext = 0;
1011 if (data_sec != NULL)
1013 internal_a.o_sndata = data_sec->target_index;
1014 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1016 else
1018 internal_a.o_sndata = 0;
1019 internal_a.o_algndata = 0;
1022 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1023 if (loader_sec != NULL)
1024 internal_a.o_snloader = loader_sec->target_index;
1025 else
1026 internal_a.o_snloader = 0;
1027 if (bss_sec != NULL)
1028 internal_a.o_snbss = bss_sec->target_index;
1029 else
1030 internal_a.o_snbss = 0;
1032 toc = xcoff_data (abfd)->toc;
1033 internal_a.o_toc = toc;
1034 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1036 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1037 if (xcoff_data (abfd)->cputype != -1)
1038 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1039 else
1041 switch (bfd_get_arch (abfd))
1043 case bfd_arch_rs6000:
1044 internal_a.o_cputype = 4;
1045 break;
1046 case bfd_arch_powerpc:
1047 if (bfd_get_mach (abfd) == bfd_mach_ppc)
1048 internal_a.o_cputype = 3;
1049 else
1050 internal_a.o_cputype = 1;
1051 break;
1052 default:
1053 abort ();
1056 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1057 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
1060 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
1061 return FALSE;
1064 char * buff;
1065 bfd_size_type amount = bfd_coff_filhsz (abfd);
1067 buff = bfd_malloc (amount);
1068 if (buff == NULL)
1069 return FALSE;
1071 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1072 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1074 free (buff);
1076 if (amount != bfd_coff_filhsz (abfd))
1077 return FALSE;
1080 if (abfd->flags & EXEC_P)
1082 char * buff;
1083 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1085 buff = bfd_malloc (amount);
1086 if (buff == NULL)
1087 return FALSE;
1089 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
1090 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1092 free (buff);
1094 if (amount != bfd_coff_aoutsz (abfd))
1095 return FALSE;
1098 return TRUE;
1101 static bfd_boolean
1102 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
1103 val, addend, relocation, contents)
1104 bfd *input_bfd;
1105 asection *input_section;
1106 bfd *output_bfd ATTRIBUTE_UNUSED;
1107 struct internal_reloc *rel;
1108 struct internal_syment *sym ATTRIBUTE_UNUSED;
1109 struct reloc_howto_struct *howto;
1110 bfd_vma val;
1111 bfd_vma addend;
1112 bfd_vma *relocation;
1113 bfd_byte *contents;
1115 struct xcoff_link_hash_entry *h;
1117 if (0 > rel->r_symndx)
1118 return FALSE;
1120 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1122 /* If we see an R_BR or R_RBR reloc which is jumping to global
1123 linkage code, and it is followed by an appropriate cror nop
1124 instruction, we replace the cror with ld r2,40(r1). This
1125 restores the TOC after the glink code. Contrariwise, if the
1126 call is followed by a ld r2,40(r1), but the call is not
1127 going to global linkage code, we can replace the load with a
1128 cror. */
1129 if (NULL != h
1130 && bfd_link_hash_defined == h->root.type
1131 && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
1133 bfd_byte *pnext;
1134 unsigned long next;
1136 pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
1137 next = bfd_get_32 (input_bfd, pnext);
1139 /* The _ptrgl function is magic. It is used by the AIX compiler to call
1140 a function through a pointer. */
1141 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
1143 if (next == 0x4def7b82 /* cror 15,15,15 */
1144 || next == 0x4ffffb82 /* cror 31,31,31 */
1145 || next == 0x60000000) /* ori r0,r0,0 */
1146 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1148 else
1150 if (next == 0xe8410028) /* ld r2,40(r1) */
1151 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1154 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
1156 /* Normally, this relocation is against a defined symbol. In the
1157 case where this is a partial link and the output section offset
1158 is greater than 2^25, the linker will return an invalid error
1159 message that the relocation has been truncated. Yes it has been
1160 truncated but no it not important. For this case, disable the
1161 overflow checking. */
1162 howto->complain_on_overflow = complain_overflow_dont;
1165 howto->pc_relative = TRUE;
1166 howto->src_mask &= ~3;
1167 howto->dst_mask = howto->src_mask;
1169 /* A PC relative reloc includes the section address. */
1170 addend += input_section->vma;
1172 *relocation = val + addend;
1173 *relocation -= (input_section->output_section->vma
1174 + input_section->output_offset);
1175 return TRUE;
1178 /* This is the relocation function for the PowerPC64.
1179 See xcoff_ppc_relocation_section for more information. */
1181 bfd_boolean
1182 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1183 input_section, contents, relocs, syms,
1184 sections)
1185 bfd *output_bfd;
1186 struct bfd_link_info *info;
1187 bfd *input_bfd;
1188 asection *input_section;
1189 bfd_byte *contents;
1190 struct internal_reloc *relocs;
1191 struct internal_syment *syms;
1192 asection **sections;
1194 struct internal_reloc *rel;
1195 struct internal_reloc *relend;
1197 rel = relocs;
1198 relend = rel + input_section->reloc_count;
1199 for (; rel < relend; rel++)
1201 long symndx;
1202 struct xcoff_link_hash_entry *h;
1203 struct internal_syment *sym;
1204 bfd_vma addend;
1205 bfd_vma val;
1206 struct reloc_howto_struct howto;
1207 bfd_vma relocation;
1208 bfd_vma value_to_relocate;
1209 bfd_vma address;
1210 bfd_byte *location;
1212 /* Relocation type R_REF is a special relocation type which is
1213 merely used to prevent garbage collection from occurring for
1214 the csect including the symbol which it references. */
1215 if (rel->r_type == R_REF)
1216 continue;
1218 /* howto */
1219 howto.type = rel->r_type;
1220 howto.rightshift = 0;
1221 howto.bitsize = (rel->r_size & 0x3f) + 1;
1222 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
1223 howto.pc_relative = FALSE;
1224 howto.bitpos = 0;
1225 howto.complain_on_overflow = (rel->r_size & 0x80
1226 ? complain_overflow_signed
1227 : complain_overflow_bitfield);
1228 howto.special_function = NULL;
1229 howto.name = "internal";
1230 howto.partial_inplace = TRUE;
1231 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
1232 howto.pcrel_offset = FALSE;
1234 /* symbol */
1235 val = 0;
1236 addend = 0;
1237 h = NULL;
1238 sym = NULL;
1239 symndx = rel->r_symndx;
1241 if (-1 != symndx)
1243 asection *sec;
1245 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1246 sym = syms + symndx;
1247 addend = - sym->n_value;
1249 if (NULL == h)
1251 sec = sections[symndx];
1252 /* Hack to make sure we use the right TOC anchor value
1253 if this reloc is against the TOC anchor. */
1254 if (sec->name[3] == '0'
1255 && strcmp (sec->name, ".tc0") == 0)
1256 val = xcoff_data (output_bfd)->toc;
1257 else
1258 val = (sec->output_section->vma
1259 + sec->output_offset
1260 + sym->n_value
1261 - sec->vma);
1263 else
1265 if (h->root.type == bfd_link_hash_defined
1266 || h->root.type == bfd_link_hash_defweak)
1268 sec = h->root.u.def.section;
1269 val = (h->root.u.def.value
1270 + sec->output_section->vma
1271 + sec->output_offset);
1273 else if (h->root.type == bfd_link_hash_common)
1275 sec = h->root.u.c.p->section;
1276 val = (sec->output_section->vma
1277 + sec->output_offset);
1279 else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
1280 && ! info->relocatable)
1282 if (! ((*info->callbacks->undefined_symbol)
1283 (info, h->root.root.string, input_bfd, input_section,
1284 rel->r_vaddr - input_section->vma, TRUE)))
1285 return FALSE;
1287 /* Don't try to process the reloc. It can't help, and
1288 it may generate another error. */
1289 continue;
1294 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
1295 || !((*xcoff64_calculate_relocation[rel->r_type])
1296 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1297 addend, &relocation, contents)))
1298 return FALSE;
1300 /* address */
1301 address = rel->r_vaddr - input_section->vma;
1302 location = contents + address;
1304 if (address > input_section->size)
1305 abort ();
1307 /* Get the value we are going to relocate. */
1308 if (1 == howto.size)
1309 value_to_relocate = bfd_get_16 (input_bfd, location);
1310 else if (2 == howto.size)
1311 value_to_relocate = bfd_get_32 (input_bfd, location);
1312 else
1313 value_to_relocate = bfd_get_64 (input_bfd, location);
1315 /* overflow.
1317 FIXME: We may drop bits during the addition
1318 which we don't check for. We must either check at every single
1319 operation, which would be tedious, or we must do the computations
1320 in a type larger than bfd_vma, which would be inefficient. */
1322 if ((unsigned int) howto.complain_on_overflow
1323 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1324 abort ();
1326 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1327 (input_bfd, value_to_relocate, relocation, &howto)))
1329 const char *name;
1330 char buf[SYMNMLEN + 1];
1331 char reloc_type_name[10];
1333 if (symndx == -1)
1335 name = "*ABS*";
1337 else if (h != NULL)
1339 name = NULL;
1341 else
1343 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1344 if (name == NULL)
1345 name = "UNKNOWN";
1347 sprintf (reloc_type_name, "0x%02x", rel->r_type);
1349 if (! ((*info->callbacks->reloc_overflow)
1350 (info, (h ? &h->root : NULL), name, reloc_type_name,
1351 (bfd_vma) 0, input_bfd, input_section,
1352 rel->r_vaddr - input_section->vma)))
1353 return FALSE;
1356 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
1357 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1358 | (((value_to_relocate & howto.src_mask)
1359 + relocation) & howto.dst_mask));
1361 /* Put the value back in the object file. */
1362 if (1 == howto.size)
1363 bfd_put_16 (input_bfd, value_to_relocate, location);
1364 else if (2 == howto.size)
1365 bfd_put_32 (input_bfd, value_to_relocate, location);
1366 else
1367 bfd_put_64 (input_bfd, value_to_relocate, location);
1370 return TRUE;
1374 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1375 bitsize and whether they are signed or not, along with a
1376 conventional type. This table is for the types, which are used for
1377 different algorithms for putting in the reloc. Many of these
1378 relocs need special_function entries, which I have not written. */
1380 reloc_howto_type xcoff64_howto_table[] =
1382 /* Standard 64 bit relocation. */
1383 HOWTO (R_POS, /* type */
1384 0, /* rightshift */
1385 4, /* size (0 = byte, 1 = short, 2 = long) */
1386 64, /* bitsize */
1387 FALSE, /* pc_relative */
1388 0, /* bitpos */
1389 complain_overflow_bitfield, /* complain_on_overflow */
1390 0, /* special_function */
1391 "R_POS_64", /* name */
1392 TRUE, /* partial_inplace */
1393 MINUS_ONE, /* src_mask */
1394 MINUS_ONE, /* dst_mask */
1395 FALSE), /* pcrel_offset */
1397 /* 64 bit relocation, but store negative value. */
1398 HOWTO (R_NEG, /* type */
1399 0, /* rightshift */
1400 -4, /* size (0 = byte, 1 = short, 2 = long) */
1401 64, /* bitsize */
1402 FALSE, /* pc_relative */
1403 0, /* bitpos */
1404 complain_overflow_bitfield, /* complain_on_overflow */
1405 0, /* special_function */
1406 "R_NEG", /* name */
1407 TRUE, /* partial_inplace */
1408 MINUS_ONE, /* src_mask */
1409 MINUS_ONE, /* dst_mask */
1410 FALSE), /* pcrel_offset */
1412 /* 32 bit PC relative relocation. */
1413 HOWTO (R_REL, /* type */
1414 0, /* rightshift */
1415 2, /* size (0 = byte, 1 = short, 2 = long) */
1416 32, /* bitsize */
1417 TRUE, /* pc_relative */
1418 0, /* bitpos */
1419 complain_overflow_signed, /* complain_on_overflow */
1420 0, /* special_function */
1421 "R_REL", /* name */
1422 TRUE, /* partial_inplace */
1423 0xffffffff, /* src_mask */
1424 0xffffffff, /* dst_mask */
1425 FALSE), /* pcrel_offset */
1427 /* 16 bit TOC relative relocation. */
1428 HOWTO (R_TOC, /* type */
1429 0, /* rightshift */
1430 1, /* size (0 = byte, 1 = short, 2 = long) */
1431 16, /* bitsize */
1432 FALSE, /* pc_relative */
1433 0, /* bitpos */
1434 complain_overflow_bitfield, /* complain_on_overflow */
1435 0, /* special_function */
1436 "R_TOC", /* name */
1437 TRUE, /* partial_inplace */
1438 0xffff, /* src_mask */
1439 0xffff, /* dst_mask */
1440 FALSE), /* pcrel_offset */
1442 /* I don't really know what this is. */
1443 HOWTO (R_RTB, /* type */
1444 1, /* rightshift */
1445 2, /* size (0 = byte, 1 = short, 2 = long) */
1446 32, /* bitsize */
1447 FALSE, /* pc_relative */
1448 0, /* bitpos */
1449 complain_overflow_bitfield, /* complain_on_overflow */
1450 0, /* special_function */
1451 "R_RTB", /* name */
1452 TRUE, /* partial_inplace */
1453 0xffffffff, /* src_mask */
1454 0xffffffff, /* dst_mask */
1455 FALSE), /* pcrel_offset */
1457 /* External TOC relative symbol. */
1458 HOWTO (R_GL, /* type */
1459 0, /* rightshift */
1460 1, /* size (0 = byte, 1 = short, 2 = long) */
1461 16, /* bitsize */
1462 FALSE, /* pc_relative */
1463 0, /* bitpos */
1464 complain_overflow_bitfield, /* complain_on_overflow */
1465 0, /* special_function */
1466 "R_GL", /* name */
1467 TRUE, /* partial_inplace */
1468 0xffff, /* src_mask */
1469 0xffff, /* dst_mask */
1470 FALSE), /* pcrel_offset */
1472 /* Local TOC relative symbol. */
1473 HOWTO (R_TCL, /* type */
1474 0, /* rightshift */
1475 1, /* size (0 = byte, 1 = short, 2 = long) */
1476 16, /* bitsize */
1477 FALSE, /* pc_relative */
1478 0, /* bitpos */
1479 complain_overflow_bitfield, /* complain_on_overflow */
1480 0, /* special_function */
1481 "R_TCL", /* name */
1482 TRUE, /* partial_inplace */
1483 0xffff, /* src_mask */
1484 0xffff, /* dst_mask */
1485 FALSE), /* pcrel_offset */
1487 EMPTY_HOWTO (7),
1489 /* Non modifiable absolute branch. */
1490 HOWTO (R_BA, /* type */
1491 0, /* rightshift */
1492 2, /* size (0 = byte, 1 = short, 2 = long) */
1493 26, /* bitsize */
1494 FALSE, /* pc_relative */
1495 0, /* bitpos */
1496 complain_overflow_bitfield, /* complain_on_overflow */
1497 0, /* special_function */
1498 "R_BA_26", /* name */
1499 TRUE, /* partial_inplace */
1500 0x03fffffc, /* src_mask */
1501 0x03fffffc, /* dst_mask */
1502 FALSE), /* pcrel_offset */
1504 EMPTY_HOWTO (9),
1506 /* Non modifiable relative branch. */
1507 HOWTO (R_BR, /* type */
1508 0, /* rightshift */
1509 2, /* size (0 = byte, 1 = short, 2 = long) */
1510 26, /* bitsize */
1511 TRUE, /* pc_relative */
1512 0, /* bitpos */
1513 complain_overflow_signed, /* complain_on_overflow */
1514 0, /* special_function */
1515 "R_BR", /* name */
1516 TRUE, /* partial_inplace */
1517 0x03fffffc, /* src_mask */
1518 0x03fffffc, /* dst_mask */
1519 FALSE), /* pcrel_offset */
1521 EMPTY_HOWTO (0xb),
1523 /* Indirect load. */
1524 HOWTO (R_RL, /* type */
1525 0, /* rightshift */
1526 1, /* size (0 = byte, 1 = short, 2 = long) */
1527 16, /* bitsize */
1528 FALSE, /* pc_relative */
1529 0, /* bitpos */
1530 complain_overflow_bitfield, /* complain_on_overflow */
1531 0, /* special_function */
1532 "R_RL", /* name */
1533 TRUE, /* partial_inplace */
1534 0xffff, /* src_mask */
1535 0xffff, /* dst_mask */
1536 FALSE), /* pcrel_offset */
1538 /* Load address. */
1539 HOWTO (R_RLA, /* type */
1540 0, /* rightshift */
1541 1, /* size (0 = byte, 1 = short, 2 = long) */
1542 16, /* bitsize */
1543 FALSE, /* pc_relative */
1544 0, /* bitpos */
1545 complain_overflow_bitfield, /* complain_on_overflow */
1546 0, /* special_function */
1547 "R_RLA", /* name */
1548 TRUE, /* partial_inplace */
1549 0xffff, /* src_mask */
1550 0xffff, /* dst_mask */
1551 FALSE), /* pcrel_offset */
1553 EMPTY_HOWTO (0xe),
1555 /* Non-relocating reference. */
1556 HOWTO (R_REF, /* type */
1557 0, /* rightshift */
1558 2, /* size (0 = byte, 1 = short, 2 = long) */
1559 32, /* bitsize */
1560 FALSE, /* pc_relative */
1561 0, /* bitpos */
1562 complain_overflow_dont, /* complain_on_overflow */
1563 0, /* special_function */
1564 "R_REF", /* name */
1565 FALSE, /* partial_inplace */
1566 0, /* src_mask */
1567 0, /* dst_mask */
1568 FALSE), /* pcrel_offset */
1570 EMPTY_HOWTO (0x10),
1571 EMPTY_HOWTO (0x11),
1573 /* TOC relative indirect load. */
1574 HOWTO (R_TRL, /* type */
1575 0, /* rightshift */
1576 1, /* size (0 = byte, 1 = short, 2 = long) */
1577 16, /* bitsize */
1578 FALSE, /* pc_relative */
1579 0, /* bitpos */
1580 complain_overflow_bitfield, /* complain_on_overflow */
1581 0, /* special_function */
1582 "R_TRL", /* name */
1583 TRUE, /* partial_inplace */
1584 0xffff, /* src_mask */
1585 0xffff, /* dst_mask */
1586 FALSE), /* pcrel_offset */
1588 /* TOC relative load address. */
1589 HOWTO (R_TRLA, /* type */
1590 0, /* rightshift */
1591 1, /* size (0 = byte, 1 = short, 2 = long) */
1592 16, /* bitsize */
1593 FALSE, /* pc_relative */
1594 0, /* bitpos */
1595 complain_overflow_bitfield, /* complain_on_overflow */
1596 0, /* special_function */
1597 "R_TRLA", /* name */
1598 TRUE, /* partial_inplace */
1599 0xffff, /* src_mask */
1600 0xffff, /* dst_mask */
1601 FALSE), /* pcrel_offset */
1603 /* Modifiable relative branch. */
1604 HOWTO (R_RRTBI, /* type */
1605 1, /* rightshift */
1606 2, /* size (0 = byte, 1 = short, 2 = long) */
1607 32, /* bitsize */
1608 FALSE, /* pc_relative */
1609 0, /* bitpos */
1610 complain_overflow_bitfield, /* complain_on_overflow */
1611 0, /* special_function */
1612 "R_RRTBI", /* name */
1613 TRUE, /* partial_inplace */
1614 0xffffffff, /* src_mask */
1615 0xffffffff, /* dst_mask */
1616 FALSE), /* pcrel_offset */
1618 /* Modifiable absolute branch. */
1619 HOWTO (R_RRTBA, /* type */
1620 1, /* rightshift */
1621 2, /* size (0 = byte, 1 = short, 2 = long) */
1622 32, /* bitsize */
1623 FALSE, /* pc_relative */
1624 0, /* bitpos */
1625 complain_overflow_bitfield, /* complain_on_overflow */
1626 0, /* special_function */
1627 "R_RRTBA", /* name */
1628 TRUE, /* partial_inplace */
1629 0xffffffff, /* src_mask */
1630 0xffffffff, /* dst_mask */
1631 FALSE), /* pcrel_offset */
1633 /* Modifiable call absolute indirect. */
1634 HOWTO (R_CAI, /* type */
1635 0, /* rightshift */
1636 1, /* size (0 = byte, 1 = short, 2 = long) */
1637 16, /* bitsize */
1638 FALSE, /* pc_relative */
1639 0, /* bitpos */
1640 complain_overflow_bitfield, /* complain_on_overflow */
1641 0, /* special_function */
1642 "R_CAI", /* name */
1643 TRUE, /* partial_inplace */
1644 0xffff, /* src_mask */
1645 0xffff, /* dst_mask */
1646 FALSE), /* pcrel_offset */
1648 /* Modifiable call relative. */
1649 HOWTO (R_CREL, /* type */
1650 0, /* rightshift */
1651 1, /* size (0 = byte, 1 = short, 2 = long) */
1652 16, /* bitsize */
1653 FALSE, /* pc_relative */
1654 0, /* bitpos */
1655 complain_overflow_bitfield, /* complain_on_overflow */
1656 0, /* special_function */
1657 "R_CREL", /* name */
1658 TRUE, /* partial_inplace */
1659 0xffff, /* src_mask */
1660 0xffff, /* dst_mask */
1661 FALSE), /* pcrel_offset */
1663 /* Modifiable branch absolute. */
1664 HOWTO (R_RBA, /* type */
1665 0, /* rightshift */
1666 2, /* size (0 = byte, 1 = short, 2 = long) */
1667 26, /* bitsize */
1668 FALSE, /* pc_relative */
1669 0, /* bitpos */
1670 complain_overflow_bitfield, /* complain_on_overflow */
1671 0, /* special_function */
1672 "R_RBA", /* name */
1673 TRUE, /* partial_inplace */
1674 0x03fffffc, /* src_mask */
1675 0x03fffffc, /* dst_mask */
1676 FALSE), /* pcrel_offset */
1678 /* Modifiable branch absolute. */
1679 HOWTO (R_RBAC, /* type */
1680 0, /* rightshift */
1681 2, /* size (0 = byte, 1 = short, 2 = long) */
1682 32, /* bitsize */
1683 FALSE, /* pc_relative */
1684 0, /* bitpos */
1685 complain_overflow_bitfield, /* complain_on_overflow */
1686 0, /* special_function */
1687 "R_RBAC", /* name */
1688 TRUE, /* partial_inplace */
1689 0xffffffff, /* src_mask */
1690 0xffffffff, /* dst_mask */
1691 FALSE), /* pcrel_offset */
1693 /* Modifiable branch relative. */
1694 HOWTO (R_RBR, /* type */
1695 0, /* rightshift */
1696 2, /* size (0 = byte, 1 = short, 2 = long) */
1697 26, /* bitsize */
1698 FALSE, /* pc_relative */
1699 0, /* bitpos */
1700 complain_overflow_signed, /* complain_on_overflow */
1701 0, /* special_function */
1702 "R_RBR_26", /* name */
1703 TRUE, /* partial_inplace */
1704 0x03fffffc, /* src_mask */
1705 0x03fffffc, /* dst_mask */
1706 FALSE), /* pcrel_offset */
1708 /* Modifiable branch absolute. */
1709 HOWTO (R_RBRC, /* type */
1710 0, /* rightshift */
1711 1, /* size (0 = byte, 1 = short, 2 = long) */
1712 16, /* bitsize */
1713 FALSE, /* pc_relative */
1714 0, /* bitpos */
1715 complain_overflow_bitfield, /* complain_on_overflow */
1716 0, /* special_function */
1717 "R_RBRC", /* name */
1718 TRUE, /* partial_inplace */
1719 0xffff, /* src_mask */
1720 0xffff, /* dst_mask */
1721 FALSE), /* pcrel_offset */
1723 HOWTO (R_POS, /* type */
1724 0, /* rightshift */
1725 2, /* size (0 = byte, 1 = short, 2 = long) */
1726 32, /* bitsize */
1727 FALSE, /* pc_relative */
1728 0, /* bitpos */
1729 complain_overflow_bitfield, /* complain_on_overflow */
1730 0, /* special_function */
1731 "R_POS_32", /* name */
1732 TRUE, /* partial_inplace */
1733 0xffffffff, /* src_mask */
1734 0xffffffff, /* dst_mask */
1735 FALSE), /* pcrel_offset */
1737 /* 16 bit Non modifiable absolute branch. */
1738 HOWTO (R_BA, /* type */
1739 0, /* rightshift */
1740 1, /* size (0 = byte, 1 = short, 2 = long) */
1741 16, /* bitsize */
1742 FALSE, /* pc_relative */
1743 0, /* bitpos */
1744 complain_overflow_bitfield, /* complain_on_overflow */
1745 0, /* special_function */
1746 "R_BA_16", /* name */
1747 TRUE, /* partial_inplace */
1748 0xfffc, /* src_mask */
1749 0xfffc, /* dst_mask */
1750 FALSE), /* pcrel_offset */
1752 /* Modifiable branch relative. */
1753 HOWTO (R_RBR, /* type */
1754 0, /* rightshift */
1755 1, /* size (0 = byte, 1 = short, 2 = long) */
1756 16, /* bitsize */
1757 FALSE, /* pc_relative */
1758 0, /* bitpos */
1759 complain_overflow_signed, /* complain_on_overflow */
1760 0, /* special_function */
1761 "R_RBR_16", /* name */
1762 TRUE, /* partial_inplace */
1763 0xffff, /* src_mask */
1764 0xffff, /* dst_mask */
1765 FALSE), /* pcrel_offset */
1767 /* Modifiable branch absolute. */
1768 HOWTO (R_RBA, /* type */
1769 0, /* rightshift */
1770 1, /* size (0 = byte, 1 = short, 2 = long) */
1771 16, /* bitsize */
1772 FALSE, /* pc_relative */
1773 0, /* bitpos */
1774 complain_overflow_bitfield, /* complain_on_overflow */
1775 0, /* special_function */
1776 "R_RBA_16", /* name */
1777 TRUE, /* partial_inplace */
1778 0xffff, /* src_mask */
1779 0xffff, /* dst_mask */
1780 FALSE), /* pcrel_offset */
1784 void
1785 xcoff64_rtype2howto (relent, internal)
1786 arelent *relent;
1787 struct internal_reloc *internal;
1789 if (internal->r_type > R_RBRC)
1790 abort ();
1792 /* Default howto layout works most of the time */
1793 relent->howto = &xcoff64_howto_table[internal->r_type];
1795 /* Special case some 16 bit reloc */
1796 if (15 == (internal->r_size & 0x3f))
1798 if (R_BA == internal->r_type)
1799 relent->howto = &xcoff64_howto_table[0x1d];
1800 else if (R_RBR == internal->r_type)
1801 relent->howto = &xcoff64_howto_table[0x1e];
1802 else if (R_RBA == internal->r_type)
1803 relent->howto = &xcoff64_howto_table[0x1f];
1805 /* Special case 32 bit */
1806 else if (31 == (internal->r_size & 0x3f))
1808 if (R_POS == internal->r_type)
1809 relent->howto = &xcoff64_howto_table[0x1c];
1812 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1813 relocation, as well as indicating whether it is signed or not.
1814 Doublecheck that the relocation information gathered from the
1815 type matches this information. The bitsize is not significant
1816 for R_REF relocs. */
1817 if (relent->howto->dst_mask != 0
1818 && (relent->howto->bitsize
1819 != ((unsigned int) internal->r_size & 0x3f) + 1))
1820 abort ();
1823 reloc_howto_type *
1824 xcoff64_reloc_type_lookup (abfd, code)
1825 bfd *abfd ATTRIBUTE_UNUSED;
1826 bfd_reloc_code_real_type code;
1828 switch (code)
1830 case BFD_RELOC_PPC_B26:
1831 return &xcoff64_howto_table[0xa];
1832 case BFD_RELOC_PPC_BA16:
1833 return &xcoff64_howto_table[0x1d];
1834 case BFD_RELOC_PPC_BA26:
1835 return &xcoff64_howto_table[8];
1836 case BFD_RELOC_PPC_TOC16:
1837 return &xcoff64_howto_table[3];
1838 case BFD_RELOC_32:
1839 case BFD_RELOC_CTOR:
1840 return &xcoff64_howto_table[0x1c];
1841 case BFD_RELOC_64:
1842 return &xcoff64_howto_table[0];
1843 default:
1844 return NULL;
1848 static reloc_howto_type *
1849 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1850 const char *r_name)
1852 unsigned int i;
1854 for (i = 0;
1855 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1856 i++)
1857 if (xcoff64_howto_table[i].name != NULL
1858 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1859 return &xcoff64_howto_table[i];
1861 return NULL;
1864 /* Read in the armap of an XCOFF archive. */
1866 static bfd_boolean
1867 xcoff64_slurp_armap (abfd)
1868 bfd *abfd;
1870 file_ptr off;
1871 size_t namlen;
1872 bfd_size_type sz, amt;
1873 bfd_byte *contents, *cend;
1874 bfd_vma c, i;
1875 carsym *arsym;
1876 bfd_byte *p;
1877 file_ptr pos;
1879 /* This is for the new format. */
1880 struct xcoff_ar_hdr_big hdr;
1882 if (xcoff_ardata (abfd) == NULL)
1884 bfd_has_map (abfd) = FALSE;
1885 return TRUE;
1888 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1889 (const char **) NULL, 10);
1890 if (off == 0)
1892 bfd_has_map (abfd) = FALSE;
1893 return TRUE;
1896 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1897 return FALSE;
1899 /* The symbol table starts with a normal archive header. */
1900 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1901 != SIZEOF_AR_HDR_BIG)
1902 return FALSE;
1904 /* Skip the name (normally empty). */
1905 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1906 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1907 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1908 return FALSE;
1910 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1912 /* Read in the entire symbol table. */
1913 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1914 if (contents == NULL)
1915 return FALSE;
1916 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1917 return FALSE;
1919 /* The symbol table starts with an eight byte count. */
1920 c = H_GET_64 (abfd, contents);
1922 if (c * 8 >= sz)
1924 bfd_set_error (bfd_error_bad_value);
1925 return FALSE;
1927 amt = c;
1928 amt *= sizeof (carsym);
1929 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1930 if (bfd_ardata (abfd)->symdefs == NULL)
1931 return FALSE;
1933 /* After the count comes a list of eight byte file offsets. */
1934 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1935 i < c;
1936 ++i, ++arsym, p += 8)
1937 arsym->file_offset = H_GET_64 (abfd, p);
1939 /* After the file offsets come null terminated symbol names. */
1940 cend = contents + sz;
1941 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1942 i < c;
1943 ++i, ++arsym, p += strlen ((char *) p) + 1)
1945 if (p >= cend)
1947 bfd_set_error (bfd_error_bad_value);
1948 return FALSE;
1950 arsym->name = (char *) p;
1953 bfd_ardata (abfd)->symdef_count = c;
1954 bfd_has_map (abfd) = TRUE;
1956 return TRUE;
1960 /* See if this is an NEW XCOFF archive. */
1962 static const bfd_target *
1963 xcoff64_archive_p (abfd)
1964 bfd *abfd;
1966 struct artdata *tdata_hold;
1967 char magic[SXCOFFARMAG];
1968 /* This is the new format. */
1969 struct xcoff_ar_file_hdr_big hdr;
1970 bfd_size_type amt = SXCOFFARMAG;
1972 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
1974 if (bfd_get_error () != bfd_error_system_call)
1975 bfd_set_error (bfd_error_wrong_format);
1976 return NULL;
1979 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1981 bfd_set_error (bfd_error_wrong_format);
1982 return NULL;
1985 /* Copy over the magic string. */
1986 memcpy (hdr.magic, magic, SXCOFFARMAG);
1988 /* Now read the rest of the file header. */
1989 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1990 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1992 if (bfd_get_error () != bfd_error_system_call)
1993 bfd_set_error (bfd_error_wrong_format);
1994 return NULL;
1997 tdata_hold = bfd_ardata (abfd);
1999 amt = sizeof (struct artdata);
2000 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2001 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2002 goto error_ret_restore;
2004 /* Already cleared by bfd_zalloc above.
2005 bfd_ardata (abfd)->cache = NULL;
2006 bfd_ardata (abfd)->archive_head = NULL;
2007 bfd_ardata (abfd)->symdefs = NULL;
2008 bfd_ardata (abfd)->extended_names = NULL;
2009 bfd_ardata (abfd)->extended_names_size = 0; */
2010 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2011 (const char **) NULL,
2012 10);
2014 amt = SIZEOF_AR_FILE_HDR_BIG;
2015 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
2016 if (bfd_ardata (abfd)->tdata == NULL)
2017 goto error_ret;
2019 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2021 if (! xcoff64_slurp_armap (abfd))
2023 error_ret:
2024 bfd_release (abfd, bfd_ardata (abfd));
2025 error_ret_restore:
2026 bfd_ardata (abfd) = tdata_hold;
2027 return NULL;
2030 return abfd->xvec;
2034 /* Open the next element in an XCOFF archive. */
2036 static bfd *
2037 xcoff64_openr_next_archived_file (archive, last_file)
2038 bfd *archive;
2039 bfd *last_file;
2041 bfd_vma filestart;
2043 if ((xcoff_ardata (archive) == NULL)
2044 || ! xcoff_big_format_p (archive))
2046 bfd_set_error (bfd_error_invalid_operation);
2047 return NULL;
2050 if (last_file == NULL)
2052 filestart = bfd_ardata (archive)->first_file_filepos;
2054 else
2056 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2057 (const char **) NULL, 10);
2060 if (filestart == 0
2061 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2062 (const char **) NULL, 10)
2063 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2064 (const char **) NULL, 10))
2066 bfd_set_error (bfd_error_no_more_archived_files);
2067 return NULL;
2070 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
2073 /* We can't use the usual coff_sizeof_headers routine, because AIX
2074 always uses an a.out header. */
2076 static int
2077 xcoff64_sizeof_headers (bfd *abfd,
2078 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2080 int size;
2082 size = bfd_coff_filhsz (abfd);
2084 /* Don't think the small aout header can be used since some of the
2085 old elements have been reordered past the end of the old coff
2086 small aout size. */
2088 if (xcoff_data (abfd)->full_aouthdr)
2089 size += bfd_coff_aoutsz (abfd);
2091 size += abfd->section_count * bfd_coff_scnhsz (abfd);
2092 return size;
2097 static asection *
2098 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
2099 bfd *abfd;
2100 union internal_auxent *aux;
2101 const char *symbol_name;
2103 asection *return_value = NULL;
2105 /* Changes from 32 :
2106 .sv == 8, is only for 32 bit programs
2107 .ti == 12 and .tb == 13 are now reserved. */
2108 static const char *names[19] =
2110 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2111 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
2112 ".td", ".sv64", ".sv3264"
2115 if ((19 >= aux->x_csect.x_smclas)
2116 && (NULL != names[aux->x_csect.x_smclas]))
2119 return_value = bfd_make_section_anyway
2120 (abfd, names[aux->x_csect.x_smclas]);
2123 else
2125 (*_bfd_error_handler)
2126 (_("%B: symbol `%s' has unrecognized smclas %d"),
2127 abfd, symbol_name, aux->x_csect.x_smclas);
2128 bfd_set_error (bfd_error_bad_value);
2131 return return_value;
2134 static bfd_boolean
2135 xcoff64_is_lineno_count_overflow (abfd, value)
2136 bfd *abfd ATTRIBUTE_UNUSED;
2137 bfd_vma value ATTRIBUTE_UNUSED;
2139 return FALSE;
2142 static bfd_boolean
2143 xcoff64_is_reloc_count_overflow (abfd, value)
2144 bfd *abfd ATTRIBUTE_UNUSED;
2145 bfd_vma value ATTRIBUTE_UNUSED;
2147 return FALSE;
2150 static bfd_vma
2151 xcoff64_loader_symbol_offset (abfd, ldhdr)
2152 bfd *abfd ATTRIBUTE_UNUSED;
2153 struct internal_ldhdr *ldhdr;
2155 return (ldhdr->l_symoff);
2158 static bfd_vma
2159 xcoff64_loader_reloc_offset (abfd, ldhdr)
2160 bfd *abfd ATTRIBUTE_UNUSED;
2161 struct internal_ldhdr *ldhdr;
2163 return (ldhdr->l_rldoff);
2166 static bfd_boolean
2167 xcoff64_bad_format_hook (abfd, filehdr)
2168 bfd * abfd;
2169 PTR filehdr;
2171 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2173 /* Check flavor first. */
2174 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
2175 return FALSE;
2177 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
2178 return FALSE;
2180 return TRUE;
2183 static bfd_boolean
2184 xcoff64_generate_rtinit (abfd, init, fini, rtld)
2185 bfd *abfd;
2186 const char *init;
2187 const char *fini;
2188 bfd_boolean rtld;
2190 bfd_byte filehdr_ext[FILHSZ];
2191 bfd_byte scnhdr_ext[SCNHSZ * 3];
2192 bfd_byte syment_ext[SYMESZ * 10];
2193 bfd_byte reloc_ext[RELSZ * 3];
2194 bfd_byte *data_buffer;
2195 bfd_size_type data_buffer_size;
2196 bfd_byte *string_table, *st_tmp;
2197 bfd_size_type string_table_size;
2198 bfd_vma val;
2199 size_t initsz, finisz;
2200 struct internal_filehdr filehdr;
2201 struct internal_scnhdr text_scnhdr;
2202 struct internal_scnhdr data_scnhdr;
2203 struct internal_scnhdr bss_scnhdr;
2204 struct internal_syment syment;
2205 union internal_auxent auxent;
2206 struct internal_reloc reloc;
2208 char *text_name = ".text";
2209 char *data_name = ".data";
2210 char *bss_name = ".bss";
2211 char *rtinit_name = "__rtinit";
2212 char *rtld_name = "__rtld";
2214 if (! bfd_xcoff_rtinit_size (abfd))
2215 return FALSE;
2217 initsz = (init == NULL ? 0 : 1 + strlen (init));
2218 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2220 /* File header. */
2221 memset (filehdr_ext, 0, FILHSZ);
2222 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2223 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
2224 filehdr.f_nscns = 3;
2225 filehdr.f_timdat = 0;
2226 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2227 filehdr.f_symptr = 0; /* set below */
2228 filehdr.f_opthdr = 0;
2229 filehdr.f_flags = 0;
2231 /* Section headers. */
2232 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2234 /* Text. */
2235 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2236 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2237 text_scnhdr.s_paddr = 0;
2238 text_scnhdr.s_vaddr = 0;
2239 text_scnhdr.s_size = 0;
2240 text_scnhdr.s_scnptr = 0;
2241 text_scnhdr.s_relptr = 0;
2242 text_scnhdr.s_lnnoptr = 0;
2243 text_scnhdr.s_nreloc = 0;
2244 text_scnhdr.s_nlnno = 0;
2245 text_scnhdr.s_flags = STYP_TEXT;
2247 /* Data. */
2248 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2249 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2250 data_scnhdr.s_paddr = 0;
2251 data_scnhdr.s_vaddr = 0;
2252 data_scnhdr.s_size = 0; /* set below */
2253 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2254 data_scnhdr.s_relptr = 0; /* set below */
2255 data_scnhdr.s_lnnoptr = 0;
2256 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2257 data_scnhdr.s_nlnno = 0;
2258 data_scnhdr.s_flags = STYP_DATA;
2260 /* Bss. */
2261 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2262 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2263 bss_scnhdr.s_paddr = 0; /* set below */
2264 bss_scnhdr.s_vaddr = 0; /* set below */
2265 bss_scnhdr.s_size = 0; /* set below */
2266 bss_scnhdr.s_scnptr = 0;
2267 bss_scnhdr.s_relptr = 0;
2268 bss_scnhdr.s_lnnoptr = 0;
2269 bss_scnhdr.s_nreloc = 0;
2270 bss_scnhdr.s_nlnno = 0;
2271 bss_scnhdr.s_flags = STYP_BSS;
2273 /* .data
2274 0x0000 0x00000000 : rtl
2275 0x0004 0x00000000 :
2276 0x0008 0x00000018 : offset to init, or 0
2277 0x000C 0x00000038 : offset to fini, or 0
2278 0x0010 0x00000010 : size of descriptor
2279 0x0014 0x00000000 : pad
2280 0x0018 0x00000000 : init, needs a reloc
2281 0x001C 0x00000000 :
2282 0x0020 0x00000058 : offset to init name
2283 0x0024 0x00000000 : flags, padded to a word
2284 0x0028 0x00000000 : empty init
2285 0x002C 0x00000000 :
2286 0x0030 0x00000000 :
2287 0x0034 0x00000000 :
2288 0x0038 0x00000000 : fini, needs a reloc
2289 0x003C 0x00000000 :
2290 0x0040 0x00000??? : offset to fini name
2291 0x0044 0x00000000 : flags, padded to a word
2292 0x0048 0x00000000 : empty fini
2293 0x004C 0x00000000 :
2294 0x0050 0x00000000 :
2295 0x0054 0x00000000 :
2296 0x0058 init name
2297 0x0058 + initsz fini name */
2299 data_buffer_size = 0x0058 + initsz + finisz;
2300 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
2301 data_buffer = NULL;
2302 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
2303 if (data_buffer == NULL)
2304 return FALSE;
2306 if (initsz)
2308 val = 0x18;
2309 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2310 val = 0x58;
2311 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2312 memcpy (&data_buffer[val], init, initsz);
2315 if (finisz)
2317 val = 0x38;
2318 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2319 val = 0x58 + initsz;
2320 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2321 memcpy (&data_buffer[val], fini, finisz);
2324 val = 0x10;
2325 bfd_put_32 (abfd, val, &data_buffer[0x10]);
2326 data_scnhdr.s_size = data_buffer_size;
2327 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
2329 /* String table. */
2330 string_table_size = 4;
2331 string_table_size += strlen (data_name) + 1;
2332 string_table_size += strlen (rtinit_name) + 1;
2333 string_table_size += initsz;
2334 string_table_size += finisz;
2335 if (rtld)
2336 string_table_size += strlen (rtld_name) + 1;
2338 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2339 if (string_table == NULL)
2340 return FALSE;
2342 val = string_table_size;
2343 bfd_put_32 (abfd, val, &string_table[0]);
2344 st_tmp = string_table + 4;
2346 /* symbols
2347 0. .data csect
2348 2. __rtinit
2349 4. init function
2350 6. fini function
2351 8. __rtld */
2352 memset (syment_ext, 0, 10 * SYMESZ);
2353 memset (reloc_ext, 0, 3 * RELSZ);
2355 /* .data csect */
2356 memset (&syment, 0, sizeof (struct internal_syment));
2357 memset (&auxent, 0, sizeof (union internal_auxent));
2359 syment._n._n_n._n_offset = st_tmp - string_table;
2360 memcpy (st_tmp, data_name, strlen (data_name));
2361 st_tmp += strlen (data_name) + 1;
2363 syment.n_scnum = 2;
2364 syment.n_sclass = C_HIDEXT;
2365 syment.n_numaux = 1;
2366 auxent.x_csect.x_scnlen.l = data_buffer_size;
2367 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2368 auxent.x_csect.x_smclas = XMC_RW;
2369 bfd_coff_swap_sym_out (abfd, &syment,
2370 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2371 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2372 syment.n_numaux,
2373 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2374 filehdr.f_nsyms += 2;
2376 /* __rtinit */
2377 memset (&syment, 0, sizeof (struct internal_syment));
2378 memset (&auxent, 0, sizeof (union internal_auxent));
2379 syment._n._n_n._n_offset = st_tmp - string_table;
2380 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2381 st_tmp += strlen (rtinit_name) + 1;
2383 syment.n_scnum = 2;
2384 syment.n_sclass = C_EXT;
2385 syment.n_numaux = 1;
2386 auxent.x_csect.x_smtyp = XTY_LD;
2387 auxent.x_csect.x_smclas = XMC_RW;
2388 bfd_coff_swap_sym_out (abfd, &syment,
2389 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2390 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2391 syment.n_numaux,
2392 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2393 filehdr.f_nsyms += 2;
2395 /* Init. */
2396 if (initsz)
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, init, initsz);
2403 st_tmp += initsz;
2405 syment.n_sclass = C_EXT;
2406 syment.n_numaux = 1;
2407 bfd_coff_swap_sym_out (abfd, &syment,
2408 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2409 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2410 syment.n_numaux,
2411 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2412 /* Reloc. */
2413 memset (&reloc, 0, sizeof (struct internal_reloc));
2414 reloc.r_vaddr = 0x0018;
2415 reloc.r_symndx = filehdr.f_nsyms;
2416 reloc.r_type = R_POS;
2417 reloc.r_size = 63;
2418 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2420 filehdr.f_nsyms += 2;
2421 data_scnhdr.s_nreloc += 1;
2424 /* Finit. */
2425 if (finisz)
2427 memset (&syment, 0, sizeof (struct internal_syment));
2428 memset (&auxent, 0, sizeof (union internal_auxent));
2430 syment._n._n_n._n_offset = st_tmp - string_table;
2431 memcpy (st_tmp, fini, finisz);
2432 st_tmp += finisz;
2434 syment.n_sclass = C_EXT;
2435 syment.n_numaux = 1;
2436 bfd_coff_swap_sym_out (abfd, &syment,
2437 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2438 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2439 syment.n_numaux,
2440 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2442 /* Reloc. */
2443 memset (&reloc, 0, sizeof (struct internal_reloc));
2444 reloc.r_vaddr = 0x0038;
2445 reloc.r_symndx = filehdr.f_nsyms;
2446 reloc.r_type = R_POS;
2447 reloc.r_size = 63;
2448 bfd_coff_swap_reloc_out (abfd, &reloc,
2449 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2451 filehdr.f_nsyms += 2;
2452 data_scnhdr.s_nreloc += 1;
2455 if (rtld)
2457 memset (&syment, 0, sizeof (struct internal_syment));
2458 memset (&auxent, 0, sizeof (union internal_auxent));
2460 syment._n._n_n._n_offset = st_tmp - string_table;
2461 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2462 st_tmp += strlen (rtld_name) + 1;
2464 syment.n_sclass = C_EXT;
2465 syment.n_numaux = 1;
2466 bfd_coff_swap_sym_out (abfd, &syment,
2467 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2468 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2469 syment.n_numaux,
2470 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2472 /* Reloc. */
2473 memset (&reloc, 0, sizeof (struct internal_reloc));
2474 reloc.r_vaddr = 0x0000;
2475 reloc.r_symndx = filehdr.f_nsyms;
2476 reloc.r_type = R_POS;
2477 reloc.r_size = 63;
2478 bfd_coff_swap_reloc_out (abfd, &reloc,
2479 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2481 filehdr.f_nsyms += 2;
2482 data_scnhdr.s_nreloc += 1;
2484 bss_scnhdr.s_size = 0;
2487 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2488 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2490 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2491 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2492 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2493 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2494 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2495 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2496 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2497 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2498 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2499 bfd_bwrite (string_table, string_table_size, abfd);
2501 free (data_buffer);
2502 data_buffer = NULL;
2504 return TRUE;
2507 /* The typical dynamic reloc. */
2509 static reloc_howto_type xcoff64_dynamic_reloc =
2510 HOWTO (0, /* type */
2511 0, /* rightshift */
2512 4, /* size (0 = byte, 1 = short, 2 = long) */
2513 64, /* bitsize */
2514 FALSE, /* pc_relative */
2515 0, /* bitpos */
2516 complain_overflow_bitfield, /* complain_on_overflow */
2517 0, /* special_function */
2518 "R_POS", /* name */
2519 TRUE, /* partial_inplace */
2520 MINUS_ONE, /* src_mask */
2521 MINUS_ONE, /* dst_mask */
2522 FALSE); /* pcrel_offset */
2524 static unsigned long xcoff64_glink_code[10] =
2526 0xe9820000, /* ld r12,0(r2) */
2527 0xf8410028, /* std r2,40(r1) */
2528 0xe80c0000, /* ld r0,0(r12) */
2529 0xe84c0008, /* ld r0,8(r12) */
2530 0x7c0903a6, /* mtctr r0 */
2531 0x4e800420, /* bctr */
2532 0x00000000, /* start of traceback table */
2533 0x000ca000, /* traceback table */
2534 0x00000000, /* traceback table */
2535 0x00000018, /* ??? */
2538 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2540 { /* COFF backend, defined in libcoff.h. */
2541 _bfd_xcoff64_swap_aux_in,
2542 _bfd_xcoff64_swap_sym_in,
2543 _bfd_xcoff64_swap_lineno_in,
2544 _bfd_xcoff64_swap_aux_out,
2545 _bfd_xcoff64_swap_sym_out,
2546 _bfd_xcoff64_swap_lineno_out,
2547 xcoff64_swap_reloc_out,
2548 coff_swap_filehdr_out,
2549 coff_swap_aouthdr_out,
2550 coff_swap_scnhdr_out,
2551 FILHSZ,
2552 AOUTSZ,
2553 SCNHSZ,
2554 SYMESZ,
2555 AUXESZ,
2556 RELSZ,
2557 LINESZ,
2558 FILNMLEN,
2559 TRUE, /* _bfd_coff_long_filenames */
2560 FALSE, /* _bfd_coff_long_section_names */
2561 3, /* _bfd_coff_default_section_alignment_power */
2562 TRUE, /* _bfd_coff_force_symnames_in_strings */
2563 4, /* _bfd_coff_debug_string_prefix_length */
2564 coff_swap_filehdr_in,
2565 coff_swap_aouthdr_in,
2566 coff_swap_scnhdr_in,
2567 xcoff64_swap_reloc_in,
2568 xcoff64_bad_format_hook,
2569 coff_set_arch_mach_hook,
2570 coff_mkobject_hook,
2571 styp_to_sec_flags,
2572 coff_set_alignment_hook,
2573 coff_slurp_symbol_table,
2574 symname_in_debug_hook,
2575 coff_pointerize_aux_hook,
2576 coff_print_aux,
2577 dummy_reloc16_extra_cases,
2578 dummy_reloc16_estimate,
2579 NULL, /* bfd_coff_sym_is_global */
2580 coff_compute_section_file_positions,
2581 NULL, /* _bfd_coff_start_final_link */
2582 xcoff64_ppc_relocate_section,
2583 coff_rtype_to_howto,
2584 NULL, /* _bfd_coff_adjust_symndx */
2585 _bfd_generic_link_add_one_symbol,
2586 coff_link_output_has_begun,
2587 coff_final_link_postscript
2590 0x01EF, /* magic number */
2591 bfd_arch_powerpc,
2592 bfd_mach_ppc_620,
2594 /* Function pointers to xcoff specific swap routines. */
2595 xcoff64_swap_ldhdr_in,
2596 xcoff64_swap_ldhdr_out,
2597 xcoff64_swap_ldsym_in,
2598 xcoff64_swap_ldsym_out,
2599 xcoff64_swap_ldrel_in,
2600 xcoff64_swap_ldrel_out,
2602 /* Sizes. */
2603 LDHDRSZ,
2604 LDSYMSZ,
2605 LDRELSZ,
2606 24, /* _xcoff_function_descriptor_size */
2607 0, /* _xcoff_small_aout_header_size */
2609 /* Versions. */
2610 2, /* _xcoff_ldhdr_version */
2612 _bfd_xcoff64_put_symbol_name,
2613 _bfd_xcoff64_put_ldsymbol_name,
2614 &xcoff64_dynamic_reloc,
2615 xcoff64_create_csect_from_smclas,
2617 /* Lineno and reloc count overflow. */
2618 xcoff64_is_lineno_count_overflow,
2619 xcoff64_is_reloc_count_overflow,
2621 xcoff64_loader_symbol_offset,
2622 xcoff64_loader_reloc_offset,
2624 /* glink. */
2625 &xcoff64_glink_code[0],
2626 40, /* _xcoff_glink_size */
2628 /* rtinit. */
2629 88, /* _xcoff_rtinit_size */
2630 xcoff64_generate_rtinit,
2633 /* The transfer vector that leads the outside world to all of the above. */
2634 const bfd_target rs6000coff64_vec =
2636 "aixcoff64-rs6000",
2637 bfd_target_xcoff_flavour,
2638 BFD_ENDIAN_BIG, /* data byte order is big */
2639 BFD_ENDIAN_BIG, /* header byte order is big */
2641 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2642 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2644 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2645 0, /* leading char */
2646 '/', /* ar_pad_char */
2647 15, /* ar_max_namelen */
2649 /* data */
2650 bfd_getb64,
2651 bfd_getb_signed_64,
2652 bfd_putb64,
2653 bfd_getb32,
2654 bfd_getb_signed_32,
2655 bfd_putb32,
2656 bfd_getb16,
2657 bfd_getb_signed_16,
2658 bfd_putb16,
2660 /* hdrs */
2661 bfd_getb64,
2662 bfd_getb_signed_64,
2663 bfd_putb64,
2664 bfd_getb32,
2665 bfd_getb_signed_32,
2666 bfd_putb32,
2667 bfd_getb16,
2668 bfd_getb_signed_16,
2669 bfd_putb16,
2671 { /* bfd_check_format */
2672 _bfd_dummy_target,
2673 coff_object_p,
2674 xcoff64_archive_p,
2675 CORE_FILE_P
2678 { /* bfd_set_format */
2679 bfd_false,
2680 coff_mkobject,
2681 _bfd_generic_mkarchive,
2682 bfd_false
2685 {/* bfd_write_contents */
2686 bfd_false,
2687 xcoff64_write_object_contents,
2688 _bfd_xcoff_write_archive_contents,
2689 bfd_false
2692 /* Generic */
2693 bfd_true,
2694 bfd_true,
2695 coff_new_section_hook,
2696 _bfd_generic_get_section_contents,
2697 _bfd_generic_get_section_contents_in_window,
2699 /* Copy */
2700 _bfd_xcoff_copy_private_bfd_data,
2701 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2702 _bfd_generic_init_private_section_data,
2703 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2704 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2705 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2706 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2707 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
2709 /* Core */
2710 coff_core_file_failing_command,
2711 coff_core_file_failing_signal,
2712 coff_core_file_matches_executable_p,
2714 /* Archive */
2715 xcoff64_slurp_armap,
2716 bfd_false,
2717 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2718 bfd_dont_truncate_arname,
2719 _bfd_xcoff_write_armap,
2720 _bfd_xcoff_read_ar_hdr,
2721 xcoff64_openr_next_archived_file,
2722 _bfd_generic_get_elt_at_index,
2723 _bfd_xcoff_stat_arch_elt,
2724 bfd_true,
2726 /* Symbols */
2727 coff_get_symtab_upper_bound,
2728 coff_canonicalize_symtab,
2729 coff_make_empty_symbol,
2730 coff_print_symbol,
2731 coff_get_symbol_info,
2732 _bfd_xcoff_is_local_label_name,
2733 coff_bfd_is_target_special_symbol,
2734 coff_get_lineno,
2735 coff_find_nearest_line,
2736 _bfd_generic_find_line,
2737 coff_find_inliner_info,
2738 coff_bfd_make_debug_symbol,
2739 _bfd_generic_read_minisymbols,
2740 _bfd_generic_minisymbol_to_symbol,
2742 /* Reloc */
2743 coff_get_reloc_upper_bound,
2744 coff_canonicalize_reloc,
2745 xcoff64_reloc_type_lookup,
2746 xcoff64_reloc_name_lookup,
2748 /* Write */
2749 coff_set_arch_mach,
2750 coff_set_section_contents,
2752 /* Link */
2753 xcoff64_sizeof_headers,
2754 bfd_generic_get_relocated_section_contents,
2755 bfd_generic_relax_section,
2756 _bfd_xcoff_bfd_link_hash_table_create,
2757 _bfd_generic_link_hash_table_free,
2758 _bfd_xcoff_bfd_link_add_symbols,
2759 _bfd_generic_link_just_syms,
2760 _bfd_xcoff_bfd_final_link,
2761 _bfd_generic_link_split_section,
2762 bfd_generic_gc_sections,
2763 bfd_generic_merge_sections,
2764 bfd_generic_is_group_section,
2765 bfd_generic_discard_group,
2766 _bfd_generic_section_already_linked,
2768 /* Dynamic */
2769 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2770 _bfd_xcoff_canonicalize_dynamic_symtab,
2771 _bfd_nodynamic_get_synthetic_symtab,
2772 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2773 _bfd_xcoff_canonicalize_dynamic_reloc,
2775 /* Opposite endian version, none exists */
2776 NULL,
2778 (void *) &bfd_xcoff_backend_data,
2781 extern const bfd_target *xcoff64_core_p
2782 PARAMS ((bfd *));
2783 extern bfd_boolean xcoff64_core_file_matches_executable_p
2784 PARAMS ((bfd *, bfd *));
2785 extern char *xcoff64_core_file_failing_command
2786 PARAMS ((bfd *));
2787 extern int xcoff64_core_file_failing_signal
2788 PARAMS ((bfd *));
2790 /* AIX 5 */
2791 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2793 { /* COFF backend, defined in libcoff.h. */
2794 _bfd_xcoff64_swap_aux_in,
2795 _bfd_xcoff64_swap_sym_in,
2796 _bfd_xcoff64_swap_lineno_in,
2797 _bfd_xcoff64_swap_aux_out,
2798 _bfd_xcoff64_swap_sym_out,
2799 _bfd_xcoff64_swap_lineno_out,
2800 xcoff64_swap_reloc_out,
2801 coff_swap_filehdr_out,
2802 coff_swap_aouthdr_out,
2803 coff_swap_scnhdr_out,
2804 FILHSZ,
2805 AOUTSZ,
2806 SCNHSZ,
2807 SYMESZ,
2808 AUXESZ,
2809 RELSZ,
2810 LINESZ,
2811 FILNMLEN,
2812 TRUE, /* _bfd_coff_long_filenames */
2813 FALSE, /* _bfd_coff_long_section_names */
2814 3, /* _bfd_coff_default_section_alignment_power */
2815 TRUE, /* _bfd_coff_force_symnames_in_strings */
2816 4, /* _bfd_coff_debug_string_prefix_length */
2817 coff_swap_filehdr_in,
2818 coff_swap_aouthdr_in,
2819 coff_swap_scnhdr_in,
2820 xcoff64_swap_reloc_in,
2821 xcoff64_bad_format_hook,
2822 coff_set_arch_mach_hook,
2823 coff_mkobject_hook,
2824 styp_to_sec_flags,
2825 coff_set_alignment_hook,
2826 coff_slurp_symbol_table,
2827 symname_in_debug_hook,
2828 coff_pointerize_aux_hook,
2829 coff_print_aux,
2830 dummy_reloc16_extra_cases,
2831 dummy_reloc16_estimate,
2832 NULL, /* bfd_coff_sym_is_global */
2833 coff_compute_section_file_positions,
2834 NULL, /* _bfd_coff_start_final_link */
2835 xcoff64_ppc_relocate_section,
2836 coff_rtype_to_howto,
2837 NULL, /* _bfd_coff_adjust_symndx */
2838 _bfd_generic_link_add_one_symbol,
2839 coff_link_output_has_begun,
2840 coff_final_link_postscript
2843 U64_TOCMAGIC, /* magic number */
2844 bfd_arch_powerpc,
2845 bfd_mach_ppc_620,
2847 /* Function pointers to xcoff specific swap routines. */
2848 xcoff64_swap_ldhdr_in,
2849 xcoff64_swap_ldhdr_out,
2850 xcoff64_swap_ldsym_in,
2851 xcoff64_swap_ldsym_out,
2852 xcoff64_swap_ldrel_in,
2853 xcoff64_swap_ldrel_out,
2855 /* Sizes. */
2856 LDHDRSZ,
2857 LDSYMSZ,
2858 LDRELSZ,
2859 24, /* _xcoff_function_descriptor_size */
2860 0, /* _xcoff_small_aout_header_size */
2861 /* Versions. */
2862 2, /* _xcoff_ldhdr_version */
2864 _bfd_xcoff64_put_symbol_name,
2865 _bfd_xcoff64_put_ldsymbol_name,
2866 &xcoff64_dynamic_reloc,
2867 xcoff64_create_csect_from_smclas,
2869 /* Lineno and reloc count overflow. */
2870 xcoff64_is_lineno_count_overflow,
2871 xcoff64_is_reloc_count_overflow,
2873 xcoff64_loader_symbol_offset,
2874 xcoff64_loader_reloc_offset,
2876 /* glink. */
2877 &xcoff64_glink_code[0],
2878 40, /* _xcoff_glink_size */
2880 /* rtinit. */
2881 88, /* _xcoff_rtinit_size */
2882 xcoff64_generate_rtinit,
2885 /* The transfer vector that leads the outside world to all of the above. */
2886 const bfd_target aix5coff64_vec =
2888 "aix5coff64-rs6000",
2889 bfd_target_xcoff_flavour,
2890 BFD_ENDIAN_BIG, /* data byte order is big */
2891 BFD_ENDIAN_BIG, /* header byte order is big */
2893 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2894 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2896 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2897 0, /* leading char */
2898 '/', /* ar_pad_char */
2899 15, /* ar_max_namelen */
2901 /* data */
2902 bfd_getb64,
2903 bfd_getb_signed_64,
2904 bfd_putb64,
2905 bfd_getb32,
2906 bfd_getb_signed_32,
2907 bfd_putb32,
2908 bfd_getb16,
2909 bfd_getb_signed_16,
2910 bfd_putb16,
2912 /* hdrs */
2913 bfd_getb64,
2914 bfd_getb_signed_64,
2915 bfd_putb64,
2916 bfd_getb32,
2917 bfd_getb_signed_32,
2918 bfd_putb32,
2919 bfd_getb16,
2920 bfd_getb_signed_16,
2921 bfd_putb16,
2923 { /* bfd_check_format */
2924 _bfd_dummy_target,
2925 coff_object_p,
2926 xcoff64_archive_p,
2927 xcoff64_core_p
2930 { /* bfd_set_format */
2931 bfd_false,
2932 coff_mkobject,
2933 _bfd_generic_mkarchive,
2934 bfd_false
2937 {/* bfd_write_contents */
2938 bfd_false,
2939 xcoff64_write_object_contents,
2940 _bfd_xcoff_write_archive_contents,
2941 bfd_false
2944 /* Generic */
2945 bfd_true,
2946 bfd_true,
2947 coff_new_section_hook,
2948 _bfd_generic_get_section_contents,
2949 _bfd_generic_get_section_contents_in_window,
2951 /* Copy */
2952 _bfd_xcoff_copy_private_bfd_data,
2953 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2954 _bfd_generic_init_private_section_data,
2955 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2956 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2957 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
2958 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2959 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
2961 /* Core */
2962 xcoff64_core_file_failing_command,
2963 xcoff64_core_file_failing_signal,
2964 xcoff64_core_file_matches_executable_p,
2966 /* Archive */
2967 xcoff64_slurp_armap,
2968 bfd_false,
2969 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2970 bfd_dont_truncate_arname,
2971 _bfd_xcoff_write_armap,
2972 _bfd_xcoff_read_ar_hdr,
2973 xcoff64_openr_next_archived_file,
2974 _bfd_generic_get_elt_at_index,
2975 _bfd_xcoff_stat_arch_elt,
2976 bfd_true,
2978 /* Symbols */
2979 coff_get_symtab_upper_bound,
2980 coff_canonicalize_symtab,
2981 coff_make_empty_symbol,
2982 coff_print_symbol,
2983 coff_get_symbol_info,
2984 _bfd_xcoff_is_local_label_name,
2985 coff_bfd_is_target_special_symbol,
2986 coff_get_lineno,
2987 coff_find_nearest_line,
2988 _bfd_generic_find_line,
2989 coff_find_inliner_info,
2990 coff_bfd_make_debug_symbol,
2991 _bfd_generic_read_minisymbols,
2992 _bfd_generic_minisymbol_to_symbol,
2994 /* Reloc */
2995 coff_get_reloc_upper_bound,
2996 coff_canonicalize_reloc,
2997 xcoff64_reloc_type_lookup,
2998 xcoff64_reloc_name_lookup,
3000 /* Write */
3001 coff_set_arch_mach,
3002 coff_set_section_contents,
3004 /* Link */
3005 xcoff64_sizeof_headers,
3006 bfd_generic_get_relocated_section_contents,
3007 bfd_generic_relax_section,
3008 _bfd_xcoff_bfd_link_hash_table_create,
3009 _bfd_generic_link_hash_table_free,
3010 _bfd_xcoff_bfd_link_add_symbols,
3011 _bfd_generic_link_just_syms,
3012 _bfd_xcoff_bfd_final_link,
3013 _bfd_generic_link_split_section,
3014 bfd_generic_gc_sections,
3015 bfd_generic_merge_sections,
3016 bfd_generic_is_group_section,
3017 bfd_generic_discard_group,
3018 _bfd_generic_section_already_linked,
3020 /* Dynamic */
3021 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3022 _bfd_xcoff_canonicalize_dynamic_symtab,
3023 _bfd_nodynamic_get_synthetic_symtab,
3024 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3025 _bfd_xcoff_canonicalize_dynamic_reloc,
3027 /* Opposite endian version, none exists. */
3028 NULL,
3030 (void *) & bfd_xcoff_aix5_backend_data,