1/* BFD back-end for IBM RS/6000 "XCOFF" files.
2   Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3   Free Software Foundation, Inc.
4   FIXME: Can someone provide a transliteration of this name into ASCII?
5   Using the following chars caused a compiler warning on HIUX (so I replaced
6   them with octal escapes), and isn't useful without an understanding of what
7   character set it is.
8   Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
9     and John Gilmore.
10   Archive support from Damon A. Permezel.
11   Contributed by IBM Corporation and Cygnus Support.
12
13This file is part of BFD, the Binary File Descriptor library.
14
15This program is free software; you can redistribute it and/or modify
16it under the terms of the GNU General Public License as published by
17the Free Software Foundation; either version 2 of the License, or
18(at your option) any later version.
19
20This program is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23GNU General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, write to the Free Software
27Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
28
29#include "bfd.h"
30#include "sysdep.h"
31#include "bfdlink.h"
32#include "libbfd.h"
33#include "coff/internal.h"
34#include "coff/xcoff.h"
35#include "coff/rs6000.h"
36#include "libcoff.h"
37#include "libxcoff.h"
38
39extern bfd_boolean _bfd_xcoff_mkobject
40  PARAMS ((bfd *));
41extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
42  PARAMS ((bfd *, bfd *));
43extern bfd_boolean _bfd_xcoff_is_local_label_name
44  PARAMS ((bfd *, const char *));
45extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
46  PARAMS ((bfd *, bfd_reloc_code_real_type));
47extern bfd_boolean _bfd_xcoff_slurp_armap
48  PARAMS ((bfd *));
49extern const bfd_target *_bfd_xcoff_archive_p
50  PARAMS ((bfd *));
51extern PTR _bfd_xcoff_read_ar_hdr
52  PARAMS ((bfd *));
53extern bfd *_bfd_xcoff_openr_next_archived_file
54  PARAMS ((bfd *, bfd *));
55extern int _bfd_xcoff_stat_arch_elt
56  PARAMS ((bfd *, struct stat *));
57extern bfd_boolean _bfd_xcoff_write_armap
58  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
59extern bfd_boolean _bfd_xcoff_write_archive_contents
60  PARAMS ((bfd *));
61extern int _bfd_xcoff_sizeof_headers
62  PARAMS ((bfd *, bfd_boolean));
63extern void _bfd_xcoff_swap_sym_in
64  PARAMS ((bfd *, PTR, PTR));
65extern unsigned int _bfd_xcoff_swap_sym_out
66  PARAMS ((bfd *, PTR, PTR));
67extern void _bfd_xcoff_swap_aux_in
68  PARAMS ((bfd *, PTR, int, int, int, int, PTR));
69extern unsigned int _bfd_xcoff_swap_aux_out
70  PARAMS ((bfd *, PTR, int, int, int, int, PTR));
71static void xcoff_swap_reloc_in
72  PARAMS ((bfd *, PTR, PTR));
73static unsigned int xcoff_swap_reloc_out
74  PARAMS ((bfd *, PTR, PTR));
75
76/* Forward declare xcoff_rtype2howto for coffcode.h macro.  */
77void xcoff_rtype2howto
78  PARAMS ((arelent *, struct internal_reloc *));
79
80/* coffcode.h needs these to be defined.  */
81#define RS6000COFF_C 1
82
83#define SELECT_RELOC(internal, howto)					\
84  {									\
85    internal.r_type = howto->type;					\
86    internal.r_size =							\
87      ((howto->complain_on_overflow == complain_overflow_signed		\
88	? 0x80								\
89	: 0)								\
90       | (howto->bitsize - 1));						\
91  }
92
93#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
94#define COFF_LONG_FILENAMES
95#define NO_COFF_SYMBOLS
96#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
97#define coff_mkobject _bfd_xcoff_mkobject
98#define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
99#define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
100#define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
101#ifdef AIX_CORE
102extern const bfd_target * rs6000coff_core_p
103  PARAMS ((bfd *abfd));
104extern bfd_boolean rs6000coff_core_file_matches_executable_p
105  PARAMS ((bfd *cbfd, bfd *ebfd));
106extern char *rs6000coff_core_file_failing_command
107  PARAMS ((bfd *abfd));
108extern int rs6000coff_core_file_failing_signal
109  PARAMS ((bfd *abfd));
110#define CORE_FILE_P rs6000coff_core_p
111#define coff_core_file_failing_command \
112  rs6000coff_core_file_failing_command
113#define coff_core_file_failing_signal \
114  rs6000coff_core_file_failing_signal
115#define coff_core_file_matches_executable_p \
116  rs6000coff_core_file_matches_executable_p
117#else
118#define CORE_FILE_P _bfd_dummy_target
119#define coff_core_file_failing_command \
120  _bfd_nocore_core_file_failing_command
121#define coff_core_file_failing_signal \
122  _bfd_nocore_core_file_failing_signal
123#define coff_core_file_matches_executable_p \
124  _bfd_nocore_core_file_matches_executable_p
125#endif
126#define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
127#define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
128#define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
129#define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
130#define coff_swap_reloc_in xcoff_swap_reloc_in
131#define coff_swap_reloc_out xcoff_swap_reloc_out
132#define NO_COFF_RELOCS
133
134#include "coffcode.h"
135
136/* The main body of code is in coffcode.h.  */
137
138static const char *normalize_filename
139  PARAMS ((bfd *));
140static bfd_boolean xcoff_write_armap_old
141  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
142static bfd_boolean xcoff_write_armap_big
143  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
144static bfd_boolean xcoff_write_archive_contents_old
145  PARAMS ((bfd *));
146static bfd_boolean xcoff_write_archive_contents_big
147  PARAMS ((bfd *));
148static void xcoff_swap_ldhdr_in
149  PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
150static void xcoff_swap_ldhdr_out
151  PARAMS ((bfd *, const struct internal_ldhdr *, PTR));
152static void xcoff_swap_ldsym_in
153  PARAMS ((bfd *, const PTR, struct internal_ldsym *));
154static void xcoff_swap_ldsym_out
155  PARAMS ((bfd *, const struct internal_ldsym *, PTR));
156static void xcoff_swap_ldrel_in
157  PARAMS ((bfd *, const PTR, struct internal_ldrel *));
158static void xcoff_swap_ldrel_out
159  PARAMS ((bfd *, const struct internal_ldrel *, PTR));
160static bfd_boolean xcoff_ppc_relocate_section
161  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
162	   struct internal_reloc *, struct internal_syment *, asection **));
163static bfd_boolean _bfd_xcoff_put_ldsymbol_name
164  PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
165	   const char *));
166static asection *xcoff_create_csect_from_smclas
167  PARAMS ((bfd *, union internal_auxent *, const char *));
168static bfd_boolean xcoff_is_lineno_count_overflow
169  PARAMS ((bfd *, bfd_vma));
170static bfd_boolean xcoff_is_reloc_count_overflow
171  PARAMS ((bfd *, bfd_vma));
172static bfd_vma xcoff_loader_symbol_offset
173  PARAMS ((bfd *, struct internal_ldhdr *));
174static bfd_vma xcoff_loader_reloc_offset
175  PARAMS ((bfd *, struct internal_ldhdr *));
176static bfd_boolean xcoff_generate_rtinit
177  PARAMS ((bfd *, const char *, const char *, bfd_boolean));
178static bfd_boolean do_pad
179  PARAMS ((bfd *, unsigned int));
180static bfd_boolean do_copy
181  PARAMS ((bfd *, bfd *));
182static bfd_boolean do_shared_object_padding
183  PARAMS ((bfd *, bfd *, file_ptr *, int));
184
185/* Relocation functions */
186static bfd_boolean xcoff_reloc_type_br
187  PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
188
189static bfd_boolean xcoff_complain_overflow_dont_func
190  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
191static bfd_boolean xcoff_complain_overflow_bitfield_func
192  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
193static bfd_boolean xcoff_complain_overflow_signed_func
194  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
195static bfd_boolean xcoff_complain_overflow_unsigned_func
196  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
197
198bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
199  PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
200{
201  xcoff_reloc_type_pos,	 /* R_POS   (0x00) */
202  xcoff_reloc_type_neg,	 /* R_NEG   (0x01) */
203  xcoff_reloc_type_rel,	 /* R_REL   (0x02) */
204  xcoff_reloc_type_toc,	 /* R_TOC   (0x03) */
205  xcoff_reloc_type_fail, /* R_RTB   (0x04) */
206  xcoff_reloc_type_toc,	 /* R_GL    (0x05) */
207  xcoff_reloc_type_toc,	 /* R_TCL   (0x06) */
208  xcoff_reloc_type_fail, /*	    (0x07) */
209  xcoff_reloc_type_ba,	 /* R_BA    (0x08) */
210  xcoff_reloc_type_fail, /*	    (0x09) */
211  xcoff_reloc_type_br,	 /* R_BR    (0x0a) */
212  xcoff_reloc_type_fail, /*	    (0x0b) */
213  xcoff_reloc_type_pos,	 /* R_RL    (0x0c) */
214  xcoff_reloc_type_pos,	 /* R_RLA   (0x0d) */
215  xcoff_reloc_type_fail, /*	    (0x0e) */
216  xcoff_reloc_type_noop, /* R_REF   (0x0f) */
217  xcoff_reloc_type_fail, /*	    (0x10) */
218  xcoff_reloc_type_fail, /*	    (0x11) */
219  xcoff_reloc_type_toc,	 /* R_TRL   (0x12) */
220  xcoff_reloc_type_toc,	 /* R_TRLA  (0x13) */
221  xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
222  xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
223  xcoff_reloc_type_ba,	 /* R_CAI   (0x16) */
224  xcoff_reloc_type_crel, /* R_CREL  (0x17) */
225  xcoff_reloc_type_ba,	 /* R_RBA   (0x18) */
226  xcoff_reloc_type_ba,	 /* R_RBAC  (0x19) */
227  xcoff_reloc_type_br,	 /* R_RBR   (0x1a) */
228  xcoff_reloc_type_ba,	 /* R_RBRC  (0x1b) */
229};
230
231bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
232  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS)) =
233{
234  xcoff_complain_overflow_dont_func,
235  xcoff_complain_overflow_bitfield_func,
236  xcoff_complain_overflow_signed_func,
237  xcoff_complain_overflow_unsigned_func,
238};
239
240/* We use our own tdata type.  Its first field is the COFF tdata type,
241   so the COFF routines are compatible.  */
242
243bfd_boolean
244_bfd_xcoff_mkobject (abfd)
245     bfd *abfd;
246{
247  coff_data_type *coff;
248  bfd_size_type amt = sizeof (struct xcoff_tdata);
249
250  abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
251  if (abfd->tdata.xcoff_obj_data == NULL)
252    return FALSE;
253  coff = coff_data (abfd);
254  coff->symbols = (coff_symbol_type *) NULL;
255  coff->conversion_table = (unsigned int *) NULL;
256  coff->raw_syments = (struct coff_ptr_struct *) NULL;
257  coff->relocbase = 0;
258
259  xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
260
261  /* We set cputype to -1 to indicate that it has not been
262     initialized.  */
263  xcoff_data (abfd)->cputype = -1;
264
265  xcoff_data (abfd)->csects = NULL;
266  xcoff_data (abfd)->debug_indices = NULL;
267
268  /* text section alignment is different than the default */
269  bfd_xcoff_text_align_power (abfd) = 2;
270
271  return TRUE;
272}
273
274/* Copy XCOFF data from one BFD to another.  */
275
276bfd_boolean
277_bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
278     bfd *ibfd;
279     bfd *obfd;
280{
281  struct xcoff_tdata *ix, *ox;
282  asection *sec;
283
284  if (ibfd->xvec != obfd->xvec)
285    return TRUE;
286  ix = xcoff_data (ibfd);
287  ox = xcoff_data (obfd);
288  ox->full_aouthdr = ix->full_aouthdr;
289  ox->toc = ix->toc;
290  if (ix->sntoc == 0)
291    ox->sntoc = 0;
292  else
293    {
294      sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
295      if (sec == NULL)
296	ox->sntoc = 0;
297      else
298	ox->sntoc = sec->output_section->target_index;
299    }
300  if (ix->snentry == 0)
301    ox->snentry = 0;
302  else
303    {
304      sec = coff_section_from_bfd_index (ibfd, ix->snentry);
305      if (sec == NULL)
306	ox->snentry = 0;
307      else
308	ox->snentry = sec->output_section->target_index;
309    }
310  bfd_xcoff_text_align_power (obfd) = bfd_xcoff_text_align_power (ibfd);
311  bfd_xcoff_data_align_power (obfd) = bfd_xcoff_data_align_power (ibfd);
312  ox->modtype = ix->modtype;
313  ox->cputype = ix->cputype;
314  ox->maxdata = ix->maxdata;
315  ox->maxstack = ix->maxstack;
316  return TRUE;
317}
318
319/* I don't think XCOFF really has a notion of local labels based on
320   name.  This will mean that ld -X doesn't actually strip anything.
321   The AIX native linker does not have a -X option, and it ignores the
322   -x option.  */
323
324bfd_boolean
325_bfd_xcoff_is_local_label_name (abfd, name)
326     bfd *abfd ATTRIBUTE_UNUSED;
327     const char *name ATTRIBUTE_UNUSED;
328{
329  return FALSE;
330}
331
332void
333_bfd_xcoff_swap_sym_in (abfd, ext1, in1)
334     bfd *abfd;
335     PTR ext1;
336     PTR in1;
337{
338  SYMENT *ext = (SYMENT *)ext1;
339  struct internal_syment * in = (struct internal_syment *)in1;
340
341  if (ext->e.e_name[0] != 0)
342    {
343      memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
344    }
345  else
346    {
347      in->_n._n_n._n_zeroes = 0;
348      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
349    }
350
351  in->n_value = H_GET_32 (abfd, ext->e_value);
352  in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
353  in->n_type = H_GET_16 (abfd, ext->e_type);
354  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
355  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
356}
357
358unsigned int
359_bfd_xcoff_swap_sym_out (abfd, inp, extp)
360     bfd *abfd;
361     PTR inp;
362     PTR extp;
363{
364  struct internal_syment *in = (struct internal_syment *)inp;
365  SYMENT *ext =(SYMENT *)extp;
366
367  if (in->_n._n_name[0] != 0)
368    {
369      memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
370    }
371  else
372    {
373      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
374      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
375    }
376
377  H_PUT_32 (abfd, in->n_value, ext->e_value);
378  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
379  H_PUT_16 (abfd, in->n_type, ext->e_type);
380  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
381  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
382  return bfd_coff_symesz (abfd);
383}
384
385void
386_bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
387     bfd *abfd;
388     PTR ext1;
389     int type;
390     int class;
391     int indx;
392     int numaux;
393     PTR in1;
394{
395  AUXENT * ext = (AUXENT *)ext1;
396  union internal_auxent *in = (union internal_auxent *)in1;
397
398  switch (class)
399    {
400    case C_FILE:
401      if (ext->x_file.x_fname[0] == 0)
402	{
403	  in->x_file.x_n.x_zeroes = 0;
404	  in->x_file.x_n.x_offset =
405	    H_GET_32 (abfd, ext->x_file.x_n.x_offset);
406	}
407      else
408	{
409	  if (numaux > 1)
410	    {
411	      if (indx == 0)
412		memcpy (in->x_file.x_fname, ext->x_file.x_fname,
413			numaux * sizeof (AUXENT));
414	    }
415	  else
416	    {
417	      memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
418	    }
419	}
420      goto end;
421
422      /* RS/6000 "csect" auxents */
423    case C_EXT:
424    case C_HIDEXT:
425      if (indx + 1 == numaux)
426	{
427	  in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
428	  in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
429	  in->x_csect.x_snhash   = H_GET_16 (abfd, ext->x_csect.x_snhash);
430	  /* We don't have to hack bitfields in x_smtyp because it's
431	     defined by shifts-and-ands, which are equivalent on all
432	     byte orders.  */
433	  in->x_csect.x_smtyp    = H_GET_8 (abfd, ext->x_csect.x_smtyp);
434	  in->x_csect.x_smclas   = H_GET_8 (abfd, ext->x_csect.x_smclas);
435	  in->x_csect.x_stab     = H_GET_32 (abfd, ext->x_csect.x_stab);
436	  in->x_csect.x_snstab   = H_GET_16 (abfd, ext->x_csect.x_snstab);
437	  goto end;
438	}
439      break;
440
441    case C_STAT:
442    case C_LEAFSTAT:
443    case C_HIDDEN:
444      if (type == T_NULL)
445	{
446	  in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
447	  in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
448	  in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
449	  /* PE defines some extra fields; we zero them out for
450	     safety.  */
451	  in->x_scn.x_checksum = 0;
452	  in->x_scn.x_associated = 0;
453	  in->x_scn.x_comdat = 0;
454
455	  goto end;
456	}
457      break;
458    }
459
460  in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
461  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
462
463  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
464    {
465      in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
466	H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
467      in->x_sym.x_fcnary.x_fcn.x_endndx.l =
468	H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
469    }
470  else
471    {
472      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
473	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
474      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
475	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
476      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
477	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
478      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
479	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
480    }
481
482  if (ISFCN (type))
483    {
484      in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
485    }
486  else
487    {
488      in->x_sym.x_misc.x_lnsz.x_lnno =
489	H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
490      in->x_sym.x_misc.x_lnsz.x_size =
491	H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
492    }
493
494 end: ;
495  /* The semicolon is because MSVC doesn't like labels at
496     end of block.  */
497}
498
499
500unsigned int _bfd_xcoff_swap_aux_out
501  PARAMS ((bfd *, PTR, int, int, int, int, PTR));
502
503unsigned int
504_bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
505     bfd * abfd;
506     PTR   inp;
507     int   type;
508     int   class;
509     int   indx ATTRIBUTE_UNUSED;
510     int   numaux ATTRIBUTE_UNUSED;
511     PTR   extp;
512{
513  union internal_auxent *in = (union internal_auxent *)inp;
514  AUXENT *ext = (AUXENT *)extp;
515
516  memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
517  switch (class)
518    {
519    case C_FILE:
520      if (in->x_file.x_fname[0] == 0)
521	{
522	  H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
523	  H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
524	}
525      else
526	{
527	  memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
528	}
529      goto end;
530
531      /* RS/6000 "csect" auxents */
532    case C_EXT:
533    case C_HIDEXT:
534      if (indx + 1 == numaux)
535	{
536	  H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
537	  H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
538	  H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
539	  /* We don't have to hack bitfields in x_smtyp because it's
540	     defined by shifts-and-ands, which are equivalent on all
541	     byte orders.  */
542	  H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
543	  H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
544	  H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
545	  H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
546	  goto end;
547	}
548      break;
549
550    case C_STAT:
551    case C_LEAFSTAT:
552    case C_HIDDEN:
553      if (type == T_NULL)
554	{
555	  H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
556	  H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
557	  H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
558	  goto end;
559	}
560      break;
561    }
562
563  H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
564  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
565
566  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
567    {
568      H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
569		ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
570      H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
571		ext->x_sym.x_fcnary.x_fcn.x_endndx);
572    }
573  else
574    {
575      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
576		ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
577      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
578		ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
579      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
580		ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
581      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
582		ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
583    }
584
585  if (ISFCN (type))
586    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
587  else
588    {
589      H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
590		ext->x_sym.x_misc.x_lnsz.x_lnno);
591      H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
592		ext->x_sym.x_misc.x_lnsz.x_size);
593    }
594
595end:
596  return bfd_coff_auxesz (abfd);
597}
598
599
600
601/* The XCOFF reloc table.  Actually, XCOFF relocations specify the
602   bitsize and whether they are signed or not, along with a
603   conventional type.  This table is for the types, which are used for
604   different algorithms for putting in the reloc.  Many of these
605   relocs need special_function entries, which I have not written.  */
606
607
608reloc_howto_type xcoff_howto_table[] =
609{
610  /* Standard 32 bit relocation.  */
611  HOWTO (R_POS,			/* type */
612	 0,			/* rightshift */
613	 2,			/* size (0 = byte, 1 = short, 2 = long) */
614	 32,			/* bitsize */
615	 FALSE,			/* pc_relative */
616	 0,			/* bitpos */
617	 complain_overflow_bitfield, /* complain_on_overflow */
618	 0,			/* special_function */
619	 "R_POS",		/* name */
620	 TRUE,			/* partial_inplace */
621	 0xffffffff,		/* src_mask */
622	 0xffffffff,		/* dst_mask */
623	 FALSE),		/* pcrel_offset */
624
625  /* 32 bit relocation, but store negative value.  */
626  HOWTO (R_NEG,			/* type */
627	 0,			/* rightshift */
628	 -2,			/* size (0 = byte, 1 = short, 2 = long) */
629	 32,			/* bitsize */
630	 FALSE,			/* pc_relative */
631	 0,			/* bitpos */
632	 complain_overflow_bitfield, /* complain_on_overflow */
633	 0,			/* special_function */
634	 "R_NEG",		/* name */
635	 TRUE,			/* partial_inplace */
636	 0xffffffff,		/* src_mask */
637	 0xffffffff,		/* dst_mask */
638	 FALSE),		/* pcrel_offset */
639
640  /* 32 bit PC relative relocation.  */
641  HOWTO (R_REL,			/* type */
642	 0,			/* rightshift */
643	 2,			/* size (0 = byte, 1 = short, 2 = long) */
644	 32,			/* bitsize */
645	 TRUE,			/* pc_relative */
646	 0,			/* bitpos */
647	 complain_overflow_signed, /* complain_on_overflow */
648	 0,			/* special_function */
649	 "R_REL",		/* name */
650	 TRUE,			/* partial_inplace */
651	 0xffffffff,		/* src_mask */
652	 0xffffffff,		/* dst_mask */
653	 FALSE),		/* pcrel_offset */
654
655  /* 16 bit TOC relative relocation.  */
656  HOWTO (R_TOC,			/* type */
657	 0,			/* rightshift */
658	 1,			/* size (0 = byte, 1 = short, 2 = long) */
659	 16,			/* bitsize */
660	 FALSE,			/* pc_relative */
661	 0,			/* bitpos */
662	 complain_overflow_bitfield, /* complain_on_overflow */
663	 0,			/* special_function */
664	 "R_TOC",		/* name */
665	 TRUE,			/* partial_inplace */
666	 0xffff,		/* src_mask */
667	 0xffff,		/* dst_mask */
668	 FALSE),		/* pcrel_offset */
669
670  /* I don't really know what this is.  */
671  HOWTO (R_RTB,			/* type */
672	 1,			/* rightshift */
673	 2,			/* size (0 = byte, 1 = short, 2 = long) */
674	 32,			/* bitsize */
675	 FALSE,			/* pc_relative */
676	 0,			/* bitpos */
677	 complain_overflow_bitfield, /* complain_on_overflow */
678	 0,			/* special_function */
679	 "R_RTB",		/* name */
680	 TRUE,			/* partial_inplace */
681	 0xffffffff,		/* src_mask */
682	 0xffffffff,		/* dst_mask */
683	 FALSE),		/* pcrel_offset */
684
685  /* External TOC relative symbol.  */
686  HOWTO (R_GL,			/* type */
687	 0,			/* rightshift */
688	 1,			/* size (0 = byte, 1 = short, 2 = long) */
689	 16,			/* bitsize */
690	 FALSE,			/* pc_relative */
691	 0,			/* bitpos */
692	 complain_overflow_bitfield, /* complain_on_overflow */
693	 0,			/* special_function */
694	 "R_GL",		/* name */
695	 TRUE,			/* partial_inplace */
696	 0xffff,		/* src_mask */
697	 0xffff,		/* dst_mask */
698	 FALSE),		/* pcrel_offset */
699
700  /* Local TOC relative symbol.	 */
701  HOWTO (R_TCL,			/* type */
702	 0,			/* rightshift */
703	 1,			/* size (0 = byte, 1 = short, 2 = long) */
704	 16,			/* bitsize */
705	 FALSE,			/* pc_relative */
706	 0,			/* bitpos */
707	 complain_overflow_bitfield, /* complain_on_overflow */
708	 0,			/* special_function */
709	 "R_TCL",		/* name */
710	 TRUE,			/* partial_inplace */
711	 0xffff,		/* src_mask */
712	 0xffff,		/* dst_mask */
713	 FALSE),		/* pcrel_offset */
714
715  EMPTY_HOWTO (7),
716
717  /* Non modifiable absolute branch.  */
718  HOWTO (R_BA,			/* type */
719	 0,			/* rightshift */
720	 2,			/* size (0 = byte, 1 = short, 2 = long) */
721	 26,			/* bitsize */
722	 FALSE,			/* pc_relative */
723	 0,			/* bitpos */
724	 complain_overflow_bitfield, /* complain_on_overflow */
725	 0,			/* special_function */
726	 "R_BA_26",		/* name */
727	 TRUE,			/* partial_inplace */
728	 0x03fffffc,		/* src_mask */
729	 0x03fffffc,		/* dst_mask */
730	 FALSE),		/* pcrel_offset */
731
732  EMPTY_HOWTO (9),
733
734  /* Non modifiable relative branch.  */
735  HOWTO (R_BR,			/* type */
736	 0,			/* rightshift */
737	 2,			/* size (0 = byte, 1 = short, 2 = long) */
738	 26,			/* bitsize */
739	 TRUE,			/* pc_relative */
740	 0,			/* bitpos */
741	 complain_overflow_signed, /* complain_on_overflow */
742	 0,			/* special_function */
743	 "R_BR",		/* name */
744	 TRUE,			/* partial_inplace */
745	 0x03fffffc,		/* src_mask */
746	 0x03fffffc,		/* dst_mask */
747	 FALSE),		/* pcrel_offset */
748
749  EMPTY_HOWTO (0xb),
750
751  /* Indirect load.  */
752  HOWTO (R_RL,			/* type */
753	 0,			/* rightshift */
754	 1,			/* size (0 = byte, 1 = short, 2 = long) */
755	 16,			/* bitsize */
756	 FALSE,			/* pc_relative */
757	 0,			/* bitpos */
758	 complain_overflow_bitfield, /* complain_on_overflow */
759	 0,			/* special_function */
760	 "R_RL",		/* name */
761	 TRUE,			/* partial_inplace */
762	 0xffff,		/* src_mask */
763	 0xffff,		/* dst_mask */
764	 FALSE),		/* pcrel_offset */
765
766  /* Load address.  */
767  HOWTO (R_RLA,			/* type */
768	 0,			/* rightshift */
769	 1,			/* size (0 = byte, 1 = short, 2 = long) */
770	 16,			/* bitsize */
771	 FALSE,			/* pc_relative */
772	 0,			/* bitpos */
773	 complain_overflow_bitfield, /* complain_on_overflow */
774	 0,			/* special_function */
775	 "R_RLA",		/* name */
776	 TRUE,			/* partial_inplace */
777	 0xffff,		/* src_mask */
778	 0xffff,		/* dst_mask */
779	 FALSE),		/* pcrel_offset */
780
781  EMPTY_HOWTO (0xe),
782
783  /* Non-relocating reference.  */
784  HOWTO (R_REF,			/* type */
785	 0,			/* rightshift */
786	 2,			/* size (0 = byte, 1 = short, 2 = long) */
787	 32,			/* bitsize */
788	 FALSE,			/* pc_relative */
789	 0,			/* bitpos */
790	 complain_overflow_dont, /* complain_on_overflow */
791	 0,			/* special_function */
792	 "R_REF",		/* name */
793	 FALSE,			/* partial_inplace */
794	 0,			/* src_mask */
795	 0,			/* dst_mask */
796	 FALSE),		/* pcrel_offset */
797
798  EMPTY_HOWTO (0x10),
799  EMPTY_HOWTO (0x11),
800
801  /* TOC relative indirect load.  */
802  HOWTO (R_TRL,			/* type */
803	 0,			/* rightshift */
804	 1,			/* size (0 = byte, 1 = short, 2 = long) */
805	 16,			/* bitsize */
806	 FALSE,			/* pc_relative */
807	 0,			/* bitpos */
808	 complain_overflow_bitfield, /* complain_on_overflow */
809	 0,			/* special_function */
810	 "R_TRL",		/* name */
811	 TRUE,			/* partial_inplace */
812	 0xffff,		/* src_mask */
813	 0xffff,		/* dst_mask */
814	 FALSE),		/* pcrel_offset */
815
816  /* TOC relative load address.  */
817  HOWTO (R_TRLA,		/* type */
818	 0,			/* rightshift */
819	 1,			/* size (0 = byte, 1 = short, 2 = long) */
820	 16,			/* bitsize */
821	 FALSE,			/* pc_relative */
822	 0,			/* bitpos */
823	 complain_overflow_bitfield, /* complain_on_overflow */
824	 0,			/* special_function */
825	 "R_TRLA",		/* name */
826	 TRUE,			/* partial_inplace */
827	 0xffff,		/* src_mask */
828	 0xffff,		/* dst_mask */
829	 FALSE),		/* pcrel_offset */
830
831  /* Modifiable relative branch.  */
832  HOWTO (R_RRTBI,		 /* type */
833	 1,			/* rightshift */
834	 2,			/* size (0 = byte, 1 = short, 2 = long) */
835	 32,			/* bitsize */
836	 FALSE,			/* pc_relative */
837	 0,			/* bitpos */
838	 complain_overflow_bitfield, /* complain_on_overflow */
839	 0,			/* special_function */
840	 "R_RRTBI",		/* name */
841	 TRUE,			/* partial_inplace */
842	 0xffffffff,		/* src_mask */
843	 0xffffffff,		/* dst_mask */
844	 FALSE),		/* pcrel_offset */
845
846  /* Modifiable absolute branch.  */
847  HOWTO (R_RRTBA,		 /* type */
848	 1,			/* rightshift */
849	 2,			/* size (0 = byte, 1 = short, 2 = long) */
850	 32,			/* bitsize */
851	 FALSE,			/* pc_relative */
852	 0,			/* bitpos */
853	 complain_overflow_bitfield, /* complain_on_overflow */
854	 0,			/* special_function */
855	 "R_RRTBA",		/* name */
856	 TRUE,			/* partial_inplace */
857	 0xffffffff,		/* src_mask */
858	 0xffffffff,		/* dst_mask */
859	 FALSE),		/* pcrel_offset */
860
861  /* Modifiable call absolute indirect.  */
862  HOWTO (R_CAI,			/* type */
863	 0,			/* rightshift */
864	 1,			/* size (0 = byte, 1 = short, 2 = long) */
865	 16,			/* bitsize */
866	 FALSE,			/* pc_relative */
867	 0,			/* bitpos */
868	 complain_overflow_bitfield, /* complain_on_overflow */
869	 0,			/* special_function */
870	 "R_CAI",		/* name */
871	 TRUE,			/* partial_inplace */
872	 0xffff,		/* src_mask */
873	 0xffff,		/* dst_mask */
874	 FALSE),		/* pcrel_offset */
875
876  /* Modifiable call relative.  */
877  HOWTO (R_CREL,		/* type */
878	 0,			/* rightshift */
879	 1,			/* size (0 = byte, 1 = short, 2 = long) */
880	 16,			/* bitsize */
881	 FALSE,			/* pc_relative */
882	 0,			/* bitpos */
883	 complain_overflow_bitfield, /* complain_on_overflow */
884	 0,			/* special_function */
885	 "R_CREL",		/* name */
886	 TRUE,			/* partial_inplace */
887	 0xffff,		/* src_mask */
888	 0xffff,		/* dst_mask */
889	 FALSE),		/* pcrel_offset */
890
891  /* Modifiable branch absolute.  */
892  HOWTO (R_RBA,			/* type */
893	 0,			/* rightshift */
894	 2,			/* size (0 = byte, 1 = short, 2 = long) */
895	 26,			/* bitsize */
896	 FALSE,			/* pc_relative */
897	 0,			/* bitpos */
898	 complain_overflow_bitfield, /* complain_on_overflow */
899	 0,			/* special_function */
900	 "R_RBA",		/* name */
901	 TRUE,			/* partial_inplace */
902	 0x03fffffc,		/* src_mask */
903	 0x03fffffc,		/* dst_mask */
904	 FALSE),		/* pcrel_offset */
905
906  /* Modifiable branch absolute.  */
907  HOWTO (R_RBAC,		/* type */
908	 0,			/* rightshift */
909	 2,			/* size (0 = byte, 1 = short, 2 = long) */
910	 32,			/* bitsize */
911	 FALSE,			/* pc_relative */
912	 0,			/* bitpos */
913	 complain_overflow_bitfield, /* complain_on_overflow */
914	 0,			/* special_function */
915	 "R_RBAC",		/* name */
916	 TRUE,			/* partial_inplace */
917	 0xffffffff,		/* src_mask */
918	 0xffffffff,		/* dst_mask */
919	 FALSE),		/* pcrel_offset */
920
921  /* Modifiable branch relative.  */
922  HOWTO (R_RBR,			/* type */
923	 0,			/* rightshift */
924	 2,			/* size (0 = byte, 1 = short, 2 = long) */
925	 26,			/* bitsize */
926	 FALSE,			/* pc_relative */
927	 0,			/* bitpos */
928	 complain_overflow_signed, /* complain_on_overflow */
929	 0,			/* special_function */
930	 "R_RBR_26",		/* name */
931	 TRUE,			/* partial_inplace */
932	 0x03fffffc,		/* src_mask */
933	 0x03fffffc,		/* dst_mask */
934	 FALSE),		/* pcrel_offset */
935
936  /* Modifiable branch absolute.  */
937  HOWTO (R_RBRC,		/* type */
938	 0,			/* rightshift */
939	 1,			/* size (0 = byte, 1 = short, 2 = long) */
940	 16,			/* bitsize */
941	 FALSE,			/* pc_relative */
942	 0,			/* bitpos */
943	 complain_overflow_bitfield, /* complain_on_overflow */
944	 0,			/* special_function */
945	 "R_RBRC",		/* name */
946	 TRUE,			/* partial_inplace */
947	 0xffff,		/* src_mask */
948	 0xffff,		/* dst_mask */
949	 FALSE),		/* pcrel_offset */
950
951  /* 16 bit Non modifiable absolute branch.  */
952  HOWTO (R_BA,			/* type */
953	 0,			/* rightshift */
954	 1,			/* size (0 = byte, 1 = short, 2 = long) */
955	 16,			/* bitsize */
956	 FALSE,			/* pc_relative */
957	 0,			/* bitpos */
958	 complain_overflow_bitfield, /* complain_on_overflow */
959	 0,			/* special_function */
960	 "R_BA_16",		/* name */
961	 TRUE,			/* partial_inplace */
962	 0xfffc,		/* src_mask */
963	 0xfffc,		/* dst_mask */
964	 FALSE),		/* pcrel_offset */
965
966  /* Modifiable branch relative.  */
967  HOWTO (R_RBR,			/* type */
968	 0,			/* rightshift */
969	 1,			/* size (0 = byte, 1 = short, 2 = long) */
970	 16,			/* bitsize */
971	 FALSE,			/* pc_relative */
972	 0,			/* bitpos */
973	 complain_overflow_signed, /* complain_on_overflow */
974	 0,			/* special_function */
975	 "R_RBR_16",		/* name */
976	 TRUE,			/* partial_inplace */
977	 0xffff,		/* src_mask */
978	 0xffff,		/* dst_mask */
979	 FALSE),		/* pcrel_offset */
980
981  /* Modifiable branch relative.  */
982  HOWTO (R_RBA,			/* type */
983	 0,			/* rightshift */
984	 1,			/* size (0 = byte, 1 = short, 2 = long) */
985	 16,			/* bitsize */
986	 FALSE,			/* pc_relative */
987	 0,			/* bitpos */
988	 complain_overflow_signed, /* complain_on_overflow */
989	 0,			/* special_function */
990	 "R_RBA_16",		/* name */
991	 TRUE,			/* partial_inplace */
992	 0xffff,		/* src_mask */
993	 0xffff,		/* dst_mask */
994	 FALSE),		/* pcrel_offset */
995
996};
997
998void
999xcoff_rtype2howto (relent, internal)
1000     arelent *relent;
1001     struct internal_reloc *internal;
1002{
1003  if (internal->r_type > R_RBRC)
1004    abort ();
1005
1006  /* Default howto layout works most of the time */
1007  relent->howto = &xcoff_howto_table[internal->r_type];
1008
1009  /* Special case some 16 bit reloc */
1010  if (15 == (internal->r_size & 0x1f))
1011    {
1012      if (R_BA == internal->r_type)
1013	relent->howto = &xcoff_howto_table[0x1c];
1014      else if (R_RBR == internal->r_type)
1015	relent->howto = &xcoff_howto_table[0x1d];
1016      else if (R_RBA == internal->r_type)
1017	relent->howto = &xcoff_howto_table[0x1e];
1018    }
1019
1020  /* The r_size field of an XCOFF reloc encodes the bitsize of the
1021     relocation, as well as indicating whether it is signed or not.
1022     Doublecheck that the relocation information gathered from the
1023     type matches this information.  The bitsize is not significant
1024     for R_REF relocs.  */
1025  if (relent->howto->dst_mask != 0
1026      && (relent->howto->bitsize
1027	  != ((unsigned int) internal->r_size & 0x1f) + 1))
1028    abort ();
1029}
1030
1031reloc_howto_type *
1032_bfd_xcoff_reloc_type_lookup (abfd, code)
1033     bfd *abfd ATTRIBUTE_UNUSED;
1034     bfd_reloc_code_real_type code;
1035{
1036  switch (code)
1037    {
1038    case BFD_RELOC_PPC_B26:
1039      return &xcoff_howto_table[0xa];
1040    case BFD_RELOC_PPC_BA16:
1041      return &xcoff_howto_table[0x1c];
1042    case BFD_RELOC_PPC_BA26:
1043      return &xcoff_howto_table[8];
1044    case BFD_RELOC_PPC_TOC16:
1045      return &xcoff_howto_table[3];
1046    case BFD_RELOC_32:
1047    case BFD_RELOC_CTOR:
1048      return &xcoff_howto_table[0];
1049    default:
1050      return NULL;
1051    }
1052}
1053
1054
1055/* XCOFF archive support.  The original version of this code was by
1056   Damon A. Permezel.  It was enhanced to permit cross support, and
1057   writing archive files, by Ian Lance Taylor, Cygnus Support.
1058
1059   XCOFF uses its own archive format.  Everything is hooked together
1060   with file offset links, so it is possible to rapidly update an
1061   archive in place.  Of course, we don't do that.  An XCOFF archive
1062   has a real file header, not just an ARMAG string.  The structure of
1063   the file header and of each archive header appear below.
1064
1065   An XCOFF archive also has a member table, which is a list of
1066   elements in the archive (you can get that by looking through the
1067   linked list, but you have to read a lot more of the file).  The
1068   member table has a normal archive header with an empty name.  It is
1069   normally (and perhaps must be) the second to last entry in the
1070   archive.  The member table data is almost printable ASCII.  It
1071   starts with a 12 character decimal string which is the number of
1072   entries in the table.  For each entry it has a 12 character decimal
1073   string which is the offset in the archive of that member.  These
1074   entries are followed by a series of null terminated strings which
1075   are the member names for each entry.
1076
1077   Finally, an XCOFF archive has a global symbol table, which is what
1078   we call the armap.  The global symbol table has a normal archive
1079   header with an empty name.  It is normally (and perhaps must be)
1080   the last entry in the archive.  The contents start with a four byte
1081   binary number which is the number of entries.  This is followed by
1082   a that many four byte binary numbers; each is the file offset of an
1083   entry in the archive.  These numbers are followed by a series of
1084   null terminated strings, which are symbol names.
1085
1086   AIX 4.3 introduced a new archive format which can handle larger
1087   files and also 32- and 64-bit objects in the same archive.  The
1088   things said above remain true except that there is now more than
1089   one global symbol table.  The one is used to index 32-bit objects,
1090   the other for 64-bit objects.
1091
1092   The new archives (recognizable by the new ARMAG string) has larger
1093   field lengths so that we cannot really share any code.  Also we have
1094   to take care that we are not generating the new form of archives
1095   on AIX 4.2 or earlier systems.  */
1096
1097/* XCOFF archives use this as a magic string.  Note that both strings
1098   have the same length.  */
1099
1100/* Set the magic for archive.  */
1101
1102bfd_boolean
1103bfd_xcoff_ar_archive_set_magic (abfd, magic)
1104     bfd *abfd ATTRIBUTE_UNUSED;
1105     char *magic ATTRIBUTE_UNUSED;
1106{
1107  /* Not supported yet.  */
1108  return FALSE;
1109 /* bfd_xcoff_archive_set_magic (abfd, magic); */
1110}
1111
1112/* Read in the armap of an XCOFF archive.  */
1113
1114bfd_boolean
1115_bfd_xcoff_slurp_armap (abfd)
1116     bfd *abfd;
1117{
1118  file_ptr off;
1119  size_t namlen;
1120  bfd_size_type sz;
1121  bfd_byte *contents, *cend;
1122  bfd_vma c, i;
1123  carsym *arsym;
1124  bfd_byte *p;
1125
1126  if (xcoff_ardata (abfd) == NULL)
1127    {
1128      bfd_has_map (abfd) = FALSE;
1129      return TRUE;
1130    }
1131
1132  if (! xcoff_big_format_p (abfd))
1133    {
1134      /* This is for the old format.  */
1135      struct xcoff_ar_hdr hdr;
1136
1137      off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
1138      if (off == 0)
1139	{
1140	  bfd_has_map (abfd) = FALSE;
1141	  return TRUE;
1142	}
1143
1144      if (bfd_seek (abfd, off, SEEK_SET) != 0)
1145	return FALSE;
1146
1147      /* The symbol table starts with a normal archive header.  */
1148      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1149	  != SIZEOF_AR_HDR)
1150	return FALSE;
1151
1152      /* Skip the name (normally empty).  */
1153      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1154      off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1155      if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1156	return FALSE;
1157
1158      sz = strtol (hdr.size, (char **) NULL, 10);
1159
1160      /* Read in the entire symbol table.  */
1161      contents = (bfd_byte *) bfd_alloc (abfd, sz);
1162      if (contents == NULL)
1163	return FALSE;
1164      if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1165	return FALSE;
1166
1167      /* The symbol table starts with a four byte count.  */
1168      c = H_GET_32 (abfd, contents);
1169
1170      if (c * 4 >= sz)
1171	{
1172	  bfd_set_error (bfd_error_bad_value);
1173	  return FALSE;
1174	}
1175
1176      bfd_ardata (abfd)->symdefs =
1177	((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1178      if (bfd_ardata (abfd)->symdefs == NULL)
1179	return FALSE;
1180
1181      /* After the count comes a list of four byte file offsets.  */
1182      for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
1183	   i < c;
1184	   ++i, ++arsym, p += 4)
1185	arsym->file_offset = H_GET_32 (abfd, p);
1186    }
1187  else
1188    {
1189      /* This is for the new format.  */
1190      struct xcoff_ar_hdr_big hdr;
1191
1192      off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
1193      if (off == 0)
1194	{
1195	  bfd_has_map (abfd) = FALSE;
1196	  return TRUE;
1197	}
1198
1199      if (bfd_seek (abfd, off, SEEK_SET) != 0)
1200	return FALSE;
1201
1202      /* The symbol table starts with a normal archive header.  */
1203      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1204	  != SIZEOF_AR_HDR_BIG)
1205	return FALSE;
1206
1207      /* Skip the name (normally empty).  */
1208      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1209      off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1210      if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1211	return FALSE;
1212
1213      /* XXX This actually has to be a call to strtoll (at least on 32-bit
1214	 machines) since the field width is 20 and there numbers with more
1215	 than 32 bits can be represented.  */
1216      sz = strtol (hdr.size, (char **) NULL, 10);
1217
1218      /* Read in the entire symbol table.  */
1219      contents = (bfd_byte *) bfd_alloc (abfd, sz);
1220      if (contents == NULL)
1221	return FALSE;
1222      if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1223	return FALSE;
1224
1225      /* The symbol table starts with an eight byte count.  */
1226      c = H_GET_64 (abfd, contents);
1227
1228      if (c * 8 >= sz)
1229	{
1230	  bfd_set_error (bfd_error_bad_value);
1231	  return FALSE;
1232	}
1233
1234      bfd_ardata (abfd)->symdefs =
1235	((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1236      if (bfd_ardata (abfd)->symdefs == NULL)
1237	return FALSE;
1238
1239      /* After the count comes a list of eight byte file offsets.  */
1240      for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1241	   i < c;
1242	   ++i, ++arsym, p += 8)
1243	arsym->file_offset = H_GET_64 (abfd, p);
1244    }
1245
1246  /* After the file offsets come null terminated symbol names.  */
1247  cend = contents + sz;
1248  for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1249       i < c;
1250       ++i, ++arsym, p += strlen ((char *) p) + 1)
1251    {
1252      if (p >= cend)
1253	{
1254	  bfd_set_error (bfd_error_bad_value);
1255	  return FALSE;
1256	}
1257      arsym->name = (char *) p;
1258    }
1259
1260  bfd_ardata (abfd)->symdef_count = c;
1261  bfd_has_map (abfd) = TRUE;
1262
1263  return TRUE;
1264}
1265
1266/* See if this is an XCOFF archive.  */
1267
1268const bfd_target *
1269_bfd_xcoff_archive_p (abfd)
1270     bfd *abfd;
1271{
1272  struct artdata *tdata_hold;
1273  char magic[SXCOFFARMAG];
1274  bfd_size_type amt = SXCOFFARMAG;
1275
1276  if (bfd_bread ((PTR) magic, amt, abfd) != amt)
1277    {
1278      if (bfd_get_error () != bfd_error_system_call)
1279	bfd_set_error (bfd_error_wrong_format);
1280      return NULL;
1281    }
1282
1283  if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
1284      && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1285    {
1286      bfd_set_error (bfd_error_wrong_format);
1287      return NULL;
1288    }
1289
1290  tdata_hold = bfd_ardata (abfd);
1291
1292  amt = sizeof (struct artdata);
1293  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
1294  if (bfd_ardata (abfd) == (struct artdata *) NULL)
1295    goto error_ret_restore;
1296
1297  /* Cleared by bfd_zalloc above.
1298     bfd_ardata (abfd)->cache = NULL;
1299     bfd_ardata (abfd)->archive_head = NULL;
1300     bfd_ardata (abfd)->symdefs = NULL;
1301     bfd_ardata (abfd)->extended_names = NULL;
1302     bfd_ardata (abfd)->extended_names_size = 0;  */
1303
1304  /* Now handle the two formats.  */
1305  if (magic[1] != 'b')
1306    {
1307      /* This is the old format.  */
1308      struct xcoff_ar_file_hdr hdr;
1309
1310      /* Copy over the magic string.  */
1311      memcpy (hdr.magic, magic, SXCOFFARMAG);
1312
1313      /* Now read the rest of the file header.  */
1314      amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
1315      if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1316	{
1317	  if (bfd_get_error () != bfd_error_system_call)
1318	    bfd_set_error (bfd_error_wrong_format);
1319	  goto error_ret;
1320	}
1321
1322      bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1323						      (char **) NULL, 10);
1324
1325      amt = SIZEOF_AR_FILE_HDR;
1326      bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1327      if (bfd_ardata (abfd)->tdata == NULL)
1328	goto error_ret;
1329
1330      memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
1331    }
1332  else
1333    {
1334      /* This is the new format.  */
1335      struct xcoff_ar_file_hdr_big hdr;
1336
1337      /* Copy over the magic string.  */
1338      memcpy (hdr.magic, magic, SXCOFFARMAG);
1339
1340      /* Now read the rest of the file header.  */
1341      amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1342      if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1343	{
1344	  if (bfd_get_error () != bfd_error_system_call)
1345	    bfd_set_error (bfd_error_wrong_format);
1346	  goto error_ret;
1347	}
1348
1349      bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
1350							    (const char **) 0,
1351							    10);
1352
1353      amt = SIZEOF_AR_FILE_HDR_BIG;
1354      bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1355      if (bfd_ardata (abfd)->tdata == NULL)
1356	goto error_ret;
1357
1358      memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1359    }
1360
1361  if (! _bfd_xcoff_slurp_armap (abfd))
1362    {
1363    error_ret:
1364      bfd_release (abfd, bfd_ardata (abfd));
1365    error_ret_restore:
1366      bfd_ardata (abfd) = tdata_hold;
1367      return NULL;
1368    }
1369
1370  return abfd->xvec;
1371}
1372
1373/* Read the archive header in an XCOFF archive.  */
1374
1375PTR
1376_bfd_xcoff_read_ar_hdr (abfd)
1377     bfd *abfd;
1378{
1379  bfd_size_type namlen;
1380  struct areltdata *ret;
1381  bfd_size_type amt = sizeof (struct areltdata);
1382
1383  ret = (struct areltdata *) bfd_alloc (abfd, amt);
1384  if (ret == NULL)
1385    return NULL;
1386
1387  if (! xcoff_big_format_p (abfd))
1388    {
1389      struct xcoff_ar_hdr hdr;
1390      struct xcoff_ar_hdr *hdrp;
1391
1392      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1393	  != SIZEOF_AR_HDR)
1394	{
1395	  free (ret);
1396	  return NULL;
1397	}
1398
1399      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1400      amt = SIZEOF_AR_HDR + namlen + 1;
1401      hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
1402      if (hdrp == NULL)
1403	{
1404	  free (ret);
1405	  return NULL;
1406	}
1407      memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
1408      if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
1409	{
1410	  free (ret);
1411	  return NULL;
1412	}
1413      ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
1414
1415      ret->arch_header = (char *) hdrp;
1416      ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1417      ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
1418    }
1419  else
1420    {
1421      struct xcoff_ar_hdr_big hdr;
1422      struct xcoff_ar_hdr_big *hdrp;
1423
1424      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1425	  != SIZEOF_AR_HDR_BIG)
1426	{
1427	  free (ret);
1428	  return NULL;
1429	}
1430
1431      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1432      amt = SIZEOF_AR_HDR_BIG + namlen + 1;
1433      hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
1434      if (hdrp == NULL)
1435	{
1436	  free (ret);
1437	  return NULL;
1438	}
1439      memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
1440      if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
1441	{
1442	  free (ret);
1443	  return NULL;
1444	}
1445      ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
1446
1447      ret->arch_header = (char *) hdrp;
1448      /* XXX This actually has to be a call to strtoll (at least on 32-bit
1449	 machines) since the field width is 20 and there numbers with more
1450	 than 32 bits can be represented.  */
1451      ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1452      ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
1453    }
1454
1455  /* Skip over the XCOFFARFMAG at the end of the file name.  */
1456  if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
1457    return NULL;
1458
1459  return (PTR) ret;
1460}
1461
1462/* Open the next element in an XCOFF archive.  */
1463
1464bfd *
1465_bfd_xcoff_openr_next_archived_file (archive, last_file)
1466     bfd *archive;
1467     bfd *last_file;
1468{
1469  file_ptr filestart;
1470
1471  if (xcoff_ardata (archive) == NULL)
1472    {
1473      bfd_set_error (bfd_error_invalid_operation);
1474      return NULL;
1475    }
1476
1477  if (! xcoff_big_format_p (archive))
1478    {
1479      if (last_file == NULL)
1480	filestart = bfd_ardata (archive)->first_file_filepos;
1481      else
1482	filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
1483			    10);
1484
1485      if (filestart == 0
1486	  || filestart == strtol (xcoff_ardata (archive)->memoff,
1487				  (char **) NULL, 10)
1488	  || filestart == strtol (xcoff_ardata (archive)->symoff,
1489				  (char **) NULL, 10))
1490	{
1491	  bfd_set_error (bfd_error_no_more_archived_files);
1492	  return NULL;
1493	}
1494    }
1495  else
1496    {
1497      if (last_file == NULL)
1498	filestart = bfd_ardata (archive)->first_file_filepos;
1499      else
1500	/* XXX These actually have to be a calls to strtoll (at least
1501	   on 32-bit machines) since the fields's width is 20 and
1502	   there numbers with more than 32 bits can be represented.  */
1503	filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
1504			    10);
1505
1506      /* XXX These actually have to be calls to strtoll (at least on 32-bit
1507	 machines) since the fields's width is 20 and there numbers with more
1508	 than 32 bits can be represented.  */
1509      if (filestart == 0
1510	  || filestart == strtol (xcoff_ardata_big (archive)->memoff,
1511				  (char **) NULL, 10)
1512	  || filestart == strtol (xcoff_ardata_big (archive)->symoff,
1513				  (char **) NULL, 10))
1514	{
1515	  bfd_set_error (bfd_error_no_more_archived_files);
1516	  return NULL;
1517	}
1518    }
1519
1520  return _bfd_get_elt_at_filepos (archive, filestart);
1521}
1522
1523/* Stat an element in an XCOFF archive.  */
1524
1525int
1526_bfd_xcoff_stat_arch_elt (abfd, s)
1527     bfd *abfd;
1528     struct stat *s;
1529{
1530  if (abfd->arelt_data == NULL)
1531    {
1532      bfd_set_error (bfd_error_invalid_operation);
1533      return -1;
1534    }
1535
1536  if (! xcoff_big_format_p (abfd->my_archive))
1537    {
1538      struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
1539
1540      s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1541      s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1542      s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1543      s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1544      s->st_size = arch_eltdata (abfd)->parsed_size;
1545    }
1546  else
1547    {
1548      struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
1549
1550      s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1551      s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1552      s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1553      s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1554      s->st_size = arch_eltdata (abfd)->parsed_size;
1555    }
1556
1557  return 0;
1558}
1559
1560/* Normalize a file name for inclusion in an archive.  */
1561
1562static const char *
1563normalize_filename (abfd)
1564     bfd *abfd;
1565{
1566  const char *file;
1567  const char *filename;
1568
1569  file = bfd_get_filename (abfd);
1570  filename = strrchr (file, '/');
1571  if (filename != NULL)
1572    filename++;
1573  else
1574    filename = file;
1575  return filename;
1576}
1577
1578/* Write out an XCOFF armap.  */
1579
1580static bfd_boolean
1581xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
1582     bfd *abfd;
1583     unsigned int elength ATTRIBUTE_UNUSED;
1584     struct orl *map;
1585     unsigned int orl_count;
1586     int stridx;
1587{
1588  struct xcoff_ar_hdr hdr;
1589  char *p;
1590  unsigned char buf[4];
1591  bfd *sub;
1592  file_ptr fileoff;
1593  unsigned int i;
1594
1595  memset (&hdr, 0, sizeof hdr);
1596  sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
1597  sprintf (hdr.nextoff, "%d", 0);
1598  memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
1599  sprintf (hdr.date, "%d", 0);
1600  sprintf (hdr.uid, "%d", 0);
1601  sprintf (hdr.gid, "%d", 0);
1602  sprintf (hdr.mode, "%d", 0);
1603  sprintf (hdr.namlen, "%d", 0);
1604
1605  /* We need spaces, not null bytes, in the header.  */
1606  for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
1607    if (*p == '\0')
1608      *p = ' ';
1609
1610  if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1611      != SIZEOF_AR_HDR
1612      || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
1613	  != SXCOFFARFMAG))
1614    return FALSE;
1615
1616  H_PUT_32 (abfd, orl_count, buf);
1617  if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1618    return FALSE;
1619
1620  sub = abfd->archive_head;
1621  fileoff = SIZEOF_AR_FILE_HDR;
1622  i = 0;
1623  while (sub != NULL && i < orl_count)
1624    {
1625      size_t namlen;
1626
1627      while (map[i].u.abfd == sub)
1628	{
1629	  H_PUT_32 (abfd, fileoff, buf);
1630	  if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1631	    return FALSE;
1632	  ++i;
1633	}
1634      namlen = strlen (normalize_filename (sub));
1635      namlen = (namlen + 1) &~ (size_t) 1;
1636      fileoff += (SIZEOF_AR_HDR
1637		  + namlen
1638		  + SXCOFFARFMAG
1639		  + arelt_size (sub));
1640      fileoff = (fileoff + 1) &~ 1;
1641      sub = sub->next;
1642    }
1643
1644  for (i = 0; i < orl_count; i++)
1645    {
1646      const char *name;
1647      size_t namlen;
1648
1649      name = *map[i].name;
1650      namlen = strlen (name);
1651      if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
1652	return FALSE;
1653    }
1654
1655  if ((stridx & 1) != 0)
1656    {
1657      char b;
1658
1659      b = '\0';
1660      if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1661	return FALSE;
1662    }
1663
1664  return TRUE;
1665}
1666
1667static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
1668#define FMT20  "%-20lld"
1669#define FMT12  "%-12d"
1670#define FMT12_OCTAL  "%-12o"
1671#define FMT4  "%-4d"
1672#define PRINT20(d, v) \
1673  sprintf (buff20, FMT20, (long long)(v)), \
1674  memcpy ((void *) (d), buff20, 20)
1675
1676#define PRINT12(d, v) \
1677  sprintf (buff20, FMT12, (int)(v)), \
1678  memcpy ((void *) (d), buff20, 12)
1679
1680#define PRINT12_OCTAL(d, v) \
1681  sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
1682  memcpy ((void *) (d), buff20, 12)
1683
1684#define PRINT4(d, v) \
1685  sprintf (buff20, FMT4, (int)(v)), \
1686  memcpy ((void *) (d), buff20, 4)
1687
1688#define READ20(d, v) \
1689  buff20[20] = 0, \
1690  memcpy (buff20, (d), 20), \
1691  (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
1692
1693static bfd_boolean
1694do_pad (abfd, number)
1695     bfd *abfd;
1696     unsigned int number;
1697{
1698  bfd_byte b = 0;
1699
1700  /* Limit pad to <= 4096.  */
1701  if (number > 4096)
1702    return FALSE;
1703
1704  while (number--)
1705    if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1706      return FALSE;
1707
1708  return TRUE;
1709}
1710
1711static bfd_boolean
1712do_copy (out_bfd, in_bfd)
1713     bfd *out_bfd;
1714     bfd *in_bfd;
1715{
1716  bfd_size_type remaining;
1717  bfd_byte buffer[DEFAULT_BUFFERSIZE];
1718
1719  if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
1720    return FALSE;
1721
1722  remaining = arelt_size (in_bfd);
1723
1724  while (remaining >= DEFAULT_BUFFERSIZE)
1725    {
1726      if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
1727	  || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
1728	return FALSE;
1729
1730      remaining -= DEFAULT_BUFFERSIZE;
1731    }
1732
1733  if (remaining)
1734    {
1735      if (bfd_bread (buffer, remaining, in_bfd) != remaining
1736	  || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
1737	return FALSE;
1738    }
1739
1740  return TRUE;
1741}
1742
1743static bfd_boolean
1744do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
1745     bfd *out_bfd;
1746     bfd *in_bfd;
1747     file_ptr *offset;
1748     int ar_header_size;
1749{
1750  if (bfd_check_format (in_bfd, bfd_object)
1751      && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
1752      && (in_bfd->flags & DYNAMIC) != 0)
1753    {
1754      bfd_size_type pad = 0;
1755      int text_align_power;
1756
1757      text_align_power = bfd_xcoff_text_align_power (in_bfd);
1758
1759      pad = 1 << text_align_power;
1760      pad -= (*offset + ar_header_size) & (pad - 1);
1761
1762      if (! do_pad (out_bfd, pad))
1763	return FALSE;
1764
1765      *offset += pad;
1766    }
1767
1768  return TRUE;
1769}
1770
1771static bfd_boolean
1772xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
1773     bfd *abfd;
1774     unsigned int elength ATTRIBUTE_UNUSED;
1775     struct orl *map;
1776     unsigned int orl_count;
1777     int stridx;
1778{
1779  struct xcoff_ar_file_hdr_big *fhdr;
1780  bfd_vma i, sym_32, sym_64, str_32, str_64;
1781  const bfd_arch_info_type *arch_info = NULL;
1782  bfd *current_bfd;
1783  size_t string_length;
1784  file_ptr nextoff, prevoff;
1785
1786  /* First, we look through the symbols and work out which are
1787     from 32-bit objects and which from 64-bit ones.  */
1788  sym_32 = sym_64 = str_32 = str_64 = 0;
1789
1790  current_bfd = abfd->archive_head;
1791  if (current_bfd != NULL)
1792    arch_info = bfd_get_arch_info (current_bfd);
1793    i = 0;
1794    while (current_bfd != NULL && i < orl_count)
1795    {
1796      while (map[i].u.abfd == current_bfd)
1797	{
1798	  string_length = strlen (*map[i].name) + 1;
1799
1800	  if (arch_info->bits_per_address == 64)
1801	    {
1802	      sym_64++;
1803	      str_64 += string_length;
1804	    }
1805	  else
1806	    {
1807	      sym_32++;
1808	      str_32 += string_length;
1809	    }
1810	  i++;
1811	}
1812      current_bfd = current_bfd->next;
1813      if (current_bfd != NULL)
1814	arch_info = bfd_get_arch_info (current_bfd);
1815    }
1816
1817  /* A quick sanity check... */
1818  BFD_ASSERT (sym_64 + sym_32 == orl_count);
1819  /* Explicit cast to int for compiler.  */
1820  BFD_ASSERT ((int)(str_64 + str_32) == stridx);
1821
1822  fhdr = xcoff_ardata_big (abfd);
1823
1824  /* xcoff_write_archive_contents_big passes nextoff in symoff. */
1825  READ20 (fhdr->memoff, prevoff);
1826  READ20 (fhdr->symoff, nextoff);
1827
1828  BFD_ASSERT (nextoff == bfd_tell (abfd));
1829
1830  /* Write out the symbol table.
1831     Layout :
1832
1833     standard big archive header
1834     0x0000		      ar_size	[0x14]
1835     0x0014		      ar_nxtmem [0x14]
1836     0x0028		      ar_prvmem [0x14]
1837     0x003C		      ar_date	[0x0C]
1838     0x0048		      ar_uid	[0x0C]
1839     0x0054		      ar_gid	[0x0C]
1840     0x0060		      ar_mod	[0x0C]
1841     0x006C		      ar_namelen[0x04]
1842     0x0070		      ar_fmag	[SXCOFFARFMAG]
1843
1844     Symbol table
1845     0x0072		      num_syms	[0x08], binary
1846     0x0078		      offsets	[0x08 * num_syms], binary
1847     0x0086 + 0x08 * num_syms names	[??]
1848     ??			      pad to even bytes.
1849  */
1850
1851  if (sym_32)
1852    {
1853      struct xcoff_ar_hdr_big *hdr;
1854      char *symbol_table;
1855      char *st;
1856      file_ptr fileoff;
1857
1858      bfd_vma symbol_table_size =
1859	SIZEOF_AR_HDR_BIG
1860	+ SXCOFFARFMAG
1861	+ 8
1862	+ 8 * sym_32
1863	+ str_32 + (str_32 & 1);
1864
1865      symbol_table = bfd_zmalloc (symbol_table_size);
1866      if (symbol_table == NULL)
1867	return FALSE;
1868
1869      hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1870
1871      PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
1872
1873      if (sym_64)
1874	PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
1875      else
1876	PRINT20 (hdr->nextoff, 0);
1877
1878      PRINT20 (hdr->prevoff, prevoff);
1879      PRINT12 (hdr->date, 0);
1880      PRINT12 (hdr->uid, 0);
1881      PRINT12 (hdr->gid, 0);
1882      PRINT12 (hdr->mode, 0);
1883      PRINT4 (hdr->namlen, 0) ;
1884
1885      st = symbol_table + SIZEOF_AR_HDR_BIG;
1886      memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1887      st += SXCOFFARFMAG;
1888
1889      bfd_h_put_64 (abfd, sym_32, st);
1890      st += 8;
1891
1892      /* loop over the 32 bit offsets */
1893      current_bfd = abfd->archive_head;
1894      if (current_bfd != NULL)
1895	arch_info = bfd_get_arch_info (current_bfd);
1896      fileoff = SIZEOF_AR_FILE_HDR_BIG;
1897      i = 0;
1898      while (current_bfd != NULL && i < orl_count)
1899	{
1900	  while (map[i].u.abfd == current_bfd)
1901	    {
1902	      if (arch_info->bits_per_address == 32)
1903		{
1904		  bfd_h_put_64 (abfd, fileoff, st);
1905		  st += 8;
1906		}
1907	      i++;
1908	    }
1909	  string_length = strlen (normalize_filename (current_bfd));
1910	  string_length += string_length & 1;
1911	  fileoff += (SIZEOF_AR_HDR_BIG
1912		      + string_length
1913		      + SXCOFFARFMAG
1914		      + arelt_size (current_bfd));
1915	  fileoff += fileoff & 1;
1916	  current_bfd = current_bfd->next;
1917	  if (current_bfd != NULL)
1918	    arch_info = bfd_get_arch_info (current_bfd);
1919	}
1920
1921      /* loop over the 32 bit symbol names */
1922      current_bfd = abfd->archive_head;
1923      if (current_bfd != NULL)
1924	arch_info = bfd_get_arch_info (current_bfd);
1925      i = 0;
1926      while (current_bfd != NULL && i < orl_count)
1927	{
1928	  while (map[i].u.abfd == current_bfd)
1929	    {
1930	      if (arch_info->bits_per_address == 32)
1931		{
1932		  string_length = sprintf (st, "%s", *map[i].name);
1933		  st += string_length + 1;
1934		}
1935	      i++;
1936	    }
1937	  current_bfd = current_bfd->next;
1938	  if (current_bfd != NULL)
1939	    arch_info = bfd_get_arch_info (current_bfd);
1940	}
1941
1942      bfd_bwrite (symbol_table, symbol_table_size, abfd);
1943
1944      free (symbol_table);
1945
1946      prevoff = nextoff;
1947      nextoff = nextoff + symbol_table_size;
1948    }
1949  else
1950    PRINT20 (fhdr->symoff, 0);
1951
1952  if (sym_64)
1953    {
1954      struct xcoff_ar_hdr_big *hdr;
1955      char *symbol_table;
1956      char *st;
1957      file_ptr fileoff;
1958
1959      bfd_vma symbol_table_size =
1960	SIZEOF_AR_HDR_BIG
1961	+ SXCOFFARFMAG
1962	+ 8
1963	+ 8 * sym_64
1964	+ str_64 + (str_64 & 1);
1965
1966      symbol_table = bfd_zmalloc (symbol_table_size);
1967      if (symbol_table == NULL)
1968	return FALSE;
1969
1970      hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1971
1972      PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
1973      PRINT20 (hdr->nextoff, 0);
1974      PRINT20 (hdr->prevoff, prevoff);
1975      PRINT12 (hdr->date, 0);
1976      PRINT12 (hdr->uid, 0);
1977      PRINT12 (hdr->gid, 0);
1978      PRINT12 (hdr->mode, 0);
1979      PRINT4 (hdr->namlen, 0);
1980
1981      st = symbol_table + SIZEOF_AR_HDR_BIG;
1982      memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1983      st += SXCOFFARFMAG;
1984
1985      bfd_h_put_64 (abfd, sym_64, st);
1986      st += 8;
1987
1988      /* loop over the 64 bit offsets */
1989      current_bfd = abfd->archive_head;
1990      if (current_bfd != NULL)
1991	arch_info = bfd_get_arch_info (current_bfd);
1992      fileoff = SIZEOF_AR_FILE_HDR_BIG;
1993      i = 0;
1994      while (current_bfd != NULL && i < orl_count)
1995	{
1996	  while (map[i].u.abfd == current_bfd)
1997	    {
1998	      if (arch_info->bits_per_address == 64)
1999		{
2000		  bfd_h_put_64 (abfd, fileoff, st);
2001		  st += 8;
2002		}
2003	      i++;
2004	    }
2005	  string_length = strlen (normalize_filename (current_bfd));
2006	  string_length += string_length & 1;
2007	  fileoff += (SIZEOF_AR_HDR_BIG
2008		      + string_length
2009		      + SXCOFFARFMAG
2010		      + arelt_size (current_bfd));
2011	  fileoff += fileoff & 1;
2012	  current_bfd = current_bfd->next;
2013	  if (current_bfd != NULL)
2014	    arch_info = bfd_get_arch_info (current_bfd);
2015	}
2016
2017      /* loop over the 64 bit symbol names */
2018      current_bfd = abfd->archive_head;
2019      if (current_bfd != NULL)
2020	arch_info = bfd_get_arch_info (current_bfd);
2021      i = 0;
2022      while (current_bfd != NULL && i < orl_count)
2023	{
2024	  while (map[i].u.abfd == current_bfd)
2025	    {
2026	      if (arch_info->bits_per_address == 64)
2027		{
2028		  string_length = sprintf (st, "%s", *map[i].name);
2029		  st += string_length + 1;
2030		}
2031	      i++;
2032	    }
2033	  current_bfd = current_bfd->next;
2034	  if (current_bfd != NULL)
2035	    arch_info = bfd_get_arch_info (current_bfd);
2036	}
2037
2038      bfd_bwrite (symbol_table, symbol_table_size, abfd);
2039
2040      free (symbol_table);
2041
2042      PRINT20 (fhdr->symoff64, nextoff);
2043    }
2044  else
2045    PRINT20 (fhdr->symoff64, 0);
2046
2047  return TRUE;
2048}
2049
2050bfd_boolean
2051_bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
2052     bfd *abfd;
2053     unsigned int elength ATTRIBUTE_UNUSED;
2054     struct orl *map;
2055     unsigned int orl_count;
2056     int stridx;
2057{
2058  if (! xcoff_big_format_p (abfd))
2059    return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
2060  else
2061    return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
2062}
2063
2064/* Write out an XCOFF archive.  We always write an entire archive,
2065   rather than fussing with the freelist and so forth.  */
2066
2067static bfd_boolean
2068xcoff_write_archive_contents_old (abfd)
2069     bfd *abfd;
2070{
2071  struct xcoff_ar_file_hdr fhdr;
2072  bfd_size_type count;
2073  bfd_size_type total_namlen;
2074  file_ptr *offsets;
2075  bfd_boolean makemap;
2076  bfd_boolean hasobjects;
2077  file_ptr prevoff, nextoff;
2078  bfd *sub;
2079  size_t i;
2080  struct xcoff_ar_hdr ahdr;
2081  bfd_size_type size;
2082  char *p;
2083  char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
2084
2085  memset (&fhdr, 0, sizeof fhdr);
2086  (void) strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
2087  sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
2088  sprintf (fhdr.freeoff, "%d", 0);
2089
2090  count = 0;
2091  total_namlen = 0;
2092  for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2093    {
2094      ++count;
2095      total_namlen += strlen (normalize_filename (sub)) + 1;
2096    }
2097  offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2098  if (offsets == NULL)
2099    return FALSE;
2100
2101  if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
2102    return FALSE;
2103
2104  makemap = bfd_has_map (abfd);
2105  hasobjects = FALSE;
2106  prevoff = 0;
2107  nextoff = SIZEOF_AR_FILE_HDR;
2108  for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
2109    {
2110      const char *name;
2111      bfd_size_type namlen;
2112      struct xcoff_ar_hdr *ahdrp;
2113      bfd_size_type remaining;
2114
2115      if (makemap && ! hasobjects)
2116	{
2117	  if (bfd_check_format (sub, bfd_object))
2118	    hasobjects = TRUE;
2119	}
2120
2121      name = normalize_filename (sub);
2122      namlen = strlen (name);
2123
2124      if (sub->arelt_data != NULL)
2125	ahdrp = arch_xhdr (sub);
2126      else
2127	ahdrp = NULL;
2128
2129      if (ahdrp == NULL)
2130	{
2131	  struct stat s;
2132
2133	  memset (&ahdr, 0, sizeof ahdr);
2134	  ahdrp = &ahdr;
2135	  if (stat (bfd_get_filename (sub), &s) != 0)
2136	    {
2137	      bfd_set_error (bfd_error_system_call);
2138	      return FALSE;
2139	    }
2140
2141	  sprintf (ahdrp->size, "%ld", (long) s.st_size);
2142	  sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2143	  sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2144	  sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2145	  sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2146
2147	  if (sub->arelt_data == NULL)
2148	    {
2149	      size = sizeof (struct areltdata);
2150	      sub->arelt_data = bfd_alloc (sub, size);
2151	      if (sub->arelt_data == NULL)
2152		return FALSE;
2153	    }
2154
2155	  arch_eltdata (sub)->parsed_size = s.st_size;
2156	}
2157
2158      sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2159      sprintf (ahdrp->namlen, "%ld", (long) namlen);
2160
2161      /* If the length of the name is odd, we write out the null byte
2162	 after the name as well.  */
2163      namlen = (namlen + 1) &~ (bfd_size_type) 1;
2164
2165      remaining = arelt_size (sub);
2166      size = (SIZEOF_AR_HDR
2167	      + namlen
2168	      + SXCOFFARFMAG
2169	      + remaining);
2170
2171      BFD_ASSERT (nextoff == bfd_tell (abfd));
2172
2173      offsets[i] = nextoff;
2174
2175      prevoff = nextoff;
2176      nextoff += size + (size & 1);
2177
2178      sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
2179
2180      /* We need spaces, not null bytes, in the header.  */
2181      for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2182	if (*p == '\0')
2183	  *p = ' ';
2184
2185      if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2186	   != SIZEOF_AR_HDR)
2187	  || bfd_bwrite ((PTR) name, namlen, abfd) != namlen
2188	  || bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
2189			 abfd) != SXCOFFARFMAG)
2190	return FALSE;
2191
2192      if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
2193	return FALSE;
2194
2195      if (! do_copy (abfd, sub))
2196	return FALSE;
2197
2198      if (! do_pad (abfd, size & 1))
2199	return FALSE;
2200    }
2201
2202  sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2203
2204  /* Write out the member table.  */
2205
2206  BFD_ASSERT (nextoff == bfd_tell (abfd));
2207  sprintf (fhdr.memoff, "%ld", (long) nextoff);
2208
2209  memset (&ahdr, 0, sizeof ahdr);
2210  sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
2211				     + count * XCOFFARMAG_ELEMENT_SIZE
2212				     + total_namlen));
2213  sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2214  sprintf (ahdr.date, "%d", 0);
2215  sprintf (ahdr.uid, "%d", 0);
2216  sprintf (ahdr.gid, "%d", 0);
2217  sprintf (ahdr.mode, "%d", 0);
2218  sprintf (ahdr.namlen, "%d", 0);
2219
2220  size = (SIZEOF_AR_HDR
2221	  + XCOFFARMAG_ELEMENT_SIZE
2222	  + count * XCOFFARMAG_ELEMENT_SIZE
2223	  + total_namlen
2224	  + SXCOFFARFMAG);
2225
2226  prevoff = nextoff;
2227  nextoff += size + (size & 1);
2228
2229  if (makemap && hasobjects)
2230    sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2231  else
2232    sprintf (ahdr.nextoff, "%d", 0);
2233
2234  /* We need spaces, not null bytes, in the header.  */
2235  for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2236    if (*p == '\0')
2237      *p = ' ';
2238
2239  if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2240       != SIZEOF_AR_HDR)
2241      || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2242	  != SXCOFFARFMAG))
2243    return FALSE;
2244
2245  sprintf (decbuf, "%-12ld", (long) count);
2246  if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
2247      != XCOFFARMAG_ELEMENT_SIZE)
2248    return FALSE;
2249  for (i = 0; i < (size_t) count; i++)
2250    {
2251      sprintf (decbuf, "%-12ld", (long) offsets[i]);
2252      if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
2253		      abfd) != XCOFFARMAG_ELEMENT_SIZE)
2254	return FALSE;
2255    }
2256  for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2257    {
2258      const char *name;
2259      bfd_size_type namlen;
2260
2261      name = normalize_filename (sub);
2262      namlen = strlen (name);
2263      if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
2264	return FALSE;
2265    }
2266
2267  if (! do_pad (abfd, size & 1))
2268    return FALSE;
2269
2270  /* Write out the armap, if appropriate.  */
2271  if (! makemap || ! hasobjects)
2272    sprintf (fhdr.symoff, "%d", 0);
2273  else
2274    {
2275      BFD_ASSERT (nextoff == bfd_tell (abfd));
2276      sprintf (fhdr.symoff, "%ld", (long) nextoff);
2277      bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2278      if (! _bfd_compute_and_write_armap (abfd, 0))
2279	return FALSE;
2280    }
2281
2282  /* Write out the archive file header.  */
2283
2284  /* We need spaces, not null bytes, in the header.  */
2285  for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2286    if (*p == '\0')
2287      *p = ' ';
2288
2289  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2290      || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
2291	  != SIZEOF_AR_FILE_HDR))
2292    return FALSE;
2293
2294  return TRUE;
2295}
2296
2297static bfd_boolean
2298xcoff_write_archive_contents_big (abfd)
2299     bfd *abfd;
2300{
2301  struct xcoff_ar_file_hdr_big fhdr;
2302  bfd_size_type count;
2303  bfd_size_type total_namlen;
2304  file_ptr *offsets;
2305  bfd_boolean makemap;
2306  bfd_boolean hasobjects;
2307  file_ptr prevoff, nextoff;
2308  bfd *current_bfd;
2309  size_t i;
2310  struct xcoff_ar_hdr_big *hdr, ahdr;
2311  bfd_size_type size;
2312  char *member_table, *mt;
2313  bfd_vma member_table_size;
2314
2315  memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
2316  memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
2317
2318  if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
2319    return FALSE;
2320
2321  /* Calculate count and total_namlen.  */
2322  makemap = bfd_has_map (abfd);
2323  hasobjects = FALSE;
2324  for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
2325       current_bfd != NULL;
2326       current_bfd = current_bfd->next, count++)
2327    {
2328      total_namlen += strlen (normalize_filename (current_bfd)) + 1;
2329
2330      if (makemap
2331	  && ! hasobjects
2332	  && bfd_check_format (current_bfd, bfd_object))
2333	hasobjects = TRUE;
2334    }
2335
2336  offsets = NULL;
2337  if (count)
2338    {
2339      offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2340      if (offsets == NULL)
2341	return FALSE;
2342    }
2343
2344  prevoff = 0;
2345  nextoff = SIZEOF_AR_FILE_HDR_BIG;
2346  for (current_bfd = abfd->archive_head, i = 0;
2347       current_bfd != NULL;
2348       current_bfd = current_bfd->next, i++)
2349    {
2350      const char *name;
2351      bfd_size_type namlen;
2352      struct xcoff_ar_hdr_big *ahdrp;
2353      bfd_size_type remaining;
2354
2355      name = normalize_filename (current_bfd);
2356      namlen = strlen (name);
2357
2358      if (current_bfd->arelt_data != NULL)
2359	ahdrp = arch_xhdr_big (current_bfd);
2360      else
2361	ahdrp = NULL;
2362
2363      if (ahdrp == NULL)
2364	{
2365	  struct stat s;
2366
2367	  ahdrp = &ahdr;
2368	  /* XXX This should actually be a call to stat64 (at least on
2369	     32-bit machines).
2370	     XXX This call will fail if the original object is not found.  */
2371	  if (stat (bfd_get_filename (current_bfd), &s) != 0)
2372	    {
2373	      bfd_set_error (bfd_error_system_call);
2374	      return FALSE;
2375	    }
2376
2377	  PRINT20 (ahdrp->size, s.st_size);
2378	  PRINT12 (ahdrp->date, s.st_mtime);
2379	  PRINT12 (ahdrp->uid,  s.st_uid);
2380	  PRINT12 (ahdrp->gid,  s.st_gid);
2381	  PRINT12_OCTAL (ahdrp->mode, s.st_mode);
2382
2383	  if (current_bfd->arelt_data == NULL)
2384	    {
2385	      size = sizeof (struct areltdata);
2386	      current_bfd->arelt_data = bfd_alloc (current_bfd, size);
2387	      if (current_bfd->arelt_data == NULL)
2388		return FALSE;
2389	    }
2390
2391	  arch_eltdata (current_bfd)->parsed_size = s.st_size;
2392	}
2393
2394      PRINT20 (ahdrp->prevoff, prevoff);
2395      PRINT4 (ahdrp->namlen, namlen);
2396
2397      /* If the length of the name is odd, we write out the null byte
2398	 after the name as well.  */
2399      namlen = (namlen + 1) &~ (bfd_size_type) 1;
2400
2401      remaining = arelt_size (current_bfd);
2402      size = (SIZEOF_AR_HDR_BIG
2403	      + namlen
2404	      + SXCOFFARFMAG
2405	      + remaining);
2406
2407      BFD_ASSERT (nextoff == bfd_tell (abfd));
2408
2409      /* Check for xcoff shared objects.
2410	 Their text section needs to be aligned wrt the archive file position.
2411	 This requires extra padding before the archive header.  */
2412      if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
2413				      SIZEOF_AR_HDR_BIG + namlen
2414				      + SXCOFFARFMAG))
2415	return FALSE;
2416
2417      offsets[i] = nextoff;
2418
2419      prevoff = nextoff;
2420      nextoff += size + (size & 1);
2421
2422      PRINT20 (ahdrp->nextoff, nextoff);
2423
2424      if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
2425	   != SIZEOF_AR_HDR_BIG)
2426	  || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
2427	  || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
2428			  abfd) != SXCOFFARFMAG))
2429	return FALSE;
2430
2431      if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
2432	return FALSE;
2433
2434      if (! do_copy (abfd, current_bfd))
2435	return FALSE;
2436
2437      if (! do_pad (abfd, size & 1))
2438	return FALSE;
2439    }
2440
2441  if (count)
2442    {
2443      PRINT20 (fhdr.firstmemoff, offsets[0]);
2444      PRINT20 (fhdr.lastmemoff, prevoff);
2445    }
2446
2447  /* Write out the member table.
2448     Layout :
2449
2450     standard big archive header
2451     0x0000		      ar_size	[0x14]
2452     0x0014		      ar_nxtmem [0x14]
2453     0x0028		      ar_prvmem [0x14]
2454     0x003C		      ar_date	[0x0C]
2455     0x0048		      ar_uid	[0x0C]
2456     0x0054		      ar_gid	[0x0C]
2457     0x0060		      ar_mod	[0x0C]
2458     0x006C		      ar_namelen[0x04]
2459     0x0070		      ar_fmag	[0x02]
2460
2461     Member table
2462     0x0072		      count	[0x14]
2463     0x0086		      offsets	[0x14 * counts]
2464     0x0086 + 0x14 * counts   names	[??]
2465     ??			      pad to even bytes.
2466   */
2467
2468  BFD_ASSERT (nextoff == bfd_tell (abfd));
2469
2470  member_table_size = (SIZEOF_AR_HDR_BIG
2471		       + SXCOFFARFMAG
2472		       + XCOFFARMAGBIG_ELEMENT_SIZE
2473		       + count * XCOFFARMAGBIG_ELEMENT_SIZE
2474		       + total_namlen);
2475
2476  member_table_size += member_table_size & 1;
2477  member_table = bfd_zmalloc (member_table_size);
2478  if (member_table == NULL)
2479    return FALSE;
2480
2481  hdr = (struct xcoff_ar_hdr_big *) member_table;
2482
2483  PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
2484		       + count * XCOFFARMAGBIG_ELEMENT_SIZE
2485		       + total_namlen + (total_namlen & 1)));
2486  if (makemap && hasobjects)
2487    PRINT20 (hdr->nextoff, nextoff + member_table_size);
2488  else
2489    PRINT20 (hdr->nextoff, 0);
2490  PRINT20 (hdr->prevoff, prevoff);
2491  PRINT12 (hdr->date, 0);
2492  PRINT12 (hdr->uid, 0);
2493  PRINT12 (hdr->gid, 0);
2494  PRINT12 (hdr->mode, 0);
2495  PRINT4 (hdr->namlen, 0);
2496
2497  mt = member_table + SIZEOF_AR_HDR_BIG;
2498  memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
2499  mt += SXCOFFARFMAG;
2500
2501  PRINT20 (mt, count);
2502  mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2503  for (i = 0; i < (size_t) count; i++)
2504    {
2505      PRINT20 (mt, offsets[i]);
2506      mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2507    }
2508
2509  if (count)
2510    {
2511      free (offsets);
2512      offsets = NULL;
2513    }
2514
2515  for (current_bfd = abfd->archive_head; current_bfd != NULL;
2516       current_bfd = current_bfd->next)
2517    {
2518      const char *name;
2519      size_t namlen;
2520
2521      name = normalize_filename (current_bfd);
2522      namlen = sprintf (mt, "%s", name);
2523      mt += namlen + 1;
2524    }
2525
2526  if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
2527    return FALSE;
2528
2529  free (member_table);
2530
2531  PRINT20 (fhdr.memoff, nextoff);
2532
2533  prevoff = nextoff;
2534  nextoff += member_table_size;
2535
2536  /* Write out the armap, if appropriate.  */
2537
2538  if (! makemap || ! hasobjects)
2539    PRINT20 (fhdr.symoff, 0);
2540  else
2541    {
2542      BFD_ASSERT (nextoff == bfd_tell (abfd));
2543
2544      /* Save nextoff in fhdr.symoff so the armap routine can use it.  */
2545      PRINT20 (fhdr.symoff, nextoff);
2546
2547      bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2548      if (! _bfd_compute_and_write_armap (abfd, 0))
2549	return FALSE;
2550    }
2551
2552  /* Write out the archive file header.  */
2553
2554  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2555      || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
2556		      abfd) != SIZEOF_AR_FILE_HDR_BIG))
2557    return FALSE;
2558
2559  return TRUE;
2560}
2561
2562bfd_boolean
2563_bfd_xcoff_write_archive_contents (abfd)
2564     bfd *abfd;
2565{
2566  if (! xcoff_big_format_p (abfd))
2567    return xcoff_write_archive_contents_old (abfd);
2568  else
2569    return xcoff_write_archive_contents_big (abfd);
2570}
2571
2572/* We can't use the usual coff_sizeof_headers routine, because AIX
2573   always uses an a.out header.  */
2574
2575int
2576_bfd_xcoff_sizeof_headers (abfd, reloc)
2577     bfd *abfd;
2578     bfd_boolean reloc ATTRIBUTE_UNUSED;
2579{
2580  int size;
2581
2582  size = FILHSZ;
2583  if (xcoff_data (abfd)->full_aouthdr)
2584    size += AOUTSZ;
2585  else
2586    size += SMALL_AOUTSZ;
2587  size += abfd->section_count * SCNHSZ;
2588  return size;
2589}
2590
2591/* Routines to swap information in the XCOFF .loader section.  If we
2592   ever need to write an XCOFF loader, this stuff will need to be
2593   moved to another file shared by the linker (which XCOFF calls the
2594   ``binder'') and the loader.  */
2595
2596/* Swap in the ldhdr structure.  */
2597
2598static void
2599xcoff_swap_ldhdr_in (abfd, s, dst)
2600     bfd *abfd;
2601     const PTR s;
2602     struct internal_ldhdr *dst;
2603{
2604  const struct external_ldhdr *src = (const struct external_ldhdr *) s;
2605
2606  dst->l_version = bfd_get_32 (abfd, src->l_version);
2607  dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
2608  dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
2609  dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
2610  dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
2611  dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
2612  dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
2613  dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
2614}
2615
2616/* Swap out the ldhdr structure.  */
2617
2618static void
2619xcoff_swap_ldhdr_out (abfd, src, d)
2620     bfd *abfd;
2621     const struct internal_ldhdr *src;
2622     PTR d;
2623{
2624  struct external_ldhdr *dst = (struct external_ldhdr *) d;
2625
2626  bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
2627  bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
2628  bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
2629  bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
2630  bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
2631  bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
2632  bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
2633  bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
2634}
2635
2636/* Swap in the ldsym structure.  */
2637
2638static void
2639xcoff_swap_ldsym_in (abfd, s, dst)
2640     bfd *abfd;
2641     const PTR s;
2642     struct internal_ldsym *dst;
2643{
2644  const struct external_ldsym *src = (const struct external_ldsym *) s;
2645
2646  if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
2647    memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2648  } else {
2649    dst->_l._l_l._l_zeroes = 0;
2650    dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
2651  }
2652  dst->l_value = bfd_get_32 (abfd, src->l_value);
2653  dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
2654  dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
2655  dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
2656  dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
2657  dst->l_parm = bfd_get_32 (abfd, src->l_parm);
2658}
2659
2660/* Swap out the ldsym structure.  */
2661
2662static void
2663xcoff_swap_ldsym_out (abfd, src, d)
2664     bfd *abfd;
2665     const struct internal_ldsym *src;
2666     PTR d;
2667{
2668  struct external_ldsym *dst = (struct external_ldsym *) d;
2669
2670  if (src->_l._l_l._l_zeroes != 0)
2671    memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2672  else
2673    {
2674      bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
2675      bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
2676		  dst->_l._l_l._l_offset);
2677    }
2678  bfd_put_32 (abfd, src->l_value, dst->l_value);
2679  bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
2680  bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
2681  bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
2682  bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
2683  bfd_put_32 (abfd, src->l_parm, dst->l_parm);
2684}
2685
2686static void
2687xcoff_swap_reloc_in (abfd, s, d)
2688     bfd *abfd;
2689     PTR s;
2690     PTR d;
2691{
2692  struct external_reloc *src = (struct external_reloc *) s;
2693  struct internal_reloc *dst = (struct internal_reloc *) d;
2694
2695  memset (dst, 0, sizeof (struct internal_reloc));
2696
2697  dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
2698  dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
2699  dst->r_size = bfd_get_8 (abfd, src->r_size);
2700  dst->r_type = bfd_get_8 (abfd, src->r_type);
2701}
2702
2703static unsigned int
2704xcoff_swap_reloc_out (abfd, s, d)
2705     bfd *abfd;
2706     PTR s;
2707     PTR d;
2708{
2709  struct internal_reloc *src = (struct internal_reloc *) s;
2710  struct external_reloc *dst = (struct external_reloc *) d;
2711
2712  bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
2713  bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
2714  bfd_put_8 (abfd, src->r_type, dst->r_type);
2715  bfd_put_8 (abfd, src->r_size, dst->r_size);
2716
2717  return bfd_coff_relsz (abfd);
2718}
2719
2720/* Swap in the ldrel structure.  */
2721
2722static void
2723xcoff_swap_ldrel_in (abfd, s, dst)
2724     bfd *abfd;
2725     const PTR s;
2726     struct internal_ldrel *dst;
2727{
2728  const struct external_ldrel *src = (const struct external_ldrel *) s;
2729
2730  dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
2731  dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
2732  dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
2733  dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
2734}
2735
2736/* Swap out the ldrel structure.  */
2737
2738static void
2739xcoff_swap_ldrel_out (abfd, src, d)
2740     bfd *abfd;
2741     const struct internal_ldrel *src;
2742     PTR d;
2743{
2744  struct external_ldrel *dst = (struct external_ldrel *) d;
2745
2746  bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
2747  bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
2748  bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
2749  bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
2750}
2751
2752
2753bfd_boolean
2754xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
2755		       val, addend, relocation, contents)
2756     bfd *input_bfd ATTRIBUTE_UNUSED;
2757     asection *input_section ATTRIBUTE_UNUSED;
2758     bfd *output_bfd ATTRIBUTE_UNUSED;
2759     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2760     struct internal_syment *sym ATTRIBUTE_UNUSED;
2761     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2762     bfd_vma val ATTRIBUTE_UNUSED;
2763     bfd_vma addend ATTRIBUTE_UNUSED;
2764     bfd_vma *relocation ATTRIBUTE_UNUSED;
2765     bfd_byte *contents ATTRIBUTE_UNUSED;
2766{
2767  return TRUE;
2768}
2769
2770bfd_boolean
2771xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
2772		       val, addend, relocation, contents)
2773     bfd *input_bfd;
2774     asection *input_section ATTRIBUTE_UNUSED;
2775     bfd *output_bfd ATTRIBUTE_UNUSED;
2776     struct internal_reloc *rel;
2777     struct internal_syment *sym ATTRIBUTE_UNUSED;
2778     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2779     bfd_vma val ATTRIBUTE_UNUSED;
2780     bfd_vma addend ATTRIBUTE_UNUSED;
2781     bfd_vma *relocation ATTRIBUTE_UNUSED;
2782     bfd_byte *contents ATTRIBUTE_UNUSED;
2783{
2784  (*_bfd_error_handler)
2785    (_("%s: unsupported relocation type 0x%02x"),
2786     bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
2787  bfd_set_error (bfd_error_bad_value);
2788  return FALSE;
2789}
2790
2791bfd_boolean
2792xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
2793		      val, addend, relocation, contents)
2794     bfd *input_bfd ATTRIBUTE_UNUSED;
2795     asection *input_section ATTRIBUTE_UNUSED;
2796     bfd *output_bfd ATTRIBUTE_UNUSED;
2797     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2798     struct internal_syment *sym ATTRIBUTE_UNUSED;
2799     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2800     bfd_vma val;
2801     bfd_vma addend;
2802     bfd_vma *relocation;
2803     bfd_byte *contents ATTRIBUTE_UNUSED;
2804{
2805  *relocation = val + addend;
2806  return TRUE;
2807}
2808
2809bfd_boolean
2810xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
2811		      val, addend, relocation, contents)
2812     bfd *input_bfd ATTRIBUTE_UNUSED;
2813     asection *input_section ATTRIBUTE_UNUSED;
2814     bfd *output_bfd ATTRIBUTE_UNUSED;
2815     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2816     struct internal_syment *sym ATTRIBUTE_UNUSED;
2817     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2818     bfd_vma val;
2819     bfd_vma addend;
2820     bfd_vma *relocation;
2821     bfd_byte *contents ATTRIBUTE_UNUSED;
2822{
2823  *relocation = addend - val;
2824  return TRUE;
2825}
2826
2827bfd_boolean
2828xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
2829		      val, addend, relocation, contents)
2830     bfd *input_bfd ATTRIBUTE_UNUSED;
2831     asection *input_section;
2832     bfd *output_bfd ATTRIBUTE_UNUSED;
2833     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2834     struct internal_syment *sym ATTRIBUTE_UNUSED;
2835     struct reloc_howto_struct *howto;
2836     bfd_vma val;
2837     bfd_vma addend;
2838     bfd_vma *relocation;
2839     bfd_byte *contents ATTRIBUTE_UNUSED;
2840{
2841  howto->pc_relative = TRUE;
2842
2843  /* A PC relative reloc includes the section address.  */
2844  addend += input_section->vma;
2845
2846  *relocation = val + addend;
2847  *relocation -= (input_section->output_section->vma
2848		  + input_section->output_offset);
2849  return TRUE;
2850}
2851
2852bfd_boolean
2853xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
2854		      val, addend, relocation, contents)
2855     bfd *input_bfd;
2856     asection *input_section ATTRIBUTE_UNUSED;
2857     bfd *output_bfd;
2858     struct internal_reloc *rel;
2859     struct internal_syment *sym;
2860     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2861     bfd_vma val;
2862     bfd_vma addend ATTRIBUTE_UNUSED;
2863     bfd_vma *relocation;
2864     bfd_byte *contents ATTRIBUTE_UNUSED;
2865{
2866  struct xcoff_link_hash_entry *h;
2867
2868  if (0 > rel->r_symndx)
2869    return FALSE;
2870
2871  h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2872
2873  if (h != NULL && h->smclas != XMC_TD)
2874    {
2875      if (h->toc_section == NULL)
2876	{
2877	  (*_bfd_error_handler)
2878	    (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
2879	     bfd_get_filename (input_bfd), rel->r_vaddr,
2880	     h->root.root.string);
2881	  bfd_set_error (bfd_error_bad_value);
2882	  return FALSE;
2883	}
2884
2885      BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
2886      val = (h->toc_section->output_section->vma
2887	      + h->toc_section->output_offset);
2888    }
2889
2890  *relocation = ((val - xcoff_data (output_bfd)->toc)
2891		 - (sym->n_value - xcoff_data (input_bfd)->toc));
2892  return TRUE;
2893}
2894
2895bfd_boolean
2896xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto,
2897		     val, addend, relocation, contents)
2898     bfd *input_bfd ATTRIBUTE_UNUSED;
2899     asection *input_section ATTRIBUTE_UNUSED;
2900     bfd *output_bfd ATTRIBUTE_UNUSED;
2901     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2902     struct internal_syment *sym ATTRIBUTE_UNUSED;
2903     struct reloc_howto_struct *howto;
2904     bfd_vma val;
2905     bfd_vma addend;
2906     bfd_vma *relocation;
2907     bfd_byte *contents ATTRIBUTE_UNUSED;
2908{
2909  howto->src_mask &= ~3;
2910  howto->dst_mask = howto->src_mask;
2911
2912  *relocation = val + addend;
2913
2914  return TRUE;
2915}
2916
2917static bfd_boolean
2918xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
2919		     val, addend, relocation, contents)
2920     bfd *input_bfd;
2921     asection *input_section;
2922     bfd *output_bfd ATTRIBUTE_UNUSED;
2923     struct internal_reloc *rel;
2924     struct internal_syment *sym ATTRIBUTE_UNUSED;
2925     struct reloc_howto_struct *howto;
2926     bfd_vma val;
2927     bfd_vma addend;
2928     bfd_vma *relocation;
2929     bfd_byte *contents;
2930{
2931  struct xcoff_link_hash_entry *h;
2932
2933  if (0 > rel->r_symndx)
2934    return FALSE;
2935
2936  h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2937
2938  /* If we see an R_BR or R_RBR reloc which is jumping to global
2939     linkage code, and it is followed by an appropriate cror nop
2940     instruction, we replace the cror with lwz r2,20(r1).  This
2941     restores the TOC after the glink code.  Contrariwise, if the
2942     call is followed by a lwz r2,20(r1), but the call is not
2943     going to global linkage code, we can replace the load with a
2944     cror.  */
2945  if (NULL != h
2946      && bfd_link_hash_defined == h->root.type
2947      && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
2948    {
2949      bfd_byte *pnext;
2950      unsigned long next;
2951
2952      pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
2953      next = bfd_get_32 (input_bfd, pnext);
2954
2955      /* The _ptrgl function is magic.  It is used by the AIX
2956	 compiler to call a function through a pointer.  */
2957      if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
2958	{
2959	  if (next == 0x4def7b82			/* cror 15,15,15 */
2960	      || next == 0x4ffffb82			/* cror 31,31,31 */
2961	      || next == 0x60000000)			/* ori r0,r0,0 */
2962	    bfd_put_32 (input_bfd, 0x80410014, pnext);	/* lwz r1,20(r1) */
2963
2964	}
2965      else
2966	{
2967	  if (next == 0x80410014)			/* lwz r1,20(r1) */
2968	    bfd_put_32 (input_bfd, 0x60000000, pnext);	/* ori r0,r0,0 */
2969	}
2970    }
2971  else if (NULL != h && bfd_link_hash_undefined == h->root.type)
2972    {
2973      /* Normally, this relocation is against a defined symbol.  In the
2974	 case where this is a partial link and the output section offset
2975	 is greater than 2^25, the linker will return an invalid error
2976	 message that the relocation has been truncated.  Yes it has been
2977	 truncated but no it not important.  For this case, disable the
2978	 overflow checking. */
2979
2980      howto->complain_on_overflow = complain_overflow_dont;
2981    }
2982
2983  howto->pc_relative = TRUE;
2984  howto->src_mask &= ~3;
2985  howto->dst_mask = howto->src_mask;
2986
2987  /* A PC relative reloc includes the section address.  */
2988  addend += input_section->vma;
2989
2990  *relocation = val + addend;
2991  *relocation -= (input_section->output_section->vma
2992		  + input_section->output_offset);
2993  return TRUE;
2994}
2995
2996bfd_boolean
2997xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
2998		       val, addend, relocation, contents)
2999     bfd *input_bfd ATTRIBUTE_UNUSED;
3000     asection *input_section;
3001     bfd *output_bfd ATTRIBUTE_UNUSED;
3002     struct internal_reloc *rel ATTRIBUTE_UNUSED;
3003     struct internal_syment *sym ATTRIBUTE_UNUSED;
3004     struct reloc_howto_struct *howto;
3005     bfd_vma val ATTRIBUTE_UNUSED;
3006     bfd_vma addend;
3007     bfd_vma *relocation;
3008     bfd_byte *contents ATTRIBUTE_UNUSED;
3009{
3010  howto->pc_relative = TRUE;
3011  howto->src_mask &= ~3;
3012  howto->dst_mask = howto->src_mask;
3013
3014  /* A PC relative reloc includes the section address.  */
3015  addend += input_section->vma;
3016
3017  *relocation = val + addend;
3018  *relocation -= (input_section->output_section->vma
3019		  + input_section->output_offset);
3020  return TRUE;
3021}
3022
3023static bfd_boolean
3024xcoff_complain_overflow_dont_func (input_bfd, val, relocation, howto)
3025     bfd *input_bfd ATTRIBUTE_UNUSED;
3026     bfd_vma val ATTRIBUTE_UNUSED;
3027     bfd_vma relocation ATTRIBUTE_UNUSED;
3028     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
3029{
3030  return FALSE;
3031}
3032
3033static bfd_boolean
3034xcoff_complain_overflow_bitfield_func (input_bfd, val, relocation, howto)
3035     bfd *input_bfd;
3036     bfd_vma val;
3037     bfd_vma relocation;
3038     struct reloc_howto_struct *howto;
3039{
3040  bfd_vma addrmask, fieldmask, signmask, ss;
3041  bfd_vma a, b, sum;
3042
3043  /* Get the values to be added together.  For signed and unsigned
3044     relocations, we assume that all values should be truncated to
3045     the size of an address.  For bitfields, all the bits matter.
3046     See also bfd_check_overflow.  */
3047  fieldmask = N_ONES (howto->bitsize);
3048  addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3049  a = relocation;
3050  b = val & howto->src_mask;
3051
3052  /* Much like unsigned, except no trimming with addrmask.  In
3053     addition, the sum overflows if there is a carry out of
3054     the bfd_vma, i.e., the sum is less than either input
3055     operand.  */
3056  a >>= howto->rightshift;
3057  b >>= howto->bitpos;
3058
3059  /* Bitfields are sometimes used for signed numbers; for
3060     example, a 13-bit field sometimes represents values in
3061     0..8191 and sometimes represents values in -4096..4095.
3062     If the field is signed and a is -4095 (0x1001) and b is
3063     -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
3064     0x1fff is 0x3000).  It's not clear how to handle this
3065     everywhere, since there is not way to know how many bits
3066     are significant in the relocation, but the original code
3067     assumed that it was fully sign extended, and we will keep
3068     that assumption.  */
3069  signmask = (fieldmask >> 1) + 1;
3070
3071  if ((a & ~ fieldmask) != 0)
3072    {
3073      /* Some bits out of the field are set.  This might not
3074	 be a problem: if this is a signed bitfield, it is OK
3075	 iff all the high bits are set, including the sign
3076	 bit.  We'll try setting all but the most significant
3077	 bit in the original relocation value: if this is all
3078	 ones, we are OK, assuming a signed bitfield.  */
3079      ss = (signmask << howto->rightshift) - 1;
3080      if ((ss | relocation) != ~ (bfd_vma) 0)
3081	return TRUE;
3082      a &= fieldmask;
3083    }
3084
3085  /* We just assume (b & ~ fieldmask) == 0.  */
3086
3087  /* We explicitly permit wrap around if this relocation
3088     covers the high bit of an address.  The Linux kernel
3089     relies on it, and it is the only way to write assembler
3090     code which can run when loaded at a location 0x80000000
3091     away from the location at which it is linked.  */
3092  if (howto->bitsize + howto->rightshift
3093      == bfd_arch_bits_per_address (input_bfd))
3094    return FALSE;
3095
3096  sum = a + b;
3097  if (sum < a || (sum & ~ fieldmask) != 0)
3098    {
3099      /* There was a carry out, or the field overflow.  Test
3100	 for signed operands again.  Here is the overflow test
3101	 is as for complain_overflow_signed.  */
3102      if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3103	return TRUE;
3104    }
3105
3106  return FALSE;
3107}
3108
3109static bfd_boolean
3110xcoff_complain_overflow_signed_func (input_bfd, val, relocation, howto)
3111     bfd *input_bfd;
3112     bfd_vma val;
3113     bfd_vma relocation;
3114     struct reloc_howto_struct *howto;
3115{
3116  bfd_vma addrmask, fieldmask, signmask, ss;
3117  bfd_vma a, b, sum;
3118
3119  /* Get the values to be added together.  For signed and unsigned
3120     relocations, we assume that all values should be truncated to
3121     the size of an address.  For bitfields, all the bits matter.
3122     See also bfd_check_overflow.  */
3123  fieldmask = N_ONES (howto->bitsize);
3124  addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3125  a = relocation;
3126  b = val & howto->src_mask;
3127
3128  a = (a & addrmask) >> howto->rightshift;
3129
3130  /* If any sign bits are set, all sign bits must be set.
3131     That is, A must be a valid negative address after
3132     shifting.  */
3133  signmask = ~ (fieldmask >> 1);
3134  ss = a & signmask;
3135  if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
3136    return TRUE;
3137
3138  /* We only need this next bit of code if the sign bit of B
3139     is below the sign bit of A.  This would only happen if
3140     SRC_MASK had fewer bits than BITSIZE.  Note that if
3141     SRC_MASK has more bits than BITSIZE, we can get into
3142     trouble; we would need to verify that B is in range, as
3143     we do for A above.  */
3144  signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
3145  if ((b & signmask) != 0)
3146    {
3147      /* Set all the bits above the sign bit.  */
3148      b -= signmask <<= 1;
3149    }
3150
3151  b = (b & addrmask) >> howto->bitpos;
3152
3153  /* Now we can do the addition.  */
3154  sum = a + b;
3155
3156  /* See if the result has the correct sign.  Bits above the
3157     sign bit are junk now; ignore them.  If the sum is
3158     positive, make sure we did not have all negative inputs;
3159     if the sum is negative, make sure we did not have all
3160     positive inputs.  The test below looks only at the sign
3161     bits, and it really just
3162     SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
3163  */
3164  signmask = (fieldmask >> 1) + 1;
3165  if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3166    return TRUE;
3167
3168  return FALSE;
3169}
3170
3171static bfd_boolean
3172xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto)
3173     bfd *input_bfd;
3174     bfd_vma val;
3175     bfd_vma relocation;
3176     struct reloc_howto_struct *howto;
3177{
3178  bfd_vma addrmask, fieldmask;
3179  bfd_vma a, b, sum;
3180
3181  /* Get the values to be added together.  For signed and unsigned
3182     relocations, we assume that all values should be truncated to
3183     the size of an address.  For bitfields, all the bits matter.
3184     See also bfd_check_overflow.  */
3185  fieldmask = N_ONES (howto->bitsize);
3186  addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3187  a = relocation;
3188  b = val & howto->src_mask;
3189
3190  /* Checking for an unsigned overflow is relatively easy:
3191     trim the addresses and add, and trim the result as well.
3192     Overflow is normally indicated when the result does not
3193     fit in the field.  However, we also need to consider the
3194     case when, e.g., fieldmask is 0x7fffffff or smaller, an
3195     input is 0x80000000, and bfd_vma is only 32 bits; then we
3196     will get sum == 0, but there is an overflow, since the
3197     inputs did not fit in the field.  Instead of doing a
3198     separate test, we can check for this by or-ing in the
3199     operands when testing for the sum overflowing its final
3200     field.  */
3201  a = (a & addrmask) >> howto->rightshift;
3202  b = (b & addrmask) >> howto->bitpos;
3203  sum = (a + b) & addrmask;
3204  if ((a | b | sum) & ~ fieldmask)
3205    return TRUE;
3206
3207  return FALSE;
3208}
3209
3210/* This is the relocation function for the RS/6000/POWER/PowerPC.
3211   This is currently the only processor which uses XCOFF; I hope that
3212   will never change.
3213
3214   I took the relocation type definitions from two documents:
3215   the PowerPC AIX Version 4 Application Binary Interface, First
3216   Edition (April 1992), and the PowerOpen ABI, Big-Endian
3217   32-Bit Hardware Implementation (June 30, 1994).  Differences
3218   between the documents are noted below.
3219
3220   Unsupported r_type's
3221
3222   R_RTB:
3223   R_RRTBI:
3224   R_RRTBA:
3225
3226   These relocs are defined by the PowerPC ABI to be
3227   relative branches which use half of the difference
3228   between the symbol and the program counter.  I can't
3229   quite figure out when this is useful.  These relocs are
3230   not defined by the PowerOpen ABI.
3231
3232   Supported r_type's
3233
3234   R_POS:
3235   Simple positive relocation.
3236
3237   R_NEG:
3238   Simple negative relocation.
3239
3240   R_REL:
3241   Simple PC relative relocation.
3242
3243   R_TOC:
3244   TOC relative relocation.  The value in the instruction in
3245   the input file is the offset from the input file TOC to
3246   the desired location.  We want the offset from the final
3247   TOC to the desired location.  We have:
3248   isym = iTOC + in
3249   iinsn = in + o
3250   osym = oTOC + on
3251   oinsn = on + o
3252   so we must change insn by on - in.
3253
3254   R_GL:
3255   GL linkage relocation.  The value of this relocation
3256   is the address of the entry in the TOC section.
3257
3258   R_TCL:
3259   Local object TOC address.  I can't figure out the
3260   difference between this and case R_GL.
3261
3262   R_TRL:
3263   TOC relative relocation.  A TOC relative load instruction
3264   which may be changed to a load address instruction.
3265   FIXME: We don't currently implement this optimization.
3266
3267   R_TRLA:
3268   TOC relative relocation.  This is a TOC relative load
3269   address instruction which may be changed to a load
3270   instruction.  FIXME: I don't know if this is the correct
3271   implementation.
3272
3273   R_BA:
3274   Absolute branch.  We don't want to mess with the lower
3275   two bits of the instruction.
3276
3277   R_CAI:
3278   The PowerPC ABI defines this as an absolute call which
3279   may be modified to become a relative call.  The PowerOpen
3280   ABI does not define this relocation type.
3281
3282   R_RBA:
3283   Absolute branch which may be modified to become a
3284   relative branch.
3285
3286   R_RBAC:
3287   The PowerPC ABI defines this as an absolute branch to a
3288   fixed address which may be modified to an absolute branch
3289   to a symbol.  The PowerOpen ABI does not define this
3290   relocation type.
3291
3292   R_RBRC:
3293   The PowerPC ABI defines this as an absolute branch to a
3294   fixed address which may be modified to a relative branch.
3295   The PowerOpen ABI does not define this relocation type.
3296
3297   R_BR:
3298   Relative branch.  We don't want to mess with the lower
3299   two bits of the instruction.
3300
3301   R_CREL:
3302   The PowerPC ABI defines this as a relative call which may
3303   be modified to become an absolute call.  The PowerOpen
3304   ABI does not define this relocation type.
3305
3306   R_RBR:
3307   A relative branch which may be modified to become an
3308   absolute branch.  FIXME: We don't implement this,
3309   although we should for symbols of storage mapping class
3310   XMC_XO.
3311
3312   R_RL:
3313   The PowerPC AIX ABI describes this as a load which may be
3314   changed to a load address.  The PowerOpen ABI says this
3315   is the same as case R_POS.
3316
3317   R_RLA:
3318   The PowerPC AIX ABI describes this as a load address
3319   which may be changed to a load.  The PowerOpen ABI says
3320   this is the same as R_POS.
3321*/
3322
3323bfd_boolean
3324xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
3325			    input_section, contents, relocs, syms,
3326			    sections)
3327     bfd *output_bfd;
3328     struct bfd_link_info *info;
3329     bfd *input_bfd;
3330     asection *input_section;
3331     bfd_byte *contents;
3332     struct internal_reloc *relocs;
3333     struct internal_syment *syms;
3334     asection **sections;
3335{
3336  struct internal_reloc *rel;
3337  struct internal_reloc *relend;
3338
3339  rel = relocs;
3340  relend = rel + input_section->reloc_count;
3341  for (; rel < relend; rel++)
3342    {
3343      long symndx;
3344      struct xcoff_link_hash_entry *h;
3345      struct internal_syment *sym;
3346      bfd_vma addend;
3347      bfd_vma val;
3348      struct reloc_howto_struct howto;
3349      bfd_vma relocation;
3350      bfd_vma value_to_relocate;
3351      bfd_vma address;
3352      bfd_byte *location;
3353
3354      /* Relocation type R_REF is a special relocation type which is
3355	 merely used to prevent garbage collection from occurring for
3356	 the csect including the symbol which it references.  */
3357      if (rel->r_type == R_REF)
3358	continue;
3359
3360      /* howto */
3361      howto.type = rel->r_type;
3362      howto.rightshift = 0;
3363      howto.bitsize = (rel->r_size & 0x1f) + 1;
3364      howto.size = howto.bitsize > 16 ? 2 : 1;
3365      howto.pc_relative = FALSE;
3366      howto.bitpos = 0;
3367      howto.complain_on_overflow = (rel->r_size & 0x80
3368				    ? complain_overflow_signed
3369				    : complain_overflow_bitfield);
3370      howto.special_function = NULL;
3371      howto.name = "internal";
3372      howto.partial_inplace = TRUE;
3373      howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
3374      howto.pcrel_offset = FALSE;
3375
3376      /* symbol */
3377      val = 0;
3378      addend = 0;
3379      h = NULL;
3380      sym = NULL;
3381      symndx = rel->r_symndx;
3382
3383      if (-1 != symndx)
3384	{
3385	  asection *sec;
3386
3387	  h = obj_xcoff_sym_hashes (input_bfd)[symndx];
3388	  sym = syms + symndx;
3389	  addend = - sym->n_value;
3390
3391	  if (NULL == h)
3392	    {
3393	      sec = sections[symndx];
3394	      /* Hack to make sure we use the right TOC anchor value
3395		 if this reloc is against the TOC anchor.  */
3396	      if (sec->name[3] == '0'
3397		  && strcmp (sec->name, ".tc0") == 0)
3398		val = xcoff_data (output_bfd)->toc;
3399	      else
3400		val = (sec->output_section->vma
3401		       + sec->output_offset
3402		       + sym->n_value
3403		       - sec->vma);
3404	    }
3405	  else
3406	    {
3407	      if (h->root.type == bfd_link_hash_defined
3408		  || h->root.type == bfd_link_hash_defweak)
3409		{
3410		  sec = h->root.u.def.section;
3411		  val = (h->root.u.def.value
3412			 + sec->output_section->vma
3413			 + sec->output_offset);
3414		}
3415	      else if (h->root.type == bfd_link_hash_common)
3416		{
3417		  sec = h->root.u.c.p->section;
3418		  val = (sec->output_section->vma
3419			 + sec->output_offset);
3420
3421		}
3422	      else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
3423		       && ! info->relocatable)
3424		{
3425		  if (! ((*info->callbacks->undefined_symbol)
3426			 (info, h->root.root.string, input_bfd, input_section,
3427			  rel->r_vaddr - input_section->vma, TRUE)))
3428		    return FALSE;
3429
3430		  /* Don't try to process the reloc.  It can't help, and
3431		     it may generate another error.  */
3432		  continue;
3433		}
3434	    }
3435	}
3436
3437      if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
3438	  || !((*xcoff_calculate_relocation[rel->r_type])
3439	       (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
3440		addend, &relocation, contents)))
3441	return FALSE;
3442
3443      /* address */
3444      address = rel->r_vaddr - input_section->vma;
3445      location = contents + address;
3446
3447      if (address > input_section->size)
3448	abort ();
3449
3450      /* Get the value we are going to relocate.  */
3451      if (1 == howto.size)
3452	value_to_relocate = bfd_get_16 (input_bfd, location);
3453      else
3454	value_to_relocate = bfd_get_32 (input_bfd, location);
3455
3456      /* overflow.
3457
3458	 FIXME: We may drop bits during the addition
3459	 which we don't check for.  We must either check at every single
3460	 operation, which would be tedious, or we must do the computations
3461	 in a type larger than bfd_vma, which would be inefficient.  */
3462
3463      if ((unsigned int) howto.complain_on_overflow
3464	  >= XCOFF_MAX_COMPLAIN_OVERFLOW)
3465	abort ();
3466
3467      if (((*xcoff_complain_overflow[howto.complain_on_overflow])
3468	   (input_bfd, value_to_relocate, relocation, &howto)))
3469	{
3470	  const char *name;
3471	  char buf[SYMNMLEN + 1];
3472	  char reloc_type_name[10];
3473
3474	  if (symndx == -1)
3475	    {
3476	      name = "*ABS*";
3477	    }
3478	  else if (h != NULL)
3479	    {
3480	      name = NULL;
3481	    }
3482	  else
3483	    {
3484	      name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
3485	      if (name == NULL)
3486		name = "UNKNOWN";
3487	    }
3488	  sprintf (reloc_type_name, "0x%02x", rel->r_type);
3489
3490	  if (! ((*info->callbacks->reloc_overflow)
3491		 (info, (h ? &h->root : NULL), name, reloc_type_name,
3492		  (bfd_vma) 0, input_bfd, input_section,
3493		  rel->r_vaddr - input_section->vma)))
3494	    return FALSE;
3495	}
3496
3497      /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE.  */
3498      value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
3499			   | (((value_to_relocate & howto.src_mask)
3500			       + relocation) & howto.dst_mask));
3501
3502      /* Put the value back in the object file.  */
3503      if (1 == howto.size)
3504	bfd_put_16 (input_bfd, value_to_relocate, location);
3505      else
3506	bfd_put_32 (input_bfd, value_to_relocate, location);
3507    }
3508
3509  return TRUE;
3510}
3511
3512static bfd_boolean
3513_bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
3514     bfd *abfd ATTRIBUTE_UNUSED;
3515	 struct xcoff_loader_info *ldinfo;
3516	 struct internal_ldsym *ldsym;
3517	 const char *name;
3518{
3519  size_t len;
3520  len = strlen (name);
3521
3522  if (len <= SYMNMLEN)
3523    strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3524  else
3525    {
3526      if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3527	{
3528	  bfd_size_type newalc;
3529	  char *newstrings;
3530
3531	  newalc = ldinfo->string_alc * 2;
3532	  if (newalc == 0)
3533	    newalc = 32;
3534	  while (ldinfo->string_size + len + 3 > newalc)
3535	    newalc *= 2;
3536
3537	  newstrings = bfd_realloc (ldinfo->strings, newalc);
3538	  if (newstrings == NULL)
3539	    {
3540	      ldinfo->failed = TRUE;
3541	      return FALSE;
3542	    }
3543	  ldinfo->string_alc = newalc;
3544	  ldinfo->strings = newstrings;
3545	}
3546
3547      bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3548		  ldinfo->strings + ldinfo->string_size);
3549      strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3550      ldsym->_l._l_l._l_zeroes = 0;
3551      ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3552      ldinfo->string_size += len + 3;
3553    }
3554
3555  return TRUE;
3556}
3557
3558static bfd_boolean
3559_bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
3560			    struct internal_syment *sym,
3561			    const char *name)
3562{
3563  if (strlen (name) <= SYMNMLEN)
3564    {
3565      strncpy (sym->_n._n_name, name, SYMNMLEN);
3566    }
3567  else
3568    {
3569      bfd_boolean hash;
3570      bfd_size_type indx;
3571
3572      hash = TRUE;
3573      if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
3574	hash = FALSE;
3575      indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
3576      if (indx == (bfd_size_type) -1)
3577	return FALSE;
3578      sym->_n._n_n._n_zeroes = 0;
3579      sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3580    }
3581  return TRUE;
3582}
3583
3584static asection *
3585xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
3586     bfd *abfd;
3587     union internal_auxent *aux;
3588     const char *symbol_name;
3589{
3590  asection *return_value = NULL;
3591
3592  /* .sv64 = x_smclas == 17
3593     This is an invalid csect for 32 bit apps.  */
3594  static const char *names[19] =
3595  {
3596    ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
3597    ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
3598    ".td", NULL, ".sv3264"
3599  };
3600
3601  if ((19 >= aux->x_csect.x_smclas)
3602      && (NULL != names[aux->x_csect.x_smclas]))
3603    {
3604      return_value = bfd_make_section_anyway
3605	(abfd, names[aux->x_csect.x_smclas]);
3606    }
3607  else
3608    {
3609      (*_bfd_error_handler)
3610	(_("%B: symbol `%s' has unrecognized smclas %d"),
3611	 abfd, symbol_name, aux->x_csect.x_smclas);
3612      bfd_set_error (bfd_error_bad_value);
3613    }
3614
3615  return return_value;
3616}
3617
3618static bfd_boolean
3619xcoff_is_lineno_count_overflow (abfd, value)
3620    bfd *abfd ATTRIBUTE_UNUSED;
3621	bfd_vma value;
3622{
3623  if (0xffff <= value)
3624    return TRUE;
3625
3626  return FALSE;
3627}
3628
3629static bfd_boolean
3630xcoff_is_reloc_count_overflow (abfd, value)
3631    bfd *abfd ATTRIBUTE_UNUSED;
3632	bfd_vma value;
3633{
3634  if (0xffff <= value)
3635    return TRUE;
3636
3637  return FALSE;
3638}
3639
3640static bfd_vma
3641xcoff_loader_symbol_offset (abfd, ldhdr)
3642    bfd *abfd;
3643    struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
3644{
3645  return bfd_xcoff_ldhdrsz (abfd);
3646}
3647
3648static bfd_vma
3649xcoff_loader_reloc_offset (abfd, ldhdr)
3650    bfd *abfd;
3651    struct internal_ldhdr *ldhdr;
3652{
3653  return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
3654}
3655
3656static bfd_boolean
3657xcoff_generate_rtinit  (abfd, init, fini, rtld)
3658     bfd *abfd;
3659     const char *init;
3660     const char *fini;
3661     bfd_boolean rtld;
3662{
3663  bfd_byte filehdr_ext[FILHSZ];
3664  bfd_byte scnhdr_ext[SCNHSZ];
3665  bfd_byte syment_ext[SYMESZ * 10];
3666  bfd_byte reloc_ext[RELSZ * 3];
3667  bfd_byte *data_buffer;
3668  bfd_size_type data_buffer_size;
3669  bfd_byte *string_table = NULL, *st_tmp = NULL;
3670  bfd_size_type string_table_size;
3671  bfd_vma val;
3672  size_t initsz, finisz;
3673  struct internal_filehdr filehdr;
3674  struct internal_scnhdr scnhdr;
3675  struct internal_syment syment;
3676  union internal_auxent auxent;
3677  struct internal_reloc reloc;
3678
3679  char *data_name = ".data";
3680  char *rtinit_name = "__rtinit";
3681  char *rtld_name = "__rtld";
3682
3683  if (! bfd_xcoff_rtinit_size (abfd))
3684    return FALSE;
3685
3686  initsz = (init == NULL ? 0 : 1 + strlen (init));
3687  finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3688
3689  /* file header */
3690  memset (filehdr_ext, 0, FILHSZ);
3691  memset (&filehdr, 0, sizeof (struct internal_filehdr));
3692  filehdr.f_magic = bfd_xcoff_magic_number (abfd);
3693  filehdr.f_nscns = 1;
3694  filehdr.f_timdat = 0;
3695  filehdr.f_nsyms = 0;  /* at least 6, no more than 10 */
3696  filehdr.f_symptr = 0; /* set below */
3697  filehdr.f_opthdr = 0;
3698  filehdr.f_flags = 0;
3699
3700  /* section header */
3701  memset (scnhdr_ext, 0, SCNHSZ);
3702  memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3703  memcpy (scnhdr.s_name, data_name, strlen (data_name));
3704  scnhdr.s_paddr = 0;
3705  scnhdr.s_vaddr = 0;
3706  scnhdr.s_size = 0;    /* set below */
3707  scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3708  scnhdr.s_relptr = 0;  /* set below */
3709  scnhdr.s_lnnoptr = 0;
3710  scnhdr.s_nreloc = 0;  /* either 1 or 2 */
3711  scnhdr.s_nlnno = 0;
3712  scnhdr.s_flags = STYP_DATA;
3713
3714  /* .data
3715     0x0000	      0x00000000 : rtl
3716     0x0004	      0x00000010 : offset to init, or 0
3717     0x0008	      0x00000028 : offset to fini, or 0
3718     0x000C	      0x0000000C : size of descriptor
3719     0x0010	      0x00000000 : init, needs a reloc
3720     0x0014	      0x00000040 : offset to init name
3721     0x0018	      0x00000000 : flags, padded to a word
3722     0x001C	      0x00000000 : empty init
3723     0x0020	      0x00000000 :
3724     0x0024	      0x00000000 :
3725     0x0028	      0x00000000 : fini, needs a reloc
3726     0x002C	      0x00000??? : offset to fini name
3727     0x0030	      0x00000000 : flags, padded to a word
3728     0x0034	      0x00000000 : empty fini
3729     0x0038	      0x00000000 :
3730     0x003C	      0x00000000 :
3731     0x0040	      init name
3732     0x0040 + initsz  fini name */
3733
3734  data_buffer_size = 0x0040 + initsz + finisz;
3735  data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
3736  data_buffer = NULL;
3737  data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
3738  if (data_buffer == NULL)
3739    return FALSE;
3740
3741  if (initsz)
3742    {
3743      val = 0x10;
3744      bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
3745      val = 0x40;
3746      bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
3747      memcpy (&data_buffer[val], init, initsz);
3748    }
3749
3750  if (finisz)
3751    {
3752      val = 0x28;
3753      bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
3754      val = 0x40 + initsz;
3755      bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
3756      memcpy (&data_buffer[val], fini, finisz);
3757    }
3758
3759  val = 0x0C;
3760  bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
3761
3762  scnhdr.s_size = data_buffer_size;
3763
3764  /* string table */
3765  string_table_size = 0;
3766  if (initsz > 9)
3767    string_table_size += initsz;
3768  if (finisz > 9)
3769    string_table_size += finisz;
3770  if (string_table_size)
3771    {
3772      string_table_size += 4;
3773      string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
3774      if (string_table == NULL)
3775	return FALSE;
3776
3777      val = string_table_size;
3778      bfd_h_put_32 (abfd, val, &string_table[0]);
3779      st_tmp = string_table + 4;
3780    }
3781
3782  /* symbols
3783     0. .data csect
3784     2. __rtinit
3785     4. init function
3786     6. fini function
3787     8. __rtld  */
3788  memset (syment_ext, 0, 10 * SYMESZ);
3789  memset (reloc_ext, 0, 3 * RELSZ);
3790
3791  /* .data csect */
3792  memset (&syment, 0, sizeof (struct internal_syment));
3793  memset (&auxent, 0, sizeof (union internal_auxent));
3794  memcpy (syment._n._n_name, data_name, strlen (data_name));
3795  syment.n_scnum = 1;
3796  syment.n_sclass = C_HIDEXT;
3797  syment.n_numaux = 1;
3798  auxent.x_csect.x_scnlen.l = data_buffer_size;
3799  auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
3800  auxent.x_csect.x_smclas = XMC_RW;
3801  bfd_coff_swap_sym_out (abfd, &syment,
3802			 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3803  bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3804			 syment.n_numaux,
3805			 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3806  filehdr.f_nsyms += 2;
3807
3808  /* __rtinit */
3809  memset (&syment, 0, sizeof (struct internal_syment));
3810  memset (&auxent, 0, sizeof (union internal_auxent));
3811  memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
3812  syment.n_scnum = 1;
3813  syment.n_sclass = C_EXT;
3814  syment.n_numaux = 1;
3815  auxent.x_csect.x_smtyp = XTY_LD;
3816  auxent.x_csect.x_smclas = XMC_RW;
3817  bfd_coff_swap_sym_out (abfd, &syment,
3818			 &syment_ext[filehdr.f_nsyms * SYMESZ]);
3819  bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3820			 syment.n_numaux,
3821			 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3822  filehdr.f_nsyms += 2;
3823
3824  /* init */
3825  if (initsz)
3826    {
3827      memset (&syment, 0, sizeof (struct internal_syment));
3828      memset (&auxent, 0, sizeof (union internal_auxent));
3829
3830      if (initsz > 9)
3831	{
3832	  syment._n._n_n._n_offset = st_tmp - string_table;
3833	  memcpy (st_tmp, init, initsz);
3834	  st_tmp += initsz;
3835	}
3836      else
3837	memcpy (syment._n._n_name, init, initsz - 1);
3838
3839      syment.n_sclass = C_EXT;
3840      syment.n_numaux = 1;
3841      bfd_coff_swap_sym_out (abfd, &syment,
3842			     &syment_ext[filehdr.f_nsyms * SYMESZ]);
3843      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3844			     syment.n_numaux,
3845			     &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3846
3847      /* reloc */
3848      memset (&reloc, 0, sizeof (struct internal_reloc));
3849      reloc.r_vaddr = 0x0010;
3850      reloc.r_symndx = filehdr.f_nsyms;
3851      reloc.r_type = R_POS;
3852      reloc.r_size = 31;
3853      bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
3854
3855      filehdr.f_nsyms += 2;
3856      scnhdr.s_nreloc += 1;
3857    }
3858
3859  /* fini */
3860  if (finisz)
3861    {
3862      memset (&syment, 0, sizeof (struct internal_syment));
3863      memset (&auxent, 0, sizeof (union internal_auxent));
3864
3865      if (finisz > 9)
3866	{
3867	  syment._n._n_n._n_offset = st_tmp - string_table;
3868	  memcpy (st_tmp, fini, finisz);
3869	  st_tmp += finisz;
3870	}
3871      else
3872	memcpy (syment._n._n_name, fini, finisz - 1);
3873
3874      syment.n_sclass = C_EXT;
3875      syment.n_numaux = 1;
3876      bfd_coff_swap_sym_out (abfd, &syment,
3877			     &syment_ext[filehdr.f_nsyms * SYMESZ]);
3878      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3879			     syment.n_numaux,
3880			     &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3881
3882      /* reloc */
3883      memset (&reloc, 0, sizeof (struct internal_reloc));
3884      reloc.r_vaddr = 0x0028;
3885      reloc.r_symndx = filehdr.f_nsyms;
3886      reloc.r_type = R_POS;
3887      reloc.r_size = 31;
3888      bfd_coff_swap_reloc_out (abfd, &reloc,
3889			       &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3890
3891      filehdr.f_nsyms += 2;
3892      scnhdr.s_nreloc += 1;
3893    }
3894
3895  if (rtld)
3896    {
3897      memset (&syment, 0, sizeof (struct internal_syment));
3898      memset (&auxent, 0, sizeof (union internal_auxent));
3899      memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
3900      syment.n_sclass = C_EXT;
3901      syment.n_numaux = 1;
3902      bfd_coff_swap_sym_out (abfd, &syment,
3903			     &syment_ext[filehdr.f_nsyms * SYMESZ]);
3904      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3905			     syment.n_numaux,
3906			     &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3907
3908      /* reloc */
3909      memset (&reloc, 0, sizeof (struct internal_reloc));
3910      reloc.r_vaddr = 0x0000;
3911      reloc.r_symndx = filehdr.f_nsyms;
3912      reloc.r_type = R_POS;
3913      reloc.r_size = 31;
3914      bfd_coff_swap_reloc_out (abfd, &reloc,
3915			       &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3916
3917      filehdr.f_nsyms += 2;
3918      scnhdr.s_nreloc += 1;
3919    }
3920
3921  scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
3922  filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
3923
3924  bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
3925  bfd_bwrite (filehdr_ext, FILHSZ, abfd);
3926  bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
3927  bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
3928  bfd_bwrite (data_buffer, data_buffer_size, abfd);
3929  bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
3930  bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
3931  bfd_bwrite (string_table, string_table_size, abfd);
3932
3933  free (data_buffer);
3934  data_buffer = NULL;
3935
3936  return TRUE;
3937}
3938
3939
3940static reloc_howto_type xcoff_dynamic_reloc =
3941HOWTO (0,			/* type */
3942       0,			/* rightshift */
3943       2,			/* size (0 = byte, 1 = short, 2 = long) */
3944       32,			/* bitsize */
3945       FALSE,			/* pc_relative */
3946       0,			/* bitpos */
3947       complain_overflow_bitfield, /* complain_on_overflow */
3948       0,			/* special_function */
3949       "R_POS",			/* name */
3950       TRUE,			/* partial_inplace */
3951       0xffffffff,		/* src_mask */
3952       0xffffffff,		/* dst_mask */
3953       FALSE);			/* pcrel_offset */
3954
3955/*  glink
3956
3957   The first word of global linkage code must be modified by filling in
3958   the correct TOC offset.  */
3959
3960static unsigned long xcoff_glink_code[9] =
3961  {
3962    0x81820000,	/* lwz r12,0(r2) */
3963    0x90410014,	/* stw r2,20(r1) */
3964    0x800c0000,	/* lwz r0,0(r12) */
3965    0x804c0004,	/* lwz r2,4(r12) */
3966    0x7c0903a6,	/* mtctr r0 */
3967    0x4e800420,	/* bctr */
3968    0x00000000,	/* start of traceback table */
3969    0x000c8000,	/* traceback table */
3970    0x00000000,	/* traceback table */
3971  };
3972
3973
3974static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
3975  {
3976    { /* COFF backend, defined in libcoff.h.  */
3977      _bfd_xcoff_swap_aux_in,
3978      _bfd_xcoff_swap_sym_in,
3979      coff_swap_lineno_in,
3980      _bfd_xcoff_swap_aux_out,
3981      _bfd_xcoff_swap_sym_out,
3982      coff_swap_lineno_out,
3983      xcoff_swap_reloc_out,
3984      coff_swap_filehdr_out,
3985      coff_swap_aouthdr_out,
3986      coff_swap_scnhdr_out,
3987      FILHSZ,
3988      AOUTSZ,
3989      SCNHSZ,
3990      SYMESZ,
3991      AUXESZ,
3992      RELSZ,
3993      LINESZ,
3994      FILNMLEN,
3995      TRUE,			/* _bfd_coff_long_filenames */
3996      FALSE,			/* _bfd_coff_long_section_names */
3997      3,			/* _bfd_coff_default_section_alignment_power */
3998      FALSE,			/* _bfd_coff_force_symnames_in_strings */
3999      2,			/* _bfd_coff_debug_string_prefix_length */
4000      coff_swap_filehdr_in,
4001      coff_swap_aouthdr_in,
4002      coff_swap_scnhdr_in,
4003      xcoff_swap_reloc_in,
4004      coff_bad_format_hook,
4005      coff_set_arch_mach_hook,
4006      coff_mkobject_hook,
4007      styp_to_sec_flags,
4008      coff_set_alignment_hook,
4009      coff_slurp_symbol_table,
4010      symname_in_debug_hook,
4011      coff_pointerize_aux_hook,
4012      coff_print_aux,
4013      dummy_reloc16_extra_cases,
4014      dummy_reloc16_estimate,
4015      NULL,			/* bfd_coff_sym_is_global */
4016      coff_compute_section_file_positions,
4017      NULL,			/* _bfd_coff_start_final_link */
4018      xcoff_ppc_relocate_section,
4019      coff_rtype_to_howto,
4020      NULL,			/* _bfd_coff_adjust_symndx */
4021      _bfd_generic_link_add_one_symbol,
4022      coff_link_output_has_begun,
4023      coff_final_link_postscript
4024    },
4025
4026    0x01DF,			/* magic number */
4027    bfd_arch_rs6000,
4028    bfd_mach_rs6k,
4029
4030    /* Function pointers to xcoff specific swap routines.  */
4031    xcoff_swap_ldhdr_in,
4032    xcoff_swap_ldhdr_out,
4033    xcoff_swap_ldsym_in,
4034    xcoff_swap_ldsym_out,
4035    xcoff_swap_ldrel_in,
4036    xcoff_swap_ldrel_out,
4037
4038    /* Sizes.  */
4039    LDHDRSZ,
4040    LDSYMSZ,
4041    LDRELSZ,
4042    12,				/* _xcoff_function_descriptor_size */
4043    SMALL_AOUTSZ,
4044
4045    /* Versions.  */
4046    1,				/* _xcoff_ldhdr_version */
4047
4048    _bfd_xcoff_put_symbol_name,
4049    _bfd_xcoff_put_ldsymbol_name,
4050    &xcoff_dynamic_reloc,
4051    xcoff_create_csect_from_smclas,
4052
4053    /* Lineno and reloc count overflow.  */
4054    xcoff_is_lineno_count_overflow,
4055    xcoff_is_reloc_count_overflow,
4056
4057    xcoff_loader_symbol_offset,
4058    xcoff_loader_reloc_offset,
4059
4060    /* glink.  */
4061    &xcoff_glink_code[0],
4062    36,				/* _xcoff_glink_size */
4063
4064    /* rtinit */
4065    64,				/* _xcoff_rtinit_size */
4066    xcoff_generate_rtinit,
4067  };
4068
4069/* The transfer vector that leads the outside world to all of the above.  */
4070const bfd_target rs6000coff_vec =
4071  {
4072    "aixcoff-rs6000",
4073    bfd_target_xcoff_flavour,
4074    BFD_ENDIAN_BIG,		/* data byte order is big */
4075    BFD_ENDIAN_BIG,		/* header byte order is big */
4076
4077    (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4078     | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4079
4080    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
4081    0,				/* leading char */
4082    '/',			/* ar_pad_char */
4083    15,				/* ar_max_namelen */
4084
4085    /* data */
4086    bfd_getb64,
4087    bfd_getb_signed_64,
4088    bfd_putb64,
4089    bfd_getb32,
4090    bfd_getb_signed_32,
4091    bfd_putb32,
4092    bfd_getb16,
4093    bfd_getb_signed_16,
4094    bfd_putb16,
4095
4096    /* hdrs */
4097    bfd_getb64,
4098    bfd_getb_signed_64,
4099    bfd_putb64,
4100    bfd_getb32,
4101    bfd_getb_signed_32,
4102    bfd_putb32,
4103    bfd_getb16,
4104    bfd_getb_signed_16,
4105    bfd_putb16,
4106
4107    { /* bfd_check_format */
4108      _bfd_dummy_target,
4109      coff_object_p,
4110      _bfd_xcoff_archive_p,
4111      CORE_FILE_P
4112    },
4113
4114    { /* bfd_set_format */
4115      bfd_false,
4116      coff_mkobject,
4117      _bfd_generic_mkarchive,
4118      bfd_false
4119    },
4120
4121    {/* bfd_write_contents */
4122      bfd_false,
4123      coff_write_object_contents,
4124      _bfd_xcoff_write_archive_contents,
4125      bfd_false
4126    },
4127
4128    /* Generic */
4129    bfd_true,
4130    bfd_true,
4131    coff_new_section_hook,
4132    _bfd_generic_get_section_contents,
4133    _bfd_generic_get_section_contents_in_window,
4134
4135    /* Copy */
4136    _bfd_xcoff_copy_private_bfd_data,
4137    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4138    _bfd_generic_init_private_section_data,
4139    ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4140    ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4141    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4142    ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
4143    ((bfd_boolean (*) (bfd *, void * )) bfd_true),
4144
4145    /* Core */
4146    coff_core_file_failing_command,
4147    coff_core_file_failing_signal,
4148    coff_core_file_matches_executable_p,
4149
4150    /* Archive */
4151    _bfd_xcoff_slurp_armap,
4152    bfd_false,
4153    ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4154    bfd_dont_truncate_arname,
4155    _bfd_xcoff_write_armap,
4156    _bfd_xcoff_read_ar_hdr,
4157    _bfd_xcoff_openr_next_archived_file,
4158    _bfd_generic_get_elt_at_index,
4159    _bfd_xcoff_stat_arch_elt,
4160    bfd_true,
4161
4162    /* Symbols */
4163    coff_get_symtab_upper_bound,
4164    coff_canonicalize_symtab,
4165    coff_make_empty_symbol,
4166    coff_print_symbol,
4167    coff_get_symbol_info,
4168    _bfd_xcoff_is_local_label_name,
4169    coff_bfd_is_target_special_symbol,
4170    coff_get_lineno,
4171    coff_find_nearest_line,
4172    _bfd_generic_find_line,
4173    coff_find_inliner_info,
4174    coff_bfd_make_debug_symbol,
4175    _bfd_generic_read_minisymbols,
4176    _bfd_generic_minisymbol_to_symbol,
4177
4178    /* Reloc */
4179    coff_get_reloc_upper_bound,
4180    coff_canonicalize_reloc,
4181    _bfd_xcoff_reloc_type_lookup,
4182
4183    /* Write */
4184    coff_set_arch_mach,
4185    coff_set_section_contents,
4186
4187    /* Link */
4188    _bfd_xcoff_sizeof_headers,
4189    bfd_generic_get_relocated_section_contents,
4190    bfd_generic_relax_section,
4191    _bfd_xcoff_bfd_link_hash_table_create,
4192    _bfd_generic_link_hash_table_free,
4193    _bfd_xcoff_bfd_link_add_symbols,
4194    _bfd_generic_link_just_syms,
4195    _bfd_xcoff_bfd_final_link,
4196    _bfd_generic_link_split_section,
4197    bfd_generic_gc_sections,
4198    bfd_generic_merge_sections,
4199    bfd_generic_is_group_section,
4200    bfd_generic_discard_group,
4201    _bfd_generic_section_already_linked,
4202
4203    /* Dynamic */
4204    _bfd_xcoff_get_dynamic_symtab_upper_bound,
4205    _bfd_xcoff_canonicalize_dynamic_symtab,
4206    _bfd_nodynamic_get_synthetic_symtab,
4207    _bfd_xcoff_get_dynamic_reloc_upper_bound,
4208    _bfd_xcoff_canonicalize_dynamic_reloc,
4209
4210    /* Opposite endian version, none exists */
4211    NULL,
4212
4213    (void *) &bfd_xcoff_backend_data,
4214  };
4215
4216/* xcoff-powermac target
4217   Old target.
4218   Only difference between this target and the rs6000 target is the
4219   the default architecture and machine type used in coffcode.h
4220
4221   PowerPC Macs use the same magic numbers as RS/6000
4222   (because that's how they were bootstrapped originally),
4223   but they are always PowerPC architecture.  */
4224static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
4225  {
4226    { /* COFF backend, defined in libcoff.h.  */
4227      _bfd_xcoff_swap_aux_in,
4228      _bfd_xcoff_swap_sym_in,
4229      coff_swap_lineno_in,
4230      _bfd_xcoff_swap_aux_out,
4231      _bfd_xcoff_swap_sym_out,
4232      coff_swap_lineno_out,
4233      xcoff_swap_reloc_out,
4234      coff_swap_filehdr_out,
4235      coff_swap_aouthdr_out,
4236      coff_swap_scnhdr_out,
4237      FILHSZ,
4238      AOUTSZ,
4239      SCNHSZ,
4240      SYMESZ,
4241      AUXESZ,
4242      RELSZ,
4243      LINESZ,
4244      FILNMLEN,
4245      TRUE,			/* _bfd_coff_long_filenames */
4246      FALSE,			/* _bfd_coff_long_section_names */
4247      3,			/* _bfd_coff_default_section_alignment_power */
4248      FALSE,			/* _bfd_coff_force_symnames_in_strings */
4249      2,			/* _bfd_coff_debug_string_prefix_length */
4250      coff_swap_filehdr_in,
4251      coff_swap_aouthdr_in,
4252      coff_swap_scnhdr_in,
4253      xcoff_swap_reloc_in,
4254      coff_bad_format_hook,
4255      coff_set_arch_mach_hook,
4256      coff_mkobject_hook,
4257      styp_to_sec_flags,
4258      coff_set_alignment_hook,
4259      coff_slurp_symbol_table,
4260      symname_in_debug_hook,
4261      coff_pointerize_aux_hook,
4262      coff_print_aux,
4263      dummy_reloc16_extra_cases,
4264      dummy_reloc16_estimate,
4265      NULL,			/* bfd_coff_sym_is_global */
4266      coff_compute_section_file_positions,
4267      NULL,			/* _bfd_coff_start_final_link */
4268      xcoff_ppc_relocate_section,
4269      coff_rtype_to_howto,
4270      NULL,			/* _bfd_coff_adjust_symndx */
4271      _bfd_generic_link_add_one_symbol,
4272      coff_link_output_has_begun,
4273      coff_final_link_postscript
4274    },
4275
4276    0x01DF,			/* magic number */
4277    bfd_arch_powerpc,
4278    bfd_mach_ppc,
4279
4280    /* Function pointers to xcoff specific swap routines.  */
4281    xcoff_swap_ldhdr_in,
4282    xcoff_swap_ldhdr_out,
4283    xcoff_swap_ldsym_in,
4284    xcoff_swap_ldsym_out,
4285    xcoff_swap_ldrel_in,
4286    xcoff_swap_ldrel_out,
4287
4288    /* Sizes.  */
4289    LDHDRSZ,
4290    LDSYMSZ,
4291    LDRELSZ,
4292    12,				/* _xcoff_function_descriptor_size */
4293    SMALL_AOUTSZ,
4294
4295    /* Versions.  */
4296    1,				/* _xcoff_ldhdr_version */
4297
4298    _bfd_xcoff_put_symbol_name,
4299    _bfd_xcoff_put_ldsymbol_name,
4300    &xcoff_dynamic_reloc,
4301    xcoff_create_csect_from_smclas,
4302
4303    /* Lineno and reloc count overflow.  */
4304    xcoff_is_lineno_count_overflow,
4305    xcoff_is_reloc_count_overflow,
4306
4307    xcoff_loader_symbol_offset,
4308    xcoff_loader_reloc_offset,
4309
4310    /* glink.  */
4311    &xcoff_glink_code[0],
4312    36,				/* _xcoff_glink_size */
4313
4314    /* rtinit */
4315    0,				/* _xcoff_rtinit_size */
4316    xcoff_generate_rtinit,
4317  };
4318
4319/* The transfer vector that leads the outside world to all of the above.  */
4320const bfd_target pmac_xcoff_vec =
4321  {
4322    "xcoff-powermac",
4323    bfd_target_xcoff_flavour,
4324    BFD_ENDIAN_BIG,		/* data byte order is big */
4325    BFD_ENDIAN_BIG,		/* header byte order is big */
4326
4327    (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4328     | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4329
4330    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
4331    0,				/* leading char */
4332    '/',			/* ar_pad_char */
4333    15,				/* ar_max_namelen */
4334
4335    /* data */
4336    bfd_getb64,
4337    bfd_getb_signed_64,
4338    bfd_putb64,
4339    bfd_getb32,
4340    bfd_getb_signed_32,
4341    bfd_putb32,
4342    bfd_getb16,
4343    bfd_getb_signed_16,
4344    bfd_putb16,
4345
4346    /* hdrs */
4347    bfd_getb64,
4348    bfd_getb_signed_64,
4349    bfd_putb64,
4350    bfd_getb32,
4351    bfd_getb_signed_32,
4352    bfd_putb32,
4353    bfd_getb16,
4354    bfd_getb_signed_16,
4355    bfd_putb16,
4356
4357    { /* bfd_check_format */
4358      _bfd_dummy_target,
4359      coff_object_p,
4360      _bfd_xcoff_archive_p,
4361      CORE_FILE_P
4362    },
4363
4364    { /* bfd_set_format */
4365      bfd_false,
4366      coff_mkobject,
4367      _bfd_generic_mkarchive,
4368      bfd_false
4369    },
4370
4371    {/* bfd_write_contents */
4372      bfd_false,
4373      coff_write_object_contents,
4374      _bfd_xcoff_write_archive_contents,
4375      bfd_false
4376    },
4377
4378    /* Generic */
4379    bfd_true,
4380    bfd_true,
4381    coff_new_section_hook,
4382    _bfd_generic_get_section_contents,
4383    _bfd_generic_get_section_contents_in_window,
4384
4385    /* Copy */
4386    _bfd_xcoff_copy_private_bfd_data,
4387    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4388    _bfd_generic_init_private_section_data,
4389    ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4390    ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4391    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4392    ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
4393    ((bfd_boolean (*) (bfd *, void * )) bfd_true),
4394
4395    /* Core */
4396    coff_core_file_failing_command,
4397    coff_core_file_failing_signal,
4398    coff_core_file_matches_executable_p,
4399
4400    /* Archive */
4401    _bfd_xcoff_slurp_armap,
4402    bfd_false,
4403    ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4404    bfd_dont_truncate_arname,
4405    _bfd_xcoff_write_armap,
4406    _bfd_xcoff_read_ar_hdr,
4407    _bfd_xcoff_openr_next_archived_file,
4408    _bfd_generic_get_elt_at_index,
4409    _bfd_xcoff_stat_arch_elt,
4410    bfd_true,
4411
4412    /* Symbols */
4413    coff_get_symtab_upper_bound,
4414    coff_canonicalize_symtab,
4415    coff_make_empty_symbol,
4416    coff_print_symbol,
4417    coff_get_symbol_info,
4418    _bfd_xcoff_is_local_label_name,
4419    coff_bfd_is_target_special_symbol,
4420    coff_get_lineno,
4421    coff_find_nearest_line,
4422    _bfd_generic_find_line,
4423    coff_find_inliner_info,
4424    coff_bfd_make_debug_symbol,
4425    _bfd_generic_read_minisymbols,
4426    _bfd_generic_minisymbol_to_symbol,
4427
4428    /* Reloc */
4429    coff_get_reloc_upper_bound,
4430    coff_canonicalize_reloc,
4431    _bfd_xcoff_reloc_type_lookup,
4432
4433    /* Write */
4434    coff_set_arch_mach,
4435    coff_set_section_contents,
4436
4437    /* Link */
4438    _bfd_xcoff_sizeof_headers,
4439    bfd_generic_get_relocated_section_contents,
4440    bfd_generic_relax_section,
4441    _bfd_xcoff_bfd_link_hash_table_create,
4442    _bfd_generic_link_hash_table_free,
4443    _bfd_xcoff_bfd_link_add_symbols,
4444    _bfd_generic_link_just_syms,
4445    _bfd_xcoff_bfd_final_link,
4446    _bfd_generic_link_split_section,
4447    bfd_generic_gc_sections,
4448    bfd_generic_merge_sections,
4449    bfd_generic_is_group_section,
4450    bfd_generic_discard_group,
4451    _bfd_generic_section_already_linked,
4452
4453    /* Dynamic */
4454    _bfd_xcoff_get_dynamic_symtab_upper_bound,
4455    _bfd_xcoff_canonicalize_dynamic_symtab,
4456    _bfd_nodynamic_get_synthetic_symtab,
4457    _bfd_xcoff_get_dynamic_reloc_upper_bound,
4458    _bfd_xcoff_canonicalize_dynamic_reloc,
4459
4460    /* Opposite endian version, none exists */
4461    NULL,
4462
4463    (void *) &bfd_pmac_xcoff_backend_data,
4464  };
4465