OSDN Git Service

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