bfd: use default coff_write_object_contents for XCOFF64
[binutils-gdb.git] / bfd / coff64-rs6000.c
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright (C) 2000-2021 Free Software Foundation, Inc.
3 Written Clinton Popetz.
4 Contributed by Cygnus Support.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "coff/internal.h"
28 #include "coff/xcoff.h"
29 #include "coff/rs6k64.h"
30 #include "libcoff.h"
31 #include "libxcoff.h"
32
33 #define GET_FILEHDR_SYMPTR H_GET_64
34 #define PUT_FILEHDR_SYMPTR H_PUT_64
35 #define GET_AOUTHDR_DATA_START H_GET_64
36 #define PUT_AOUTHDR_DATA_START H_PUT_64
37 #define GET_AOUTHDR_TEXT_START H_GET_64
38 #define PUT_AOUTHDR_TEXT_START H_PUT_64
39 #define GET_AOUTHDR_TSIZE H_GET_64
40 #define PUT_AOUTHDR_TSIZE H_PUT_64
41 #define GET_AOUTHDR_DSIZE H_GET_64
42 #define PUT_AOUTHDR_DSIZE H_PUT_64
43 #define GET_AOUTHDR_BSIZE H_GET_64
44 #define PUT_AOUTHDR_BSIZE H_PUT_64
45 #define GET_AOUTHDR_ENTRY H_GET_64
46 #define PUT_AOUTHDR_ENTRY H_PUT_64
47 #define GET_SCNHDR_PADDR H_GET_64
48 #define PUT_SCNHDR_PADDR H_PUT_64
49 #define GET_SCNHDR_VADDR H_GET_64
50 #define PUT_SCNHDR_VADDR H_PUT_64
51 #define GET_SCNHDR_SIZE H_GET_64
52 #define PUT_SCNHDR_SIZE H_PUT_64
53 #define GET_SCNHDR_SCNPTR H_GET_64
54 #define PUT_SCNHDR_SCNPTR H_PUT_64
55 #define GET_SCNHDR_RELPTR H_GET_64
56 #define PUT_SCNHDR_RELPTR H_PUT_64
57 #define GET_SCNHDR_LNNOPTR H_GET_64
58 #define PUT_SCNHDR_LNNOPTR H_PUT_64
59 #define GET_SCNHDR_NRELOC H_GET_32
60 #define MAX_SCNHDR_NRELOC 0xffffffff
61 #define PUT_SCNHDR_NRELOC H_PUT_32
62 #define GET_SCNHDR_NLNNO H_GET_32
63 #define MAX_SCNHDR_NLNNO 0xffffffff
64 #define PUT_SCNHDR_NLNNO H_PUT_32
65 #define GET_RELOC_VADDR H_GET_64
66 #define PUT_RELOC_VADDR H_PUT_64
67
68 #define COFF_FORCE_SYMBOLS_IN_STRINGS
69 #define COFF_DEBUG_STRING_WIDE_PREFIX
70
71
72 #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
73 do \
74 { \
75 memset (((SCNHDR *) EXT)->s_pad, 0, \
76 sizeof (((SCNHDR *) EXT)->s_pad)); \
77 } \
78 while (0)
79
80 #define NO_COFF_LINENOS
81
82 #define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
83 #define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
84
85 static void _bfd_xcoff64_swap_lineno_in
86 (bfd *, void *, void *);
87 static unsigned int _bfd_xcoff64_swap_lineno_out
88 (bfd *, void *, void *);
89 static bfd_boolean _bfd_xcoff64_put_symbol_name
90 (struct bfd_link_info *, struct bfd_strtab_hash *,
91 struct internal_syment *, const char *);
92 static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
93 (bfd *, struct xcoff_loader_info *, struct internal_ldsym *, const char *);
94 static void _bfd_xcoff64_swap_sym_in
95 (bfd *, void *, void *);
96 static unsigned int _bfd_xcoff64_swap_sym_out
97 (bfd *, void *, void *);
98 static void _bfd_xcoff64_swap_aux_in
99 (bfd *, void *, int, int, int, int, void *);
100 static unsigned int _bfd_xcoff64_swap_aux_out
101 (bfd *, void *, int, int, int, int, void *);
102 static void xcoff64_swap_reloc_in
103 (bfd *, void *, void *);
104 static unsigned int xcoff64_swap_reloc_out
105 (bfd *, void *, void *);
106 extern bfd_boolean _bfd_xcoff_mkobject
107 (bfd *);
108 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
109 (bfd *, bfd *);
110 extern bfd_boolean _bfd_xcoff_is_local_label_name
111 (bfd *, const char *);
112 extern void xcoff64_rtype2howto
113 (arelent *, struct internal_reloc *);
114 extern reloc_howto_type * xcoff64_reloc_type_lookup
115 (bfd *, bfd_reloc_code_real_type);
116 extern bfd_boolean _bfd_xcoff_slurp_armap
117 (bfd *);
118 extern void *_bfd_xcoff_read_ar_hdr
119 (bfd *);
120 extern bfd *_bfd_xcoff_openr_next_archived_file
121 (bfd *, bfd *);
122 extern int _bfd_xcoff_stat_arch_elt
123 (bfd *, struct stat *);
124 extern bfd_boolean _bfd_xcoff_write_armap
125 (bfd *, unsigned int, struct orl *, unsigned int, int);
126 extern bfd_boolean _bfd_xcoff_write_archive_contents
127 (bfd *);
128 extern int _bfd_xcoff_sizeof_headers
129 (bfd *, struct bfd_link_info *);
130 extern void _bfd_xcoff_swap_sym_in
131 (bfd *, void *, void *);
132 extern unsigned int _bfd_xcoff_swap_sym_out
133 (bfd *, void *, void *);
134 extern void _bfd_xcoff_swap_aux_in
135 (bfd *, void *, int, int, int, int, void *);
136 extern unsigned int _bfd_xcoff_swap_aux_out
137 (bfd *, void *, int, int, int, int, void *);
138 static void xcoff64_swap_ldhdr_in
139 (bfd *, const void *, struct internal_ldhdr *);
140 static void xcoff64_swap_ldhdr_out
141 (bfd *, const struct internal_ldhdr *, void *d);
142 static void xcoff64_swap_ldsym_in
143 (bfd *, const void *, struct internal_ldsym *);
144 static void xcoff64_swap_ldsym_out
145 (bfd *, const struct internal_ldsym *, void *d);
146 static void xcoff64_swap_ldrel_in
147 (bfd *, const void *, struct internal_ldrel *);
148 static void xcoff64_swap_ldrel_out
149 (bfd *, const struct internal_ldrel *, void *d);
150 static bfd_boolean xcoff64_ppc_relocate_section
151 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
152 struct internal_reloc *, struct internal_syment *,
153 asection **);
154 static bfd_boolean xcoff64_slurp_armap
155 (bfd *);
156 static bfd_cleanup xcoff64_archive_p
157 (bfd *);
158 static bfd *xcoff64_openr_next_archived_file
159 (bfd *, bfd *);
160 static int xcoff64_sizeof_headers
161 (bfd *, struct bfd_link_info *);
162 static asection *xcoff64_create_csect_from_smclas
163 (bfd *, union internal_auxent *, const char *);
164 static bfd_boolean xcoff64_is_lineno_count_overflow
165 (bfd *, bfd_vma);
166 static bfd_boolean xcoff64_is_reloc_count_overflow
167 (bfd *, bfd_vma);
168 static bfd_vma xcoff64_loader_symbol_offset
169 (bfd *, struct internal_ldhdr *);
170 static bfd_vma xcoff64_loader_reloc_offset
171 (bfd *, struct internal_ldhdr *);
172 static bfd_boolean xcoff64_generate_rtinit
173 (bfd *, const char *, const char *, bfd_boolean);
174 static bfd_boolean xcoff64_bad_format_hook
175 (bfd *, void *);
176
177 /* Relocation functions */
178 static xcoff_reloc_function xcoff64_reloc_type_br;
179
180 xcoff_reloc_function *const
181 xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
182 {
183 xcoff_reloc_type_pos, /* R_POS (0x00) */
184 xcoff_reloc_type_neg, /* R_NEG (0x01) */
185 xcoff_reloc_type_rel, /* R_REL (0x02) */
186 xcoff_reloc_type_toc, /* R_TOC (0x03) */
187 xcoff_reloc_type_fail, /* R_RTB (0x04) */
188 xcoff_reloc_type_toc, /* R_GL (0x05) */
189 xcoff_reloc_type_toc, /* R_TCL (0x06) */
190 xcoff_reloc_type_fail, /* (0x07) */
191 xcoff_reloc_type_ba, /* R_BA (0x08) */
192 xcoff_reloc_type_fail, /* (0x09) */
193 xcoff64_reloc_type_br, /* R_BR (0x0a) */
194 xcoff_reloc_type_fail, /* (0x0b) */
195 xcoff_reloc_type_pos, /* R_RL (0x0c) */
196 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
197 xcoff_reloc_type_fail, /* (0x0e) */
198 xcoff_reloc_type_noop, /* R_REF (0x0f) */
199 xcoff_reloc_type_fail, /* (0x10) */
200 xcoff_reloc_type_fail, /* (0x11) */
201 xcoff_reloc_type_toc, /* R_TRL (0x12) */
202 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
203 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
204 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
205 xcoff_reloc_type_ba, /* R_CAI (0x16) */
206 xcoff_reloc_type_crel, /* R_CREL (0x17) */
207 xcoff_reloc_type_ba, /* R_RBA (0x18) */
208 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
209 xcoff64_reloc_type_br, /* R_RBR (0x1a) */
210 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
211 };
212
213 /* coffcode.h needs these to be defined. */
214 /* Internalcoff.h and coffcode.h modify themselves based on these flags. */
215 #define XCOFF64
216 #define RS6000COFF_C 1
217
218 #define SELECT_RELOC(internal, howto) \
219 { \
220 internal.r_type = howto->type; \
221 internal.r_size = \
222 ((howto->complain_on_overflow == complain_overflow_signed \
223 ? 0x80 \
224 : 0) \
225 | (howto->bitsize - 1)); \
226 }
227
228 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
229 #define COFF_LONG_FILENAMES
230 #define NO_COFF_SYMBOLS
231 #define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
232 #define coff_mkobject _bfd_xcoff_mkobject
233 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
234 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
235 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
236 #define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
237 #ifdef AIX_CORE
238 extern bfd_cleanup rs6000coff_core_p
239 (bfd *abfd);
240 extern bfd_boolean rs6000coff_core_file_matches_executable_p
241 (bfd *cbfd, bfd *ebfd);
242 extern char *rs6000coff_core_file_failing_command
243 (bfd *abfd);
244 extern int rs6000coff_core_file_failing_signal
245 (bfd *abfd);
246 #define CORE_FILE_P rs6000coff_core_p
247 #define coff_core_file_failing_command \
248 rs6000coff_core_file_failing_command
249 #define coff_core_file_failing_signal \
250 rs6000coff_core_file_failing_signal
251 #define coff_core_file_matches_executable_p \
252 rs6000coff_core_file_matches_executable_p
253 #define coff_core_file_pid \
254 _bfd_nocore_core_file_pid
255 #else
256 #define CORE_FILE_P _bfd_dummy_target
257 #define coff_core_file_failing_command \
258 _bfd_nocore_core_file_failing_command
259 #define coff_core_file_failing_signal \
260 _bfd_nocore_core_file_failing_signal
261 #define coff_core_file_matches_executable_p \
262 _bfd_nocore_core_file_matches_executable_p
263 #define coff_core_file_pid \
264 _bfd_nocore_core_file_pid
265 #endif
266 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
267 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
268 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
269 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
270 #define coff_swap_reloc_in xcoff64_swap_reloc_in
271 #define coff_swap_reloc_out xcoff64_swap_reloc_out
272 #define NO_COFF_RELOCS
273
274 #ifndef bfd_pe_print_pdata
275 #define bfd_pe_print_pdata NULL
276 #endif
277
278 #include "coffcode.h"
279
280 /* For XCOFF64, the effective width of symndx changes depending on
281 whether we are the first entry. Sigh. */
282 static void
283 _bfd_xcoff64_swap_lineno_in (bfd *abfd, void *ext1, void *in1)
284 {
285 LINENO *ext = (LINENO *) ext1;
286 struct internal_lineno *in = (struct internal_lineno *) in1;
287
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);
293 }
294
295 static unsigned int
296 _bfd_xcoff64_swap_lineno_out (bfd *abfd, void *inp, void *outp)
297 {
298 struct internal_lineno *in = (struct internal_lineno *) inp;
299 struct external_lineno *ext = (struct external_lineno *) outp;
300
301 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
302 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
303
304 if (in->l_lnno == 0)
305 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
306 else
307 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
308
309 return bfd_coff_linesz (abfd);
310 }
311
312 static void
313 _bfd_xcoff64_swap_sym_in (bfd *abfd, void *ext1, void *in1)
314 {
315 struct external_syment *ext = (struct external_syment *) ext1;
316 struct internal_syment *in = (struct internal_syment *) in1;
317
318 in->_n._n_n._n_zeroes = 0;
319 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
320 in->n_value = H_GET_64 (abfd, ext->e_value);
321 in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
322 in->n_type = H_GET_16 (abfd, ext->e_type);
323 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
324 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
325 }
326
327 static unsigned int
328 _bfd_xcoff64_swap_sym_out (bfd *abfd, void *inp, void *extp)
329 {
330 struct internal_syment *in = (struct internal_syment *) inp;
331 struct external_syment *ext = (struct external_syment *) extp;
332
333 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
334 H_PUT_64 (abfd, in->n_value, ext->e_value);
335 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
336 H_PUT_16 (abfd, in->n_type, ext->e_type);
337 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
338 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
339 return bfd_coff_symesz (abfd);
340 }
341
342 static void
343 _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class,
344 int indx, int numaux, void *in1)
345 {
346 union external_auxent *ext = (union external_auxent *) ext1;
347 union internal_auxent *in = (union internal_auxent *) in1;
348
349 switch (in_class)
350 {
351 case C_FILE:
352 if (ext->x_file.x_n.x_n.x_zeroes[0] == 0)
353 {
354 in->x_file.x_n.x_zeroes = 0;
355 in->x_file.x_n.x_offset =
356 H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset);
357 }
358 else
359 {
360 memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN);
361 }
362 goto end;
363
364 /* RS/6000 "csect" auxents */
365 case C_EXT:
366 case C_AIX_WEAKEXT:
367 case C_HIDEXT:
368 if (indx + 1 == numaux)
369 {
370 bfd_signed_vma h = 0;
371 bfd_vma l = 0;
372
373 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
374 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
375
376 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
377
378 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
379 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
380 /* We don't have to hack bitfields in x_smtyp because it's
381 defined by shifts-and-ands, which are equivalent on all
382 byte orders. */
383 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
384 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
385 goto end;
386 }
387 break;
388
389 case C_STAT:
390 case C_LEAFSTAT:
391 case C_HIDDEN:
392 if (type == T_NULL)
393 {
394 /* PE defines some extra fields; we zero them out for
395 safety. */
396 in->x_scn.x_checksum = 0;
397 in->x_scn.x_associated = 0;
398 in->x_scn.x_comdat = 0;
399
400 goto end;
401 }
402 break;
403 }
404
405 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
406 || ISTAG (in_class))
407 {
408 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
409 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
410 in->x_sym.x_fcnary.x_fcn.x_endndx.l
411 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
412 }
413 if (ISFCN (type))
414 {
415 in->x_sym.x_misc.x_fsize
416 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
417 }
418 else
419 {
420 in->x_sym.x_misc.x_lnsz.x_lnno
421 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
422 in->x_sym.x_misc.x_lnsz.x_size
423 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
424 }
425
426 end: ;
427 }
428
429 static unsigned int
430 _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class,
431 int indx ATTRIBUTE_UNUSED,
432 int numaux ATTRIBUTE_UNUSED,
433 void *extp)
434 {
435 union internal_auxent *in = (union internal_auxent *) inp;
436 union external_auxent *ext = (union external_auxent *) extp;
437
438 memset (ext, 0, bfd_coff_auxesz (abfd));
439 switch (in_class)
440 {
441 case C_FILE:
442 if (in->x_file.x_n.x_zeroes == 0)
443 {
444 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_n.x_zeroes);
445 H_PUT_32 (abfd, in->x_file.x_n.x_offset,
446 ext->x_file.x_n.x_n.x_offset);
447 }
448 else
449 {
450 memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN);
451 }
452 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
453 goto end;
454
455 /* RS/6000 "csect" auxents */
456 case C_EXT:
457 case C_AIX_WEAKEXT:
458 case C_HIDEXT:
459 if (indx + 1 == numaux)
460 {
461 bfd_vma temp;
462
463 temp = in->x_csect.x_scnlen.l & 0xffffffff;
464 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
465 temp = in->x_csect.x_scnlen.l >> 32;
466 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
467 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
468 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
469 /* We don't have to hack bitfields in x_smtyp because it's
470 defined by shifts-and-ands, which are equivalent on all
471 byte orders. */
472 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
473 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
474 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
475 goto end;
476 }
477 break;
478
479 case C_STAT:
480 case C_LEAFSTAT:
481 case C_HIDDEN:
482 if (type == T_NULL)
483 {
484 goto end;
485 }
486 break;
487 }
488
489 if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
490 || ISTAG (in_class))
491 {
492 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
493 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
494 H_PUT_8 (abfd, _AUX_FCN,
495 ext->x_auxtype.x_auxtype);
496 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
497 ext->x_sym.x_fcnary.x_fcn.x_endndx);
498 }
499 if (ISFCN (type))
500 {
501 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
502 ext->x_sym.x_fcnary.x_fcn.x_fsize);
503 }
504 else
505 {
506 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
507 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
508 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
509 ext->x_sym.x_fcnary.x_lnsz.x_size);
510 }
511
512 end:
513
514 return bfd_coff_auxesz (abfd);
515 }
516
517 static bfd_boolean
518 _bfd_xcoff64_put_symbol_name (struct bfd_link_info *info,
519 struct bfd_strtab_hash *strtab,
520 struct internal_syment *sym,
521 const char *name)
522 {
523 bfd_boolean hash;
524 bfd_size_type indx;
525
526 hash = !info->traditional_format;
527 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
528
529 if (indx == (bfd_size_type) -1)
530 return FALSE;
531
532 sym->_n._n_n._n_zeroes = 0;
533 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
534
535 return TRUE;
536 }
537
538 static bfd_boolean
539 _bfd_xcoff64_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED,
540 struct xcoff_loader_info *ldinfo,
541 struct internal_ldsym *ldsym,
542 const char *name)
543 {
544 size_t len;
545 len = strlen (name);
546
547 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
548 {
549 bfd_size_type newalc;
550 char *newstrings;
551
552 newalc = ldinfo->string_alc * 2;
553 if (newalc == 0)
554 newalc = 32;
555 while (ldinfo->string_size + len + 3 > newalc)
556 newalc *= 2;
557
558 newstrings = bfd_realloc (ldinfo->strings, newalc);
559 if (newstrings == NULL)
560 {
561 ldinfo->failed = TRUE;
562 return FALSE;
563 }
564 ldinfo->string_alc = newalc;
565 ldinfo->strings = newstrings;
566 }
567
568 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
569 ldinfo->strings + ldinfo->string_size);
570 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
571 ldsym->_l._l_l._l_zeroes = 0;
572 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
573 ldinfo->string_size += len + 3;
574
575 return TRUE;
576 }
577
578 /* Routines to swap information in the XCOFF .loader section. If we
579 ever need to write an XCOFF loader, this stuff will need to be
580 moved to another file shared by the linker (which XCOFF calls the
581 ``binder'') and the loader. */
582
583 /* Swap in the ldhdr structure. */
584
585 static void
586 xcoff64_swap_ldhdr_in (bfd *abfd,
587 const void *s,
588 struct internal_ldhdr *dst)
589 {
590 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
591
592 dst->l_version = bfd_get_32 (abfd, src->l_version);
593 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
594 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
595 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
596 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
597 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
598 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
599 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
600 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
601 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
602 }
603
604 /* Swap out the ldhdr structure. */
605
606 static void
607 xcoff64_swap_ldhdr_out (bfd *abfd, const struct internal_ldhdr *src, void *d)
608 {
609 struct external_ldhdr *dst = (struct external_ldhdr *) d;
610
611 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
612 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
613 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
614 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
615 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
616 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
617 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
618 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
619 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
620 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
621 }
622
623 /* Swap in the ldsym structure. */
624
625 static void
626 xcoff64_swap_ldsym_in (bfd *abfd, const void *s, struct internal_ldsym *dst)
627 {
628 const struct external_ldsym *src = (const struct external_ldsym *) s;
629 /* XCOFF64 does not use l_zeroes like XCOFF32
630 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
631 as an offset into the loader symbol table. */
632 dst->_l._l_l._l_zeroes = 0;
633 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
634 dst->l_value = bfd_get_64 (abfd, src->l_value);
635 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
636 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
637 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
638 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
639 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
640 }
641
642 /* Swap out the ldsym structure. */
643
644 static void
645 xcoff64_swap_ldsym_out (bfd *abfd, const struct internal_ldsym *src, void *d)
646 {
647 struct external_ldsym *dst = (struct external_ldsym *) d;
648
649 bfd_put_64 (abfd, src->l_value, dst->l_value);
650 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
651 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
652 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
653 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
654 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
655 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
656 }
657
658 static void
659 xcoff64_swap_reloc_in (bfd *abfd, void *s, void *d)
660 {
661 struct external_reloc *src = (struct external_reloc *) s;
662 struct internal_reloc *dst = (struct internal_reloc *) d;
663
664 memset (dst, 0, sizeof (struct internal_reloc));
665
666 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
667 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
668 dst->r_size = bfd_get_8 (abfd, src->r_size);
669 dst->r_type = bfd_get_8 (abfd, src->r_type);
670 }
671
672 static unsigned int
673 xcoff64_swap_reloc_out (bfd *abfd, void *s, void *d)
674 {
675 struct internal_reloc *src = (struct internal_reloc *) s;
676 struct external_reloc *dst = (struct external_reloc *) d;
677
678 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
679 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
680 bfd_put_8 (abfd, src->r_type, dst->r_type);
681 bfd_put_8 (abfd, src->r_size, dst->r_size);
682
683 return bfd_coff_relsz (abfd);
684 }
685
686 /* Swap in the ldrel structure. */
687
688 static void
689 xcoff64_swap_ldrel_in (bfd *abfd, const void *s, struct internal_ldrel *dst)
690 {
691 const struct external_ldrel *src = (const struct external_ldrel *) s;
692
693 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
694 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
695 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
696 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
697 }
698
699 /* Swap out the ldrel structure. */
700
701 static void
702 xcoff64_swap_ldrel_out (bfd *abfd, const struct internal_ldrel *src, void *d)
703 {
704 struct external_ldrel *dst = (struct external_ldrel *) d;
705
706 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
707 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
708 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
709 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
710 }
711
712
713 static bfd_boolean
714 xcoff64_reloc_type_br (bfd *input_bfd,
715 asection *input_section,
716 bfd *output_bfd ATTRIBUTE_UNUSED,
717 struct internal_reloc *rel,
718 struct internal_syment *sym ATTRIBUTE_UNUSED,
719 struct reloc_howto_struct *howto,
720 bfd_vma val,
721 bfd_vma addend,
722 bfd_vma *relocation,
723 bfd_byte *contents)
724 {
725 struct xcoff_link_hash_entry *h;
726 bfd_vma section_offset;
727
728 if (0 > rel->r_symndx)
729 return FALSE;
730
731 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
732 section_offset = rel->r_vaddr - input_section->vma;
733
734 /* If we see an R_BR or R_RBR reloc which is jumping to global
735 linkage code, and it is followed by an appropriate cror nop
736 instruction, we replace the cror with ld r2,40(r1). This
737 restores the TOC after the glink code. Contrariwise, if the
738 call is followed by a ld r2,40(r1), but the call is not
739 going to global linkage code, we can replace the load with a
740 cror. */
741 if (NULL != h
742 && (bfd_link_hash_defined == h->root.type
743 || bfd_link_hash_defweak == h->root.type)
744 && section_offset + 8 <= input_section->size)
745 {
746 bfd_byte *pnext;
747 unsigned long next;
748
749 pnext = contents + section_offset + 4;
750 next = bfd_get_32 (input_bfd, pnext);
751
752 /* The _ptrgl function is magic. It is used by the AIX compiler to call
753 a function through a pointer. */
754 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
755 {
756 if (next == 0x4def7b82 /* cror 15,15,15 */
757 || next == 0x4ffffb82 /* cror 31,31,31 */
758 || next == 0x60000000) /* ori r0,r0,0 */
759 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
760 }
761 else
762 {
763 if (next == 0xe8410028) /* ld r2,40(r1) */
764 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
765 }
766 }
767 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
768 {
769 /* Normally, this relocation is against a defined symbol. In the
770 case where this is a partial link and the output section offset
771 is greater than 2^25, the linker will return an invalid error
772 message that the relocation has been truncated. Yes it has been
773 truncated but no it not important. For this case, disable the
774 overflow checking. */
775 howto->complain_on_overflow = complain_overflow_dont;
776 }
777
778 /* The original PC-relative relocation is biased by -r_vaddr, so adding
779 the value below will give the absolute target address. */
780 *relocation = val + addend + rel->r_vaddr;
781
782 howto->src_mask &= ~3;
783 howto->dst_mask = howto->src_mask;
784
785 if (h != NULL
786 && (h->root.type == bfd_link_hash_defined
787 || h->root.type == bfd_link_hash_defweak)
788 && bfd_is_abs_section (h->root.u.def.section)
789 && section_offset + 4 <= input_section->size)
790 {
791 bfd_byte *ptr;
792 bfd_vma insn;
793
794 /* Turn the relative branch into an absolute one by setting the
795 AA bit. */
796 ptr = contents + section_offset;
797 insn = bfd_get_32 (input_bfd, ptr);
798 insn |= 2;
799 bfd_put_32 (input_bfd, insn, ptr);
800
801 /* Make the howto absolute too. */
802 howto->pc_relative = FALSE;
803 howto->complain_on_overflow = complain_overflow_bitfield;
804 }
805 else
806 {
807 /* Use a PC-relative howto and subtract the instruction's address
808 from the target address we calculated above. */
809 howto->pc_relative = TRUE;
810 *relocation -= (input_section->output_section->vma
811 + input_section->output_offset
812 + section_offset);
813 }
814 return TRUE;
815 }
816
817 /* This is the relocation function for the PowerPC64.
818 See xcoff_ppc_relocation_section for more information. */
819
820 bfd_boolean
821 xcoff64_ppc_relocate_section (bfd *output_bfd,
822 struct bfd_link_info *info,
823 bfd *input_bfd,
824 asection *input_section,
825 bfd_byte *contents,
826 struct internal_reloc *relocs,
827 struct internal_syment *syms,
828 asection **sections)
829 {
830 struct internal_reloc *rel;
831 struct internal_reloc *relend;
832
833 rel = relocs;
834 relend = rel + input_section->reloc_count;
835 for (; rel < relend; rel++)
836 {
837 long symndx;
838 struct xcoff_link_hash_entry *h;
839 struct internal_syment *sym;
840 bfd_vma addend;
841 bfd_vma val;
842 struct reloc_howto_struct howto;
843 bfd_vma relocation;
844 bfd_vma value_to_relocate;
845 bfd_vma address;
846 bfd_byte *location;
847
848 /* Relocation type R_REF is a special relocation type which is
849 merely used to prevent garbage collection from occurring for
850 the csect including the symbol which it references. */
851 if (rel->r_type == R_REF)
852 continue;
853
854 /* howto */
855 howto.type = rel->r_type;
856 howto.rightshift = 0;
857 howto.bitsize = (rel->r_size & 0x3f) + 1;
858 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
859 howto.pc_relative = FALSE;
860 howto.bitpos = 0;
861 howto.complain_on_overflow = (rel->r_size & 0x80
862 ? complain_overflow_signed
863 : complain_overflow_bitfield);
864 howto.special_function = NULL;
865 howto.name = "internal";
866 howto.partial_inplace = TRUE;
867 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
868 howto.pcrel_offset = FALSE;
869
870 /* symbol */
871 val = 0;
872 addend = 0;
873 h = NULL;
874 sym = NULL;
875 symndx = rel->r_symndx;
876
877 if (-1 != symndx)
878 {
879 asection *sec;
880
881 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
882 sym = syms + symndx;
883 addend = - sym->n_value;
884
885 if (NULL == h)
886 {
887 sec = sections[symndx];
888 /* Hack to make sure we use the right TOC anchor value
889 if this reloc is against the TOC anchor. */
890 if (sec->name[3] == '0'
891 && strcmp (sec->name, ".tc0") == 0)
892 val = xcoff_data (output_bfd)->toc;
893 else
894 val = (sec->output_section->vma
895 + sec->output_offset
896 + sym->n_value
897 - sec->vma);
898 }
899 else
900 {
901 if (info->unresolved_syms_in_objects != RM_IGNORE
902 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
903 info->callbacks->undefined_symbol
904 (info, h->root.root.string, input_bfd, input_section,
905 rel->r_vaddr - input_section->vma,
906 info->unresolved_syms_in_objects == RM_DIAGNOSE
907 && !info->warn_unresolved_syms);
908
909 if (h->root.type == bfd_link_hash_defined
910 || h->root.type == bfd_link_hash_defweak)
911 {
912 sec = h->root.u.def.section;
913 val = (h->root.u.def.value
914 + sec->output_section->vma
915 + sec->output_offset);
916 }
917 else if (h->root.type == bfd_link_hash_common)
918 {
919 sec = h->root.u.c.p->section;
920 val = (sec->output_section->vma
921 + sec->output_offset);
922 }
923 else
924 {
925 BFD_ASSERT (bfd_link_relocatable (info)
926 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
927 || (h->flags & XCOFF_IMPORT) != 0);
928 }
929 }
930 }
931
932 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
933 || !((*xcoff64_calculate_relocation[rel->r_type])
934 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
935 addend, &relocation, contents)))
936 return FALSE;
937
938 /* address */
939 address = rel->r_vaddr - input_section->vma;
940 location = contents + address;
941
942 if (address > input_section->size)
943 abort ();
944
945 /* Get the value we are going to relocate. */
946 if (1 == howto.size)
947 value_to_relocate = bfd_get_16 (input_bfd, location);
948 else if (2 == howto.size)
949 value_to_relocate = bfd_get_32 (input_bfd, location);
950 else
951 value_to_relocate = bfd_get_64 (input_bfd, location);
952
953 /* overflow.
954
955 FIXME: We may drop bits during the addition
956 which we don't check for. We must either check at every single
957 operation, which would be tedious, or we must do the computations
958 in a type larger than bfd_vma, which would be inefficient. */
959
960 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
961 (input_bfd, value_to_relocate, relocation, &howto)))
962 {
963 const char *name;
964 char buf[SYMNMLEN + 1];
965 char reloc_type_name[10];
966
967 if (symndx == -1)
968 {
969 name = "*ABS*";
970 }
971 else if (h != NULL)
972 {
973 name = NULL;
974 }
975 else
976 {
977 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
978 if (name == NULL)
979 name = "UNKNOWN";
980 }
981 sprintf (reloc_type_name, "0x%02x", rel->r_type);
982
983 (*info->callbacks->reloc_overflow)
984 (info, (h ? &h->root : NULL), name, reloc_type_name,
985 (bfd_vma) 0, input_bfd, input_section,
986 rel->r_vaddr - input_section->vma);
987 }
988
989 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
990 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
991 | (((value_to_relocate & howto.src_mask)
992 + relocation) & howto.dst_mask));
993
994 /* Put the value back in the object file. */
995 if (1 == howto.size)
996 bfd_put_16 (input_bfd, value_to_relocate, location);
997 else if (2 == howto.size)
998 bfd_put_32 (input_bfd, value_to_relocate, location);
999 else
1000 bfd_put_64 (input_bfd, value_to_relocate, location);
1001
1002 }
1003 return TRUE;
1004 }
1005
1006 \f
1007 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1008 bitsize and whether they are signed or not, along with a
1009 conventional type. This table is for the types, which are used for
1010 different algorithms for putting in the reloc. Many of these
1011 relocs need special_function entries, which I have not written. */
1012
1013 reloc_howto_type xcoff64_howto_table[] =
1014 {
1015 /* 0x00: Standard 64 bit relocation. */
1016 HOWTO (R_POS, /* type */
1017 0, /* rightshift */
1018 4, /* size (0 = byte, 1 = short, 2 = long) */
1019 64, /* bitsize */
1020 FALSE, /* pc_relative */
1021 0, /* bitpos */
1022 complain_overflow_bitfield, /* complain_on_overflow */
1023 0, /* special_function */
1024 "R_POS_64", /* name */
1025 TRUE, /* partial_inplace */
1026 MINUS_ONE, /* src_mask */
1027 MINUS_ONE, /* dst_mask */
1028 FALSE), /* pcrel_offset */
1029
1030 /* 0x01: 64 bit relocation, but store negative value. */
1031 HOWTO (R_NEG, /* type */
1032 0, /* rightshift */
1033 -4, /* size (0 = byte, 1 = short, 2 = long) */
1034 64, /* bitsize */
1035 FALSE, /* pc_relative */
1036 0, /* bitpos */
1037 complain_overflow_bitfield, /* complain_on_overflow */
1038 0, /* special_function */
1039 "R_NEG", /* name */
1040 TRUE, /* partial_inplace */
1041 MINUS_ONE, /* src_mask */
1042 MINUS_ONE, /* dst_mask */
1043 FALSE), /* pcrel_offset */
1044
1045 /* 0x02: 32 bit PC relative relocation. */
1046 HOWTO (R_REL, /* type */
1047 0, /* rightshift */
1048 2, /* size (0 = byte, 1 = short, 2 = long) */
1049 32, /* bitsize */
1050 TRUE, /* pc_relative */
1051 0, /* bitpos */
1052 complain_overflow_signed, /* complain_on_overflow */
1053 0, /* special_function */
1054 "R_REL", /* name */
1055 TRUE, /* partial_inplace */
1056 0xffffffff, /* src_mask */
1057 0xffffffff, /* dst_mask */
1058 FALSE), /* pcrel_offset */
1059
1060 /* 0x03: 16 bit TOC relative relocation. */
1061 HOWTO (R_TOC, /* type */
1062 0, /* rightshift */
1063 1, /* size (0 = byte, 1 = short, 2 = long) */
1064 16, /* bitsize */
1065 FALSE, /* pc_relative */
1066 0, /* bitpos */
1067 complain_overflow_bitfield, /* complain_on_overflow */
1068 0, /* special_function */
1069 "R_TOC", /* name */
1070 TRUE, /* partial_inplace */
1071 0xffff, /* src_mask */
1072 0xffff, /* dst_mask */
1073 FALSE), /* pcrel_offset */
1074
1075 /* 0x04: I don't really know what this is. */
1076 HOWTO (R_RTB, /* type */
1077 1, /* rightshift */
1078 2, /* size (0 = byte, 1 = short, 2 = long) */
1079 32, /* bitsize */
1080 FALSE, /* pc_relative */
1081 0, /* bitpos */
1082 complain_overflow_bitfield, /* complain_on_overflow */
1083 0, /* special_function */
1084 "R_RTB", /* name */
1085 TRUE, /* partial_inplace */
1086 0xffffffff, /* src_mask */
1087 0xffffffff, /* dst_mask */
1088 FALSE), /* pcrel_offset */
1089
1090 /* 0x05: External TOC relative symbol. */
1091 HOWTO (R_GL, /* type */
1092 0, /* rightshift */
1093 1, /* size (0 = byte, 1 = short, 2 = long) */
1094 16, /* bitsize */
1095 FALSE, /* pc_relative */
1096 0, /* bitpos */
1097 complain_overflow_bitfield, /* complain_on_overflow */
1098 0, /* special_function */
1099 "R_GL", /* name */
1100 TRUE, /* partial_inplace */
1101 0xffff, /* src_mask */
1102 0xffff, /* dst_mask */
1103 FALSE), /* pcrel_offset */
1104
1105 /* 0x06: Local TOC relative symbol. */
1106 HOWTO (R_TCL, /* type */
1107 0, /* rightshift */
1108 1, /* size (0 = byte, 1 = short, 2 = long) */
1109 16, /* bitsize */
1110 FALSE, /* pc_relative */
1111 0, /* bitpos */
1112 complain_overflow_bitfield, /* complain_on_overflow */
1113 0, /* special_function */
1114 "R_TCL", /* name */
1115 TRUE, /* partial_inplace */
1116 0xffff, /* src_mask */
1117 0xffff, /* dst_mask */
1118 FALSE), /* pcrel_offset */
1119
1120 EMPTY_HOWTO (7),
1121
1122 /* 0x08: Non modifiable absolute branch. */
1123 HOWTO (R_BA, /* type */
1124 0, /* rightshift */
1125 2, /* size (0 = byte, 1 = short, 2 = long) */
1126 26, /* bitsize */
1127 FALSE, /* pc_relative */
1128 0, /* bitpos */
1129 complain_overflow_bitfield, /* complain_on_overflow */
1130 0, /* special_function */
1131 "R_BA_26", /* name */
1132 TRUE, /* partial_inplace */
1133 0x03fffffc, /* src_mask */
1134 0x03fffffc, /* dst_mask */
1135 FALSE), /* pcrel_offset */
1136
1137 EMPTY_HOWTO (9),
1138
1139 /* 0x0a: Non modifiable relative branch. */
1140 HOWTO (R_BR, /* type */
1141 0, /* rightshift */
1142 2, /* size (0 = byte, 1 = short, 2 = long) */
1143 26, /* bitsize */
1144 TRUE, /* pc_relative */
1145 0, /* bitpos */
1146 complain_overflow_signed, /* complain_on_overflow */
1147 0, /* special_function */
1148 "R_BR", /* name */
1149 TRUE, /* partial_inplace */
1150 0x03fffffc, /* src_mask */
1151 0x03fffffc, /* dst_mask */
1152 FALSE), /* pcrel_offset */
1153
1154 EMPTY_HOWTO (0xb),
1155
1156 /* 0x0c: Indirect load. */
1157 HOWTO (R_RL, /* type */
1158 0, /* rightshift */
1159 1, /* size (0 = byte, 1 = short, 2 = long) */
1160 16, /* bitsize */
1161 FALSE, /* pc_relative */
1162 0, /* bitpos */
1163 complain_overflow_bitfield, /* complain_on_overflow */
1164 0, /* special_function */
1165 "R_RL", /* name */
1166 TRUE, /* partial_inplace */
1167 0xffff, /* src_mask */
1168 0xffff, /* dst_mask */
1169 FALSE), /* pcrel_offset */
1170
1171 /* 0x0d: Load address. */
1172 HOWTO (R_RLA, /* type */
1173 0, /* rightshift */
1174 1, /* size (0 = byte, 1 = short, 2 = long) */
1175 16, /* bitsize */
1176 FALSE, /* pc_relative */
1177 0, /* bitpos */
1178 complain_overflow_bitfield, /* complain_on_overflow */
1179 0, /* special_function */
1180 "R_RLA", /* name */
1181 TRUE, /* partial_inplace */
1182 0xffff, /* src_mask */
1183 0xffff, /* dst_mask */
1184 FALSE), /* pcrel_offset */
1185
1186 EMPTY_HOWTO (0xe),
1187
1188 /* 0x0f: Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
1189 HOWTO (R_REF, /* type */
1190 0, /* rightshift */
1191 0, /* size (0 = byte, 1 = short, 2 = long) */
1192 1, /* bitsize */
1193 FALSE, /* pc_relative */
1194 0, /* bitpos */
1195 complain_overflow_dont, /* complain_on_overflow */
1196 0, /* special_function */
1197 "R_REF", /* name */
1198 FALSE, /* partial_inplace */
1199 0, /* src_mask */
1200 0, /* dst_mask */
1201 FALSE), /* pcrel_offset */
1202
1203 EMPTY_HOWTO (0x10),
1204 EMPTY_HOWTO (0x11),
1205
1206 /* 0x12: TOC relative indirect load. */
1207 HOWTO (R_TRL, /* type */
1208 0, /* rightshift */
1209 1, /* size (0 = byte, 1 = short, 2 = long) */
1210 16, /* bitsize */
1211 FALSE, /* pc_relative */
1212 0, /* bitpos */
1213 complain_overflow_bitfield, /* complain_on_overflow */
1214 0, /* special_function */
1215 "R_TRL", /* name */
1216 TRUE, /* partial_inplace */
1217 0xffff, /* src_mask */
1218 0xffff, /* dst_mask */
1219 FALSE), /* pcrel_offset */
1220
1221 /* 0x13: TOC relative load address. */
1222 HOWTO (R_TRLA, /* type */
1223 0, /* rightshift */
1224 1, /* size (0 = byte, 1 = short, 2 = long) */
1225 16, /* bitsize */
1226 FALSE, /* pc_relative */
1227 0, /* bitpos */
1228 complain_overflow_bitfield, /* complain_on_overflow */
1229 0, /* special_function */
1230 "R_TRLA", /* name */
1231 TRUE, /* partial_inplace */
1232 0xffff, /* src_mask */
1233 0xffff, /* dst_mask */
1234 FALSE), /* pcrel_offset */
1235
1236 /* 0x14: Modifiable relative branch. */
1237 HOWTO (R_RRTBI, /* type */
1238 1, /* rightshift */
1239 2, /* size (0 = byte, 1 = short, 2 = long) */
1240 32, /* bitsize */
1241 FALSE, /* pc_relative */
1242 0, /* bitpos */
1243 complain_overflow_bitfield, /* complain_on_overflow */
1244 0, /* special_function */
1245 "R_RRTBI", /* name */
1246 TRUE, /* partial_inplace */
1247 0xffffffff, /* src_mask */
1248 0xffffffff, /* dst_mask */
1249 FALSE), /* pcrel_offset */
1250
1251 /* 0x15: Modifiable absolute branch. */
1252 HOWTO (R_RRTBA, /* type */
1253 1, /* rightshift */
1254 2, /* size (0 = byte, 1 = short, 2 = long) */
1255 32, /* bitsize */
1256 FALSE, /* pc_relative */
1257 0, /* bitpos */
1258 complain_overflow_bitfield, /* complain_on_overflow */
1259 0, /* special_function */
1260 "R_RRTBA", /* name */
1261 TRUE, /* partial_inplace */
1262 0xffffffff, /* src_mask */
1263 0xffffffff, /* dst_mask */
1264 FALSE), /* pcrel_offset */
1265
1266 /* 0x16: Modifiable call absolute indirect. */
1267 HOWTO (R_CAI, /* type */
1268 0, /* rightshift */
1269 1, /* size (0 = byte, 1 = short, 2 = long) */
1270 16, /* bitsize */
1271 FALSE, /* pc_relative */
1272 0, /* bitpos */
1273 complain_overflow_bitfield, /* complain_on_overflow */
1274 0, /* special_function */
1275 "R_CAI", /* name */
1276 TRUE, /* partial_inplace */
1277 0xffff, /* src_mask */
1278 0xffff, /* dst_mask */
1279 FALSE), /* pcrel_offset */
1280
1281 /* 0x17: Modifiable call relative. */
1282 HOWTO (R_CREL, /* type */
1283 0, /* rightshift */
1284 1, /* size (0 = byte, 1 = short, 2 = long) */
1285 16, /* bitsize */
1286 FALSE, /* pc_relative */
1287 0, /* bitpos */
1288 complain_overflow_bitfield, /* complain_on_overflow */
1289 0, /* special_function */
1290 "R_CREL", /* name */
1291 TRUE, /* partial_inplace */
1292 0xffff, /* src_mask */
1293 0xffff, /* dst_mask */
1294 FALSE), /* pcrel_offset */
1295
1296 /* 0x18: Modifiable branch absolute. */
1297 HOWTO (R_RBA, /* type */
1298 0, /* rightshift */
1299 2, /* size (0 = byte, 1 = short, 2 = long) */
1300 26, /* bitsize */
1301 FALSE, /* pc_relative */
1302 0, /* bitpos */
1303 complain_overflow_bitfield, /* complain_on_overflow */
1304 0, /* special_function */
1305 "R_RBA", /* name */
1306 TRUE, /* partial_inplace */
1307 0x03fffffc, /* src_mask */
1308 0x03fffffc, /* dst_mask */
1309 FALSE), /* pcrel_offset */
1310
1311 /* 0x19: Modifiable branch absolute. */
1312 HOWTO (R_RBAC, /* type */
1313 0, /* rightshift */
1314 2, /* size (0 = byte, 1 = short, 2 = long) */
1315 32, /* bitsize */
1316 FALSE, /* pc_relative */
1317 0, /* bitpos */
1318 complain_overflow_bitfield, /* complain_on_overflow */
1319 0, /* special_function */
1320 "R_RBAC", /* name */
1321 TRUE, /* partial_inplace */
1322 0xffffffff, /* src_mask */
1323 0xffffffff, /* dst_mask */
1324 FALSE), /* pcrel_offset */
1325
1326 /* 0x1a: Modifiable branch relative. */
1327 HOWTO (R_RBR, /* type */
1328 0, /* rightshift */
1329 2, /* size (0 = byte, 1 = short, 2 = long) */
1330 26, /* bitsize */
1331 FALSE, /* pc_relative */
1332 0, /* bitpos */
1333 complain_overflow_signed, /* complain_on_overflow */
1334 0, /* special_function */
1335 "R_RBR_26", /* name */
1336 TRUE, /* partial_inplace */
1337 0x03fffffc, /* src_mask */
1338 0x03fffffc, /* dst_mask */
1339 FALSE), /* pcrel_offset */
1340
1341 /* 0x1b: Modifiable branch absolute. */
1342 HOWTO (R_RBRC, /* type */
1343 0, /* rightshift */
1344 1, /* size (0 = byte, 1 = short, 2 = long) */
1345 16, /* bitsize */
1346 FALSE, /* pc_relative */
1347 0, /* bitpos */
1348 complain_overflow_bitfield, /* complain_on_overflow */
1349 0, /* special_function */
1350 "R_RBRC", /* name */
1351 TRUE, /* partial_inplace */
1352 0xffff, /* src_mask */
1353 0xffff, /* dst_mask */
1354 FALSE), /* pcrel_offset */
1355
1356 /* 0x1c: Standard 32 bit relocation. */
1357 HOWTO (R_POS, /* type */
1358 0, /* rightshift */
1359 2, /* size (0 = byte, 1 = short, 2 = long) */
1360 32, /* bitsize */
1361 FALSE, /* pc_relative */
1362 0, /* bitpos */
1363 complain_overflow_bitfield, /* complain_on_overflow */
1364 0, /* special_function */
1365 "R_POS_32", /* name */
1366 TRUE, /* partial_inplace */
1367 0xffffffff, /* src_mask */
1368 0xffffffff, /* dst_mask */
1369 FALSE), /* pcrel_offset */
1370
1371 /* 0x1d: 16 bit Non modifiable absolute branch. */
1372 HOWTO (R_BA, /* type */
1373 0, /* rightshift */
1374 1, /* size (0 = byte, 1 = short, 2 = long) */
1375 16, /* bitsize */
1376 FALSE, /* pc_relative */
1377 0, /* bitpos */
1378 complain_overflow_bitfield, /* complain_on_overflow */
1379 0, /* special_function */
1380 "R_BA_16", /* name */
1381 TRUE, /* partial_inplace */
1382 0xfffc, /* src_mask */
1383 0xfffc, /* dst_mask */
1384 FALSE), /* pcrel_offset */
1385
1386 /* 0x1e: Modifiable branch relative. */
1387 HOWTO (R_RBR, /* type */
1388 0, /* rightshift */
1389 1, /* size (0 = byte, 1 = short, 2 = long) */
1390 16, /* bitsize */
1391 TRUE, /* pc_relative */
1392 0, /* bitpos */
1393 complain_overflow_signed, /* complain_on_overflow */
1394 0, /* special_function */
1395 "R_RBR_16", /* name */
1396 TRUE, /* partial_inplace */
1397 0xfffc, /* src_mask */
1398 0xfffc, /* dst_mask */
1399 FALSE), /* pcrel_offset */
1400
1401 /* 0x1f: Modifiable branch absolute. */
1402 HOWTO (R_RBA, /* type */
1403 0, /* rightshift */
1404 1, /* size (0 = byte, 1 = short, 2 = long) */
1405 16, /* bitsize */
1406 FALSE, /* pc_relative */
1407 0, /* bitpos */
1408 complain_overflow_bitfield, /* complain_on_overflow */
1409 0, /* special_function */
1410 "R_RBA_16", /* name */
1411 TRUE, /* partial_inplace */
1412 0xffff, /* src_mask */
1413 0xffff, /* dst_mask */
1414 FALSE), /* pcrel_offset */
1415
1416 };
1417
1418 void
1419 xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal)
1420 {
1421 if (internal->r_type > R_RBRC)
1422 abort ();
1423
1424 /* Default howto layout works most of the time */
1425 relent->howto = &xcoff64_howto_table[internal->r_type];
1426
1427 /* Special case some 16 bit reloc */
1428 if (15 == (internal->r_size & 0x3f))
1429 {
1430 if (R_BA == internal->r_type)
1431 relent->howto = &xcoff64_howto_table[0x1d];
1432 else if (R_RBR == internal->r_type)
1433 relent->howto = &xcoff64_howto_table[0x1e];
1434 else if (R_RBA == internal->r_type)
1435 relent->howto = &xcoff64_howto_table[0x1f];
1436 }
1437 /* Special case 32 bit */
1438 else if (31 == (internal->r_size & 0x3f))
1439 {
1440 if (R_POS == internal->r_type)
1441 relent->howto = &xcoff64_howto_table[0x1c];
1442 }
1443
1444 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1445 relocation, as well as indicating whether it is signed or not.
1446 Doublecheck that the relocation information gathered from the
1447 type matches this information. The bitsize is not significant
1448 for R_REF relocs. */
1449 if (relent->howto->dst_mask != 0
1450 && (relent->howto->bitsize
1451 != ((unsigned int) internal->r_size & 0x3f) + 1))
1452 abort ();
1453 }
1454
1455 reloc_howto_type *
1456 xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1457 bfd_reloc_code_real_type code)
1458 {
1459 switch (code)
1460 {
1461 case BFD_RELOC_PPC_B26:
1462 return &xcoff64_howto_table[0xa];
1463 case BFD_RELOC_PPC_BA16:
1464 return &xcoff64_howto_table[0x1d];
1465 case BFD_RELOC_PPC_BA26:
1466 return &xcoff64_howto_table[8];
1467 case BFD_RELOC_PPC_TOC16:
1468 return &xcoff64_howto_table[3];
1469 case BFD_RELOC_PPC_B16:
1470 return &xcoff64_howto_table[0x1e];
1471 case BFD_RELOC_32:
1472 case BFD_RELOC_CTOR:
1473 return &xcoff64_howto_table[0x1c];
1474 case BFD_RELOC_64:
1475 return &xcoff64_howto_table[0];
1476 case BFD_RELOC_NONE:
1477 return &xcoff64_howto_table[0xf];
1478 default:
1479 return NULL;
1480 }
1481 }
1482
1483 static reloc_howto_type *
1484 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1485 const char *r_name)
1486 {
1487 unsigned int i;
1488
1489 for (i = 0;
1490 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1491 i++)
1492 if (xcoff64_howto_table[i].name != NULL
1493 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1494 return &xcoff64_howto_table[i];
1495
1496 return NULL;
1497 }
1498
1499 /* PR 21786: The PE/COFF standard does not require NUL termination for any of
1500 the ASCII fields in the archive headers. So in order to be able to extract
1501 numerical values we provide our own versions of strtol and strtoll which
1502 take a maximum length as an additional parameter. Also - just to save space,
1503 we omit the endptr return parameter, since we know that it is never used. */
1504
1505 static long
1506 _bfd_strntol (const char * nptr, int base, unsigned int maxlen)
1507 {
1508 char buf[24]; /* Should be enough. */
1509
1510 BFD_ASSERT (maxlen < (sizeof (buf) - 1));
1511
1512 memcpy (buf, nptr, maxlen);
1513 buf[maxlen] = 0;
1514 return strtol (buf, NULL, base);
1515 }
1516
1517 static long long
1518 _bfd_strntoll (const char * nptr, int base, unsigned int maxlen)
1519 {
1520 char buf[32]; /* Should be enough. */
1521
1522 BFD_ASSERT (maxlen < (sizeof (buf) - 1));
1523
1524 memcpy (buf, nptr, maxlen);
1525 buf[maxlen] = 0;
1526 return strtoll (buf, NULL, base);
1527 }
1528
1529 /* Macro to read an ASCII value stored in an archive header field. */
1530 #define GET_VALUE_IN_FIELD(VAR, FIELD, BASE) \
1531 do \
1532 { \
1533 (VAR) = (sizeof (VAR) > sizeof (long) \
1534 ? _bfd_strntoll (FIELD, BASE, sizeof FIELD) \
1535 : _bfd_strntol (FIELD, BASE, sizeof FIELD)); \
1536 } \
1537 while (0)
1538
1539 /* Read in the armap of an XCOFF archive. */
1540
1541 static bfd_boolean
1542 xcoff64_slurp_armap (bfd *abfd)
1543 {
1544 file_ptr off;
1545 size_t namlen;
1546 bfd_size_type sz, amt;
1547 bfd_byte *contents, *cend;
1548 bfd_vma c, i;
1549 carsym *arsym;
1550 bfd_byte *p;
1551 file_ptr pos;
1552
1553 /* This is for the new format. */
1554 struct xcoff_ar_hdr_big hdr;
1555
1556 if (xcoff_ardata (abfd) == NULL)
1557 {
1558 abfd->has_armap = FALSE;
1559 return TRUE;
1560 }
1561
1562 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1563 (const char **) NULL, 10);
1564 if (off == 0)
1565 {
1566 abfd->has_armap = FALSE;
1567 return TRUE;
1568 }
1569
1570 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1571 return FALSE;
1572
1573 /* The symbol table starts with a normal archive header. */
1574 if (bfd_bread (&hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1575 != SIZEOF_AR_HDR_BIG)
1576 return FALSE;
1577
1578 /* Skip the name (normally empty). */
1579 GET_VALUE_IN_FIELD (namlen, hdr.namlen, 10);
1580 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1581 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
1582 return FALSE;
1583
1584 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
1585 if (sz + 1 < 9)
1586 {
1587 bfd_set_error (bfd_error_bad_value);
1588 return FALSE;
1589 }
1590
1591 /* Read in the entire symbol table. */
1592 contents = (bfd_byte *) _bfd_alloc_and_read (abfd, sz + 1, sz);
1593 if (contents == NULL)
1594 return FALSE;
1595
1596 /* Ensure strings are NULL terminated so we don't wander off the end
1597 of the buffer. */
1598 contents[sz] = 0;
1599
1600 /* The symbol table starts with an eight byte count. */
1601 c = H_GET_64 (abfd, contents);
1602
1603 if (c >= sz / 8)
1604 {
1605 bfd_set_error (bfd_error_bad_value);
1606 return FALSE;
1607 }
1608 amt = c;
1609 amt *= sizeof (carsym);
1610 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
1611 if (bfd_ardata (abfd)->symdefs == NULL)
1612 return FALSE;
1613
1614 /* After the count comes a list of eight byte file offsets. */
1615 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1616 i < c;
1617 ++i, ++arsym, p += 8)
1618 arsym->file_offset = H_GET_64 (abfd, p);
1619
1620 /* After the file offsets come null terminated symbol names. */
1621 cend = contents + sz;
1622 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1623 i < c;
1624 ++i, ++arsym, p += strlen ((char *) p) + 1)
1625 {
1626 if (p >= cend)
1627 {
1628 bfd_set_error (bfd_error_bad_value);
1629 return FALSE;
1630 }
1631 arsym->name = (char *) p;
1632 }
1633
1634 bfd_ardata (abfd)->symdef_count = c;
1635 abfd->has_armap = TRUE;
1636
1637 return TRUE;
1638 }
1639
1640
1641 /* See if this is an NEW XCOFF archive. */
1642
1643 static bfd_cleanup
1644 xcoff64_archive_p (bfd *abfd)
1645 {
1646 struct artdata *tdata_hold;
1647 char magic[SXCOFFARMAG];
1648 /* This is the new format. */
1649 struct xcoff_ar_file_hdr_big hdr;
1650 size_t amt = SXCOFFARMAG;
1651
1652 if (bfd_bread (magic, amt, abfd) != amt)
1653 {
1654 if (bfd_get_error () != bfd_error_system_call)
1655 bfd_set_error (bfd_error_wrong_format);
1656 return NULL;
1657 }
1658
1659 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1660 {
1661 bfd_set_error (bfd_error_wrong_format);
1662 return NULL;
1663 }
1664
1665 /* Copy over the magic string. */
1666 memcpy (hdr.magic, magic, SXCOFFARMAG);
1667
1668 /* Now read the rest of the file header. */
1669 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1670 if (bfd_bread (&hdr.memoff, amt, abfd) != amt)
1671 {
1672 if (bfd_get_error () != bfd_error_system_call)
1673 bfd_set_error (bfd_error_wrong_format);
1674 return NULL;
1675 }
1676
1677 tdata_hold = bfd_ardata (abfd);
1678
1679 amt = sizeof (struct artdata);
1680 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
1681 if (bfd_ardata (abfd) == (struct artdata *) NULL)
1682 goto error_ret_restore;
1683
1684 /* Already cleared by bfd_zalloc above.
1685 bfd_ardata (abfd)->cache = NULL;
1686 bfd_ardata (abfd)->archive_head = NULL;
1687 bfd_ardata (abfd)->symdefs = NULL;
1688 bfd_ardata (abfd)->extended_names = NULL;
1689 bfd_ardata (abfd)->extended_names_size = 0; */
1690 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
1691 (const char **) NULL,
1692 10);
1693
1694 amt = SIZEOF_AR_FILE_HDR_BIG;
1695 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1696 if (bfd_ardata (abfd)->tdata == NULL)
1697 goto error_ret;
1698
1699 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1700
1701 if (! xcoff64_slurp_armap (abfd))
1702 {
1703 error_ret:
1704 bfd_release (abfd, bfd_ardata (abfd));
1705 error_ret_restore:
1706 bfd_ardata (abfd) = tdata_hold;
1707 return NULL;
1708 }
1709
1710 return _bfd_no_cleanup;
1711 }
1712
1713
1714 /* Open the next element in an XCOFF archive. */
1715
1716 static bfd *
1717 xcoff64_openr_next_archived_file (bfd *archive, bfd *last_file)
1718 {
1719 bfd_vma filestart;
1720
1721 if ((xcoff_ardata (archive) == NULL)
1722 || ! xcoff_big_format_p (archive))
1723 {
1724 bfd_set_error (bfd_error_invalid_operation);
1725 return NULL;
1726 }
1727
1728 if (last_file == NULL)
1729 {
1730 filestart = bfd_ardata (archive)->first_file_filepos;
1731 }
1732 else
1733 {
1734 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
1735 (const char **) NULL, 10);
1736 }
1737
1738 if (filestart == 0
1739 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
1740 (const char **) NULL, 10)
1741 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
1742 (const char **) NULL, 10))
1743 {
1744 bfd_set_error (bfd_error_no_more_archived_files);
1745 return NULL;
1746 }
1747
1748 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
1749 }
1750
1751 /* We can't use the usual coff_sizeof_headers routine, because AIX
1752 always uses an a.out header. */
1753
1754 static int
1755 xcoff64_sizeof_headers (bfd *abfd,
1756 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1757 {
1758 int size;
1759
1760 size = bfd_coff_filhsz (abfd);
1761
1762 /* Don't think the small aout header can be used since some of the
1763 old elements have been reordered past the end of the old coff
1764 small aout size. */
1765
1766 if (xcoff_data (abfd)->full_aouthdr)
1767 size += bfd_coff_aoutsz (abfd);
1768
1769 size += abfd->section_count * bfd_coff_scnhsz (abfd);
1770 return size;
1771 }
1772
1773 static asection *
1774 xcoff64_create_csect_from_smclas (bfd *abfd, union internal_auxent *aux,
1775 const char *symbol_name)
1776 {
1777 asection *return_value = NULL;
1778
1779 /* Changes from 32 :
1780 .sv == 8, is only for 32 bit programs
1781 .ti == 12 and .tb == 13 are now reserved. */
1782 static const char * const names[] =
1783 {
1784 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
1785 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
1786 ".td", ".sv64", ".sv3264", NULL, ".tl", ".ul", ".te"
1787 };
1788
1789 if ((aux->x_csect.x_smclas < ARRAY_SIZE (names))
1790 && (NULL != names[aux->x_csect.x_smclas]))
1791 {
1792
1793 return_value = bfd_make_section_anyway
1794 (abfd, names[aux->x_csect.x_smclas]);
1795
1796 }
1797 else
1798 {
1799 _bfd_error_handler
1800 /* xgettext: c-format */
1801 (_("%pB: symbol `%s' has unrecognized smclas %d"),
1802 abfd, symbol_name, aux->x_csect.x_smclas);
1803 bfd_set_error (bfd_error_bad_value);
1804 }
1805
1806 return return_value;
1807 }
1808
1809 static bfd_boolean
1810 xcoff64_is_lineno_count_overflow (bfd *abfd ATTRIBUTE_UNUSED,
1811 bfd_vma value ATTRIBUTE_UNUSED)
1812 {
1813 return FALSE;
1814 }
1815
1816 static bfd_boolean
1817 xcoff64_is_reloc_count_overflow (bfd *abfd ATTRIBUTE_UNUSED,
1818 bfd_vma value ATTRIBUTE_UNUSED)
1819 {
1820 return FALSE;
1821 }
1822
1823 static bfd_vma
1824 xcoff64_loader_symbol_offset (bfd *abfd ATTRIBUTE_UNUSED,
1825 struct internal_ldhdr *ldhdr)
1826 {
1827 return (ldhdr->l_symoff);
1828 }
1829
1830 static bfd_vma
1831 xcoff64_loader_reloc_offset (bfd *abfd ATTRIBUTE_UNUSED,
1832 struct internal_ldhdr *ldhdr)
1833 {
1834 return (ldhdr->l_rldoff);
1835 }
1836
1837 static bfd_boolean
1838 xcoff64_bad_format_hook (bfd * abfd, void *filehdr)
1839 {
1840 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1841
1842 /* Check flavor first. */
1843 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
1844 return FALSE;
1845
1846 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
1847 return FALSE;
1848
1849 return TRUE;
1850 }
1851
1852 static bfd_boolean
1853 xcoff64_generate_rtinit (bfd *abfd, const char *init, const char *fini,
1854 bfd_boolean rtld)
1855 {
1856 bfd_byte filehdr_ext[FILHSZ];
1857 bfd_byte scnhdr_ext[SCNHSZ * 3];
1858 bfd_byte syment_ext[SYMESZ * 10];
1859 bfd_byte reloc_ext[RELSZ * 3];
1860 bfd_byte *data_buffer;
1861 bfd_size_type data_buffer_size;
1862 bfd_byte *string_table, *st_tmp;
1863 bfd_size_type string_table_size;
1864 bfd_vma val;
1865 size_t initsz, finisz;
1866 struct internal_filehdr filehdr;
1867 struct internal_scnhdr text_scnhdr;
1868 struct internal_scnhdr data_scnhdr;
1869 struct internal_scnhdr bss_scnhdr;
1870 struct internal_syment syment;
1871 union internal_auxent auxent;
1872 struct internal_reloc reloc;
1873
1874 char *text_name = ".text";
1875 char *data_name = ".data";
1876 char *bss_name = ".bss";
1877 char *rtinit_name = "__rtinit";
1878 char *rtld_name = "__rtld";
1879
1880 if (! bfd_xcoff_rtinit_size (abfd))
1881 return FALSE;
1882
1883 initsz = (init == NULL ? 0 : 1 + strlen (init));
1884 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
1885
1886 /* File header. */
1887 memset (filehdr_ext, 0, FILHSZ);
1888 memset (&filehdr, 0, sizeof (struct internal_filehdr));
1889 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
1890 filehdr.f_nscns = 3;
1891 filehdr.f_timdat = 0;
1892 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
1893 filehdr.f_symptr = 0; /* set below */
1894 filehdr.f_opthdr = 0;
1895 filehdr.f_flags = 0;
1896
1897 /* Section headers. */
1898 memset (scnhdr_ext, 0, 3 * SCNHSZ);
1899
1900 /* Text. */
1901 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
1902 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
1903 text_scnhdr.s_paddr = 0;
1904 text_scnhdr.s_vaddr = 0;
1905 text_scnhdr.s_size = 0;
1906 text_scnhdr.s_scnptr = 0;
1907 text_scnhdr.s_relptr = 0;
1908 text_scnhdr.s_lnnoptr = 0;
1909 text_scnhdr.s_nreloc = 0;
1910 text_scnhdr.s_nlnno = 0;
1911 text_scnhdr.s_flags = STYP_TEXT;
1912
1913 /* Data. */
1914 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
1915 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
1916 data_scnhdr.s_paddr = 0;
1917 data_scnhdr.s_vaddr = 0;
1918 data_scnhdr.s_size = 0; /* set below */
1919 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
1920 data_scnhdr.s_relptr = 0; /* set below */
1921 data_scnhdr.s_lnnoptr = 0;
1922 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
1923 data_scnhdr.s_nlnno = 0;
1924 data_scnhdr.s_flags = STYP_DATA;
1925
1926 /* Bss. */
1927 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
1928 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
1929 bss_scnhdr.s_paddr = 0; /* set below */
1930 bss_scnhdr.s_vaddr = 0; /* set below */
1931 bss_scnhdr.s_size = 0; /* set below */
1932 bss_scnhdr.s_scnptr = 0;
1933 bss_scnhdr.s_relptr = 0;
1934 bss_scnhdr.s_lnnoptr = 0;
1935 bss_scnhdr.s_nreloc = 0;
1936 bss_scnhdr.s_nlnno = 0;
1937 bss_scnhdr.s_flags = STYP_BSS;
1938
1939 /* .data
1940 0x0000 0x00000000 : rtl
1941 0x0004 0x00000000 :
1942 0x0008 0x00000018 : offset to init, or 0
1943 0x000C 0x00000038 : offset to fini, or 0
1944 0x0010 0x00000010 : size of descriptor
1945 0x0014 0x00000000 : pad
1946 0x0018 0x00000000 : init, needs a reloc
1947 0x001C 0x00000000 :
1948 0x0020 0x00000058 : offset to init name
1949 0x0024 0x00000000 : flags, padded to a word
1950 0x0028 0x00000000 : empty init
1951 0x002C 0x00000000 :
1952 0x0030 0x00000000 :
1953 0x0034 0x00000000 :
1954 0x0038 0x00000000 : fini, needs a reloc
1955 0x003C 0x00000000 :
1956 0x0040 0x00000??? : offset to fini name
1957 0x0044 0x00000000 : flags, padded to a word
1958 0x0048 0x00000000 : empty fini
1959 0x004C 0x00000000 :
1960 0x0050 0x00000000 :
1961 0x0054 0x00000000 :
1962 0x0058 init name
1963 0x0058 + initsz fini name */
1964
1965 data_buffer_size = 0x0058 + initsz + finisz;
1966 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
1967 data_buffer = NULL;
1968 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
1969 if (data_buffer == NULL)
1970 return FALSE;
1971
1972 if (initsz)
1973 {
1974 val = 0x18;
1975 bfd_put_32 (abfd, val, &data_buffer[0x08]);
1976 val = 0x58;
1977 bfd_put_32 (abfd, val, &data_buffer[0x20]);
1978 memcpy (&data_buffer[val], init, initsz);
1979 }
1980
1981 if (finisz)
1982 {
1983 val = 0x38;
1984 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
1985 val = 0x58 + initsz;
1986 bfd_put_32 (abfd, val, &data_buffer[0x40]);
1987 memcpy (&data_buffer[val], fini, finisz);
1988 }
1989
1990 val = 0x10;
1991 bfd_put_32 (abfd, val, &data_buffer[0x10]);
1992 data_scnhdr.s_size = data_buffer_size;
1993 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
1994
1995 /* String table. */
1996 string_table_size = 4;
1997 string_table_size += strlen (data_name) + 1;
1998 string_table_size += strlen (rtinit_name) + 1;
1999 string_table_size += initsz;
2000 string_table_size += finisz;
2001 if (rtld)
2002 string_table_size += strlen (rtld_name) + 1;
2003
2004 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2005 if (string_table == NULL)
2006 return FALSE;
2007
2008 val = string_table_size;
2009 bfd_put_32 (abfd, val, &string_table[0]);
2010 st_tmp = string_table + 4;
2011
2012 /* symbols
2013 0. .data csect
2014 2. __rtinit
2015 4. init function
2016 6. fini function
2017 8. __rtld */
2018 memset (syment_ext, 0, 10 * SYMESZ);
2019 memset (reloc_ext, 0, 3 * RELSZ);
2020
2021 /* .data csect */
2022 memset (&syment, 0, sizeof (struct internal_syment));
2023 memset (&auxent, 0, sizeof (union internal_auxent));
2024
2025 syment._n._n_n._n_offset = st_tmp - string_table;
2026 memcpy (st_tmp, data_name, strlen (data_name));
2027 st_tmp += strlen (data_name) + 1;
2028
2029 syment.n_scnum = 2;
2030 syment.n_sclass = C_HIDEXT;
2031 syment.n_numaux = 1;
2032 auxent.x_csect.x_scnlen.l = data_buffer_size;
2033 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2034 auxent.x_csect.x_smclas = XMC_RW;
2035 bfd_coff_swap_sym_out (abfd, &syment,
2036 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2037 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2038 syment.n_numaux,
2039 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2040 filehdr.f_nsyms += 2;
2041
2042 /* __rtinit */
2043 memset (&syment, 0, sizeof (struct internal_syment));
2044 memset (&auxent, 0, sizeof (union internal_auxent));
2045 syment._n._n_n._n_offset = st_tmp - string_table;
2046 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2047 st_tmp += strlen (rtinit_name) + 1;
2048
2049 syment.n_scnum = 2;
2050 syment.n_sclass = C_EXT;
2051 syment.n_numaux = 1;
2052 auxent.x_csect.x_smtyp = XTY_LD;
2053 auxent.x_csect.x_smclas = XMC_RW;
2054 bfd_coff_swap_sym_out (abfd, &syment,
2055 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2056 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2057 syment.n_numaux,
2058 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2059 filehdr.f_nsyms += 2;
2060
2061 /* Init. */
2062 if (initsz)
2063 {
2064 memset (&syment, 0, sizeof (struct internal_syment));
2065 memset (&auxent, 0, sizeof (union internal_auxent));
2066
2067 syment._n._n_n._n_offset = st_tmp - string_table;
2068 memcpy (st_tmp, init, initsz);
2069 st_tmp += initsz;
2070
2071 syment.n_sclass = C_EXT;
2072 syment.n_numaux = 1;
2073 bfd_coff_swap_sym_out (abfd, &syment,
2074 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2075 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2076 syment.n_numaux,
2077 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2078 /* Reloc. */
2079 memset (&reloc, 0, sizeof (struct internal_reloc));
2080 reloc.r_vaddr = 0x0018;
2081 reloc.r_symndx = filehdr.f_nsyms;
2082 reloc.r_type = R_POS;
2083 reloc.r_size = 63;
2084 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2085
2086 filehdr.f_nsyms += 2;
2087 data_scnhdr.s_nreloc += 1;
2088 }
2089
2090 /* Finit. */
2091 if (finisz)
2092 {
2093 memset (&syment, 0, sizeof (struct internal_syment));
2094 memset (&auxent, 0, sizeof (union internal_auxent));
2095
2096 syment._n._n_n._n_offset = st_tmp - string_table;
2097 memcpy (st_tmp, fini, finisz);
2098 st_tmp += finisz;
2099
2100 syment.n_sclass = C_EXT;
2101 syment.n_numaux = 1;
2102 bfd_coff_swap_sym_out (abfd, &syment,
2103 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2104 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2105 syment.n_numaux,
2106 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2107
2108 /* Reloc. */
2109 memset (&reloc, 0, sizeof (struct internal_reloc));
2110 reloc.r_vaddr = 0x0038;
2111 reloc.r_symndx = filehdr.f_nsyms;
2112 reloc.r_type = R_POS;
2113 reloc.r_size = 63;
2114 bfd_coff_swap_reloc_out (abfd, &reloc,
2115 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2116
2117 filehdr.f_nsyms += 2;
2118 data_scnhdr.s_nreloc += 1;
2119 }
2120
2121 if (rtld)
2122 {
2123 memset (&syment, 0, sizeof (struct internal_syment));
2124 memset (&auxent, 0, sizeof (union internal_auxent));
2125
2126 syment._n._n_n._n_offset = st_tmp - string_table;
2127 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2128 st_tmp += strlen (rtld_name) + 1;
2129
2130 syment.n_sclass = C_EXT;
2131 syment.n_numaux = 1;
2132 bfd_coff_swap_sym_out (abfd, &syment,
2133 &syment_ext[filehdr.f_nsyms * SYMESZ]);
2134 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2135 syment.n_numaux,
2136 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2137
2138 /* Reloc. */
2139 memset (&reloc, 0, sizeof (struct internal_reloc));
2140 reloc.r_vaddr = 0x0000;
2141 reloc.r_symndx = filehdr.f_nsyms;
2142 reloc.r_type = R_POS;
2143 reloc.r_size = 63;
2144 bfd_coff_swap_reloc_out (abfd, &reloc,
2145 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2146
2147 filehdr.f_nsyms += 2;
2148 data_scnhdr.s_nreloc += 1;
2149
2150 bss_scnhdr.s_size = 0;
2151 }
2152
2153 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2154 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
2155
2156 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2157 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
2158 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2159 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2160 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2161 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
2162 bfd_bwrite (data_buffer, data_buffer_size, abfd);
2163 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
2164 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2165 bfd_bwrite (string_table, string_table_size, abfd);
2166
2167 free (data_buffer);
2168 data_buffer = NULL;
2169
2170 return TRUE;
2171 }
2172
2173 /* The typical dynamic reloc. */
2174
2175 static reloc_howto_type xcoff64_dynamic_reloc =
2176 HOWTO (0, /* type */
2177 0, /* rightshift */
2178 4, /* size (0 = byte, 1 = short, 2 = long) */
2179 64, /* bitsize */
2180 FALSE, /* pc_relative */
2181 0, /* bitpos */
2182 complain_overflow_bitfield, /* complain_on_overflow */
2183 0, /* special_function */
2184 "R_POS", /* name */
2185 TRUE, /* partial_inplace */
2186 MINUS_ONE, /* src_mask */
2187 MINUS_ONE, /* dst_mask */
2188 FALSE); /* pcrel_offset */
2189
2190 static const unsigned long xcoff64_glink_code[10] =
2191 {
2192 0xe9820000, /* ld r12,0(r2) */
2193 0xf8410028, /* std r2,40(r1) */
2194 0xe80c0000, /* ld r0,0(r12) */
2195 0xe84c0008, /* ld r0,8(r12) */
2196 0x7c0903a6, /* mtctr r0 */
2197 0x4e800420, /* bctr */
2198 0x00000000, /* start of traceback table */
2199 0x000ca000, /* traceback table */
2200 0x00000000, /* traceback table */
2201 0x00000018, /* ??? */
2202 };
2203
2204 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2205 {
2206 { /* COFF backend, defined in libcoff.h. */
2207 _bfd_xcoff64_swap_aux_in,
2208 _bfd_xcoff64_swap_sym_in,
2209 _bfd_xcoff64_swap_lineno_in,
2210 _bfd_xcoff64_swap_aux_out,
2211 _bfd_xcoff64_swap_sym_out,
2212 _bfd_xcoff64_swap_lineno_out,
2213 xcoff64_swap_reloc_out,
2214 coff_swap_filehdr_out,
2215 coff_swap_aouthdr_out,
2216 coff_swap_scnhdr_out,
2217 FILHSZ,
2218 AOUTSZ,
2219 SCNHSZ,
2220 SYMESZ,
2221 AUXESZ,
2222 RELSZ,
2223 LINESZ,
2224 FILNMLEN,
2225 TRUE, /* _bfd_coff_long_filenames */
2226 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2227 3, /* _bfd_coff_default_section_alignment_power */
2228 TRUE, /* _bfd_coff_force_symnames_in_strings */
2229 4, /* _bfd_coff_debug_string_prefix_length */
2230 32768, /* _bfd_coff_max_nscns */
2231 coff_swap_filehdr_in,
2232 coff_swap_aouthdr_in,
2233 coff_swap_scnhdr_in,
2234 xcoff64_swap_reloc_in,
2235 xcoff64_bad_format_hook,
2236 coff_set_arch_mach_hook,
2237 coff_mkobject_hook,
2238 styp_to_sec_flags,
2239 coff_set_alignment_hook,
2240 coff_slurp_symbol_table,
2241 symname_in_debug_hook,
2242 coff_pointerize_aux_hook,
2243 coff_print_aux,
2244 dummy_reloc16_extra_cases,
2245 dummy_reloc16_estimate,
2246 NULL, /* bfd_coff_symbol_classification */
2247 coff_compute_section_file_positions,
2248 NULL, /* _bfd_coff_start_final_link */
2249 xcoff64_ppc_relocate_section,
2250 coff_rtype_to_howto,
2251 NULL, /* _bfd_coff_adjust_symndx */
2252 _bfd_generic_link_add_one_symbol,
2253 coff_link_output_has_begun,
2254 coff_final_link_postscript,
2255 NULL /* print_pdata. */
2256 },
2257
2258 0x01EF, /* magic number */
2259 bfd_arch_powerpc,
2260 bfd_mach_ppc_620,
2261
2262 /* Function pointers to xcoff specific swap routines. */
2263 xcoff64_swap_ldhdr_in,
2264 xcoff64_swap_ldhdr_out,
2265 xcoff64_swap_ldsym_in,
2266 xcoff64_swap_ldsym_out,
2267 xcoff64_swap_ldrel_in,
2268 xcoff64_swap_ldrel_out,
2269
2270 /* Sizes. */
2271 LDHDRSZ,
2272 LDSYMSZ,
2273 LDRELSZ,
2274 24, /* _xcoff_function_descriptor_size */
2275 0, /* _xcoff_small_aout_header_size */
2276
2277 /* Versions. */
2278 2, /* _xcoff_ldhdr_version */
2279
2280 _bfd_xcoff64_put_symbol_name,
2281 _bfd_xcoff64_put_ldsymbol_name,
2282 &xcoff64_dynamic_reloc,
2283 xcoff64_create_csect_from_smclas,
2284
2285 /* Lineno and reloc count overflow. */
2286 xcoff64_is_lineno_count_overflow,
2287 xcoff64_is_reloc_count_overflow,
2288
2289 xcoff64_loader_symbol_offset,
2290 xcoff64_loader_reloc_offset,
2291
2292 /* glink. */
2293 &xcoff64_glink_code[0],
2294 40, /* _xcoff_glink_size */
2295
2296 /* rtinit. */
2297 88, /* _xcoff_rtinit_size */
2298 xcoff64_generate_rtinit,
2299 };
2300
2301 /* The transfer vector that leads the outside world to all of the above. */
2302 const bfd_target rs6000_xcoff64_vec =
2303 {
2304 "aixcoff64-rs6000",
2305 bfd_target_xcoff_flavour,
2306 BFD_ENDIAN_BIG, /* data byte order is big */
2307 BFD_ENDIAN_BIG, /* header byte order is big */
2308
2309 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2310 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2311
2312 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2313 0, /* leading char */
2314 '/', /* ar_pad_char */
2315 15, /* ar_max_namelen */
2316 0, /* match priority. */
2317 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
2318
2319 /* data */
2320 bfd_getb64,
2321 bfd_getb_signed_64,
2322 bfd_putb64,
2323 bfd_getb32,
2324 bfd_getb_signed_32,
2325 bfd_putb32,
2326 bfd_getb16,
2327 bfd_getb_signed_16,
2328 bfd_putb16,
2329
2330 /* hdrs */
2331 bfd_getb64,
2332 bfd_getb_signed_64,
2333 bfd_putb64,
2334 bfd_getb32,
2335 bfd_getb_signed_32,
2336 bfd_putb32,
2337 bfd_getb16,
2338 bfd_getb_signed_16,
2339 bfd_putb16,
2340
2341 { /* bfd_check_format */
2342 _bfd_dummy_target,
2343 coff_object_p,
2344 xcoff64_archive_p,
2345 CORE_FILE_P
2346 },
2347
2348 { /* bfd_set_format */
2349 _bfd_bool_bfd_false_error,
2350 coff_mkobject,
2351 _bfd_generic_mkarchive,
2352 _bfd_bool_bfd_false_error
2353 },
2354
2355 {/* bfd_write_contents */
2356 _bfd_bool_bfd_false_error,
2357 coff_write_object_contents,
2358 _bfd_xcoff_write_archive_contents,
2359 _bfd_bool_bfd_false_error
2360 },
2361
2362 /* Generic */
2363 _bfd_archive_close_and_cleanup,
2364 _bfd_bool_bfd_true,
2365 coff_new_section_hook,
2366 _bfd_generic_get_section_contents,
2367 _bfd_generic_get_section_contents_in_window,
2368
2369 /* Copy */
2370 _bfd_xcoff_copy_private_bfd_data,
2371 _bfd_generic_bfd_merge_private_bfd_data,
2372 _bfd_generic_init_private_section_data,
2373 _bfd_generic_bfd_copy_private_section_data,
2374 _bfd_generic_bfd_copy_private_symbol_data,
2375 _bfd_generic_bfd_copy_private_header_data,
2376 _bfd_generic_bfd_set_private_flags,
2377 _bfd_generic_bfd_print_private_bfd_data,
2378
2379 /* Core */
2380 BFD_JUMP_TABLE_CORE (coff),
2381
2382 /* Archive */
2383 xcoff64_slurp_armap,
2384 _bfd_noarchive_slurp_extended_name_table,
2385 _bfd_noarchive_construct_extended_name_table,
2386 bfd_dont_truncate_arname,
2387 _bfd_xcoff_write_armap,
2388 _bfd_xcoff_read_ar_hdr,
2389 _bfd_generic_write_ar_hdr,
2390 xcoff64_openr_next_archived_file,
2391 _bfd_generic_get_elt_at_index,
2392 _bfd_xcoff_stat_arch_elt,
2393 _bfd_bool_bfd_true,
2394
2395 /* Symbols */
2396 coff_get_symtab_upper_bound,
2397 coff_canonicalize_symtab,
2398 coff_make_empty_symbol,
2399 coff_print_symbol,
2400 coff_get_symbol_info,
2401 coff_get_symbol_version_string,
2402 _bfd_xcoff_is_local_label_name,
2403 coff_bfd_is_target_special_symbol,
2404 coff_get_lineno,
2405 coff_find_nearest_line,
2406 coff_find_line,
2407 coff_find_inliner_info,
2408 coff_bfd_make_debug_symbol,
2409 _bfd_generic_read_minisymbols,
2410 _bfd_generic_minisymbol_to_symbol,
2411
2412 /* Reloc */
2413 coff_get_reloc_upper_bound,
2414 coff_canonicalize_reloc,
2415 _bfd_generic_set_reloc,
2416 xcoff64_reloc_type_lookup,
2417 xcoff64_reloc_name_lookup,
2418
2419 /* Write */
2420 coff_set_arch_mach,
2421 coff_set_section_contents,
2422
2423 /* Link */
2424 xcoff64_sizeof_headers,
2425 bfd_generic_get_relocated_section_contents,
2426 bfd_generic_relax_section,
2427 _bfd_xcoff_bfd_link_hash_table_create,
2428 _bfd_xcoff_bfd_link_add_symbols,
2429 _bfd_generic_link_just_syms,
2430 _bfd_generic_copy_link_hash_symbol_type,
2431 _bfd_xcoff_bfd_final_link,
2432 _bfd_generic_link_split_section,
2433 _bfd_generic_link_check_relocs,
2434 bfd_generic_gc_sections,
2435 bfd_generic_lookup_section_flags,
2436 bfd_generic_merge_sections,
2437 bfd_generic_is_group_section,
2438 bfd_generic_group_name,
2439 bfd_generic_discard_group,
2440 _bfd_generic_section_already_linked,
2441 _bfd_xcoff_define_common_symbol,
2442 _bfd_generic_link_hide_symbol,
2443 bfd_generic_define_start_stop,
2444
2445 /* Dynamic */
2446 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2447 _bfd_xcoff_canonicalize_dynamic_symtab,
2448 _bfd_nodynamic_get_synthetic_symtab,
2449 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2450 _bfd_xcoff_canonicalize_dynamic_reloc,
2451
2452 /* Opposite endian version, none exists */
2453 NULL,
2454
2455 &bfd_xcoff_backend_data,
2456 };
2457
2458 extern bfd_cleanup xcoff64_core_p
2459 (bfd *);
2460 extern bfd_boolean xcoff64_core_file_matches_executable_p
2461 (bfd *, bfd *);
2462 extern char *xcoff64_core_file_failing_command
2463 (bfd *);
2464 extern int xcoff64_core_file_failing_signal
2465 (bfd *);
2466 #define xcoff64_core_file_pid _bfd_nocore_core_file_pid
2467
2468 /* AIX 5 */
2469 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
2470 {
2471 { /* COFF backend, defined in libcoff.h. */
2472 _bfd_xcoff64_swap_aux_in,
2473 _bfd_xcoff64_swap_sym_in,
2474 _bfd_xcoff64_swap_lineno_in,
2475 _bfd_xcoff64_swap_aux_out,
2476 _bfd_xcoff64_swap_sym_out,
2477 _bfd_xcoff64_swap_lineno_out,
2478 xcoff64_swap_reloc_out,
2479 coff_swap_filehdr_out,
2480 coff_swap_aouthdr_out,
2481 coff_swap_scnhdr_out,
2482 FILHSZ,
2483 AOUTSZ,
2484 SCNHSZ,
2485 SYMESZ,
2486 AUXESZ,
2487 RELSZ,
2488 LINESZ,
2489 FILNMLEN,
2490 TRUE, /* _bfd_coff_long_filenames */
2491 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
2492 3, /* _bfd_coff_default_section_alignment_power */
2493 TRUE, /* _bfd_coff_force_symnames_in_strings */
2494 4, /* _bfd_coff_debug_string_prefix_length */
2495 32768, /* _bfd_coff_max_nscns */
2496 coff_swap_filehdr_in,
2497 coff_swap_aouthdr_in,
2498 coff_swap_scnhdr_in,
2499 xcoff64_swap_reloc_in,
2500 xcoff64_bad_format_hook,
2501 coff_set_arch_mach_hook,
2502 coff_mkobject_hook,
2503 styp_to_sec_flags,
2504 coff_set_alignment_hook,
2505 coff_slurp_symbol_table,
2506 symname_in_debug_hook,
2507 coff_pointerize_aux_hook,
2508 coff_print_aux,
2509 dummy_reloc16_extra_cases,
2510 dummy_reloc16_estimate,
2511 NULL, /* bfd_coff_sym_is_global */
2512 coff_compute_section_file_positions,
2513 NULL, /* _bfd_coff_start_final_link */
2514 xcoff64_ppc_relocate_section,
2515 coff_rtype_to_howto,
2516 NULL, /* _bfd_coff_adjust_symndx */
2517 _bfd_generic_link_add_one_symbol,
2518 coff_link_output_has_begun,
2519 coff_final_link_postscript,
2520 NULL /* print_pdata. */
2521 },
2522
2523 U64_TOCMAGIC, /* magic number */
2524 bfd_arch_powerpc,
2525 bfd_mach_ppc_620,
2526
2527 /* Function pointers to xcoff specific swap routines. */
2528 xcoff64_swap_ldhdr_in,
2529 xcoff64_swap_ldhdr_out,
2530 xcoff64_swap_ldsym_in,
2531 xcoff64_swap_ldsym_out,
2532 xcoff64_swap_ldrel_in,
2533 xcoff64_swap_ldrel_out,
2534
2535 /* Sizes. */
2536 LDHDRSZ,
2537 LDSYMSZ,
2538 LDRELSZ,
2539 24, /* _xcoff_function_descriptor_size */
2540 0, /* _xcoff_small_aout_header_size */
2541 /* Versions. */
2542 2, /* _xcoff_ldhdr_version */
2543
2544 _bfd_xcoff64_put_symbol_name,
2545 _bfd_xcoff64_put_ldsymbol_name,
2546 &xcoff64_dynamic_reloc,
2547 xcoff64_create_csect_from_smclas,
2548
2549 /* Lineno and reloc count overflow. */
2550 xcoff64_is_lineno_count_overflow,
2551 xcoff64_is_reloc_count_overflow,
2552
2553 xcoff64_loader_symbol_offset,
2554 xcoff64_loader_reloc_offset,
2555
2556 /* glink. */
2557 &xcoff64_glink_code[0],
2558 40, /* _xcoff_glink_size */
2559
2560 /* rtinit. */
2561 88, /* _xcoff_rtinit_size */
2562 xcoff64_generate_rtinit,
2563 };
2564
2565 /* The transfer vector that leads the outside world to all of the above. */
2566 const bfd_target rs6000_xcoff64_aix_vec =
2567 {
2568 "aix5coff64-rs6000",
2569 bfd_target_xcoff_flavour,
2570 BFD_ENDIAN_BIG, /* data byte order is big */
2571 BFD_ENDIAN_BIG, /* header byte order is big */
2572
2573 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2574 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2575
2576 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
2577 0, /* leading char */
2578 '/', /* ar_pad_char */
2579 15, /* ar_max_namelen */
2580 0, /* match priority. */
2581 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
2582
2583 /* data */
2584 bfd_getb64,
2585 bfd_getb_signed_64,
2586 bfd_putb64,
2587 bfd_getb32,
2588 bfd_getb_signed_32,
2589 bfd_putb32,
2590 bfd_getb16,
2591 bfd_getb_signed_16,
2592 bfd_putb16,
2593
2594 /* hdrs */
2595 bfd_getb64,
2596 bfd_getb_signed_64,
2597 bfd_putb64,
2598 bfd_getb32,
2599 bfd_getb_signed_32,
2600 bfd_putb32,
2601 bfd_getb16,
2602 bfd_getb_signed_16,
2603 bfd_putb16,
2604
2605 { /* bfd_check_format */
2606 _bfd_dummy_target,
2607 coff_object_p,
2608 xcoff64_archive_p,
2609 xcoff64_core_p
2610 },
2611
2612 { /* bfd_set_format */
2613 _bfd_bool_bfd_false_error,
2614 coff_mkobject,
2615 _bfd_generic_mkarchive,
2616 _bfd_bool_bfd_false_error
2617 },
2618
2619 {/* bfd_write_contents */
2620 _bfd_bool_bfd_false_error,
2621 coff_write_object_contents,
2622 _bfd_xcoff_write_archive_contents,
2623 _bfd_bool_bfd_false_error
2624 },
2625
2626 /* Generic */
2627 _bfd_archive_close_and_cleanup,
2628 _bfd_bool_bfd_true,
2629 coff_new_section_hook,
2630 _bfd_generic_get_section_contents,
2631 _bfd_generic_get_section_contents_in_window,
2632
2633 /* Copy */
2634 _bfd_xcoff_copy_private_bfd_data,
2635 _bfd_generic_bfd_merge_private_bfd_data,
2636 _bfd_generic_init_private_section_data,
2637 _bfd_generic_bfd_copy_private_section_data,
2638 _bfd_generic_bfd_copy_private_symbol_data,
2639 _bfd_generic_bfd_copy_private_header_data,
2640 _bfd_generic_bfd_set_private_flags,
2641 _bfd_generic_bfd_print_private_bfd_data,
2642
2643 /* Core */
2644 BFD_JUMP_TABLE_CORE (xcoff64),
2645
2646 /* Archive */
2647 xcoff64_slurp_armap,
2648 _bfd_noarchive_slurp_extended_name_table,
2649 _bfd_noarchive_construct_extended_name_table,
2650 bfd_dont_truncate_arname,
2651 _bfd_xcoff_write_armap,
2652 _bfd_xcoff_read_ar_hdr,
2653 _bfd_generic_write_ar_hdr,
2654 xcoff64_openr_next_archived_file,
2655 _bfd_generic_get_elt_at_index,
2656 _bfd_xcoff_stat_arch_elt,
2657 _bfd_bool_bfd_true,
2658
2659 /* Symbols */
2660 coff_get_symtab_upper_bound,
2661 coff_canonicalize_symtab,
2662 coff_make_empty_symbol,
2663 coff_print_symbol,
2664 coff_get_symbol_info,
2665 coff_get_symbol_version_string,
2666 _bfd_xcoff_is_local_label_name,
2667 coff_bfd_is_target_special_symbol,
2668 coff_get_lineno,
2669 coff_find_nearest_line,
2670 coff_find_line,
2671 coff_find_inliner_info,
2672 coff_bfd_make_debug_symbol,
2673 _bfd_generic_read_minisymbols,
2674 _bfd_generic_minisymbol_to_symbol,
2675
2676 /* Reloc */
2677 coff_get_reloc_upper_bound,
2678 coff_canonicalize_reloc,
2679 _bfd_generic_set_reloc,
2680 xcoff64_reloc_type_lookup,
2681 xcoff64_reloc_name_lookup,
2682
2683 /* Write */
2684 coff_set_arch_mach,
2685 coff_set_section_contents,
2686
2687 /* Link */
2688 xcoff64_sizeof_headers,
2689 bfd_generic_get_relocated_section_contents,
2690 bfd_generic_relax_section,
2691 _bfd_xcoff_bfd_link_hash_table_create,
2692 _bfd_xcoff_bfd_link_add_symbols,
2693 _bfd_generic_link_just_syms,
2694 _bfd_generic_copy_link_hash_symbol_type,
2695 _bfd_xcoff_bfd_final_link,
2696 _bfd_generic_link_split_section,
2697 _bfd_generic_link_check_relocs,
2698 bfd_generic_gc_sections,
2699 bfd_generic_lookup_section_flags,
2700 bfd_generic_merge_sections,
2701 bfd_generic_is_group_section,
2702 bfd_generic_group_name,
2703 bfd_generic_discard_group,
2704 _bfd_generic_section_already_linked,
2705 _bfd_xcoff_define_common_symbol,
2706 _bfd_generic_link_hide_symbol,
2707 bfd_generic_define_start_stop,
2708
2709 /* Dynamic */
2710 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2711 _bfd_xcoff_canonicalize_dynamic_symtab,
2712 _bfd_nodynamic_get_synthetic_symtab,
2713 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2714 _bfd_xcoff_canonicalize_dynamic_reloc,
2715
2716 /* Opposite endian version, none exists. */
2717 NULL,
2718
2719 & bfd_xcoff_aix5_backend_data,
2720 };