OSDN Git Service

Replace bfd_alloc/bfd_malloc + memset with bfd_zalloc/bfd_zmalloc
[pf3gnuchains/pf3gnuchains3x.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_zmalloc (symbol_table_size);
1843       if (symbol_table == NULL)
1844         return false;
1845
1846       hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1847         
1848       PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
1849         
1850       if (sym_64)
1851         PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
1852       else
1853         PRINT20 (hdr->nextoff, 0);
1854
1855       PRINT20 (hdr->prevoff, prevoff);
1856       PRINT12 (hdr->date, 0);
1857       PRINT12 (hdr->uid, 0);
1858       PRINT12 (hdr->gid, 0);
1859       PRINT12 (hdr->mode, 0);
1860       PRINT4 (hdr->namlen, 0) ;
1861
1862       st = symbol_table + SIZEOF_AR_HDR_BIG;
1863       memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1864       st += SXCOFFARFMAG;
1865
1866       bfd_h_put_64 (abfd, sym_32, st);
1867       st += 8;
1868       
1869       /* loop over the 32 bit offsets */
1870       current_bfd = abfd->archive_head;
1871       if (current_bfd != NULL)
1872         arch_info = bfd_get_arch_info (current_bfd);
1873       fileoff = SIZEOF_AR_FILE_HDR_BIG;
1874       i = 0;
1875       while (current_bfd != NULL && i < orl_count)
1876         {
1877           while (map[i].u.abfd == current_bfd)
1878             {
1879               if (arch_info->bits_per_address == 32)
1880                 {
1881                   bfd_h_put_64 (abfd, fileoff, st);
1882                   st += 8;
1883                 }
1884               i++;
1885             }
1886           string_length = strlen (normalize_filename (current_bfd));
1887           string_length += string_length & 1;
1888           fileoff += (SIZEOF_AR_HDR_BIG
1889                       + string_length
1890                       + SXCOFFARFMAG
1891                       + arelt_size (current_bfd));
1892           fileoff += fileoff & 1;
1893           current_bfd = current_bfd->next;
1894           if (current_bfd != NULL)
1895             arch_info = bfd_get_arch_info (current_bfd);
1896         }
1897
1898       /* loop over the 32 bit symbol names */
1899       current_bfd = abfd->archive_head;
1900       if (current_bfd != NULL)
1901         arch_info = bfd_get_arch_info (current_bfd);
1902       i = 0;
1903       while (current_bfd != NULL && i < orl_count)
1904         {
1905           while (map[i].u.abfd == current_bfd)
1906             {
1907               if (arch_info->bits_per_address == 32)
1908                 {
1909                   string_length = sprintf (st, "%s", *map[i].name);
1910                   st += string_length + 1;
1911                 }
1912               i++;
1913             }
1914           current_bfd = current_bfd->next;
1915           if (current_bfd != NULL)
1916             arch_info = bfd_get_arch_info (current_bfd);
1917         }
1918
1919       bfd_bwrite (symbol_table, symbol_table_size, abfd);
1920
1921       free (symbol_table);
1922       symbol_table = NULL;
1923
1924       prevoff = nextoff;
1925       nextoff = nextoff + symbol_table_size;
1926     }
1927   else 
1928     PRINT20 (fhdr->symoff, 0);
1929   
1930   if (sym_64) 
1931     {
1932       struct xcoff_ar_hdr_big *hdr;
1933       bfd_byte *symbol_table;
1934       bfd_byte *st;
1935       file_ptr fileoff;
1936
1937       bfd_vma symbol_table_size = 
1938         SIZEOF_AR_HDR_BIG
1939         + SXCOFFARFMAG
1940         + 8 
1941         + 8 * sym_64 
1942         + str_64 + (str_64 & 1);
1943
1944       symbol_table = NULL;
1945       symbol_table = (bfd_byte *) bfd_zmalloc (symbol_table_size);
1946       if (symbol_table == NULL)
1947         return false;
1948
1949       hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1950
1951       PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
1952       PRINT20 (hdr->nextoff, 0);
1953       PRINT20 (hdr->prevoff, prevoff);
1954       PRINT12 (hdr->date, 0);
1955       PRINT12 (hdr->uid, 0);
1956       PRINT12 (hdr->gid, 0);
1957       PRINT12 (hdr->mode, 0);
1958       PRINT4 (hdr->namlen, 0);
1959
1960       st = symbol_table + SIZEOF_AR_HDR_BIG;
1961       memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1962       st += SXCOFFARFMAG;
1963
1964       bfd_h_put_64 (abfd, sym_64, st);
1965       st += 8;
1966       
1967       /* loop over the 64 bit offsets */
1968       current_bfd = abfd->archive_head;
1969       if (current_bfd != NULL)
1970         arch_info = bfd_get_arch_info (current_bfd);
1971       fileoff = SIZEOF_AR_FILE_HDR_BIG;
1972       i = 0;
1973       while (current_bfd != NULL && i < orl_count)
1974         {
1975           while (map[i].u.abfd == current_bfd)
1976             {
1977               if (arch_info->bits_per_address == 64)
1978                 {
1979                   bfd_h_put_64 (abfd, fileoff, st);
1980                   st += 8;
1981                 }
1982               i++;
1983             }
1984           string_length = strlen (normalize_filename (current_bfd));
1985           string_length += string_length & 1;
1986           fileoff += (SIZEOF_AR_HDR_BIG
1987                       + string_length
1988                       + SXCOFFARFMAG
1989                       + arelt_size (current_bfd));
1990           fileoff += fileoff & 1;
1991           current_bfd = current_bfd->next;
1992           if (current_bfd != NULL)
1993             arch_info = bfd_get_arch_info (current_bfd);
1994         }
1995
1996       /* loop over the 64 bit symbol names */
1997       current_bfd = abfd->archive_head;
1998       if (current_bfd != NULL)
1999         arch_info = bfd_get_arch_info (current_bfd);
2000       i = 0;
2001       while (current_bfd != NULL && i < orl_count)
2002         {
2003           while (map[i].u.abfd == current_bfd)
2004             {
2005               if (arch_info->bits_per_address == 64)
2006                 {
2007                   string_length = sprintf (st, "%s", *map[i].name);
2008                   st += string_length + 1;
2009                 }
2010               i++;
2011             }
2012           current_bfd = current_bfd->next;
2013           if (current_bfd != NULL)
2014             arch_info = bfd_get_arch_info (current_bfd);
2015         }
2016
2017       bfd_bwrite (symbol_table, symbol_table_size, abfd);
2018
2019       free (symbol_table);
2020       symbol_table = NULL;
2021
2022       PRINT20 (fhdr->symoff64, nextoff);
2023     }
2024   else 
2025     PRINT20 (fhdr->symoff64, 0);
2026   
2027   return true;
2028 }
2029
2030 boolean
2031 _bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
2032      bfd *abfd;
2033      unsigned int elength ATTRIBUTE_UNUSED;
2034      struct orl *map;
2035      unsigned int orl_count;
2036      int stridx;
2037 {
2038   if (! xcoff_big_format_p (abfd))
2039     return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
2040   else
2041     return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
2042 }
2043
2044 /* Write out an XCOFF archive.  We always write an entire archive,
2045    rather than fussing with the freelist and so forth.  */
2046
2047 static boolean
2048 xcoff_write_archive_contents_old (abfd)
2049      bfd *abfd;
2050 {
2051   struct xcoff_ar_file_hdr fhdr;
2052   bfd_size_type count;
2053   bfd_size_type total_namlen;
2054   file_ptr *offsets;
2055   boolean makemap;
2056   boolean hasobjects;
2057   ufile_ptr prevoff, nextoff;
2058   bfd *sub;
2059   size_t i;
2060   struct xcoff_ar_hdr ahdr;
2061   bfd_size_type size;
2062   char *p;
2063   char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
2064
2065   memset (&fhdr, 0, sizeof fhdr);
2066   strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
2067   sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
2068   sprintf (fhdr.freeoff, "%d", 0);
2069
2070   count = 0;
2071   total_namlen = 0;
2072   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2073     {
2074       ++count;
2075       total_namlen += strlen (normalize_filename (sub)) + 1;
2076     }
2077   offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2078   if (offsets == NULL)
2079     return false;
2080
2081   if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
2082     return false;
2083
2084   makemap = bfd_has_map (abfd);
2085   hasobjects = false;
2086   prevoff = 0;
2087   nextoff = SIZEOF_AR_FILE_HDR;
2088   for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
2089     {
2090       const char *name;
2091       bfd_size_type namlen;
2092       struct xcoff_ar_hdr *ahdrp;
2093       bfd_size_type remaining;
2094
2095       if (makemap && ! hasobjects)
2096         {
2097           if (bfd_check_format (sub, bfd_object))
2098             hasobjects = true;
2099         }
2100
2101       name = normalize_filename (sub);
2102       namlen = strlen (name);
2103
2104       if (sub->arelt_data != NULL)
2105         ahdrp = arch_xhdr (sub);
2106       else
2107         ahdrp = NULL;
2108
2109       if (ahdrp == NULL)
2110         {
2111           struct stat s;
2112
2113           memset (&ahdr, 0, sizeof ahdr);
2114           ahdrp = &ahdr;
2115           if (stat (bfd_get_filename (sub), &s) != 0)
2116             {
2117               bfd_set_error (bfd_error_system_call);
2118               return false;
2119             }
2120
2121           sprintf (ahdrp->size, "%ld", (long) s.st_size);
2122           sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2123           sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2124           sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2125           sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2126
2127           if (sub->arelt_data == NULL)
2128             {
2129               size = sizeof (struct areltdata);
2130               sub->arelt_data = bfd_alloc (sub, size);
2131               if (sub->arelt_data == NULL)
2132                 return false;
2133             }
2134
2135           arch_eltdata (sub)->parsed_size = s.st_size;
2136         }
2137
2138       sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2139       sprintf (ahdrp->namlen, "%ld", (long) namlen);
2140
2141       /* If the length of the name is odd, we write out the null byte
2142          after the name as well.  */
2143       namlen = (namlen + 1) &~ (bfd_size_type) 1;
2144
2145       remaining = arelt_size (sub);
2146       size = (SIZEOF_AR_HDR
2147               + namlen
2148               + SXCOFFARFMAG
2149               + remaining);
2150
2151       BFD_ASSERT (nextoff == bfd_tell (abfd));
2152
2153       offsets[i] = nextoff;
2154
2155       prevoff = nextoff;
2156       nextoff += size + (size & 1);
2157
2158       sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
2159
2160       /* We need spaces, not null bytes, in the header.  */
2161       for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2162         if (*p == '\0')
2163           *p = ' ';
2164
2165       if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2166            != SIZEOF_AR_HDR)
2167           || (bfd_bwrite ((PTR) name, namlen, abfd) != namlen)
2168           || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2169               != SXCOFFARFMAG))
2170         return false;
2171
2172       if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
2173         return false;
2174
2175       if (! do_copy (abfd, sub))
2176         return false;
2177       
2178       if (! do_pad (abfd, size & 1))
2179         return false;
2180     }
2181
2182   sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2183
2184   /* Write out the member table.  */
2185
2186   BFD_ASSERT (nextoff == bfd_tell (abfd));
2187   sprintf (fhdr.memoff, "%ld", (long) nextoff);
2188
2189   memset (&ahdr, 0, sizeof ahdr);
2190   sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE + 
2191                                      count * XCOFFARMAG_ELEMENT_SIZE + 
2192                                      total_namlen));
2193   sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2194   sprintf (ahdr.date, "%d", 0);
2195   sprintf (ahdr.uid, "%d", 0);
2196   sprintf (ahdr.gid, "%d", 0);
2197   sprintf (ahdr.mode, "%d", 0);
2198   sprintf (ahdr.namlen, "%d", 0);
2199
2200   size = (SIZEOF_AR_HDR
2201           + XCOFFARMAG_ELEMENT_SIZE
2202           + count * XCOFFARMAG_ELEMENT_SIZE
2203           + total_namlen
2204           + SXCOFFARFMAG);
2205
2206   prevoff = nextoff;
2207   nextoff += size + (size & 1);
2208
2209   if (makemap && hasobjects)
2210     sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2211   else
2212     sprintf (ahdr.nextoff, "%d", 0);
2213
2214   /* We need spaces, not null bytes, in the header.  */
2215   for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2216     if (*p == '\0')
2217       *p = ' ';
2218
2219   if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2220        != SIZEOF_AR_HDR)
2221       || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2222           != SXCOFFARFMAG))
2223     return false;
2224
2225   sprintf (decbuf, "%-12ld", (long) count);
2226   if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
2227       != XCOFFARMAG_ELEMENT_SIZE)
2228     return false;
2229   for (i = 0; i < (size_t) count; i++)
2230     {
2231       sprintf (decbuf, "%-12ld", (long) offsets[i]);
2232       if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, 
2233                       abfd) != XCOFFARMAG_ELEMENT_SIZE)
2234         return false;
2235     }
2236   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2237     {
2238       const char *name;
2239       bfd_size_type namlen;
2240
2241       name = normalize_filename (sub);
2242       namlen = strlen (name);
2243       if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
2244         return false;
2245     }
2246
2247   if (! do_pad (abfd, size & 1))
2248     return false;
2249
2250   /* Write out the armap, if appropriate.  */
2251   if (! makemap || ! hasobjects)
2252     sprintf (fhdr.symoff, "%d", 0);
2253   else
2254     {
2255       BFD_ASSERT (nextoff == bfd_tell (abfd));
2256       sprintf (fhdr.symoff, "%ld", (long) nextoff);
2257       bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2258       if (! _bfd_compute_and_write_armap (abfd, 0))
2259         return false;
2260     }
2261
2262   /* Write out the archive file header.  */
2263
2264   /* We need spaces, not null bytes, in the header.  */
2265   for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2266     if (*p == '\0')
2267       *p = ' ';
2268
2269   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2270       || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
2271           != SIZEOF_AR_FILE_HDR))
2272     return false;
2273
2274   return true;
2275 }
2276
2277 static boolean
2278 xcoff_write_archive_contents_big (abfd)
2279      bfd *abfd;
2280 {
2281   struct xcoff_ar_file_hdr_big fhdr;
2282   bfd_size_type count;
2283   bfd_size_type total_namlen;
2284   file_ptr *offsets;
2285   boolean makemap;
2286   boolean hasobjects;
2287   ufile_ptr prevoff, nextoff;
2288   bfd *current_bfd;
2289   size_t i;
2290   struct xcoff_ar_hdr_big *hdr, ahdr;
2291   bfd_size_type size;
2292   bfd_byte *member_table, *mt;
2293   bfd_vma member_table_size;
2294
2295   memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
2296   memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
2297
2298   if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
2299     return false;
2300   
2301   /* Calculate count and total_namlen.  */
2302   makemap = bfd_has_map (abfd);
2303   hasobjects = false;
2304   for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0; 
2305        current_bfd != NULL; 
2306        current_bfd = current_bfd->next, count++)
2307     {
2308       total_namlen += strlen (normalize_filename (current_bfd)) + 1;
2309
2310       if (makemap
2311           && ! hasobjects
2312           && bfd_check_format (current_bfd, bfd_object))
2313         hasobjects = true;
2314     }
2315
2316   offsets = NULL;
2317   if (count)
2318     {
2319       offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2320       if (offsets == NULL)
2321         return false;
2322     }
2323
2324   prevoff = 0;
2325   nextoff = SIZEOF_AR_FILE_HDR_BIG;
2326   for (current_bfd = abfd->archive_head, i = 0; 
2327        current_bfd != NULL; 
2328        current_bfd = current_bfd->next, i++)
2329     {
2330       const char *name;
2331       bfd_size_type namlen;
2332       struct xcoff_ar_hdr_big *ahdrp;
2333       bfd_size_type remaining;
2334
2335       name = normalize_filename (current_bfd);
2336       namlen = strlen (name);
2337
2338       if (current_bfd->arelt_data != NULL)
2339         ahdrp = arch_xhdr_big (current_bfd);
2340       else
2341         ahdrp = NULL;
2342
2343       if (ahdrp == NULL)
2344         {
2345           struct stat s;
2346
2347           ahdrp = &ahdr;
2348           /* XXX This should actually be a call to stat64 (at least on
2349              32-bit machines).  
2350              XXX This call will fail if the original object is not found.  */
2351           if (stat (bfd_get_filename (current_bfd), &s) != 0)
2352             {
2353               bfd_set_error (bfd_error_system_call);
2354               return false;
2355             }
2356
2357           PRINT20 (ahdrp->size, s.st_size);
2358           PRINT12 (ahdrp->date, s.st_mtime);
2359           PRINT12 (ahdrp->uid,  s.st_uid);
2360           PRINT12 (ahdrp->gid,  s.st_gid);
2361           PRINT12_OCTAL (ahdrp->mode, s.st_mode);
2362
2363           if (current_bfd->arelt_data == NULL)
2364             {
2365               size = sizeof (struct areltdata);
2366               current_bfd->arelt_data = bfd_alloc (current_bfd, size);
2367               if (current_bfd->arelt_data == NULL)
2368                 return false;
2369             }
2370
2371           arch_eltdata (current_bfd)->parsed_size = s.st_size;
2372         }
2373
2374       PRINT20 (ahdrp->prevoff, prevoff);
2375       PRINT4 (ahdrp->namlen, namlen);
2376
2377       /* If the length of the name is odd, we write out the null byte
2378          after the name as well.  */
2379       namlen = (namlen + 1) &~ (bfd_size_type) 1;
2380
2381       remaining = arelt_size (current_bfd);
2382       size = (SIZEOF_AR_HDR_BIG
2383               + namlen
2384               + SXCOFFARFMAG
2385               + remaining);
2386
2387       BFD_ASSERT (nextoff == bfd_tell (abfd));
2388
2389       /* Check for xcoff shared objects.
2390          Their text section needs to be aligned wrt the archive file position.
2391          This requires extra padding before the archive header.  */
2392       if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
2393                                       SIZEOF_AR_HDR_BIG + namlen 
2394                                       + SXCOFFARFMAG))
2395         return false;
2396
2397       offsets[i] = nextoff;
2398
2399       prevoff = nextoff;
2400       nextoff += size + (size & 1);
2401
2402       PRINT20 (ahdrp->nextoff, nextoff);
2403
2404       if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
2405            != SIZEOF_AR_HDR_BIG)
2406           || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
2407           || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, 
2408                           abfd) != SXCOFFARFMAG))
2409         return false;
2410
2411       if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
2412         return false;
2413
2414       if (! do_copy (abfd, current_bfd))
2415         return false;
2416   
2417       if (! do_pad (abfd, size & 1))
2418         return false;
2419     }
2420
2421   if (count)
2422     {
2423       PRINT20 (fhdr.firstmemoff, offsets[0]);
2424       PRINT20 (fhdr.lastmemoff, prevoff);
2425     }
2426
2427   /* Write out the member table.  
2428      Layout : 
2429
2430      standard big archive header
2431      0x0000                   ar_size   [0x14]
2432      0x0014                   ar_nxtmem [0x14]
2433      0x0028                   ar_prvmem [0x14]
2434      0x003C                   ar_date   [0x0C]
2435      0x0048                   ar_uid    [0x0C]
2436      0x0054                   ar_gid    [0x0C]
2437      0x0060                   ar_mod    [0x0C]
2438      0x006C                   ar_namelen[0x04]
2439      0x0070                   ar_fmag   [0x02]
2440
2441      Member table 
2442      0x0072                   count     [0x14]
2443      0x0086                   offsets   [0x14 * counts]
2444      0x0086 + 0x14 * counts   names     [??]
2445      ??                       pad to even bytes.
2446    */
2447
2448   BFD_ASSERT (nextoff == bfd_tell (abfd));
2449
2450   member_table_size = (SIZEOF_AR_HDR_BIG
2451                        + SXCOFFARFMAG
2452                        + XCOFFARMAGBIG_ELEMENT_SIZE
2453                        + count * XCOFFARMAGBIG_ELEMENT_SIZE
2454                        + total_namlen);
2455
2456   member_table_size += member_table_size & 1;
2457   member_table = NULL;
2458   member_table = (bfd_byte *) bfd_zmalloc (member_table_size);
2459   if (member_table == NULL)
2460     return false;
2461
2462   hdr = (struct xcoff_ar_hdr_big *) member_table;
2463
2464   PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE + 
2465                        count * XCOFFARMAGBIG_ELEMENT_SIZE + 
2466                        total_namlen + (total_namlen & 1)));
2467   if (makemap && hasobjects) 
2468     PRINT20 (hdr->nextoff, nextoff + member_table_size);
2469   else
2470     PRINT20 (hdr->nextoff, 0);
2471   PRINT20 (hdr->prevoff, prevoff);
2472   PRINT12 (hdr->date, 0);
2473   PRINT12 (hdr->uid, 0);
2474   PRINT12 (hdr->gid, 0);
2475   PRINT12 (hdr->mode, 0);
2476   PRINT4 (hdr->namlen, 0);
2477   
2478   mt = member_table + SIZEOF_AR_HDR_BIG;
2479   memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
2480   mt += SXCOFFARFMAG;
2481
2482   PRINT20 (mt, count);
2483   mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2484   for (i = 0; i < (size_t) count; i++)
2485     {
2486       PRINT20 (mt, offsets[i]);
2487       mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2488     }
2489
2490   if (count) 
2491     {
2492       free (offsets);
2493       offsets = NULL;
2494     }
2495
2496   for (current_bfd = abfd->archive_head; current_bfd != NULL; 
2497        current_bfd = current_bfd->next)
2498     {
2499       const char *name;
2500       size_t namlen;
2501
2502       name = normalize_filename (current_bfd);
2503       namlen = sprintf(mt, "%s", name);
2504       mt += namlen + 1;
2505     }
2506   
2507   if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
2508     return false;
2509
2510   free (member_table);
2511   member_table = NULL;
2512
2513   PRINT20 (fhdr.memoff, nextoff);
2514
2515   prevoff = nextoff;
2516   nextoff += member_table_size;
2517
2518   /* Write out the armap, if appropriate.  */
2519
2520   if (! makemap || ! hasobjects) 
2521     PRINT20 (fhdr.symoff, 0);
2522   else
2523     {
2524       BFD_ASSERT (nextoff == bfd_tell (abfd));
2525
2526       /* Save nextoff in fhdr.symoff so the armap routine can use it.  */
2527       PRINT20 (fhdr.symoff, nextoff);
2528       
2529       bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2530       if (! _bfd_compute_and_write_armap (abfd, 0))
2531         return false;
2532     }
2533
2534   /* Write out the archive file header.  */
2535
2536   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2537       || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG, 
2538                       abfd) != SIZEOF_AR_FILE_HDR_BIG))
2539     return false;
2540   
2541   return true;
2542 }
2543
2544 boolean
2545 _bfd_xcoff_write_archive_contents (abfd)
2546      bfd *abfd;
2547 {
2548   if (! xcoff_big_format_p (abfd))
2549     return xcoff_write_archive_contents_old (abfd);
2550   else
2551     return xcoff_write_archive_contents_big (abfd);
2552 }
2553 \f
2554 /* We can't use the usual coff_sizeof_headers routine, because AIX
2555    always uses an a.out header.  */
2556
2557 int
2558 _bfd_xcoff_sizeof_headers (abfd, reloc)
2559      bfd *abfd;
2560      boolean reloc ATTRIBUTE_UNUSED;
2561 {
2562   int size;
2563
2564   size = FILHSZ;
2565   if (xcoff_data (abfd)->full_aouthdr)
2566     size += AOUTSZ;
2567   else
2568     size += SMALL_AOUTSZ;
2569   size += abfd->section_count * SCNHSZ;
2570   return size;
2571 }
2572 \f
2573 /* Routines to swap information in the XCOFF .loader section.  If we
2574    ever need to write an XCOFF loader, this stuff will need to be
2575    moved to another file shared by the linker (which XCOFF calls the
2576    ``binder'') and the loader.  */
2577
2578 /* Swap in the ldhdr structure.  */
2579
2580 static void
2581 xcoff_swap_ldhdr_in (abfd, s, dst)
2582      bfd *abfd;
2583      const PTR s;
2584      struct internal_ldhdr *dst;
2585 {
2586   const struct external_ldhdr *src = (const struct external_ldhdr *) s;
2587
2588   dst->l_version = bfd_get_32 (abfd, src->l_version);
2589   dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
2590   dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
2591   dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
2592   dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
2593   dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
2594   dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
2595   dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
2596 }
2597
2598 /* Swap out the ldhdr structure.  */
2599
2600 static void
2601 xcoff_swap_ldhdr_out (abfd, src, d)
2602      bfd *abfd;
2603      const struct internal_ldhdr *src;
2604      PTR d;
2605 {
2606   struct external_ldhdr *dst = (struct external_ldhdr *) d;
2607
2608   bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
2609   bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
2610   bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
2611   bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
2612   bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
2613   bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
2614   bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
2615   bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
2616 }
2617
2618 /* Swap in the ldsym structure.  */
2619
2620 static void
2621 xcoff_swap_ldsym_in (abfd, s, dst)
2622      bfd *abfd;
2623      const PTR s;
2624      struct internal_ldsym *dst;
2625 {
2626   const struct external_ldsym *src = (const struct external_ldsym *) s;
2627
2628   if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
2629     memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2630   } else {
2631     dst->_l._l_l._l_zeroes = 0;
2632     dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
2633   }
2634   dst->l_value = bfd_get_32 (abfd, src->l_value);
2635   dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
2636   dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
2637   dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
2638   dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
2639   dst->l_parm = bfd_get_32 (abfd, src->l_parm);
2640 }
2641
2642 /* Swap out the ldsym structure.  */
2643
2644 static void
2645 xcoff_swap_ldsym_out (abfd, src, d)
2646      bfd *abfd;
2647      const struct internal_ldsym *src;
2648      PTR d;
2649 {
2650   struct external_ldsym *dst = (struct external_ldsym *) d;
2651
2652   if (src->_l._l_l._l_zeroes != 0)
2653     memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2654   else
2655     {
2656       bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
2657       bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
2658                   dst->_l._l_l._l_offset);
2659     }
2660   bfd_put_32 (abfd, src->l_value, dst->l_value);
2661   bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
2662   bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
2663   bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
2664   bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
2665   bfd_put_32 (abfd, src->l_parm, dst->l_parm);
2666 }
2667
2668 static void
2669 xcoff_swap_reloc_in (abfd, s, d)
2670      bfd *abfd;
2671      PTR s;
2672      PTR d;
2673 {
2674   struct external_reloc *src = (struct external_reloc *) s;
2675   struct internal_reloc *dst = (struct internal_reloc *) d;
2676
2677   memset (dst, 0, sizeof (struct internal_reloc));
2678
2679   dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
2680   dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
2681   dst->r_size = bfd_get_8 (abfd, src->r_size);
2682   dst->r_type = bfd_get_8 (abfd, src->r_type);
2683 }
2684
2685 static unsigned int
2686 xcoff_swap_reloc_out (abfd, s, d)
2687      bfd *abfd;
2688      PTR s;
2689      PTR d;
2690 {
2691   struct internal_reloc *src = (struct internal_reloc *) s;
2692   struct external_reloc *dst = (struct external_reloc *) d;
2693
2694   bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
2695   bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
2696   bfd_put_8 (abfd, src->r_type, dst->r_type);
2697   bfd_put_8 (abfd, src->r_size, dst->r_size);
2698
2699   return bfd_coff_relsz (abfd);
2700 }
2701
2702 /* Swap in the ldrel structure.  */
2703
2704 static void
2705 xcoff_swap_ldrel_in (abfd, s, dst)
2706      bfd *abfd;
2707      const PTR s;
2708      struct internal_ldrel *dst;
2709 {
2710   const struct external_ldrel *src = (const struct external_ldrel *) s;
2711
2712   dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
2713   dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
2714   dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
2715   dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
2716 }
2717
2718 /* Swap out the ldrel structure.  */
2719
2720 static void
2721 xcoff_swap_ldrel_out (abfd, src, d)
2722      bfd *abfd;
2723      const struct internal_ldrel *src;
2724      PTR d;
2725 {
2726   struct external_ldrel *dst = (struct external_ldrel *) d;
2727
2728   bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
2729   bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
2730   bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
2731   bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
2732 }
2733 \f
2734
2735 boolean 
2736 xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto, 
2737                        val, addend, relocation, contents)
2738      bfd *input_bfd ATTRIBUTE_UNUSED;
2739      asection *input_section ATTRIBUTE_UNUSED;
2740      bfd *output_bfd ATTRIBUTE_UNUSED;
2741      struct internal_reloc *rel ATTRIBUTE_UNUSED;
2742      struct internal_syment *sym ATTRIBUTE_UNUSED;
2743      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2744      bfd_vma val ATTRIBUTE_UNUSED;
2745      bfd_vma addend ATTRIBUTE_UNUSED;
2746      bfd_vma *relocation ATTRIBUTE_UNUSED;
2747      bfd_byte *contents ATTRIBUTE_UNUSED;
2748 {
2749   return true;
2750 }
2751
2752 boolean 
2753 xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto, 
2754                        val, addend, relocation, contents)
2755      bfd *input_bfd;
2756      asection *input_section ATTRIBUTE_UNUSED;
2757      bfd *output_bfd ATTRIBUTE_UNUSED;
2758      struct internal_reloc *rel;
2759      struct internal_syment *sym ATTRIBUTE_UNUSED;
2760      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2761      bfd_vma val ATTRIBUTE_UNUSED;
2762      bfd_vma addend ATTRIBUTE_UNUSED;
2763      bfd_vma *relocation ATTRIBUTE_UNUSED;
2764      bfd_byte *contents ATTRIBUTE_UNUSED;
2765 {
2766   (*_bfd_error_handler)
2767     (_("%s: unsupported relocation type 0x%02x"),
2768      bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
2769   bfd_set_error (bfd_error_bad_value);
2770   return false;
2771 }
2772
2773 boolean 
2774 xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto, 
2775                       val, addend, relocation, contents)
2776      bfd *input_bfd ATTRIBUTE_UNUSED;
2777      asection *input_section ATTRIBUTE_UNUSED;
2778      bfd *output_bfd ATTRIBUTE_UNUSED;
2779      struct internal_reloc *rel ATTRIBUTE_UNUSED;
2780      struct internal_syment *sym ATTRIBUTE_UNUSED;
2781      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2782      bfd_vma val;
2783      bfd_vma addend;
2784      bfd_vma *relocation;
2785      bfd_byte *contents ATTRIBUTE_UNUSED;
2786 {
2787   *relocation = val + addend;
2788   return true;
2789 }
2790
2791 boolean 
2792 xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto, 
2793                       val, addend, relocation, contents)
2794      bfd *input_bfd ATTRIBUTE_UNUSED;
2795      asection *input_section ATTRIBUTE_UNUSED;
2796      bfd *output_bfd ATTRIBUTE_UNUSED;
2797      struct internal_reloc *rel ATTRIBUTE_UNUSED;
2798      struct internal_syment *sym ATTRIBUTE_UNUSED;
2799      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2800      bfd_vma val;
2801      bfd_vma addend;
2802      bfd_vma *relocation;
2803      bfd_byte *contents ATTRIBUTE_UNUSED;
2804 {
2805   *relocation = addend - val;
2806   return true;
2807 }
2808
2809 boolean 
2810 xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto, 
2811                       val, addend, relocation, contents)
2812      bfd *input_bfd ATTRIBUTE_UNUSED;
2813      asection *input_section;
2814      bfd *output_bfd ATTRIBUTE_UNUSED;
2815      struct internal_reloc *rel ATTRIBUTE_UNUSED;
2816      struct internal_syment *sym ATTRIBUTE_UNUSED;
2817      struct reloc_howto_struct *howto;
2818      bfd_vma val;
2819      bfd_vma addend;
2820      bfd_vma *relocation;
2821      bfd_byte *contents ATTRIBUTE_UNUSED;
2822 {
2823   howto->pc_relative = true;
2824
2825   /* A PC relative reloc includes the section address.  */
2826   addend += input_section->vma;
2827
2828   *relocation = val + addend;
2829   *relocation -= (input_section->output_section->vma + 
2830                   input_section->output_offset);
2831   return true;
2832 }
2833
2834 boolean 
2835 xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto, 
2836                       val, addend, relocation, contents)
2837      bfd *input_bfd;
2838      asection *input_section ATTRIBUTE_UNUSED;
2839      bfd *output_bfd;
2840      struct internal_reloc *rel;
2841      struct internal_syment *sym;
2842      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2843      bfd_vma val;
2844      bfd_vma addend ATTRIBUTE_UNUSED;
2845      bfd_vma *relocation;
2846      bfd_byte *contents ATTRIBUTE_UNUSED;
2847 {
2848   struct xcoff_link_hash_entry *h;
2849
2850   if (0 > rel->r_symndx) 
2851     return false;
2852
2853   h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2854
2855   if (h != NULL && h->smclas != XMC_TD)
2856     {
2857       if (h->toc_section == NULL)
2858         {
2859           (*_bfd_error_handler)
2860             (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
2861              bfd_get_filename (input_bfd), rel->r_vaddr,
2862              h->root.root.string);
2863           bfd_set_error (bfd_error_bad_value);
2864           return false;
2865         }
2866       
2867       BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
2868       val = (h->toc_section->output_section->vma
2869               + h->toc_section->output_offset);
2870     }
2871   
2872   *relocation = ((val - xcoff_data (output_bfd)->toc) - 
2873                  (sym->n_value - xcoff_data (input_bfd)->toc));
2874   return true;
2875 }
2876
2877 boolean 
2878 xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto, 
2879                      val, addend, relocation, contents)
2880      bfd *input_bfd ATTRIBUTE_UNUSED;
2881      asection *input_section ATTRIBUTE_UNUSED;
2882      bfd *output_bfd ATTRIBUTE_UNUSED;
2883      struct internal_reloc *rel ATTRIBUTE_UNUSED;
2884      struct internal_syment *sym ATTRIBUTE_UNUSED;
2885      struct reloc_howto_struct *howto;
2886      bfd_vma val;
2887      bfd_vma addend;
2888      bfd_vma *relocation;
2889      bfd_byte *contents ATTRIBUTE_UNUSED;
2890 {
2891   howto->src_mask &= ~3;
2892   howto->dst_mask = howto->src_mask;
2893
2894   *relocation = val + addend;
2895
2896   return true;
2897 }
2898
2899 static boolean 
2900 xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, 
2901                      val, addend, relocation, contents)
2902      bfd *input_bfd;
2903      asection *input_section;
2904      bfd *output_bfd ATTRIBUTE_UNUSED;
2905      struct internal_reloc *rel;
2906      struct internal_syment *sym ATTRIBUTE_UNUSED;
2907      struct reloc_howto_struct *howto;
2908      bfd_vma val;
2909      bfd_vma addend;
2910      bfd_vma *relocation;
2911      bfd_byte *contents;
2912 {
2913   struct xcoff_link_hash_entry *h;
2914
2915   if (0 > rel->r_symndx) 
2916     return false;
2917
2918   h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2919
2920   /* If we see an R_BR or R_RBR reloc which is jumping to global
2921      linkage code, and it is followed by an appropriate cror nop
2922      instruction, we replace the cror with lwz r2,20(r1).  This
2923      restores the TOC after the glink code.  Contrariwise, if the
2924      call is followed by a lwz r2,20(r1), but the call is not
2925      going to global linkage code, we can replace the load with a
2926      cror.  */
2927   if (NULL != h 
2928       && bfd_link_hash_defined == h->root.type 
2929       && (rel->r_vaddr - input_section->vma + 8 <= 
2930           input_section->_cooked_size)) 
2931     {
2932       bfd_byte *pnext;
2933       unsigned long next;
2934       
2935       pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
2936       next = bfd_get_32 (input_bfd, pnext);
2937       
2938       /* The _ptrgl function is magic.  It is used by the AIX
2939          compiler to call a function through a pointer.  */
2940       if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
2941         {
2942           if (next == 0x4def7b82                        /* cror 15,15,15 */
2943               || next == 0x4ffffb82                     /* cror 31,31,31 */
2944               || next == 0x60000000)                    /* ori r0,r0,0 */
2945             bfd_put_32 (input_bfd, 0x80410014, pnext);  /* lwz r1,20(r1) */
2946           
2947         } else 
2948           {
2949             if (next == 0x80410014)                      /* lwz r1,20(r1) */
2950               bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
2951           }
2952     } 
2953   else if (NULL != h && bfd_link_hash_undefined == h->root.type) 
2954     {
2955       /* Normally, this relocation is against a defined symbol.  In the
2956          case where this is a partial link and the output section offset
2957          is greater than 2^25, the linker will return an invalid error 
2958          message that the relocation has been truncated.  Yes it has been
2959          truncated but no it not important.  For this case, disable the 
2960          overflow checking. */
2961       
2962       howto->complain_on_overflow = complain_overflow_dont;
2963     }
2964   
2965   howto->pc_relative = true;
2966   howto->src_mask &= ~3;
2967   howto->dst_mask = howto->src_mask;
2968
2969   /* A PC relative reloc includes the section address.  */
2970   addend += input_section->vma;
2971   
2972   *relocation = val + addend;
2973   *relocation -= (input_section->output_section->vma + 
2974                   input_section->output_offset);
2975   return true;
2976 }
2977
2978 boolean 
2979 xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto, 
2980                        val, addend, relocation, contents)
2981      bfd *input_bfd ATTRIBUTE_UNUSED;
2982      asection *input_section;
2983      bfd *output_bfd ATTRIBUTE_UNUSED;
2984      struct internal_reloc *rel ATTRIBUTE_UNUSED;
2985      struct internal_syment *sym ATTRIBUTE_UNUSED;
2986      struct reloc_howto_struct *howto;
2987      bfd_vma val ATTRIBUTE_UNUSED;
2988      bfd_vma addend;
2989      bfd_vma *relocation;
2990      bfd_byte *contents ATTRIBUTE_UNUSED;
2991 {
2992   howto->pc_relative = true;
2993   howto->src_mask &= ~3;
2994   howto->dst_mask = howto->src_mask;
2995
2996   /* A PC relative reloc includes the section address.  */
2997   addend += input_section->vma;
2998
2999   *relocation = val + addend;
3000   *relocation -= (input_section->output_section->vma + 
3001                   input_section->output_offset);
3002   return true;
3003 }
3004
3005 static boolean 
3006 xcoff_complain_overflow_dont_func (input_bfd, val, relocation, howto) 
3007      bfd *input_bfd ATTRIBUTE_UNUSED;
3008      bfd_vma val ATTRIBUTE_UNUSED;
3009      bfd_vma relocation ATTRIBUTE_UNUSED;
3010      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
3011 {
3012   return false;
3013 }
3014
3015 static boolean 
3016 xcoff_complain_overflow_bitfield_func (input_bfd, val, relocation, howto) 
3017      bfd *input_bfd;
3018      bfd_vma val;
3019      bfd_vma relocation;
3020      struct reloc_howto_struct *howto; 
3021 {
3022   bfd_vma addrmask, fieldmask, signmask, ss;
3023   bfd_vma a, b, sum;
3024   
3025   /* Get the values to be added together.  For signed and unsigned
3026      relocations, we assume that all values should be truncated to
3027      the size of an address.  For bitfields, all the bits matter.
3028      See also bfd_check_overflow.  */
3029   fieldmask = N_ONES (howto->bitsize);
3030   addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3031   a = relocation;
3032   b = val & howto->src_mask;
3033
3034   /* Much like unsigned, except no trimming with addrmask.  In
3035      addition, the sum overflows if there is a carry out of
3036      the bfd_vma, i.e., the sum is less than either input
3037      operand.  */
3038   a >>= howto->rightshift;
3039   b >>= howto->bitpos;
3040   
3041   /* Bitfields are sometimes used for signed numbers; for
3042      example, a 13-bit field sometimes represents values in
3043      0..8191 and sometimes represents values in -4096..4095.
3044      If the field is signed and a is -4095 (0x1001) and b is
3045      -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
3046      0x1fff is 0x3000).  It's not clear how to handle this
3047      everywhere, since there is not way to know how many bits
3048      are significant in the relocation, but the original code
3049      assumed that it was fully sign extended, and we will keep
3050      that assumption.  */
3051   signmask = (fieldmask >> 1) + 1;
3052                   
3053   if ((a & ~ fieldmask) != 0)
3054     {
3055       /* Some bits out of the field are set.  This might not
3056          be a problem: if this is a signed bitfield, it is OK
3057          iff all the high bits are set, including the sign
3058          bit.  We'll try setting all but the most significant
3059          bit in the original relocation value: if this is all
3060          ones, we are OK, assuming a signed bitfield.  */
3061       ss = (signmask << howto->rightshift) - 1;
3062       if ((ss | relocation) != ~ (bfd_vma) 0)
3063         return true;
3064       a &= fieldmask;
3065     }
3066   
3067   /* We just assume (b & ~ fieldmask) == 0.  */
3068   
3069   /* We explicitly permit wrap around if this relocation
3070      covers the high bit of an address.  The Linux kernel
3071      relies on it, and it is the only way to write assembler
3072      code which can run when loaded at a location 0x80000000
3073      away from the location at which it is linked.  */
3074   if (howto->bitsize + howto->rightshift
3075       == bfd_arch_bits_per_address (input_bfd))
3076     return false;
3077   
3078   sum = a + b;
3079   if (sum < a || (sum & ~ fieldmask) != 0)
3080     {
3081       /* There was a carry out, or the field overflow.  Test
3082          for signed operands again.  Here is the overflow test
3083          is as for complain_overflow_signed.  */
3084       if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3085         return true;
3086     }
3087   
3088   return false;
3089 }
3090
3091 static boolean 
3092 xcoff_complain_overflow_signed_func (input_bfd, val, relocation, howto) 
3093      bfd *input_bfd;
3094      bfd_vma val;
3095      bfd_vma relocation;
3096      struct reloc_howto_struct *howto;
3097 {
3098   bfd_vma addrmask, fieldmask, signmask, ss;
3099   bfd_vma a, b, sum;
3100   
3101   /* Get the values to be added together.  For signed and unsigned
3102      relocations, we assume that all values should be truncated to
3103      the size of an address.  For bitfields, all the bits matter.
3104      See also bfd_check_overflow.  */
3105   fieldmask = N_ONES (howto->bitsize);
3106   addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3107   a = relocation;
3108   b = val & howto->src_mask;
3109
3110   a = (a & addrmask) >> howto->rightshift;
3111   
3112   /* If any sign bits are set, all sign bits must be set.
3113      That is, A must be a valid negative address after
3114      shifting.  */
3115   signmask = ~ (fieldmask >> 1);
3116   ss = a & signmask;
3117   if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
3118     return true;
3119   
3120   /* We only need this next bit of code if the sign bit of B
3121      is below the sign bit of A.  This would only happen if
3122      SRC_MASK had fewer bits than BITSIZE.  Note that if
3123      SRC_MASK has more bits than BITSIZE, we can get into
3124      trouble; we would need to verify that B is in range, as
3125      we do for A above.  */
3126   signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
3127   if ((b & signmask) != 0)
3128     {
3129       /* Set all the bits above the sign bit.  */
3130       b -= signmask <<= 1;
3131     }
3132   
3133   b = (b & addrmask) >> howto->bitpos;
3134   
3135   /* Now we can do the addition.  */
3136   sum = a + b;
3137   
3138   /* See if the result has the correct sign.  Bits above the
3139      sign bit are junk now; ignore them.  If the sum is
3140      positive, make sure we did not have all negative inputs;
3141      if the sum is negative, make sure we did not have all
3142      positive inputs.  The test below looks only at the sign
3143      bits, and it really just
3144      SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
3145   */
3146   signmask = (fieldmask >> 1) + 1;
3147   if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3148     return true;
3149   
3150   return false;
3151 }
3152
3153 static boolean 
3154 xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto) 
3155      bfd *input_bfd;
3156      bfd_vma val;
3157      bfd_vma relocation;
3158      struct reloc_howto_struct *howto; 
3159 {
3160   bfd_vma addrmask, fieldmask;
3161   bfd_vma a, b, sum;
3162   
3163   /* Get the values to be added together.  For signed and unsigned
3164      relocations, we assume that all values should be truncated to
3165      the size of an address.  For bitfields, all the bits matter.
3166      See also bfd_check_overflow.  */
3167   fieldmask = N_ONES (howto->bitsize);
3168   addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3169   a = relocation;
3170   b = val & howto->src_mask;
3171
3172   /* Checking for an unsigned overflow is relatively easy:
3173      trim the addresses and add, and trim the result as well.
3174      Overflow is normally indicated when the result does not
3175      fit in the field.  However, we also need to consider the
3176      case when, e.g., fieldmask is 0x7fffffff or smaller, an
3177      input is 0x80000000, and bfd_vma is only 32 bits; then we
3178      will get sum == 0, but there is an overflow, since the
3179      inputs did not fit in the field.  Instead of doing a
3180      separate test, we can check for this by or-ing in the
3181      operands when testing for the sum overflowing its final
3182      field.  */
3183   a = (a & addrmask) >> howto->rightshift;
3184   b = (b & addrmask) >> howto->bitpos;
3185   sum = (a + b) & addrmask;
3186   if ((a | b | sum) & ~ fieldmask)
3187     return true;
3188   
3189   return false;
3190 }
3191
3192 /* This is the relocation function for the RS/6000/POWER/PowerPC.
3193    This is currently the only processor which uses XCOFF; I hope that
3194    will never change.  
3195
3196    I took the relocation type definitions from two documents:
3197    the PowerPC AIX Version 4 Application Binary Interface, First
3198    Edition (April 1992), and the PowerOpen ABI, Big-Endian
3199    32-Bit Hardware Implementation (June 30, 1994).  Differences
3200    between the documents are noted below. 
3201
3202    Unsupported r_type's 
3203
3204    R_RTB:
3205    R_RRTBI:
3206    R_RRTBA:
3207         
3208    These relocs are defined by the PowerPC ABI to be
3209    relative branches which use half of the difference
3210    between the symbol and the program counter.  I can't
3211    quite figure out when this is useful.  These relocs are
3212    not defined by the PowerOpen ABI. 
3213
3214    Supported r_type's
3215
3216    R_POS:
3217    Simple positive relocation.
3218
3219    R_NEG:
3220    Simple negative relocation. 
3221
3222    R_REL:
3223    Simple PC relative relocation.
3224
3225    R_TOC:
3226    TOC relative relocation.  The value in the instruction in
3227    the input file is the offset from the input file TOC to
3228    the desired location.  We want the offset from the final
3229    TOC to the desired location.  We have:
3230    isym = iTOC + in
3231    iinsn = in + o
3232    osym = oTOC + on
3233    oinsn = on + o
3234    so we must change insn by on - in.
3235
3236    R_GL:
3237    GL linkage relocation.  The value of this relocation
3238    is the address of the entry in the TOC section. 
3239
3240    R_TCL:
3241    Local object TOC address.  I can't figure out the
3242    difference between this and case R_GL. 
3243
3244    R_TRL:
3245    TOC relative relocation.  A TOC relative load instruction
3246    which may be changed to a load address instruction.
3247    FIXME: We don't currently implement this optimization. 
3248
3249    R_TRLA:
3250    TOC relative relocation.  This is a TOC relative load
3251    address instruction which may be changed to a load
3252    instruction.  FIXME: I don't know if this is the correct
3253    implementation.
3254
3255    R_BA:
3256    Absolute branch.  We don't want to mess with the lower
3257    two bits of the instruction. 
3258
3259    R_CAI:
3260    The PowerPC ABI defines this as an absolute call which
3261    may be modified to become a relative call.  The PowerOpen
3262    ABI does not define this relocation type. 
3263    
3264    R_RBA:
3265    Absolute branch which may be modified to become a
3266    relative branch. 
3267
3268    R_RBAC:
3269    The PowerPC ABI defines this as an absolute branch to a
3270    fixed address which may be modified to an absolute branch
3271    to a symbol.  The PowerOpen ABI does not define this
3272    relocation type. 
3273
3274    R_RBRC:
3275    The PowerPC ABI defines this as an absolute branch to a
3276    fixed address which may be modified to a relative branch.
3277    The PowerOpen ABI does not define this relocation type. 
3278
3279    R_BR:
3280    Relative branch.  We don't want to mess with the lower
3281    two bits of the instruction. 
3282
3283    R_CREL:
3284    The PowerPC ABI defines this as a relative call which may
3285    be modified to become an absolute call.  The PowerOpen
3286    ABI does not define this relocation type. 
3287
3288    R_RBR:
3289    A relative branch which may be modified to become an
3290    absolute branch.  FIXME: We don't implement this,
3291    although we should for symbols of storage mapping class
3292    XMC_XO. 
3293
3294    R_RL:
3295    The PowerPC AIX ABI describes this as a load which may be
3296    changed to a load address.  The PowerOpen ABI says this
3297    is the same as case R_POS. 
3298
3299    R_RLA:
3300    The PowerPC AIX ABI describes this as a load address
3301    which may be changed to a load.  The PowerOpen ABI says
3302    this is the same as R_POS. 
3303 */
3304
3305 boolean
3306 xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
3307                             input_section, contents, relocs, syms,
3308                             sections)
3309      bfd *output_bfd;
3310      struct bfd_link_info *info;
3311      bfd *input_bfd;
3312      asection *input_section;
3313      bfd_byte *contents;
3314      struct internal_reloc *relocs;
3315      struct internal_syment *syms;
3316      asection **sections;
3317 {
3318   struct internal_reloc *rel;
3319   struct internal_reloc *relend;
3320
3321   rel = relocs;
3322   relend = rel + input_section->reloc_count;
3323   for (; rel < relend; rel++)
3324     {
3325       long symndx;
3326       struct xcoff_link_hash_entry *h;
3327       struct internal_syment *sym;
3328       bfd_vma addend;
3329       bfd_vma val;
3330       struct reloc_howto_struct howto;
3331       bfd_vma relocation;
3332       bfd_vma value_to_relocate;
3333       bfd_vma address;
3334       bfd_byte *location;
3335
3336       /* Relocation type R_REF is a special relocation type which is
3337          merely used to prevent garbage collection from occurring for
3338          the csect including the symbol which it references.  */
3339       if (rel->r_type == R_REF)
3340         continue;
3341
3342       /* howto */
3343       howto.type = rel->r_type;
3344       howto.rightshift = 0;
3345       howto.bitsize = (rel->r_size & 0x1f) + 1;
3346       howto.size = howto.bitsize > 16 ? 2 : 1;
3347       howto.pc_relative = false;
3348       howto.bitpos = 0;
3349       howto.complain_on_overflow = rel->r_size & 0x80 ? 
3350         complain_overflow_signed : complain_overflow_bitfield;
3351       howto.special_function = NULL;
3352       howto.name = "internal";
3353       howto.partial_inplace = true;
3354       howto.src_mask = howto.dst_mask = N_ONES(howto.bitsize);
3355       howto.pcrel_offset = false;
3356
3357       /* symbol */
3358       val = 0;
3359       addend = 0;
3360       h = NULL;
3361       sym = NULL;
3362       symndx = rel->r_symndx;      
3363
3364       if (-1 != symndx) 
3365         {
3366           asection *sec;
3367           
3368           h = obj_xcoff_sym_hashes (input_bfd)[symndx];
3369           sym = syms + symndx;
3370           addend = - sym->n_value;
3371           
3372           if (NULL == h) 
3373             {
3374               sec = sections[symndx];
3375               /* Hack to make sure we use the right TOC anchor value
3376                  if this reloc is against the TOC anchor.  */
3377               if (sec->name[3] == '0'
3378                   && strcmp (sec->name, ".tc0") == 0)
3379                 val = xcoff_data (output_bfd)->toc;
3380               else
3381                 val = (sec->output_section->vma
3382                        + sec->output_offset
3383                        + sym->n_value
3384                        - sec->vma);
3385             } 
3386           else 
3387             {
3388               if (h->root.type == bfd_link_hash_defined 
3389                   || h->root.type == bfd_link_hash_defweak) 
3390                 {
3391                   sec = h->root.u.def.section;
3392                   val = (h->root.u.def.value
3393                          + sec->output_section->vma
3394                          + sec->output_offset);
3395                 } 
3396               else if (h->root.type == bfd_link_hash_common) 
3397                 {
3398                   sec = h->root.u.c.p->section;
3399                   val = (sec->output_section->vma
3400                          + sec->output_offset);
3401                   
3402                 } 
3403               else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT))) 
3404                        && ! info->relocateable) 
3405                 {
3406                   if (! ((*info->callbacks->undefined_symbol)
3407                          (info, h->root.root.string, input_bfd, input_section,
3408                           rel->r_vaddr - input_section->vma, true)))
3409                     return false;
3410                   
3411                   /* Don't try to process the reloc.  It can't help, and
3412                      it may generate another error.  */
3413                   continue;
3414                 }
3415             }
3416         }
3417
3418       if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION 
3419           || (false == xcoff_calculate_relocation[rel->r_type]
3420               (input_bfd, input_section, output_bfd, rel, sym, &howto, val, 
3421                addend, &relocation, contents))) 
3422         return false;
3423       
3424       /* address */
3425       address = rel->r_vaddr - input_section->vma;
3426       location = contents + address;
3427       
3428       if (address > input_section->_raw_size)
3429         abort();
3430
3431       /* Get the value we are going to relocate.  */
3432       if (1 == howto.size)
3433         value_to_relocate = bfd_get_16 (input_bfd, location);
3434       else 
3435         value_to_relocate = bfd_get_32 (input_bfd, location);
3436       
3437       /* overflow.  
3438          
3439          FIXME: We may drop bits during the addition
3440          which we don't check for.  We must either check at every single
3441          operation, which would be tedious, or we must do the computations
3442          in a type larger than bfd_vma, which would be inefficient.  */
3443       
3444       if ((unsigned int) howto.complain_on_overflow >= 
3445           XCOFF_MAX_COMPLAIN_OVERFLOW)
3446         abort();
3447
3448       if ((true == xcoff_complain_overflow[howto.complain_on_overflow]
3449            (input_bfd, value_to_relocate, relocation, &howto))) 
3450         {
3451           const char *name;
3452           char buf[SYMNMLEN + 1];
3453           char reloc_type_name[10];
3454           
3455           if (symndx == -1) 
3456             {
3457               name = "*ABS*";
3458             } 
3459           else if (h != NULL) 
3460             {
3461               name = h->root.root.string;
3462             } 
3463           else 
3464             {
3465               name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
3466               if (name == NULL)
3467                 name = "UNKNOWN";
3468             }
3469           sprintf (reloc_type_name, "0x%02x", rel->r_type);
3470           
3471           if (! ((*info->callbacks->reloc_overflow)
3472                  (info, name, reloc_type_name, (bfd_vma) 0, input_bfd,
3473                   input_section, rel->r_vaddr - input_section->vma)))
3474             return false;
3475         }
3476       
3477       /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE.  */
3478       value_to_relocate = ((value_to_relocate & ~howto.dst_mask) | 
3479                            (((value_to_relocate & howto.src_mask) + 
3480                              relocation) & howto.dst_mask));
3481       
3482       /* Put the value back in the object file.  */
3483       if (1 == howto.size)
3484         bfd_put_16 (input_bfd, value_to_relocate, location);
3485       else 
3486         bfd_put_32 (input_bfd, value_to_relocate, location);
3487     }
3488
3489   return true;
3490 }
3491
3492 static boolean
3493 _bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
3494      bfd *abfd ATTRIBUTE_UNUSED;
3495          struct xcoff_loader_info *ldinfo;
3496          struct internal_ldsym *ldsym;
3497          const char *name;
3498 {
3499   size_t len;
3500   len = strlen (name);
3501
3502   if (len <= SYMNMLEN)
3503     strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3504   else
3505     {
3506       if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3507         {
3508           bfd_size_type newalc;
3509           bfd_byte *newstrings;
3510
3511           newalc = ldinfo->string_alc * 2;
3512           if (newalc == 0)
3513             newalc = 32;
3514           while (ldinfo->string_size + len + 3 > newalc)
3515             newalc *= 2;
3516
3517           newstrings = ((bfd_byte *)
3518                         bfd_realloc ((PTR) ldinfo->strings, newalc));
3519           if (newstrings == NULL)
3520             {
3521               ldinfo->failed = true;
3522               return false;
3523             }
3524           ldinfo->string_alc = newalc;
3525           ldinfo->strings = newstrings;
3526         }
3527
3528       bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3529                   ldinfo->strings + ldinfo->string_size);
3530       strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3531       ldsym->_l._l_l._l_zeroes = 0;
3532       ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3533       ldinfo->string_size += len + 3;
3534     }
3535
3536   return true;
3537 }
3538
3539 static boolean
3540 _bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
3541                             struct internal_syment *sym,
3542                             const char *name)
3543 {
3544   if (strlen (name) <= SYMNMLEN)
3545     {
3546       strncpy (sym->_n._n_name, name, SYMNMLEN);
3547     }
3548   else
3549     {
3550       boolean hash;
3551       bfd_size_type indx;
3552
3553       hash = true;
3554       if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
3555         hash = false;
3556       indx = _bfd_stringtab_add (strtab, name, hash, false);
3557       if (indx == (bfd_size_type) -1)
3558         return false;
3559       sym->_n._n_n._n_zeroes = 0;
3560       sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3561     }
3562   return true;
3563 }
3564
3565 static asection *
3566 xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
3567      bfd *abfd;
3568      union internal_auxent *aux;
3569      const char *symbol_name;
3570 {
3571   asection *return_value = NULL;
3572
3573   /* .sv64 = x_smclas == 17
3574      This is an invalid csect for 32 bit apps.  */
3575   static const char *names[19] =
3576   {
3577     ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
3578     ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
3579     ".td", NULL, ".sv3264"
3580   };
3581
3582   if ((19 >= aux->x_csect.x_smclas) &&
3583       (NULL != names[aux->x_csect.x_smclas]))
3584     {
3585       return_value = bfd_make_section_anyway
3586         (abfd, names[aux->x_csect.x_smclas]);
3587     }
3588   else
3589     {
3590       (*_bfd_error_handler)
3591         (_("%s: symbol `%s' has unrecognized smclas %d"),
3592          bfd_archive_filename (abfd), symbol_name, aux->x_csect.x_smclas);
3593       bfd_set_error (bfd_error_bad_value);
3594     }
3595
3596   return return_value;
3597 }
3598
3599 static boolean
3600 xcoff_is_lineno_count_overflow (abfd, value)
3601     bfd *abfd ATTRIBUTE_UNUSED;
3602         bfd_vma value;
3603 {
3604   if (0xffff <= value)
3605     return true;
3606
3607   return false;
3608 }
3609
3610 static boolean
3611 xcoff_is_reloc_count_overflow (abfd, value)
3612     bfd *abfd ATTRIBUTE_UNUSED;
3613         bfd_vma value;
3614 {
3615   if (0xffff <= value)
3616     return true;
3617
3618   return false;
3619 }
3620
3621 static bfd_vma
3622 xcoff_loader_symbol_offset (abfd, ldhdr)
3623     bfd *abfd;
3624     struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
3625 {
3626   return bfd_xcoff_ldhdrsz(abfd);
3627 }
3628
3629 static bfd_vma
3630 xcoff_loader_reloc_offset (abfd, ldhdr)
3631     bfd *abfd;
3632     struct internal_ldhdr *ldhdr;
3633 {
3634   return bfd_xcoff_ldhdrsz(abfd) +
3635     (ldhdr->l_nsyms * bfd_xcoff_ldsymsz(abfd));
3636 }
3637
3638 static boolean 
3639 xcoff_generate_rtinit  (abfd, init, fini, rtld)
3640      bfd *abfd;
3641      const char *init;
3642      const char *fini;
3643      boolean rtld;
3644 {
3645   bfd_byte filehdr_ext[FILHSZ];
3646   bfd_byte scnhdr_ext[SCNHSZ];
3647   bfd_byte syment_ext[SYMESZ * 10];
3648   bfd_byte reloc_ext[RELSZ * 3];
3649   bfd_byte *data_buffer;
3650   bfd_size_type data_buffer_size;
3651   bfd_byte *string_table = NULL, *st_tmp = NULL;
3652   bfd_size_type string_table_size;
3653   bfd_vma val;
3654   size_t initsz, finisz;
3655   struct internal_filehdr filehdr;
3656   struct internal_scnhdr scnhdr;
3657   struct internal_syment syment;
3658   union internal_auxent auxent;
3659   struct internal_reloc reloc;
3660   
3661   char *data_name = ".data";
3662   char *rtinit_name = "__rtinit";
3663   char *rtld_name = "__rtld";
3664   
3665   if (! bfd_xcoff_rtinit_size (abfd))
3666     return false;
3667
3668   initsz = (init == NULL ? 0 : 1 + strlen (init));
3669   finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3670
3671   /* file header */
3672   memset (filehdr_ext, 0, FILHSZ);
3673   memset (&filehdr, 0, sizeof (struct internal_filehdr));
3674   filehdr.f_magic = bfd_xcoff_magic_number (abfd);
3675   filehdr.f_nscns = 1; 
3676   filehdr.f_timdat = 0;
3677   filehdr.f_nsyms = 0;  /* at least 6, no more than 10 */
3678   filehdr.f_symptr = 0; /* set below */
3679   filehdr.f_opthdr = 0;
3680   filehdr.f_flags = 0;
3681
3682   /* section header */
3683   memset (scnhdr_ext, 0, SCNHSZ);
3684   memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3685   memcpy (scnhdr.s_name, data_name, strlen (data_name));
3686   scnhdr.s_paddr = 0;
3687   scnhdr.s_vaddr = 0;
3688   scnhdr.s_size = 0;    /* set below */
3689   scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3690   scnhdr.s_relptr = 0;  /* set below */
3691   scnhdr.s_lnnoptr = 0;
3692   scnhdr.s_nreloc = 0;  /* either 1 or 2 */
3693   scnhdr.s_nlnno = 0;
3694   scnhdr.s_flags = STYP_DATA;
3695
3696   /* .data 
3697      0x0000           0x00000000 : rtl
3698      0x0004           0x00000010 : offset to init, or 0
3699      0x0008           0x00000028 : offset to fini, or 0
3700      0x000C           0x0000000C : size of descriptor 
3701      0x0010           0x00000000 : init, needs a reloc
3702      0x0014           0x00000040 : offset to init name
3703      0x0018           0x00000000 : flags, padded to a word
3704      0x001C           0x00000000 : empty init
3705      0x0020           0x00000000 : 
3706      0x0024           0x00000000 : 
3707      0x0028           0x00000000 : fini, needs a reloc
3708      0x002C           0x00000??? : offset to fini name
3709      0x0030           0x00000000 : flags, padded to a word
3710      0x0034           0x00000000 : empty fini
3711      0x0038           0x00000000 : 
3712      0x003C           0x00000000 : 
3713      0x0040           init name
3714      0x0040 + initsz  fini name */
3715
3716   data_buffer_size = 0x0040 + initsz + finisz;
3717   data_buffer_size += (data_buffer_size & 7) ? 8 - (data_buffer_size & 7) : 0;
3718   data_buffer = NULL;
3719   data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
3720   if (data_buffer == NULL)
3721     return false;
3722
3723   if (initsz) 
3724     {
3725       val = 0x10;
3726       bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
3727       val = 0x40;
3728       bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
3729       memcpy (&data_buffer[val], init, initsz);
3730     }
3731
3732   if (finisz) 
3733     {
3734       val = 0x28;
3735       bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
3736       val = 0x40 + initsz;
3737       bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
3738       memcpy (&data_buffer[val], fini, finisz);
3739     }
3740
3741   val = 0x0C;
3742   bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
3743
3744   scnhdr.s_size = data_buffer_size;
3745
3746   /* string table */
3747   string_table_size = 0;
3748   if (initsz > 9) 
3749     string_table_size += initsz;
3750   if (finisz > 9)
3751     string_table_size += finisz;
3752   if (string_table_size)
3753     {
3754       string_table_size += 4;
3755       string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
3756       if (string_table_size == NULL)
3757         return false;
3758
3759       val = string_table_size;
3760       bfd_h_put_32 (abfd, val, &string_table[0]);
3761       st_tmp = string_table + 4;
3762     }
3763   
3764   /* symbols 
3765      0. .data csect
3766      2. __rtinit
3767      4. init function 
3768      6. fini function 
3769      8. __rtld  */
3770   memset (syment_ext, 0, 10 * SYMESZ);
3771   memset (reloc_ext, 0, 3 * RELSZ);
3772
3773   /* .data csect */
3774   memset (&syment, 0, sizeof (struct internal_syment));
3775   memset (&auxent, 0, sizeof (union internal_auxent));
3776   memcpy (syment._n._n_name, data_name, strlen (data_name));
3777   syment.n_scnum = 1;
3778   syment.n_sclass = C_HIDEXT;
3779   syment.n_numaux = 1;
3780   auxent.x_csect.x_scnlen.l = data_buffer_size;
3781   auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
3782   auxent.x_csect.x_smclas = XMC_RW;
3783   bfd_coff_swap_sym_out (abfd, &syment, 
3784                          &syment_ext[filehdr.f_nsyms * SYMESZ]);
3785   bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
3786                          syment.n_numaux, 
3787                          &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3788   filehdr.f_nsyms += 2;
3789
3790   /* __rtinit */
3791   memset (&syment, 0, sizeof (struct internal_syment));
3792   memset (&auxent, 0, sizeof (union internal_auxent));
3793   memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
3794   syment.n_scnum = 1;
3795   syment.n_sclass = C_EXT;
3796   syment.n_numaux = 1;
3797   auxent.x_csect.x_smtyp = XTY_LD;
3798   auxent.x_csect.x_smclas = XMC_RW;
3799   bfd_coff_swap_sym_out (abfd, &syment, 
3800                          &syment_ext[filehdr.f_nsyms * SYMESZ]);
3801   bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
3802                          syment.n_numaux, 
3803                          &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3804   filehdr.f_nsyms += 2;
3805
3806   /* init */
3807   if (initsz) 
3808     {
3809       memset (&syment, 0, sizeof (struct internal_syment));
3810       memset (&auxent, 0, sizeof (union internal_auxent));
3811
3812       if (initsz > 9) 
3813         {
3814           syment._n._n_n._n_offset = st_tmp - string_table;
3815           memcpy (st_tmp, init, initsz);
3816           st_tmp += initsz;
3817         }
3818       else
3819         memcpy (syment._n._n_name, init, initsz - 1);
3820
3821       syment.n_sclass = C_EXT;
3822       syment.n_numaux = 1;
3823       bfd_coff_swap_sym_out (abfd, &syment, 
3824                              &syment_ext[filehdr.f_nsyms * SYMESZ]);
3825       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
3826                              syment.n_numaux, 
3827                              &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3828
3829       /* reloc */
3830       memset (&reloc, 0, sizeof (struct internal_reloc));
3831       reloc.r_vaddr = 0x0010;
3832       reloc.r_symndx = filehdr.f_nsyms;
3833       reloc.r_type = R_POS;
3834       reloc.r_size = 31;
3835       bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
3836
3837       filehdr.f_nsyms += 2;
3838       scnhdr.s_nreloc += 1;
3839     }
3840   
3841   /* fini */
3842   if (finisz) 
3843     {
3844       memset (&syment, 0, sizeof (struct internal_syment));
3845       memset (&auxent, 0, sizeof (union internal_auxent));
3846
3847       if (finisz > 9) 
3848         {
3849           syment._n._n_n._n_offset = st_tmp - string_table;
3850           memcpy (st_tmp, fini, finisz);
3851           st_tmp += finisz;
3852         }
3853       else
3854         memcpy (syment._n._n_name, fini, finisz - 1);
3855
3856       syment.n_sclass = C_EXT;
3857       syment.n_numaux = 1;
3858       bfd_coff_swap_sym_out (abfd, &syment, 
3859                              &syment_ext[filehdr.f_nsyms * SYMESZ]);
3860       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
3861                              syment.n_numaux, 
3862                              &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3863
3864       /* reloc */
3865       memset (&reloc, 0, sizeof (struct internal_reloc));
3866       reloc.r_vaddr = 0x0028;
3867       reloc.r_symndx = filehdr.f_nsyms;
3868       reloc.r_type = R_POS;
3869       reloc.r_size = 31;
3870       bfd_coff_swap_reloc_out (abfd, &reloc, 
3871                                &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3872
3873       filehdr.f_nsyms += 2;
3874       scnhdr.s_nreloc += 1;
3875     }
3876
3877   if (rtld)
3878     {
3879       memset (&syment, 0, sizeof (struct internal_syment));
3880       memset (&auxent, 0, sizeof (union internal_auxent));
3881       memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
3882       syment.n_sclass = C_EXT;
3883       syment.n_numaux = 1;
3884       bfd_coff_swap_sym_out (abfd, &syment, 
3885                              &syment_ext[filehdr.f_nsyms * SYMESZ]);
3886       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
3887                              syment.n_numaux, 
3888                              &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3889
3890       /* reloc */
3891       memset (&reloc, 0, sizeof (struct internal_reloc));
3892       reloc.r_vaddr = 0x0000;
3893       reloc.r_symndx = filehdr.f_nsyms;
3894       reloc.r_type = R_POS;
3895       reloc.r_size = 31;
3896       bfd_coff_swap_reloc_out (abfd, &reloc, 
3897                                &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3898
3899       filehdr.f_nsyms += 2;
3900       scnhdr.s_nreloc += 1;
3901     }
3902
3903   scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
3904   filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
3905
3906   bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
3907   bfd_bwrite (filehdr_ext, FILHSZ, abfd);
3908   bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
3909   bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
3910   bfd_bwrite (data_buffer, data_buffer_size, abfd);
3911   bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
3912   bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
3913   bfd_bwrite (string_table, string_table_size, abfd);
3914
3915   free (data_buffer);
3916   data_buffer = NULL;
3917
3918   return true;
3919 }
3920
3921
3922 static reloc_howto_type xcoff_dynamic_reloc =
3923 HOWTO (0,                       /* type */
3924        0,                       /* rightshift */
3925        2,                       /* size (0 = byte, 1 = short, 2 = long) */
3926        32,                      /* bitsize */
3927        false,                   /* pc_relative */
3928        0,                       /* bitpos */
3929        complain_overflow_bitfield, /* complain_on_overflow */
3930        0,                       /* special_function */
3931        "R_POS",               /* name */
3932        true,                    /* partial_inplace */
3933        0xffffffff,            /* src_mask */
3934        0xffffffff,            /* dst_mask */
3935        false);                /* pcrel_offset */
3936
3937 /*  glink
3938
3939    The first word of global linkage code must be modified by filling in
3940    the correct TOC offset.  */
3941
3942 static unsigned long xcoff_glink_code[9] =
3943   {
3944     0x81820000, /* lwz r12,0(r2) */
3945     0x90410014, /* stw r2,20(r1) */
3946     0x800c0000, /* lwz r0,0(r12) */
3947     0x804c0004, /* lwz r2,4(r12) */
3948     0x7c0903a6, /* mtctr r0 */
3949     0x4e800420, /* bctr */
3950     0x00000000, /* start of traceback table */
3951     0x000c8000, /* traceback table */
3952     0x00000000, /* traceback table */
3953   };
3954
3955
3956 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
3957   {
3958     { /* COFF backend, defined in libcoff.h.  */
3959       _bfd_xcoff_swap_aux_in,           /* _bfd_coff_swap_aux_in */
3960       _bfd_xcoff_swap_sym_in,           /* _bfd_coff_swap_sym_in */
3961       coff_swap_lineno_in,              /* _bfd_coff_swap_lineno_in */
3962       _bfd_xcoff_swap_aux_out,          /* _bfd_swap_aux_out */
3963       _bfd_xcoff_swap_sym_out,          /* _bfd_swap_sym_out */
3964       coff_swap_lineno_out,             /* _bfd_swap_lineno_out */
3965       xcoff_swap_reloc_out,             /* _bfd_swap_reloc_out */
3966       coff_swap_filehdr_out,            /* _bfd_swap_filehdr_out */
3967       coff_swap_aouthdr_out,            /* _bfd_swap_aouthdr_out */
3968       coff_swap_scnhdr_out,             /* _bfd_swap_scnhdr_out */
3969       FILHSZ,                           /* _bfd_filhsz */
3970       AOUTSZ,                           /* _bfd_aoutsz */
3971       SCNHSZ,                           /* _bfd_scnhsz */
3972       SYMESZ,                           /* _bfd_symesz */
3973       AUXESZ,                           /* _bfd_auxesz */
3974       RELSZ,                            /* _bfd_relsz */
3975       LINESZ,                           /* _bfd_linesz */
3976       FILNMLEN,                         /* _bfd_filnmlen */
3977       true,                             /* _bfd_coff_long_filenames */
3978       false,                            /* _bfd_coff_long_section_names */
3979       (3),                              /* _bfd_coff_default_section_alignment_power */
3980       false,                            /* _bfd_coff_force_symnames_in_strings */
3981       2,                                /* _bfd_coff_debug_string_prefix_length */
3982       coff_swap_filehdr_in,             /* _bfd_coff_swap_filehdr_in */
3983       coff_swap_aouthdr_in,             /* _bfd_swap_aouthdr_in */
3984       coff_swap_scnhdr_in,              /* _bfd_swap_scnhdr_in */
3985       xcoff_swap_reloc_in,              /* _bfd_reloc_in */
3986       coff_bad_format_hook,             /* _bfd_bad_format_hook */
3987       coff_set_arch_mach_hook,          /* _bfd_set_arch_mach_hook */
3988       coff_mkobject_hook,               /* _bfd_mkobject_hook */
3989       styp_to_sec_flags,                /* _bfd_syp_to_sec_flags */
3990       coff_set_alignment_hook,          /* _bfd_set_alignment_hook */
3991       coff_slurp_symbol_table,          /* _bfd_coff_slurp_symbol_table */
3992       symname_in_debug_hook,            /* _coff_symname_in_debug_hook */
3993       coff_pointerize_aux_hook,         /* _bfd_coff_pointerize_aux_hook */
3994       coff_print_aux,                   /* bfd_coff_print_aux */
3995       dummy_reloc16_extra_cases,        /* _bfd_coff_reloc16_extra_cases */
3996       dummy_reloc16_estimate,           /* _bfd_coff_reloc16_estimate */
3997       NULL,                             /* bfd_coff_sym_is_global */
3998       coff_compute_section_file_positions, /* _bfd_coff_compute_section_file_positions */
3999       NULL,                             /* _bfd_coff_start_final_link */
4000       xcoff_ppc_relocate_section,       /* _bfd_coff_relocate_section */
4001       coff_rtype_to_howto,              /* _bfd_coff_rtype_to_howto */
4002       NULL,                             /* _bfd_coff_addust_symndx */
4003       _bfd_generic_link_add_one_symbol, /* _bfd_coff_add_one_symbol */
4004       coff_link_output_has_begun,       /* _bfd_coff_link_output_has_begun */
4005       coff_final_link_postscript        /* _bfd_coff_final_link_postscript */
4006     },
4007
4008     0x01DF,                             /* magic number */
4009     bfd_arch_rs6000,                    /* architecture */
4010     bfd_mach_rs6k,                      /* machine */
4011
4012     /* Function pointers to xcoff specific swap routines.  */
4013     xcoff_swap_ldhdr_in,                /* _xcoff_swap_ldhdr_in */
4014     xcoff_swap_ldhdr_out,               /* _xcoff_swap_ldhdr_out */
4015     xcoff_swap_ldsym_in,                /* _xcoff_swap_ldsym_in */
4016     xcoff_swap_ldsym_out,               /* _xcoff_swap_ldsym_out */
4017     xcoff_swap_ldrel_in,                /* _xcoff_swap_ldrel_in */
4018     xcoff_swap_ldrel_out,               /* _xcoff_swap_ldrel_out */
4019
4020     /* Sizes.  */
4021     LDHDRSZ,                            /* _xcoff_ldhdrsz */
4022     LDSYMSZ,                            /* _xcoff_ldsymsz */
4023     LDRELSZ,                            /* _xcoff_ldrelsz */
4024     12,                                 /* _xcoff_function_descriptor_size */
4025     SMALL_AOUTSZ,                       /* _xcoff_small_aout_header_size */
4026
4027   /* Versions. */
4028     1,                                   /* _xcoff_ldhdr_version */
4029
4030     _bfd_xcoff_put_symbol_name,          /* _xcoff_put_symbol_name */
4031     _bfd_xcoff_put_ldsymbol_name,        /* _xcoff_put_ldsymbol_name */
4032     & xcoff_dynamic_reloc,               /* dynamic reloc howto */
4033     xcoff_create_csect_from_smclas,      /* _xcoff_create_csect_from_smclas */
4034
4035     /* Lineno and reloc count overflow.  */
4036     xcoff_is_lineno_count_overflow,
4037     xcoff_is_reloc_count_overflow,
4038
4039     xcoff_loader_symbol_offset,
4040     xcoff_loader_reloc_offset,
4041
4042     /* glink.  */
4043     & xcoff_glink_code[0],
4044     (36),           /* _xcoff_glink_size */
4045
4046     /* rtinit */
4047     64,           /* _xcoff_rtinit_size */
4048     xcoff_generate_rtinit,  /* _xcoff_generate_rtinit */
4049 };
4050
4051 /* The transfer vector that leads the outside world to all of the above.  */
4052 const bfd_target rs6000coff_vec =
4053 {
4054   "aixcoff-rs6000",
4055   bfd_target_xcoff_flavour,
4056   BFD_ENDIAN_BIG,               /* data byte order is big */
4057   BFD_ENDIAN_BIG,               /* header byte order is big */
4058
4059   (HAS_RELOC | EXEC_P |         /* object flags */
4060    HAS_LINENO | HAS_DEBUG | DYNAMIC |
4061    HAS_SYMS | HAS_LOCALS | WP_TEXT),
4062
4063   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
4064   0,                            /* leading char */
4065   '/',                          /* ar_pad_char */
4066   15,                           /* ar_max_namelen??? FIXMEmgo */
4067
4068                       /* data */
4069   bfd_getb64,         /* bfd_getx64 */
4070   bfd_getb_signed_64, /* bfd_getx_signed_64 */
4071   bfd_putb64,         /* bfd_putx64 */
4072   bfd_getb32,         /* bfd_getx32 */
4073   bfd_getb_signed_32, /* bfd_getx_signed_32 */
4074   bfd_putb32,         /* bfd_putx32 */
4075   bfd_getb16,         /* bfd_getx16 */
4076   bfd_getb_signed_16, /* bfd_getx_signed_16 */
4077   bfd_putb16,         /* bfd_putx16 */
4078
4079                       /* hdrs */
4080   bfd_getb64,         /* bfd_h_getx64 */
4081   bfd_getb_signed_64, /* bfd_h_getx_signed_64 */
4082   bfd_putb64,         /* bfd_h_putx64 */
4083   bfd_getb32,         /* bfd_h_getx32 */
4084   bfd_getb_signed_32, /* bfd_h_getx_signed_32 */
4085   bfd_putb32,         /* bfd_h_putx32 */
4086   bfd_getb16,         /* bfd_h_getx16 */
4087   bfd_getb_signed_16, /* bfd_h_getx_signed_16 */
4088   bfd_putb16,         /* bfd_h_putx16 */
4089
4090   { /* bfd_check_format */
4091     _bfd_dummy_target,
4092     coff_object_p,
4093     _bfd_xcoff_archive_p,
4094     CORE_FILE_P
4095   },
4096
4097   { /* bfd_set_format */
4098     bfd_false,
4099     coff_mkobject,
4100     _bfd_generic_mkarchive,
4101     bfd_false
4102   },
4103
4104   {/* bfd_write_contents */
4105     bfd_false,
4106     coff_write_object_contents,
4107     _bfd_xcoff_write_archive_contents,
4108     bfd_false
4109   },
4110
4111   /* Generic */
4112   bfd_true,                          /* _close_and_cleanup */
4113   bfd_true,                          /* _bfd_free_cached_info */
4114   coff_new_section_hook,             /* _new_section_hook */
4115   _bfd_generic_get_section_contents, /* _bfd_get_section_contents */
4116                                      /* _bfd_get_section_contents_in_window */
4117   _bfd_generic_get_section_contents_in_window,
4118
4119   /* Copy */
4120   _bfd_xcoff_copy_private_bfd_data, /* _bfd_copy_private_bfd */
4121                                     /* _bfd_merge_private_bfd_data */
4122   ((boolean (*) (bfd *, bfd *)) bfd_true),
4123                                     /* _bfd_copy_pivate_section_data */
4124   ((boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4125                                     /* _bfd_copy_private_symbol_data */
4126   ((boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4127   ((boolean (*) (bfd *, flagword)) bfd_true), /* _bfd_set_private_flags */
4128   ((boolean (*) (bfd *, void * )) bfd_true),  /* _bfd_print_private_bfd_data */
4129
4130   /* Core */
4131   coff_core_file_failing_command,    /* _core_file_failing_command */
4132   coff_core_file_failing_signal,     /* _core_file_failing_signal */
4133                                           /* _core_file_matches_executable_p */
4134   coff_core_file_matches_executable_p,
4135
4136   /* Archive */
4137   _bfd_xcoff_slurp_armap,                  /* _slurp_armap */
4138                                            /* XCOFF archives do not have
4139                                               anything which corresponds to
4140                                               an extended name table.  */
4141   bfd_false,                               /* _slurp_extended_name_table */
4142                                            /* _construct_extended_name_table */
4143   ((boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4144   bfd_dont_truncate_arname,                /* _truncate_arname */
4145   _bfd_xcoff_write_armap,                  /* _write_armap */
4146   _bfd_xcoff_read_ar_hdr,                  /* _read_ar_hdr */
4147   _bfd_xcoff_openr_next_archived_file,     /* _openr_next_archived_file */
4148   _bfd_generic_get_elt_at_index,           /* _get_elt_at_index */
4149   _bfd_xcoff_stat_arch_elt,                /* _generic_stat_arch_elt */
4150                                            /* XCOFF archives do not have
4151                                               a timestamp.  */
4152   bfd_true,                                /* _update_armap_timestamp */
4153
4154   /* Symbols */
4155   coff_get_symtab_upper_bound,             /* _get_symtab_upper_bound */
4156   coff_get_symtab,                         /* _get_symtab */
4157   coff_make_empty_symbol,                  /* _make_empty_symbol */
4158   coff_print_symbol,                       /* _print_symbol */
4159   coff_get_symbol_info,                    /* _get_symbol_info */
4160   _bfd_xcoff_is_local_label_name,          /* _bfd_is_local_label_name */
4161   coff_get_lineno,                         /* _get_lineno */
4162   coff_find_nearest_line,                  /* _find_nearest_line */
4163   coff_bfd_make_debug_symbol,              /* _bfd_make_debug_symbol */
4164   _bfd_generic_read_minisymbols,           /* _read_minisymbols */
4165   _bfd_generic_minisymbol_to_symbol,       /* _minsymbol_to_symbol */
4166
4167   /* Reloc */
4168   coff_get_reloc_upper_bound,              /* _get_reloc_upper_bound */
4169   coff_canonicalize_reloc,                 /* _cononicalize_reloc */
4170   _bfd_xcoff_reloc_type_lookup,            /* _bfd_reloc_type_lookup */
4171
4172   /* Write */
4173   coff_set_arch_mach,                      /* _set_arch_mach */
4174   coff_set_section_contents,               /* _set_section_contents */
4175
4176   /* Link */
4177   _bfd_xcoff_sizeof_headers,               /* _sizeof_headers */
4178                                       /* _bfd_get_relocated_section_contents */
4179   bfd_generic_get_relocated_section_contents,
4180   bfd_generic_relax_section,               /* _bfd_relax_section */
4181   _bfd_xcoff_bfd_link_hash_table_create,   /* _bfd_link_hash_table_create */
4182   _bfd_generic_link_hash_table_free,       /* _bfd_link_hash_table_free */
4183   _bfd_xcoff_bfd_link_add_symbols,         /* _bfd_link_add_symbols */
4184   _bfd_generic_link_just_syms,             /* _bfd_link_just_syms */
4185   _bfd_xcoff_bfd_final_link,               /* _bfd_final_link */
4186   _bfd_generic_link_split_section,         /* _bfd_link_split_section */
4187   bfd_generic_gc_sections,                 /* _bfd_gc_sections */
4188   bfd_generic_merge_sections,              /* _bfd_merge_sections */
4189   bfd_generic_discard_group,               /* _bfd_discard_group */
4190
4191   /* Dynamic */
4192                                           /* _get_dynamic_symtab_upper_bound */
4193   _bfd_xcoff_get_dynamic_symtab_upper_bound,
4194   _bfd_xcoff_canonicalize_dynamic_symtab,  /* _cononicalize_dynamic_symtab */
4195   _bfd_xcoff_get_dynamic_reloc_upper_bound,/* _get_dynamic_reloc_upper_bound */
4196   _bfd_xcoff_canonicalize_dynamic_reloc,   /* _cononicalize_dynamic_reloc */
4197
4198   /* Opposite endian version, none exists */
4199   NULL,
4200
4201   /* back end data */
4202   (void *) &bfd_xcoff_backend_data,
4203 };
4204
4205 /*
4206  * xcoff-powermac target
4207  * Old target.
4208  * Only difference between this target and the rs6000 target is the
4209  * the default architecture and machine type used in coffcode.h
4210  *
4211  * PowerPC Macs use the same magic numbers as RS/6000
4212  * (because that's how they were bootstrapped originally),
4213  * but they are always PowerPC architecture.
4214  */
4215 static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
4216 {
4217   { /* COFF backend, defined in libcoff.h */
4218     _bfd_xcoff_swap_aux_in,           /* _bfd_coff_swap_aux_in */
4219     _bfd_xcoff_swap_sym_in,           /* _bfd_coff_swap_sym_in */
4220     coff_swap_lineno_in,              /* _bfd_coff_swap_lineno_in */
4221     _bfd_xcoff_swap_aux_out,          /* _bfd_swap_aux_out */
4222     _bfd_xcoff_swap_sym_out,          /* _bfd_swap_sym_out */
4223     coff_swap_lineno_out,             /* _bfd_swap_lineno_out */
4224     xcoff_swap_reloc_out,             /* _bfd_swap_reloc_out */
4225     coff_swap_filehdr_out,            /* _bfd_swap_filehdr_out */
4226     coff_swap_aouthdr_out,            /* _bfd_swap_aouthdr_out */
4227     coff_swap_scnhdr_out,             /* _bfd_swap_scnhdr_out */
4228     FILHSZ,                           /* _bfd_filhsz */
4229     AOUTSZ,                           /* _bfd_aoutsz */
4230     SCNHSZ,                           /* _bfd_scnhsz */
4231     SYMESZ,                           /* _bfd_symesz */
4232     AUXESZ,                           /* _bfd_auxesz */
4233     RELSZ,                            /* _bfd_relsz */
4234     LINESZ,                           /* _bfd_linesz */
4235     FILNMLEN,                         /* _bfd_filnmlen */
4236     true,                             /* _bfd_coff_long_filenames */
4237     false,                            /* _bfd_coff_long_section_names */
4238     (3),                        /* _bfd_coff_default_section_alignment_power */
4239     false,                            /* _bfd_coff_force_symnames_in_strings */
4240     2,                               /* _bfd_coff_debug_string_prefix_length */
4241     coff_swap_filehdr_in,             /* _bfd_coff_swap_filehdr_in */
4242     coff_swap_aouthdr_in,             /* _bfd_swap_aouthdr_in */
4243     coff_swap_scnhdr_in,              /* _bfd_swap_scnhdr_in */
4244     xcoff_swap_reloc_in,              /* _bfd_reloc_in */
4245     coff_bad_format_hook,             /* _bfd_bad_format_hook */
4246     coff_set_arch_mach_hook,          /* _bfd_set_arch_mach_hook */
4247     coff_mkobject_hook,               /* _bfd_mkobject_hook */
4248     styp_to_sec_flags,                /* _bfd_syp_to_sec_flags */
4249     coff_set_alignment_hook,          /* _bfd_set_alignment_hook */
4250     coff_slurp_symbol_table,          /* _bfd_coff_slurp_symbol_table */
4251     symname_in_debug_hook,            /* _coff_symname_in_debug_hook */
4252     coff_pointerize_aux_hook,         /* _bfd_coff_pointerize_aux_hook */
4253     coff_print_aux,                   /* bfd_coff_print_aux */
4254     dummy_reloc16_extra_cases,        /* _bfd_coff_reloc16_extra_cases */
4255     dummy_reloc16_estimate,           /* _bfd_coff_reloc16_estimate */
4256     NULL,                             /* bfd_coff_sym_is_global */
4257                                  /* _bfd_coff_compute_section_file_positions */
4258     coff_compute_section_file_positions,
4259     NULL,                             /* _bfd_coff_start_final_link */
4260     xcoff_ppc_relocate_section,       /* _bfd_coff_relocate_section */
4261     coff_rtype_to_howto,              /* _bfd_coff_rtype_to_howto */
4262     NULL,                             /* _bfd_coff_addust_symndx */
4263     _bfd_generic_link_add_one_symbol, /* _bfd_coff_add_one_symbol */
4264     coff_link_output_has_begun,       /* _bfd_coff_link_output_has_begun */
4265     coff_final_link_postscript        /* _bfd_coff_final_link_postscript */
4266   },
4267
4268   0x01DF,                             /* magic number */
4269   bfd_arch_powerpc,                   /* architecture */
4270   bfd_mach_ppc,                       /* machine */
4271
4272   /* function pointers to xcoff specific swap routines */
4273   xcoff_swap_ldhdr_in,                /* _xcoff_swap_ldhdr_in */
4274   xcoff_swap_ldhdr_out,               /* _xcoff_swap_ldhdr_out */
4275   xcoff_swap_ldsym_in,                /* _xcoff_swap_ldsym_in */
4276   xcoff_swap_ldsym_out,               /* _xcoff_swap_ldsym_out */
4277   xcoff_swap_ldrel_in,                /* _xcoff_swap_ldrel_in */
4278   xcoff_swap_ldrel_out,               /* _xcoff_swap_ldrel_out */
4279
4280   /* sizes */
4281   LDHDRSZ,                            /* _xcoff_ldhdrsz */
4282   LDSYMSZ,                            /* _xcoff_ldsymsz */
4283   LDRELSZ,                            /* _xcoff_ldrelsz */
4284   12,                                 /* _xcoff_function_descriptor_size */
4285   SMALL_AOUTSZ,                       /* _xcoff_small_aout_header_size */
4286
4287   /* versions */
4288   1,                                    /* _xcoff_ldhdr_version */
4289
4290   /* xcoff vs xcoff64 putting symbol names */
4291   _bfd_xcoff_put_symbol_name,          /* _xcoff_put_symbol_name */
4292   _bfd_xcoff_put_ldsymbol_name,          /* _xcoff_put_ldsymbol_name */
4293
4294   &xcoff_dynamic_reloc,                  /* dynamic reloc howto */
4295
4296   xcoff_create_csect_from_smclas,      /* _xcoff_create_csect_from_smclas */
4297
4298   /* lineno and reloc count overflow */
4299   xcoff_is_lineno_count_overflow,
4300   xcoff_is_reloc_count_overflow,
4301
4302   xcoff_loader_symbol_offset,
4303   xcoff_loader_reloc_offset,
4304
4305   /* glink */
4306   &xcoff_glink_code[0],
4307   (36),           /* _xcoff_glink_size */
4308
4309   /* rtinit */
4310   0,           /* _xcoff_rtinit_size */
4311   xcoff_generate_rtinit,  /* _xcoff_generate_rtinit */
4312 };
4313
4314 /* The transfer vector that leads the outside world to all of the above. */
4315 const bfd_target pmac_xcoff_vec =
4316 {
4317   "xcoff-powermac",
4318   bfd_target_xcoff_flavour,
4319   BFD_ENDIAN_BIG,               /* data byte order is big */
4320   BFD_ENDIAN_BIG,               /* header byte order is big */
4321
4322   (HAS_RELOC | EXEC_P |         /* object flags */
4323    HAS_LINENO | HAS_DEBUG | DYNAMIC |
4324    HAS_SYMS | HAS_LOCALS | WP_TEXT),
4325
4326   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
4327   0,                            /* leading char */
4328   '/',                          /* ar_pad_char */
4329   15,                           /* ar_max_namelen??? FIXMEmgo */
4330
4331                       /* data */
4332   bfd_getb64,         /* bfd_getx64 */
4333   bfd_getb_signed_64, /* bfd_getx_signed_64 */
4334   bfd_putb64,         /* bfd_putx64 */
4335   bfd_getb32,         /* bfd_getx32 */
4336   bfd_getb_signed_32, /* bfd_getx_signed_32 */
4337   bfd_putb32,         /* bfd_putx32 */
4338   bfd_getb16,         /* bfd_getx16 */
4339   bfd_getb_signed_16, /* bfd_getx_signed_16 */
4340   bfd_putb16,         /* bfd_putx16 */
4341
4342                       /* hdrs */
4343   bfd_getb64,         /* bfd_h_getx64 */
4344   bfd_getb_signed_64, /* bfd_h_getx_signed_64 */
4345   bfd_putb64,         /* bfd_h_putx64 */
4346   bfd_getb32,         /* bfd_h_getx32 */
4347   bfd_getb_signed_32, /* bfd_h_getx_signed_32 */
4348   bfd_putb32,         /* bfd_h_putx32 */
4349   bfd_getb16,         /* bfd_h_getx16 */
4350   bfd_getb_signed_16, /* bfd_h_getx_signed_16 */
4351   bfd_putb16,         /* bfd_h_putx16 */
4352
4353   { /* bfd_check_format */
4354     _bfd_dummy_target,
4355     coff_object_p,
4356     _bfd_xcoff_archive_p,
4357     CORE_FILE_P
4358   },
4359
4360   { /* bfd_set_format */
4361     bfd_false,
4362     coff_mkobject,
4363     _bfd_generic_mkarchive,
4364     bfd_false
4365   },
4366
4367   {/* bfd_write_contents */
4368     bfd_false,
4369     coff_write_object_contents,
4370     _bfd_xcoff_write_archive_contents,
4371     bfd_false
4372   },
4373
4374   /* Generic */
4375   bfd_true,                          /* _close_and_cleanup */
4376   bfd_true,                          /* _bfd_free_cached_info */
4377   coff_new_section_hook,             /* _new_section_hook */
4378   _bfd_generic_get_section_contents, /* _bfd_get_section_contents */
4379                                      /* _bfd_get_section_contents_in_window */
4380   _bfd_generic_get_section_contents_in_window,
4381
4382   /* Copy */
4383   _bfd_xcoff_copy_private_bfd_data, /* _bfd_copy_private_bfd */
4384                                     /* _bfd_merge_private_bfd_data */
4385   ((boolean (*) (bfd *, bfd *)) bfd_true),
4386                                     /* _bfd_copy_pivate_section_data */
4387   ((boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4388                                     /* _bfd_copy_private_symbol_data */
4389   ((boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4390   ((boolean (*) (bfd *, flagword)) bfd_true), /* _bfd_set_private_flags */
4391   ((boolean (*) (bfd *, void * )) bfd_true),  /* _bfd_print_private_bfd_data */
4392
4393   /* Core */
4394   coff_core_file_failing_command,    /* _core_file_failing_command */
4395   coff_core_file_failing_signal,     /* _core_file_failing_signal */
4396                                           /* _core_file_matches_executable_p */
4397   coff_core_file_matches_executable_p,
4398
4399   /* Archive */
4400   _bfd_xcoff_slurp_armap,                  /* _slurp_armap */
4401                                            /* XCOFF archives do not have
4402                                               anything which corresponds to
4403                                               an extended name table.  */
4404   bfd_false,                               /* _slurp_extended_name_table */
4405                                            /* _construct_extended_name_table */
4406   ((boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4407   bfd_dont_truncate_arname,                /* _truncate_arname */
4408   _bfd_xcoff_write_armap,                  /* _write_armap */
4409   _bfd_xcoff_read_ar_hdr,                  /* _read_ar_hdr */
4410   _bfd_xcoff_openr_next_archived_file,     /* _openr_next_archived_file */
4411   _bfd_generic_get_elt_at_index,           /* _get_elt_at_index */
4412   _bfd_xcoff_stat_arch_elt,                /* _generic_stat_arch_elt */
4413                                            /* XCOFF archives do not have
4414                                               a timestamp.  */
4415   bfd_true,                                /* _update_armap_timestamp */
4416
4417   /* Symbols */
4418   coff_get_symtab_upper_bound,             /* _get_symtab_upper_bound */
4419   coff_get_symtab,                         /* _get_symtab */
4420   coff_make_empty_symbol,                  /* _make_empty_symbol */
4421   coff_print_symbol,                       /* _print_symbol */
4422   coff_get_symbol_info,                    /* _get_symbol_info */
4423   _bfd_xcoff_is_local_label_name,          /* _bfd_is_local_label_name */
4424   coff_get_lineno,                         /* _get_lineno */
4425   coff_find_nearest_line,                  /* _find_nearest_line */
4426   coff_bfd_make_debug_symbol,              /* _bfd_make_debug_symbol */
4427   _bfd_generic_read_minisymbols,           /* _read_minisymbols */
4428   _bfd_generic_minisymbol_to_symbol,       /* _minsymbol_to_symbol */
4429
4430   /* Reloc */
4431   coff_get_reloc_upper_bound,              /* _get_reloc_upper_bound */
4432   coff_canonicalize_reloc,                 /* _cononicalize_reloc */
4433   _bfd_xcoff_reloc_type_lookup,            /* _bfd_reloc_type_lookup */
4434
4435   /* Write */
4436   coff_set_arch_mach,                      /* _set_arch_mach */
4437   coff_set_section_contents,               /* _set_section_contents */
4438
4439   /* Link */
4440   _bfd_xcoff_sizeof_headers,               /* _sizeof_headers */
4441                                       /* _bfd_get_relocated_section_contents */
4442   bfd_generic_get_relocated_section_contents,
4443   bfd_generic_relax_section,               /* _bfd_relax_section */
4444   _bfd_xcoff_bfd_link_hash_table_create,   /* _bfd_link_hash_table_create */
4445   _bfd_generic_link_hash_table_free,       /* _bfd_link_hash_table_free */
4446   _bfd_xcoff_bfd_link_add_symbols,         /* _bfd_link_add_symbols */
4447   _bfd_generic_link_just_syms,             /* _bfd_link_just_syms */
4448   _bfd_xcoff_bfd_final_link,               /* _bfd_final_link */
4449   _bfd_generic_link_split_section,         /* _bfd_link_split_section */
4450   bfd_generic_gc_sections,                 /* _bfd_gc_sections */
4451   bfd_generic_merge_sections,              /* _bfd_merge_sections */
4452   bfd_generic_discard_group,               /* _bfd_discard_group */
4453
4454   /* Dynamic */
4455                                           /* _get_dynamic_symtab_upper_bound */
4456   _bfd_xcoff_get_dynamic_symtab_upper_bound,
4457   _bfd_xcoff_canonicalize_dynamic_symtab,  /* _cononicalize_dynamic_symtab */
4458   _bfd_xcoff_get_dynamic_reloc_upper_bound,/* _get_dynamic_reloc_upper_bound */
4459   _bfd_xcoff_canonicalize_dynamic_reloc,   /* _cononicalize_dynamic_reloc */
4460
4461   /* Opposite endian version, none exists */
4462   NULL,
4463
4464   /* back end data */
4465   (void *) &bfd_pmac_xcoff_backend_data,
4466 };