OSDN Git Service

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