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