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