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