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