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