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