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