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