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