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