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