Revert the value change of DT_ENCODING from 2003-01-17. Luckily (and
[deliverable/binutils-gdb.git] / bfd / coff64-rs6000.c
CommitLineData
7f6d05e8 1/* BFD back-end for IBM RS/6000 "XCOFF64" files.
157090f7 2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
7f6d05e8
CP
3 Free Software Foundation, Inc.
4 Written Clinton Popetz.
5 Contributed by Cygnus Support.
6
eb1e0e80 7 This file is part of BFD, the Binary File Descriptor library.
7f6d05e8 8
eb1e0e80
NC
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
7f6d05e8 13
eb1e0e80
NC
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
7f6d05e8 18
eb1e0e80
NC
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
3e110533 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
7f6d05e8 22
7f6d05e8
CP
23#include "bfd.h"
24#include "sysdep.h"
beb1bf64 25#include "bfdlink.h"
7f6d05e8
CP
26#include "libbfd.h"
27#include "coff/internal.h"
beb1bf64 28#include "coff/xcoff.h"
7f6d05e8 29#include "coff/rs6k64.h"
dc810e39 30#include "libcoff.h"
beb1bf64 31#include "libxcoff.h"
7f6d05e8 32
dc810e39
AM
33#define GET_FILEHDR_SYMPTR H_GET_64
34#define PUT_FILEHDR_SYMPTR H_PUT_64
35#define GET_AOUTHDR_DATA_START H_GET_64
36#define PUT_AOUTHDR_DATA_START H_PUT_64
37#define GET_AOUTHDR_TEXT_START H_GET_64
38#define PUT_AOUTHDR_TEXT_START H_PUT_64
39#define GET_AOUTHDR_TSIZE H_GET_64
40#define PUT_AOUTHDR_TSIZE H_PUT_64
41#define GET_AOUTHDR_DSIZE H_GET_64
42#define PUT_AOUTHDR_DSIZE H_PUT_64
43#define GET_AOUTHDR_BSIZE H_GET_64
44#define PUT_AOUTHDR_BSIZE H_PUT_64
45#define GET_AOUTHDR_ENTRY H_GET_64
46#define PUT_AOUTHDR_ENTRY H_PUT_64
47#define GET_SCNHDR_PADDR H_GET_64
48#define PUT_SCNHDR_PADDR H_PUT_64
49#define GET_SCNHDR_VADDR H_GET_64
50#define PUT_SCNHDR_VADDR H_PUT_64
51#define GET_SCNHDR_SIZE H_GET_64
52#define PUT_SCNHDR_SIZE H_PUT_64
53#define GET_SCNHDR_SCNPTR H_GET_64
54#define PUT_SCNHDR_SCNPTR H_PUT_64
55#define GET_SCNHDR_RELPTR H_GET_64
56#define PUT_SCNHDR_RELPTR H_PUT_64
57#define GET_SCNHDR_LNNOPTR H_GET_64
58#define PUT_SCNHDR_LNNOPTR H_PUT_64
59#define GET_SCNHDR_NRELOC H_GET_32
7f6d05e8 60#define MAX_SCNHDR_NRELOC 0xffffffff
dc810e39
AM
61#define PUT_SCNHDR_NRELOC H_PUT_32
62#define GET_SCNHDR_NLNNO H_GET_32
7f6d05e8 63#define MAX_SCNHDR_NLNNO 0xffffffff
dc810e39
AM
64#define PUT_SCNHDR_NLNNO H_PUT_32
65#define GET_RELOC_VADDR H_GET_64
66#define PUT_RELOC_VADDR H_PUT_64
7f6d05e8
CP
67
68#define COFF_FORCE_SYMBOLS_IN_STRINGS
69#define COFF_DEBUG_STRING_WIDE_PREFIX
70
beb1bf64 71
dc810e39
AM
72#define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
73 do \
74 { \
75 memset (((SCNHDR *) EXT)->s_pad, 0, \
76 sizeof (((SCNHDR *) EXT)->s_pad)); \
77 } \
78 while (0)
7f6d05e8
CP
79
80#define NO_COFF_LINENOS
81
beb1bf64
TR
82#define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
83#define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
7f6d05e8 84
b34976b6
AM
85static void _bfd_xcoff64_swap_lineno_in
86 PARAMS ((bfd *, PTR, PTR));
87static unsigned int _bfd_xcoff64_swap_lineno_out
88 PARAMS ((bfd *, PTR, PTR));
89static bfd_boolean _bfd_xcoff64_put_symbol_name
54327882
AM
90 PARAMS ((bfd *, struct bfd_strtab_hash *, struct internal_syment *,
91 const char *));
b34976b6 92static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
814fa6ab
AM
93 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
94 const char *));
b34976b6
AM
95static void _bfd_xcoff64_swap_sym_in
96 PARAMS ((bfd *, PTR, PTR));
97static unsigned int _bfd_xcoff64_swap_sym_out
98 PARAMS ((bfd *, PTR, PTR));
dc810e39
AM
99static void _bfd_xcoff64_swap_aux_in
100 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
101static unsigned int _bfd_xcoff64_swap_aux_out
102 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
b34976b6
AM
103static void xcoff64_swap_reloc_in
104 PARAMS ((bfd *, PTR, PTR));
105static unsigned int xcoff64_swap_reloc_out
106 PARAMS ((bfd *, PTR, PTR));
107extern bfd_boolean _bfd_xcoff_mkobject
108 PARAMS ((bfd *));
109extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
110 PARAMS ((bfd *, bfd *));
111extern bfd_boolean _bfd_xcoff_is_local_label_name
112 PARAMS ((bfd *, const char *));
dc810e39
AM
113extern void xcoff64_rtype2howto
114 PARAMS ((arelent *, struct internal_reloc *));
115extern reloc_howto_type * xcoff64_reloc_type_lookup
116 PARAMS ((bfd *, bfd_reloc_code_real_type));
b34976b6
AM
117extern bfd_boolean _bfd_xcoff_slurp_armap
118 PARAMS ((bfd *));
119extern PTR _bfd_xcoff_read_ar_hdr
120 PARAMS ((bfd *));
121extern bfd *_bfd_xcoff_openr_next_archived_file
122 PARAMS ((bfd *, bfd *));
123extern int _bfd_xcoff_stat_arch_elt
124 PARAMS ((bfd *, struct stat *));
125extern bfd_boolean _bfd_xcoff_write_armap
dc810e39 126 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
b34976b6
AM
127extern bfd_boolean _bfd_xcoff_write_archive_contents
128 PARAMS ((bfd *));
129extern int _bfd_xcoff_sizeof_headers
a6b96beb 130 PARAMS ((bfd *, struct bfd_link_info *));
b34976b6
AM
131extern void _bfd_xcoff_swap_sym_in
132 PARAMS ((bfd *, PTR, PTR));
133extern unsigned int _bfd_xcoff_swap_sym_out
134 PARAMS ((bfd *, PTR, PTR));
dc810e39
AM
135extern void _bfd_xcoff_swap_aux_in
136 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
137extern unsigned int _bfd_xcoff_swap_aux_out
138 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
139static void xcoff64_swap_ldhdr_in
140 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
141static void xcoff64_swap_ldhdr_out
142 PARAMS ((bfd *, const struct internal_ldhdr *, PTR d));
143static void xcoff64_swap_ldsym_in
144 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
145static void xcoff64_swap_ldsym_out
146 PARAMS ((bfd *, const struct internal_ldsym *, PTR d));
147static void xcoff64_swap_ldrel_in
148 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
149static void xcoff64_swap_ldrel_out
150 PARAMS ((bfd *, const struct internal_ldrel *, PTR d));
b34976b6
AM
151static bfd_boolean xcoff64_write_object_contents
152 PARAMS ((bfd *));
153static bfd_boolean xcoff64_ppc_relocate_section
dc810e39 154 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
54327882
AM
155 struct internal_reloc *, struct internal_syment *,
156 asection **));
b34976b6
AM
157static bfd_boolean xcoff64_slurp_armap
158 PARAMS ((bfd *));
159static const bfd_target *xcoff64_archive_p
160 PARAMS ((bfd *));
161static bfd *xcoff64_openr_next_archived_file
162 PARAMS ((bfd *, bfd *));
163static int xcoff64_sizeof_headers
a6b96beb 164 PARAMS ((bfd *, struct bfd_link_info *));
dc810e39
AM
165static asection *xcoff64_create_csect_from_smclas
166 PARAMS ((bfd *, union internal_auxent *, const char *));
b34976b6
AM
167static bfd_boolean xcoff64_is_lineno_count_overflow
168 PARAMS ((bfd *, bfd_vma));
169static bfd_boolean xcoff64_is_reloc_count_overflow
170 PARAMS ((bfd *, bfd_vma));
dc810e39
AM
171static bfd_vma xcoff64_loader_symbol_offset
172 PARAMS ((bfd *, struct internal_ldhdr *));
173static bfd_vma xcoff64_loader_reloc_offset
174 PARAMS ((bfd *, struct internal_ldhdr *));
b34976b6
AM
175static bfd_boolean xcoff64_generate_rtinit
176 PARAMS ((bfd *, const char *, const char *, bfd_boolean));
177static bfd_boolean xcoff64_bad_format_hook
178 PARAMS ((bfd *, PTR ));
dc810e39 179
f1f0d9ab 180/* Relocation functions */
b34976b6
AM
181static bfd_boolean xcoff64_reloc_type_br
182 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
f1f0d9ab 183
b34976b6 184bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
cf9ab45b 185 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
f1f0d9ab 186{
cf9ab45b
AM
187 xcoff_reloc_type_pos, /* R_POS (0x00) */
188 xcoff_reloc_type_neg, /* R_NEG (0x01) */
189 xcoff_reloc_type_rel, /* R_REL (0x02) */
190 xcoff_reloc_type_toc, /* R_TOC (0x03) */
f1f0d9ab 191 xcoff_reloc_type_fail, /* R_RTB (0x04) */
cf9ab45b
AM
192 xcoff_reloc_type_toc, /* R_GL (0x05) */
193 xcoff_reloc_type_toc, /* R_TCL (0x06) */
194 xcoff_reloc_type_fail, /* (0x07) */
195 xcoff_reloc_type_ba, /* R_BA (0x08) */
196 xcoff_reloc_type_fail, /* (0x09) */
f1f0d9ab 197 xcoff64_reloc_type_br, /* R_BR (0x0a) */
cf9ab45b
AM
198 xcoff_reloc_type_fail, /* (0x0b) */
199 xcoff_reloc_type_pos, /* R_RL (0x0c) */
200 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
201 xcoff_reloc_type_fail, /* (0x0e) */
f1f0d9ab 202 xcoff_reloc_type_noop, /* R_REF (0x0f) */
cf9ab45b
AM
203 xcoff_reloc_type_fail, /* (0x10) */
204 xcoff_reloc_type_fail, /* (0x11) */
205 xcoff_reloc_type_toc, /* R_TRL (0x12) */
206 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
f1f0d9ab
TR
207 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
208 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
cf9ab45b 209 xcoff_reloc_type_ba, /* R_CAI (0x16) */
f1f0d9ab 210 xcoff_reloc_type_crel, /* R_CREL (0x17) */
cf9ab45b
AM
211 xcoff_reloc_type_ba, /* R_RBA (0x18) */
212 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
f1f0d9ab 213 xcoff64_reloc_type_br, /* R_RBR (0x1a) */
cf9ab45b 214 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
f1f0d9ab
TR
215};
216
eb1e0e80 217/* coffcode.h needs these to be defined. */
dc810e39
AM
218/* Internalcoff.h and coffcode.h modify themselves based on these flags. */
219#define XCOFF64
220#define RS6000COFF_C 1
221
222#define SELECT_RELOC(internal, howto) \
223 { \
224 internal.r_type = howto->type; \
225 internal.r_size = \
226 ((howto->complain_on_overflow == complain_overflow_signed \
227 ? 0x80 \
228 : 0) \
229 | (howto->bitsize - 1)); \
230 }
814fa6ab 231
dc810e39
AM
232#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
233#define COFF_LONG_FILENAMES
234#define NO_COFF_SYMBOLS
235#define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
236#define coff_mkobject _bfd_xcoff_mkobject
237#define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
238#define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
239#define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
157090f7 240#define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
dc810e39 241#ifdef AIX_CORE
b34976b6
AM
242extern const bfd_target * rs6000coff_core_p
243 PARAMS ((bfd *abfd));
244extern bfd_boolean rs6000coff_core_file_matches_executable_p
cf9ab45b 245 PARAMS ((bfd *cbfd, bfd *ebfd));
b34976b6
AM
246extern char *rs6000coff_core_file_failing_command
247 PARAMS ((bfd *abfd));
248extern int rs6000coff_core_file_failing_signal
249 PARAMS ((bfd *abfd));
dc810e39
AM
250#define CORE_FILE_P rs6000coff_core_p
251#define coff_core_file_failing_command \
252 rs6000coff_core_file_failing_command
253#define coff_core_file_failing_signal \
254 rs6000coff_core_file_failing_signal
255#define coff_core_file_matches_executable_p \
256 rs6000coff_core_file_matches_executable_p
257#else
258#define CORE_FILE_P _bfd_dummy_target
259#define coff_core_file_failing_command \
260 _bfd_nocore_core_file_failing_command
261#define coff_core_file_failing_signal \
262 _bfd_nocore_core_file_failing_signal
263#define coff_core_file_matches_executable_p \
264 _bfd_nocore_core_file_matches_executable_p
265#endif
266#define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
267#define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
268#define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
269#define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
59862849
TR
270#define coff_swap_reloc_in xcoff64_swap_reloc_in
271#define coff_swap_reloc_out xcoff64_swap_reloc_out
272#define NO_COFF_RELOCS
dc810e39
AM
273
274#include "coffcode.h"
275
276/* For XCOFF64, the effective width of symndx changes depending on
7f6d05e8
CP
277 whether we are the first entry. Sigh. */
278static void
beb1bf64 279_bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
dc810e39 280 bfd *abfd;
7f6d05e8
CP
281 PTR ext1;
282 PTR in1;
283{
dc810e39
AM
284 LINENO *ext = (LINENO *) ext1;
285 struct internal_lineno *in = (struct internal_lineno *) in1;
7f6d05e8 286
dc810e39 287 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
7f6d05e8 288 if (in->l_lnno == 0)
dc810e39 289 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
7f6d05e8 290 else
dc810e39 291 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
7f6d05e8
CP
292}
293
294static unsigned int
beb1bf64 295_bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
dc810e39
AM
296 bfd *abfd;
297 PTR inp;
298 PTR outp;
7f6d05e8 299{
dc810e39
AM
300 struct internal_lineno *in = (struct internal_lineno *) inp;
301 struct external_lineno *ext = (struct external_lineno *) outp;
302
303 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
304 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
7f6d05e8 305
7f6d05e8 306 if (in->l_lnno == 0)
dc810e39 307 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
7f6d05e8 308 else
dc810e39 309 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
7f6d05e8
CP
310
311 return bfd_coff_linesz (abfd);
312}
313
7f6d05e8 314static void
beb1bf64 315_bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
dc810e39 316 bfd *abfd;
7f6d05e8
CP
317 PTR ext1;
318 PTR in1;
319{
dc810e39
AM
320 struct external_syment *ext = (struct external_syment *) ext1;
321 struct internal_syment *in = (struct internal_syment *) in1;
7f6d05e8 322
7f6d05e8 323 in->_n._n_n._n_zeroes = 0;
dc810e39
AM
324 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
325 in->n_value = H_GET_64 (abfd, ext->e_value);
326 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
327 in->n_type = H_GET_16 (abfd, ext->e_type);
328 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
329 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
7f6d05e8
CP
330}
331
332static unsigned int
beb1bf64 333_bfd_xcoff64_swap_sym_out (abfd, inp, extp)
dc810e39
AM
334 bfd *abfd;
335 PTR inp;
336 PTR extp;
7f6d05e8 337{
dc810e39
AM
338 struct internal_syment *in = (struct internal_syment *) inp;
339 struct external_syment *ext = (struct external_syment *) extp;
340
341 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
342 H_PUT_64 (abfd, in->n_value, ext->e_value);
343 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
344 H_PUT_16 (abfd, in->n_type, ext->e_type);
345 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
346 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
7f6d05e8
CP
347 return bfd_coff_symesz (abfd);
348}
349
350static void
beb1bf64 351_bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
dc810e39
AM
352 bfd *abfd;
353 PTR ext1;
354 int type;
355 int class;
356 int indx;
357 int numaux;
358 PTR in1;
7f6d05e8 359{
dc810e39
AM
360 union external_auxent *ext = (union external_auxent *) ext1;
361 union internal_auxent *in = (union internal_auxent *) in1;
7f6d05e8 362
dc810e39
AM
363 switch (class)
364 {
7f6d05e8 365 case C_FILE:
deeb2cd7 366 if (ext->x_file.x_n.x_zeroes[0] == 0)
dc810e39 367 {
7f6d05e8 368 in->x_file.x_n.x_zeroes = 0;
dc810e39
AM
369 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
370 }
371 else
372 {
beb1bf64
TR
373 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
374 }
7f6d05e8
CP
375 goto end;
376
377 /* RS/6000 "csect" auxents */
378 case C_EXT:
379 case C_HIDEXT:
380 if (indx + 1 == numaux)
381 {
beb1bf64
TR
382 bfd_signed_vma h = 0;
383 bfd_vma l = 0;
384
dc810e39
AM
385 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
386 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
beb1bf64
TR
387
388 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
389
dc810e39
AM
390 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
391 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
7f6d05e8
CP
392 /* We don't have to hack bitfields in x_smtyp because it's
393 defined by shifts-and-ands, which are equivalent on all
394 byte orders. */
dc810e39
AM
395 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
396 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
7f6d05e8
CP
397 goto end;
398 }
399 break;
400
401 case C_STAT:
402 case C_LEAFSTAT:
403 case C_HIDDEN:
dc810e39
AM
404 if (type == T_NULL)
405 {
7f6d05e8 406 /* PE defines some extra fields; we zero them out for
dc810e39 407 safety. */
7f6d05e8
CP
408 in->x_scn.x_checksum = 0;
409 in->x_scn.x_associated = 0;
410 in->x_scn.x_comdat = 0;
411
412 goto end;
413 }
414 break;
415 }
416
417 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
418 {
dc810e39
AM
419 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
420 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
421 in->x_sym.x_fcnary.x_fcn.x_endndx.l
422 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
423 }
424 if (ISFCN (type))
425 {
426 in->x_sym.x_misc.x_fsize
427 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
428 }
429 else
430 {
431 in->x_sym.x_misc.x_lnsz.x_lnno
432 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
433 in->x_sym.x_misc.x_lnsz.x_size
434 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
7f6d05e8 435 }
7f6d05e8 436
dc810e39 437 end: ;
7f6d05e8
CP
438}
439
7f6d05e8 440static unsigned int
beb1bf64 441_bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
dc810e39
AM
442 bfd *abfd;
443 PTR inp;
444 int type;
445 int class;
446 int indx ATTRIBUTE_UNUSED;
447 int numaux ATTRIBUTE_UNUSED;
448 PTR extp;
7f6d05e8 449{
dc810e39
AM
450 union internal_auxent *in = (union internal_auxent *) inp;
451 union external_auxent *ext = (union external_auxent *) extp;
7f6d05e8 452
dc810e39 453 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
7f6d05e8
CP
454 switch (class)
455 {
dc810e39 456 case C_FILE:
a58d9c34 457 if (in->x_file.x_n.x_zeroes == 0)
dc810e39
AM
458 {
459 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
460 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
461 }
462 else
463 {
464 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
465 }
466 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
7f6d05e8 467 goto end;
dc810e39
AM
468
469 /* RS/6000 "csect" auxents */
470 case C_EXT:
471 case C_HIDEXT:
472 if (indx + 1 == numaux)
473 {
474 bfd_vma temp;
475
476 temp = in->x_csect.x_scnlen.l & 0xffffffff;
477 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
478 temp = in->x_csect.x_scnlen.l >> 32;
479 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
480 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
481 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
482 /* We don't have to hack bitfields in x_smtyp because it's
483 defined by shifts-and-ands, which are equivalent on all
484 byte orders. */
485 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
486 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
487 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
488 goto end;
489 }
490 break;
491
492 case C_STAT:
493 case C_LEAFSTAT:
494 case C_HIDDEN:
495 if (type == T_NULL)
496 {
497 goto end;
498 }
499 break;
7f6d05e8 500 }
7f6d05e8
CP
501
502 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
503 {
dc810e39
AM
504 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
505 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
506 H_PUT_8 (abfd, _AUX_FCN,
507 ext->x_auxtype.x_auxtype);
508 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
509 ext->x_sym.x_fcnary.x_fcn.x_endndx);
7f6d05e8
CP
510 }
511 if (ISFCN (type))
dc810e39
AM
512 {
513 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
514 ext->x_sym.x_fcnary.x_fcn.x_fsize);
515 }
7f6d05e8
CP
516 else
517 {
dc810e39
AM
518 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
519 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
520 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
521 ext->x_sym.x_fcnary.x_lnsz.x_size);
7f6d05e8
CP
522 }
523
dc810e39 524 end:
beb1bf64 525
7f6d05e8
CP
526 return bfd_coff_auxesz (abfd);
527}
528
b34976b6 529static bfd_boolean
eb1e0e80
NC
530_bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
531 bfd *abfd;
532 struct bfd_strtab_hash *strtab;
533 struct internal_syment *sym;
534 const char *name;
535{
b34976b6 536 bfd_boolean hash;
beb1bf64 537 bfd_size_type indx;
dc810e39 538
b34976b6 539 hash = TRUE;
dc810e39 540
beb1bf64 541 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
b34976b6 542 hash = FALSE;
dc810e39 543
b34976b6 544 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
dc810e39 545
beb1bf64 546 if (indx == (bfd_size_type) -1)
b34976b6 547 return FALSE;
dc810e39 548
beb1bf64
TR
549 sym->_n._n_n._n_zeroes = 0;
550 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
dc810e39 551
b34976b6 552 return TRUE;
beb1bf64
TR
553}
554
b34976b6 555static bfd_boolean
beb1bf64
TR
556_bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
557 bfd *abfd ATTRIBUTE_UNUSED;
dc810e39
AM
558 struct xcoff_loader_info *ldinfo;
559 struct internal_ldsym *ldsym;
560 const char *name;
beb1bf64 561{
beb1bf64
TR
562 size_t len;
563 len = strlen (name);
564
dc810e39
AM
565 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
566 {
567 bfd_size_type newalc;
f075ee0c 568 char *newstrings;
dc810e39
AM
569
570 newalc = ldinfo->string_alc * 2;
571 if (newalc == 0)
572 newalc = 32;
573 while (ldinfo->string_size + len + 3 > newalc)
574 newalc *= 2;
575
f075ee0c 576 newstrings = bfd_realloc (ldinfo->strings, newalc);
dc810e39
AM
577 if (newstrings == NULL)
578 {
b34976b6
AM
579 ldinfo->failed = TRUE;
580 return FALSE;
dc810e39
AM
581 }
582 ldinfo->string_alc = newalc;
583 ldinfo->strings = newstrings;
beb1bf64 584 }
dc810e39
AM
585
586 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
beb1bf64
TR
587 ldinfo->strings + ldinfo->string_size);
588 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
589 ldsym->_l._l_l._l_zeroes = 0;
590 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
591 ldinfo->string_size += len + 3;
dc810e39 592
b34976b6 593 return TRUE;
beb1bf64
TR
594}
595
beb1bf64
TR
596/* Routines to swap information in the XCOFF .loader section. If we
597 ever need to write an XCOFF loader, this stuff will need to be
598 moved to another file shared by the linker (which XCOFF calls the
599 ``binder'') and the loader. */
600
601/* Swap in the ldhdr structure. */
602
603static void
814fa6ab
AM
604xcoff64_swap_ldhdr_in (abfd, s, dst)
605 bfd *abfd;
606 const PTR s;
607 struct internal_ldhdr *dst;
608{
609 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
610
beb1bf64
TR
611 dst->l_version = bfd_get_32 (abfd, src->l_version);
612 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
613 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
614 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
615 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
616 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
617 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
618 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
619 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
620 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
621}
622
623/* Swap out the ldhdr structure. */
624
625static void
814fa6ab 626xcoff64_swap_ldhdr_out (abfd, src, d)
beb1bf64
TR
627 bfd *abfd;
628 const struct internal_ldhdr *src;
814fa6ab 629 PTR d;
beb1bf64 630{
814fa6ab
AM
631 struct external_ldhdr *dst = (struct external_ldhdr *) d;
632
dc810e39 633 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
beb1bf64
TR
634 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
635 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
636 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
637 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
638 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
639 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
640 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
641 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
642 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
643}
644
645/* Swap in the ldsym structure. */
646
647static void
814fa6ab 648xcoff64_swap_ldsym_in (abfd, s, dst)
beb1bf64 649 bfd *abfd;
814fa6ab 650 const PTR s;
beb1bf64
TR
651 struct internal_ldsym *dst;
652{
814fa6ab 653 const struct external_ldsym *src = (const struct external_ldsym *) s;
dc810e39
AM
654 /* XCOFF64 does not use l_zeroes like XCOFF32
655 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
656 as an offset into the loader symbol table. */
beb1bf64
TR
657 dst->_l._l_l._l_zeroes = 0;
658 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
659 dst->l_value = bfd_get_64 (abfd, src->l_value);
660 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
661 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
662 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
663 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
664 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
665}
666
667/* Swap out the ldsym structure. */
668
669static void
814fa6ab 670xcoff64_swap_ldsym_out (abfd, src, d)
beb1bf64
TR
671 bfd *abfd;
672 const struct internal_ldsym *src;
814fa6ab 673 PTR d;
beb1bf64 674{
814fa6ab
AM
675 struct external_ldsym *dst = (struct external_ldsym *) d;
676
beb1bf64 677 bfd_put_64 (abfd, src->l_value, dst->l_value);
dc810e39
AM
678 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
679 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
beb1bf64
TR
680 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
681 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
682 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
683 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
684}
685
59862849
TR
686static void
687xcoff64_swap_reloc_in (abfd, s, d)
688 bfd *abfd;
689 PTR s;
690 PTR d;
691{
692 struct external_reloc *src = (struct external_reloc *) s;
693 struct internal_reloc *dst = (struct internal_reloc *) d;
694
695 memset (dst, 0, sizeof (struct internal_reloc));
696
697 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
698 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
699 dst->r_size = bfd_get_8 (abfd, src->r_size);
700 dst->r_type = bfd_get_8 (abfd, src->r_type);
701}
702
703static unsigned int
704xcoff64_swap_reloc_out (abfd, s, d)
705 bfd *abfd;
706 PTR s;
707 PTR d;
708{
709 struct internal_reloc *src = (struct internal_reloc *) s;
710 struct external_reloc *dst = (struct external_reloc *) d;
711
712 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
713 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
714 bfd_put_8 (abfd, src->r_type, dst->r_type);
715 bfd_put_8 (abfd, src->r_size, dst->r_size);
716
717 return bfd_coff_relsz (abfd);
718}
719
beb1bf64
TR
720/* Swap in the ldrel structure. */
721
722static void
814fa6ab 723xcoff64_swap_ldrel_in (abfd, s, dst)
beb1bf64 724 bfd *abfd;
814fa6ab 725 const PTR s;
beb1bf64
TR
726 struct internal_ldrel *dst;
727{
814fa6ab
AM
728 const struct external_ldrel *src = (const struct external_ldrel *) s;
729
beb1bf64
TR
730 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
731 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
732 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
733 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
734}
735
736/* Swap out the ldrel structure. */
737
738static void
814fa6ab 739xcoff64_swap_ldrel_out (abfd, src, d)
beb1bf64
TR
740 bfd *abfd;
741 const struct internal_ldrel *src;
814fa6ab 742 PTR d;
beb1bf64 743{
814fa6ab
AM
744 struct external_ldrel *dst = (struct external_ldrel *) d;
745
beb1bf64 746 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
dc810e39
AM
747 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
748 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
beb1bf64
TR
749 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
750}
751
b34976b6 752static bfd_boolean
beb1bf64 753xcoff64_write_object_contents (abfd)
cf9ab45b 754 bfd *abfd;
beb1bf64
TR
755{
756 asection *current;
b34976b6
AM
757 bfd_boolean hasrelocs = FALSE;
758 bfd_boolean haslinno = FALSE;
beb1bf64
TR
759 file_ptr scn_base;
760 file_ptr reloc_base;
761 file_ptr lineno_base;
762 file_ptr sym_base;
763 unsigned long reloc_size = 0;
764 unsigned long lnno_size = 0;
b34976b6 765 bfd_boolean long_section_names;
dc810e39
AM
766 asection *text_sec = ((void *) 0);
767 asection *data_sec = ((void *) 0);
768 asection *bss_sec = ((void *) 0);
beb1bf64
TR
769 struct internal_filehdr internal_f;
770 struct internal_aouthdr internal_a;
771
772 bfd_set_error (bfd_error_system_call);
773
82e51918 774 if (! abfd->output_has_begun)
dc810e39
AM
775 {
776 if (! bfd_coff_compute_section_file_positions (abfd))
b34976b6 777 return FALSE;
dc810e39 778 }
beb1bf64 779
eb1e0e80 780 /* Work out the size of the reloc and linno areas. */
beb1bf64
TR
781 reloc_base = obj_relocbase (abfd);
782
dc810e39 783 for (current = abfd->sections; current != NULL; current = current->next)
beb1bf64 784 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
beb1bf64
TR
785
786 lineno_base = reloc_base + reloc_size;
787
788 /* Make a pass through the symbol table to count line number entries and
eb1e0e80 789 put them into the correct asections. */
beb1bf64
TR
790 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
791
792 sym_base = lineno_base + lnno_size;
793
eb1e0e80 794 /* Indicate in each section->line_filepos its actual file address. */
dc810e39
AM
795 for (current = abfd->sections; current != NULL; current = current->next)
796 {
797 if (current->lineno_count)
798 {
799 current->line_filepos = lineno_base;
800 current->moving_line_filepos = lineno_base;
801 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
802 }
803 else
804 {
805 current->line_filepos = 0;
806 }
807
808 if (current->reloc_count)
809 {
810 current->rel_filepos = reloc_base;
811 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
812 }
813 else
814 {
815 current->rel_filepos = 0;
816 }
817 }
818
819 if ((abfd->flags & EXEC_P) != 0)
820 {
821 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
822 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
beb1bf64 823 }
dc810e39
AM
824 else
825 {
826 scn_base = bfd_coff_filhsz (abfd);
827 internal_f.f_opthdr = 0;
beb1bf64 828 }
beb1bf64
TR
829
830 internal_f.f_nscns = 0;
831
832 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
b34976b6 833 return FALSE;
beb1bf64 834
b34976b6 835 long_section_names = FALSE;
dc810e39
AM
836 for (current = abfd->sections; current != NULL; current = current->next)
837 {
838 struct internal_scnhdr section;
839 struct external_scnhdr buff;
840 bfd_size_type amount;
beb1bf64 841
dc810e39 842 internal_f.f_nscns++;
beb1bf64 843
dc810e39 844 strncpy (section.s_name, current->name, SCNNMLEN);
beb1bf64 845
dc810e39
AM
846 section.s_vaddr = current->vma;
847 section.s_paddr = current->lma;
eea6121a 848 section.s_size = current->size;
beb1bf64 849
dc810e39
AM
850 /* If this section has no size or is unloadable then the scnptr
851 will be 0 too. */
eea6121a 852 if (current->size == 0
dc810e39
AM
853 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
854 {
855 section.s_scnptr = 0;
856 }
857 else
858 {
859 section.s_scnptr = current->filepos;
860 }
861
862 section.s_relptr = current->rel_filepos;
863 section.s_lnnoptr = current->line_filepos;
864 section.s_nreloc = current->reloc_count;
865
866 section.s_nlnno = current->lineno_count;
867 if (current->reloc_count != 0)
b34976b6 868 hasrelocs = TRUE;
dc810e39 869 if (current->lineno_count != 0)
b34976b6 870 haslinno = TRUE;
beb1bf64 871
dc810e39
AM
872 section.s_flags = sec_to_styp_flags (current->name, current->flags);
873
874 if (!strcmp (current->name, _TEXT))
875 {
876 text_sec = current;
877 }
878 else if (!strcmp (current->name, _DATA))
879 {
880 data_sec = current;
881 }
882 else if (!strcmp (current->name, _BSS))
883 {
884 bss_sec = current;
885 }
886
887 amount = bfd_coff_scnhsz (abfd);
888 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
889 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
b34976b6 890 return FALSE;
dc810e39 891 }
beb1bf64
TR
892
893 internal_f.f_timdat = 0;
894
895 internal_f.f_flags = 0;
896
897 if (!hasrelocs)
898 internal_f.f_flags |= F_RELFLG;
899 if (!haslinno)
900 internal_f.f_flags |= F_LNNO;
901 if (abfd->flags & EXEC_P)
902 internal_f.f_flags |= F_EXEC;
903
eb1e0e80 904 /* FIXME: this is wrong for PPC_PE! */
beb1bf64
TR
905 if (bfd_little_endian (abfd))
906 internal_f.f_flags |= F_AR32WR;
907 else
908 internal_f.f_flags |= F_AR32W;
909
910 if ((abfd->flags & DYNAMIC) != 0)
911 internal_f.f_flags |= F_SHROBJ;
912 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
913 internal_f.f_flags |= F_DYNLOAD;
914
915 memset (&internal_a, 0, sizeof internal_a);
916
eb1e0e80 917 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
cf9ab45b
AM
918 internal_a.magic = (abfd->flags & D_PAGED
919 ? RS6K_AOUTHDR_ZMAGIC
920 : (abfd->flags & WP_TEXT
921 ? RS6K_AOUTHDR_NMAGIC
922 : RS6K_AOUTHDR_OMAGIC));
beb1bf64
TR
923
924 /* FIXME: Does anybody ever set this to another value? */
925 internal_a.vstamp = 0;
926
eb1e0e80 927 /* Now should write relocs, strings, syms. */
beb1bf64
TR
928 obj_sym_filepos (abfd) = sym_base;
929
930 internal_f.f_symptr = 0;
931 internal_f.f_nsyms = 0;
932
dc810e39
AM
933 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
934 backend linker, and obj_raw_syment_count is not valid until after
935 coff_write_symbols is called. */
936 if (bfd_get_symcount (abfd) != 0)
937 {
938 int firstundef;
beb1bf64 939
dc810e39 940 if (!coff_renumber_symbols (abfd, &firstundef))
b34976b6 941 return FALSE;
dc810e39
AM
942 coff_mangle_symbols (abfd);
943 if (! coff_write_symbols (abfd))
b34976b6 944 return FALSE;
dc810e39 945 if (! coff_write_linenumbers (abfd))
b34976b6 946 return FALSE;
dc810e39 947 if (! coff_write_relocs (abfd, firstundef))
b34976b6 948 return FALSE;
beb1bf64 949
dc810e39
AM
950 internal_f.f_symptr = sym_base;
951 internal_f.f_nsyms = bfd_get_symcount (abfd);
952 }
953 else if (obj_raw_syment_count (abfd) != 0)
954 {
955 internal_f.f_symptr = sym_base;
956
957 /* AIX appears to require that F_RELFLG not be set if there are
958 local symbols but no relocations. */
959 internal_f.f_flags &=~ F_RELFLG;
960 }
961 else
962 {
963 internal_f.f_flags |= F_LSYMS;
964 }
beb1bf64 965
dc810e39
AM
966 if (text_sec)
967 {
eea6121a 968 internal_a.tsize = text_sec->size;
beb1bf64 969 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
dc810e39 970 }
beb1bf64 971
dc810e39
AM
972 if (data_sec)
973 {
eea6121a 974 internal_a.dsize = data_sec->size;
dc810e39
AM
975 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
976 }
beb1bf64 977
dc810e39
AM
978 if (bss_sec)
979 {
eea6121a 980 internal_a.bsize = bss_sec->size;
dc810e39
AM
981 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
982 internal_a.data_start = bss_sec->vma;
983 }
beb1bf64
TR
984
985 internal_a.entry = bfd_get_start_address (abfd);
986 internal_f.f_nsyms = obj_raw_syment_count (abfd);
987
dc810e39
AM
988 if (xcoff_data (abfd)->full_aouthdr)
989 {
beb1bf64
TR
990 bfd_vma toc;
991 asection *loader_sec;
992
993 internal_a.vstamp = 1;
994
995 internal_a.o_snentry = xcoff_data (abfd)->snentry;
996 if (internal_a.o_snentry == 0)
997 internal_a.entry = (bfd_vma) -1;
998
dc810e39
AM
999 if (text_sec != NULL)
1000 {
beb1bf64
TR
1001 internal_a.o_sntext = text_sec->target_index;
1002 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
dc810e39
AM
1003 }
1004 else
1005 {
1006 internal_a.o_sntext = 0;
1007 internal_a.o_algntext = 0;
1008 }
1009
1010 if (data_sec != NULL)
1011 {
1012 internal_a.o_sndata = data_sec->target_index;
1013 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1014 }
1015 else
1016 {
1017 internal_a.o_sndata = 0;
1018 internal_a.o_algndata = 0;
1019 }
beb1bf64
TR
1020
1021 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1022 if (loader_sec != NULL)
1023 internal_a.o_snloader = loader_sec->target_index;
1024 else
1025 internal_a.o_snloader = 0;
1026 if (bss_sec != NULL)
1027 internal_a.o_snbss = bss_sec->target_index;
1028 else
1029 internal_a.o_snbss = 0;
1030
1031 toc = xcoff_data (abfd)->toc;
1032 internal_a.o_toc = toc;
1033 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1034
1035 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1036 if (xcoff_data (abfd)->cputype != -1)
1037 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1038 else
1039 {
1040 switch (bfd_get_arch (abfd))
1041 {
1042 case bfd_arch_rs6000:
1043 internal_a.o_cputype = 4;
1044 break;
1045 case bfd_arch_powerpc:
250d94fd 1046 if (bfd_get_mach (abfd) == bfd_mach_ppc)
beb1bf64
TR
1047 internal_a.o_cputype = 3;
1048 else
1049 internal_a.o_cputype = 1;
1050 break;
1051 default:
1052 abort ();
1053 }
1054 }
1055 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1056 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
dc810e39
AM
1057 }
1058
1059 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
b34976b6 1060 return FALSE;
dc810e39 1061
beb1bf64
TR
1062 {
1063 char * buff;
dc810e39
AM
1064 bfd_size_type amount = bfd_coff_filhsz (abfd);
1065
1066 buff = bfd_malloc (amount);
1067 if (buff == NULL)
b34976b6 1068 return FALSE;
dc810e39
AM
1069
1070 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1071 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1072
beb1bf64 1073 free (buff);
dc810e39 1074
beb1bf64 1075 if (amount != bfd_coff_filhsz (abfd))
b34976b6 1076 return FALSE;
beb1bf64 1077 }
beb1bf64 1078
dc810e39
AM
1079 if (abfd->flags & EXEC_P)
1080 {
1081 char * buff;
1082 bfd_size_type amount = bfd_coff_aoutsz (abfd);
beb1bf64 1083
dc810e39
AM
1084 buff = bfd_malloc (amount);
1085 if (buff == NULL)
b34976b6 1086 return FALSE;
beb1bf64 1087
cf9ab45b 1088 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
dc810e39
AM
1089 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1090
1091 free (buff);
beb1bf64 1092
dc810e39 1093 if (amount != bfd_coff_aoutsz (abfd))
b34976b6 1094 return FALSE;
dc810e39 1095 }
beb1bf64 1096
b34976b6 1097 return TRUE;
beb1bf64
TR
1098}
1099
b34976b6 1100static bfd_boolean
cf9ab45b 1101xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
f1f0d9ab
TR
1102 val, addend, relocation, contents)
1103 bfd *input_bfd;
1104 asection *input_section;
1105 bfd *output_bfd ATTRIBUTE_UNUSED;
1106 struct internal_reloc *rel;
1107 struct internal_syment *sym ATTRIBUTE_UNUSED;
1108 struct reloc_howto_struct *howto;
1109 bfd_vma val;
1110 bfd_vma addend;
1111 bfd_vma *relocation;
1112 bfd_byte *contents;
1113{
1114 struct xcoff_link_hash_entry *h;
1115
cf9ab45b 1116 if (0 > rel->r_symndx)
b34976b6 1117 return FALSE;
f1f0d9ab
TR
1118
1119 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
1120
1121 /* If we see an R_BR or R_RBR reloc which is jumping to global
1122 linkage code, and it is followed by an appropriate cror nop
1123 instruction, we replace the cror with ld r2,40(r1). This
1124 restores the TOC after the glink code. Contrariwise, if the
1125 call is followed by a ld r2,40(r1), but the call is not
1126 going to global linkage code, we can replace the load with a
1127 cror. */
cf9ab45b
AM
1128 if (NULL != h
1129 && bfd_link_hash_defined == h->root.type
eea6121a 1130 && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
f1f0d9ab
TR
1131 {
1132 bfd_byte *pnext;
1133 unsigned long next;
cf9ab45b 1134
f1f0d9ab
TR
1135 pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
1136 next = bfd_get_32 (input_bfd, pnext);
cf9ab45b
AM
1137
1138 /* The _ptrgl function is magic. It is used by the AIX compiler to call
f1f0d9ab 1139 a function through a pointer. */
cf9ab45b 1140 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
f1f0d9ab 1141 {
cf9ab45b
AM
1142 if (next == 0x4def7b82 /* cror 15,15,15 */
1143 || next == 0x4ffffb82 /* cror 31,31,31 */
1144 || next == 0x60000000) /* ori r0,r0,0 */
1145 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1146 }
1147 else
f1f0d9ab 1148 {
cf9ab45b
AM
1149 if (next == 0xe8410028) /* ld r2,40(r1) */
1150 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
f1f0d9ab 1151 }
cf9ab45b
AM
1152 }
1153 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
f1f0d9ab
TR
1154 {
1155 /* Normally, this relocation is against a defined symbol. In the
1156 case where this is a partial link and the output section offset
cf9ab45b 1157 is greater than 2^25, the linker will return an invalid error
f1f0d9ab 1158 message that the relocation has been truncated. Yes it has been
cf9ab45b 1159 truncated but no it not important. For this case, disable the
f1f0d9ab
TR
1160 overflow checking. */
1161 howto->complain_on_overflow = complain_overflow_dont;
1162 }
cf9ab45b 1163
b34976b6 1164 howto->pc_relative = TRUE;
a78eab4e
AM
1165 howto->src_mask &= ~3;
1166 howto->dst_mask = howto->src_mask;
cf9ab45b 1167
f1f0d9ab
TR
1168 /* A PC relative reloc includes the section address. */
1169 addend += input_section->vma;
cf9ab45b 1170
f1f0d9ab 1171 *relocation = val + addend;
cf9ab45b
AM
1172 *relocation -= (input_section->output_section->vma
1173 + input_section->output_offset);
b34976b6 1174 return TRUE;
f1f0d9ab
TR
1175}
1176
dbe341c6
TR
1177/* This is the relocation function for the PowerPC64.
1178 See xcoff_ppc_relocation_section for more information. */
beb1bf64 1179
b34976b6 1180bfd_boolean
beb1bf64
TR
1181xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1182 input_section, contents, relocs, syms,
1183 sections)
1184 bfd *output_bfd;
1185 struct bfd_link_info *info;
1186 bfd *input_bfd;
1187 asection *input_section;
1188 bfd_byte *contents;
1189 struct internal_reloc *relocs;
1190 struct internal_syment *syms;
1191 asection **sections;
1192{
1193 struct internal_reloc *rel;
1194 struct internal_reloc *relend;
1195
1196 rel = relocs;
1197 relend = rel + input_section->reloc_count;
1198 for (; rel < relend; rel++)
1199 {
1200 long symndx;
1201 struct xcoff_link_hash_entry *h;
1202 struct internal_syment *sym;
1203 bfd_vma addend;
1204 bfd_vma val;
1205 struct reloc_howto_struct howto;
dbe341c6
TR
1206 bfd_vma relocation;
1207 bfd_vma value_to_relocate;
1208 bfd_vma address;
1209 bfd_byte *location;
beb1bf64
TR
1210
1211 /* Relocation type R_REF is a special relocation type which is
cf9ab45b
AM
1212 merely used to prevent garbage collection from occurring for
1213 the csect including the symbol which it references. */
beb1bf64
TR
1214 if (rel->r_type == R_REF)
1215 continue;
1216
dbe341c6 1217 /* howto */
beb1bf64
TR
1218 howto.type = rel->r_type;
1219 howto.rightshift = 0;
beb1bf64 1220 howto.bitsize = (rel->r_size & 0x3f) + 1;
dbe341c6 1221 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
b34976b6 1222 howto.pc_relative = FALSE;
beb1bf64 1223 howto.bitpos = 0;
cf9ab45b
AM
1224 howto.complain_on_overflow = (rel->r_size & 0x80
1225 ? complain_overflow_signed
1226 : complain_overflow_bitfield);
beb1bf64
TR
1227 howto.special_function = NULL;
1228 howto.name = "internal";
b34976b6 1229 howto.partial_inplace = TRUE;
cf9ab45b 1230 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
b34976b6 1231 howto.pcrel_offset = FALSE;
beb1bf64 1232
dbe341c6 1233 /* symbol */
beb1bf64 1234 val = 0;
dbe341c6
TR
1235 addend = 0;
1236 h = NULL;
1237 sym = NULL;
cf9ab45b 1238 symndx = rel->r_symndx;
beb1bf64 1239
cf9ab45b 1240 if (-1 != symndx)
dc810e39
AM
1241 {
1242 asection *sec;
cf9ab45b 1243
dbe341c6
TR
1244 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1245 sym = syms + symndx;
1246 addend = - sym->n_value;
cf9ab45b
AM
1247
1248 if (NULL == h)
dc810e39
AM
1249 {
1250 sec = sections[symndx];
1251 /* Hack to make sure we use the right TOC anchor value
1252 if this reloc is against the TOC anchor. */
1253 if (sec->name[3] == '0'
1254 && strcmp (sec->name, ".tc0") == 0)
1255 val = xcoff_data (output_bfd)->toc;
1256 else
1257 val = (sec->output_section->vma
1258 + sec->output_offset
1259 + sym->n_value
1260 - sec->vma);
cf9ab45b
AM
1261 }
1262 else
dc810e39 1263 {
cf9ab45b
AM
1264 if (h->root.type == bfd_link_hash_defined
1265 || h->root.type == bfd_link_hash_defweak)
dc810e39 1266 {
dbe341c6
TR
1267 sec = h->root.u.def.section;
1268 val = (h->root.u.def.value
1269 + sec->output_section->vma
1270 + sec->output_offset);
cf9ab45b
AM
1271 }
1272 else if (h->root.type == bfd_link_hash_common)
dbe341c6
TR
1273 {
1274 sec = h->root.u.c.p->section;
1275 val = (sec->output_section->vma
1276 + sec->output_offset);
cf9ab45b
AM
1277 }
1278 else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
1049f94e 1279 && ! info->relocatable)
dbe341c6
TR
1280 {
1281 if (! ((*info->callbacks->undefined_symbol)
1282 (info, h->root.root.string, input_bfd, input_section,
b34976b6
AM
1283 rel->r_vaddr - input_section->vma, TRUE)))
1284 return FALSE;
cf9ab45b 1285
dbe341c6
TR
1286 /* Don't try to process the reloc. It can't help, and
1287 it may generate another error. */
1288 continue;
dc810e39 1289 }
dc810e39 1290 }
dc810e39 1291 }
cf9ab45b
AM
1292
1293 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
213e90f4 1294 || !((*xcoff64_calculate_relocation[rel->r_type])
cf9ab45b
AM
1295 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1296 addend, &relocation, contents)))
b34976b6 1297 return FALSE;
cf9ab45b 1298
dbe341c6
TR
1299 /* address */
1300 address = rel->r_vaddr - input_section->vma;
1301 location = contents + address;
cf9ab45b 1302
eea6121a 1303 if (address > input_section->size)
cf9ab45b
AM
1304 abort ();
1305
dbe341c6
TR
1306 /* Get the value we are going to relocate. */
1307 if (1 == howto.size)
1308 value_to_relocate = bfd_get_16 (input_bfd, location);
1309 else if (2 == howto.size)
1310 value_to_relocate = bfd_get_32 (input_bfd, location);
cf9ab45b 1311 else
dbe341c6 1312 value_to_relocate = bfd_get_64 (input_bfd, location);
cf9ab45b
AM
1313
1314 /* overflow.
1315
dbe341c6
TR
1316 FIXME: We may drop bits during the addition
1317 which we don't check for. We must either check at every single
1318 operation, which would be tedious, or we must do the computations
1319 in a type larger than bfd_vma, which would be inefficient. */
cf9ab45b
AM
1320
1321 if ((unsigned int) howto.complain_on_overflow
1322 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1323 abort ();
1324
1325 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1326 (input_bfd, value_to_relocate, relocation, &howto)))
dc810e39 1327 {
dbe341c6
TR
1328 const char *name;
1329 char buf[SYMNMLEN + 1];
1330 char reloc_type_name[10];
cf9ab45b
AM
1331
1332 if (symndx == -1)
beb1bf64 1333 {
dbe341c6 1334 name = "*ABS*";
cf9ab45b
AM
1335 }
1336 else if (h != NULL)
dbe341c6 1337 {
dfeffb9f 1338 name = NULL;
cf9ab45b
AM
1339 }
1340 else
beb1bf64 1341 {
dbe341c6
TR
1342 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1343 if (name == NULL)
1344 name = "UNKNOWN";
beb1bf64 1345 }
dbe341c6 1346 sprintf (reloc_type_name, "0x%02x", rel->r_type);
cf9ab45b 1347
dbe341c6 1348 if (! ((*info->callbacks->reloc_overflow)
dfeffb9f
L
1349 (info, (h ? &h->root : NULL), name, reloc_type_name,
1350 (bfd_vma) 0, input_bfd, input_section,
1351 rel->r_vaddr - input_section->vma)))
b34976b6 1352 return FALSE;
beb1bf64
TR
1353 }
1354
dbe341c6 1355 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
cf9ab45b
AM
1356 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1357 | (((value_to_relocate & howto.src_mask)
1358 + relocation) & howto.dst_mask));
1359
dbe341c6
TR
1360 /* Put the value back in the object file. */
1361 if (1 == howto.size)
1362 bfd_put_16 (input_bfd, value_to_relocate, location);
1363 else if (2 == howto.size)
1364 bfd_put_32 (input_bfd, value_to_relocate, location);
1365 else
1366 bfd_put_64 (input_bfd, value_to_relocate, location);
cf9ab45b 1367
beb1bf64 1368 }
b34976b6 1369 return TRUE;
beb1bf64
TR
1370}
1371
beb1bf64
TR
1372\f
1373/* The XCOFF reloc table. Actually, XCOFF relocations specify the
1374 bitsize and whether they are signed or not, along with a
1375 conventional type. This table is for the types, which are used for
1376 different algorithms for putting in the reloc. Many of these
1377 relocs need special_function entries, which I have not written. */
1378
beb1bf64
TR
1379reloc_howto_type xcoff64_howto_table[] =
1380{
1381 /* Standard 64 bit relocation. */
38487e5e 1382 HOWTO (R_POS, /* type */
dc810e39
AM
1383 0, /* rightshift */
1384 4, /* size (0 = byte, 1 = short, 2 = long) */
1385 64, /* bitsize */
b34976b6 1386 FALSE, /* pc_relative */
dc810e39 1387 0, /* bitpos */
beb1bf64 1388 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39 1389 0, /* special_function */
59862849 1390 "R_POS_64", /* name */
b34976b6 1391 TRUE, /* partial_inplace */
a78eab4e 1392 MINUS_ONE, /* src_mask */
dc810e39 1393 MINUS_ONE, /* dst_mask */
b34976b6 1394 FALSE), /* pcrel_offset */
beb1bf64
TR
1395
1396 /* 64 bit relocation, but store negative value. */
38487e5e 1397 HOWTO (R_NEG, /* type */
dc810e39
AM
1398 0, /* rightshift */
1399 -4, /* size (0 = byte, 1 = short, 2 = long) */
1400 64, /* bitsize */
b34976b6 1401 FALSE, /* pc_relative */
dc810e39 1402 0, /* bitpos */
beb1bf64 1403 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1404 0, /* special_function */
1405 "R_NEG", /* name */
b34976b6 1406 TRUE, /* partial_inplace */
a78eab4e 1407 MINUS_ONE, /* src_mask */
dc810e39 1408 MINUS_ONE, /* dst_mask */
b34976b6 1409 FALSE), /* pcrel_offset */
beb1bf64
TR
1410
1411 /* 32 bit PC relative relocation. */
38487e5e 1412 HOWTO (R_REL, /* type */
dc810e39
AM
1413 0, /* rightshift */
1414 2, /* size (0 = byte, 1 = short, 2 = long) */
1415 32, /* bitsize */
b34976b6 1416 TRUE, /* pc_relative */
dc810e39 1417 0, /* bitpos */
beb1bf64 1418 complain_overflow_signed, /* complain_on_overflow */
dc810e39
AM
1419 0, /* special_function */
1420 "R_REL", /* name */
b34976b6 1421 TRUE, /* partial_inplace */
a78eab4e 1422 0xffffffff, /* src_mask */
dc810e39 1423 0xffffffff, /* dst_mask */
b34976b6 1424 FALSE), /* pcrel_offset */
beb1bf64
TR
1425
1426 /* 16 bit TOC relative relocation. */
38487e5e 1427 HOWTO (R_TOC, /* type */
dc810e39
AM
1428 0, /* rightshift */
1429 1, /* size (0 = byte, 1 = short, 2 = long) */
1430 16, /* bitsize */
b34976b6 1431 FALSE, /* pc_relative */
dc810e39 1432 0, /* bitpos */
beb1bf64 1433 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1434 0, /* special_function */
1435 "R_TOC", /* name */
b34976b6 1436 TRUE, /* partial_inplace */
a78eab4e 1437 0xffff, /* src_mask */
dc810e39 1438 0xffff, /* dst_mask */
b34976b6 1439 FALSE), /* pcrel_offset */
dc810e39 1440
cf9ab45b 1441 /* I don't really know what this is. */
38487e5e 1442 HOWTO (R_RTB, /* type */
dc810e39
AM
1443 1, /* rightshift */
1444 2, /* size (0 = byte, 1 = short, 2 = long) */
1445 32, /* bitsize */
b34976b6 1446 FALSE, /* pc_relative */
dc810e39 1447 0, /* bitpos */
beb1bf64 1448 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1449 0, /* special_function */
1450 "R_RTB", /* name */
b34976b6 1451 TRUE, /* partial_inplace */
a78eab4e 1452 0xffffffff, /* src_mask */
dc810e39 1453 0xffffffff, /* dst_mask */
b34976b6 1454 FALSE), /* pcrel_offset */
beb1bf64
TR
1455
1456 /* External TOC relative symbol. */
38487e5e 1457 HOWTO (R_GL, /* type */
dc810e39 1458 0, /* rightshift */
48bfecdd 1459 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1460 16, /* bitsize */
b34976b6 1461 FALSE, /* pc_relative */
dc810e39 1462 0, /* bitpos */
beb1bf64 1463 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1464 0, /* special_function */
1465 "R_GL", /* name */
b34976b6 1466 TRUE, /* partial_inplace */
a78eab4e 1467 0xffff, /* src_mask */
dc810e39 1468 0xffff, /* dst_mask */
b34976b6 1469 FALSE), /* pcrel_offset */
dc810e39
AM
1470
1471 /* Local TOC relative symbol. */
38487e5e 1472 HOWTO (R_TCL, /* type */
dc810e39 1473 0, /* rightshift */
48bfecdd 1474 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1475 16, /* bitsize */
b34976b6 1476 FALSE, /* pc_relative */
dc810e39 1477 0, /* bitpos */
beb1bf64 1478 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1479 0, /* special_function */
1480 "R_TCL", /* name */
b34976b6 1481 TRUE, /* partial_inplace */
a78eab4e 1482 0xffff, /* src_mask */
dc810e39 1483 0xffff, /* dst_mask */
b34976b6 1484 FALSE), /* pcrel_offset */
beb1bf64
TR
1485
1486 EMPTY_HOWTO (7),
1487
1488 /* Non modifiable absolute branch. */
38487e5e 1489 HOWTO (R_BA, /* type */
dc810e39
AM
1490 0, /* rightshift */
1491 2, /* size (0 = byte, 1 = short, 2 = long) */
1492 26, /* bitsize */
b34976b6 1493 FALSE, /* pc_relative */
dc810e39 1494 0, /* bitpos */
beb1bf64 1495 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39 1496 0, /* special_function */
59862849 1497 "R_BA_26", /* name */
b34976b6 1498 TRUE, /* partial_inplace */
a78eab4e 1499 0x03fffffc, /* src_mask */
48bfecdd 1500 0x03fffffc, /* dst_mask */
b34976b6 1501 FALSE), /* pcrel_offset */
beb1bf64
TR
1502
1503 EMPTY_HOWTO (9),
1504
1505 /* Non modifiable relative branch. */
38487e5e 1506 HOWTO (R_BR, /* type */
dc810e39
AM
1507 0, /* rightshift */
1508 2, /* size (0 = byte, 1 = short, 2 = long) */
1509 26, /* bitsize */
b34976b6 1510 TRUE, /* pc_relative */
dc810e39 1511 0, /* bitpos */
beb1bf64 1512 complain_overflow_signed, /* complain_on_overflow */
dc810e39
AM
1513 0, /* special_function */
1514 "R_BR", /* name */
b34976b6 1515 TRUE, /* partial_inplace */
a78eab4e 1516 0x03fffffc, /* src_mask */
48bfecdd 1517 0x03fffffc, /* dst_mask */
b34976b6 1518 FALSE), /* pcrel_offset */
beb1bf64
TR
1519
1520 EMPTY_HOWTO (0xb),
1521
1522 /* Indirect load. */
38487e5e 1523 HOWTO (R_RL, /* type */
dc810e39 1524 0, /* rightshift */
48bfecdd 1525 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1526 16, /* bitsize */
b34976b6 1527 FALSE, /* pc_relative */
dc810e39 1528 0, /* bitpos */
beb1bf64 1529 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1530 0, /* special_function */
1531 "R_RL", /* name */
b34976b6 1532 TRUE, /* partial_inplace */
a78eab4e 1533 0xffff, /* src_mask */
dc810e39 1534 0xffff, /* dst_mask */
b34976b6 1535 FALSE), /* pcrel_offset */
beb1bf64
TR
1536
1537 /* Load address. */
38487e5e 1538 HOWTO (R_RLA, /* type */
dc810e39 1539 0, /* rightshift */
48bfecdd 1540 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1541 16, /* bitsize */
b34976b6 1542 FALSE, /* pc_relative */
dc810e39 1543 0, /* bitpos */
beb1bf64 1544 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1545 0, /* special_function */
1546 "R_RLA", /* name */
b34976b6 1547 TRUE, /* partial_inplace */
a78eab4e 1548 0xffff, /* src_mask */
dc810e39 1549 0xffff, /* dst_mask */
b34976b6 1550 FALSE), /* pcrel_offset */
beb1bf64
TR
1551
1552 EMPTY_HOWTO (0xe),
1553
cf9ab45b 1554 /* Non-relocating reference. */
38487e5e 1555 HOWTO (R_REF, /* type */
dc810e39
AM
1556 0, /* rightshift */
1557 2, /* size (0 = byte, 1 = short, 2 = long) */
1558 32, /* bitsize */
b34976b6 1559 FALSE, /* pc_relative */
dc810e39 1560 0, /* bitpos */
a78eab4e 1561 complain_overflow_dont, /* complain_on_overflow */
dc810e39
AM
1562 0, /* special_function */
1563 "R_REF", /* name */
b34976b6 1564 FALSE, /* partial_inplace */
dc810e39
AM
1565 0, /* src_mask */
1566 0, /* dst_mask */
b34976b6 1567 FALSE), /* pcrel_offset */
beb1bf64
TR
1568
1569 EMPTY_HOWTO (0x10),
1570 EMPTY_HOWTO (0x11),
1571
1572 /* TOC relative indirect load. */
38487e5e 1573 HOWTO (R_TRL, /* type */
dc810e39 1574 0, /* rightshift */
48bfecdd 1575 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1576 16, /* bitsize */
b34976b6 1577 FALSE, /* pc_relative */
dc810e39 1578 0, /* bitpos */
beb1bf64 1579 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1580 0, /* special_function */
1581 "R_TRL", /* name */
b34976b6 1582 TRUE, /* partial_inplace */
a78eab4e 1583 0xffff, /* src_mask */
dc810e39 1584 0xffff, /* dst_mask */
b34976b6 1585 FALSE), /* pcrel_offset */
dc810e39
AM
1586
1587 /* TOC relative load address. */
38487e5e 1588 HOWTO (R_TRLA, /* type */
dc810e39 1589 0, /* rightshift */
48bfecdd 1590 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1591 16, /* bitsize */
b34976b6 1592 FALSE, /* pc_relative */
dc810e39 1593 0, /* bitpos */
beb1bf64 1594 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1595 0, /* special_function */
1596 "R_TRLA", /* name */
b34976b6 1597 TRUE, /* partial_inplace */
a78eab4e 1598 0xffff, /* src_mask */
dc810e39 1599 0xffff, /* dst_mask */
b34976b6 1600 FALSE), /* pcrel_offset */
beb1bf64
TR
1601
1602 /* Modifiable relative branch. */
38487e5e 1603 HOWTO (R_RRTBI, /* type */
dc810e39
AM
1604 1, /* rightshift */
1605 2, /* size (0 = byte, 1 = short, 2 = long) */
1606 32, /* bitsize */
b34976b6 1607 FALSE, /* pc_relative */
dc810e39 1608 0, /* bitpos */
beb1bf64 1609 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1610 0, /* special_function */
1611 "R_RRTBI", /* name */
b34976b6 1612 TRUE, /* partial_inplace */
a78eab4e 1613 0xffffffff, /* src_mask */
dc810e39 1614 0xffffffff, /* dst_mask */
b34976b6 1615 FALSE), /* pcrel_offset */
beb1bf64
TR
1616
1617 /* Modifiable absolute branch. */
38487e5e 1618 HOWTO (R_RRTBA, /* type */
dc810e39
AM
1619 1, /* rightshift */
1620 2, /* size (0 = byte, 1 = short, 2 = long) */
1621 32, /* bitsize */
b34976b6 1622 FALSE, /* pc_relative */
dc810e39 1623 0, /* bitpos */
beb1bf64 1624 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1625 0, /* special_function */
1626 "R_RRTBA", /* name */
b34976b6 1627 TRUE, /* partial_inplace */
a78eab4e 1628 0xffffffff, /* src_mask */
dc810e39 1629 0xffffffff, /* dst_mask */
b34976b6 1630 FALSE), /* pcrel_offset */
dc810e39
AM
1631
1632 /* Modifiable call absolute indirect. */
38487e5e 1633 HOWTO (R_CAI, /* type */
dc810e39 1634 0, /* rightshift */
48bfecdd 1635 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1636 16, /* bitsize */
b34976b6 1637 FALSE, /* pc_relative */
dc810e39 1638 0, /* bitpos */
beb1bf64 1639 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1640 0, /* special_function */
1641 "R_CAI", /* name */
b34976b6 1642 TRUE, /* partial_inplace */
a78eab4e 1643 0xffff, /* src_mask */
dc810e39 1644 0xffff, /* dst_mask */
b34976b6 1645 FALSE), /* pcrel_offset */
dc810e39 1646
cf9ab45b 1647 /* Modifiable call relative. */
38487e5e 1648 HOWTO (R_CREL, /* type */
dc810e39 1649 0, /* rightshift */
48bfecdd 1650 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1651 16, /* bitsize */
b34976b6 1652 FALSE, /* pc_relative */
dc810e39 1653 0, /* bitpos */
beb1bf64 1654 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1655 0, /* special_function */
1656 "R_CREL", /* name */
b34976b6 1657 TRUE, /* partial_inplace */
a78eab4e 1658 0xffff, /* src_mask */
dc810e39 1659 0xffff, /* dst_mask */
b34976b6 1660 FALSE), /* pcrel_offset */
beb1bf64
TR
1661
1662 /* Modifiable branch absolute. */
38487e5e 1663 HOWTO (R_RBA, /* type */
dc810e39
AM
1664 0, /* rightshift */
1665 2, /* size (0 = byte, 1 = short, 2 = long) */
1666 26, /* bitsize */
b34976b6 1667 FALSE, /* pc_relative */
dc810e39 1668 0, /* bitpos */
beb1bf64 1669 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1670 0, /* special_function */
1671 "R_RBA", /* name */
b34976b6 1672 TRUE, /* partial_inplace */
a78eab4e 1673 0x03fffffc, /* src_mask */
48bfecdd 1674 0x03fffffc, /* dst_mask */
b34976b6 1675 FALSE), /* pcrel_offset */
beb1bf64
TR
1676
1677 /* Modifiable branch absolute. */
38487e5e 1678 HOWTO (R_RBAC, /* type */
dc810e39
AM
1679 0, /* rightshift */
1680 2, /* size (0 = byte, 1 = short, 2 = long) */
1681 32, /* bitsize */
b34976b6 1682 FALSE, /* pc_relative */
dc810e39 1683 0, /* bitpos */
beb1bf64 1684 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1685 0, /* special_function */
1686 "R_RBAC", /* name */
b34976b6 1687 TRUE, /* partial_inplace */
a78eab4e 1688 0xffffffff, /* src_mask */
48bfecdd 1689 0xffffffff, /* dst_mask */
b34976b6 1690 FALSE), /* pcrel_offset */
beb1bf64
TR
1691
1692 /* Modifiable branch relative. */
38487e5e 1693 HOWTO (R_RBR, /* type */
dc810e39
AM
1694 0, /* rightshift */
1695 2, /* size (0 = byte, 1 = short, 2 = long) */
1696 26, /* bitsize */
b34976b6 1697 FALSE, /* pc_relative */
dc810e39 1698 0, /* bitpos */
beb1bf64 1699 complain_overflow_signed, /* complain_on_overflow */
dc810e39 1700 0, /* special_function */
59862849 1701 "R_RBR_26", /* name */
b34976b6 1702 TRUE, /* partial_inplace */
a78eab4e 1703 0x03fffffc, /* src_mask */
48bfecdd 1704 0x03fffffc, /* dst_mask */
b34976b6 1705 FALSE), /* pcrel_offset */
beb1bf64
TR
1706
1707 /* Modifiable branch absolute. */
38487e5e 1708 HOWTO (R_RBRC, /* type */
dc810e39 1709 0, /* rightshift */
48bfecdd 1710 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1711 16, /* bitsize */
b34976b6 1712 FALSE, /* pc_relative */
dc810e39 1713 0, /* bitpos */
beb1bf64 1714 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1715 0, /* special_function */
1716 "R_RBRC", /* name */
b34976b6 1717 TRUE, /* partial_inplace */
a78eab4e 1718 0xffff, /* src_mask */
dc810e39 1719 0xffff, /* dst_mask */
b34976b6 1720 FALSE), /* pcrel_offset */
dc810e39 1721
38487e5e 1722 HOWTO (R_POS, /* type */
dc810e39 1723 0, /* rightshift */
59862849
TR
1724 2, /* size (0 = byte, 1 = short, 2 = long) */
1725 32, /* bitsize */
b34976b6 1726 FALSE, /* pc_relative */
dc810e39
AM
1727 0, /* bitpos */
1728 complain_overflow_bitfield, /* complain_on_overflow */
1729 0, /* special_function */
59862849 1730 "R_POS_32", /* name */
b34976b6 1731 TRUE, /* partial_inplace */
a78eab4e 1732 0xffffffff, /* src_mask */
59862849 1733 0xffffffff, /* dst_mask */
b34976b6 1734 FALSE), /* pcrel_offset */
ff3a6ee3
TR
1735
1736 /* 16 bit Non modifiable absolute branch. */
54327882
AM
1737 HOWTO (R_BA, /* type */
1738 0, /* rightshift */
59862849 1739 1, /* size (0 = byte, 1 = short, 2 = long) */
54327882 1740 16, /* bitsize */
b34976b6 1741 FALSE, /* pc_relative */
54327882 1742 0, /* bitpos */
ff3a6ee3 1743 complain_overflow_bitfield, /* complain_on_overflow */
54327882 1744 0, /* special_function */
59862849 1745 "R_BA_16", /* name */
b34976b6 1746 TRUE, /* partial_inplace */
a78eab4e 1747 0xfffc, /* src_mask */
54327882 1748 0xfffc, /* dst_mask */
b34976b6 1749 FALSE), /* pcrel_offset */
59862849
TR
1750
1751 /* Modifiable branch relative. */
cf9ab45b
AM
1752 HOWTO (R_RBR, /* type */
1753 0, /* rightshift */
1754 1, /* size (0 = byte, 1 = short, 2 = long) */
1755 16, /* bitsize */
b34976b6 1756 FALSE, /* pc_relative */
cf9ab45b 1757 0, /* bitpos */
59862849 1758 complain_overflow_signed, /* complain_on_overflow */
cf9ab45b
AM
1759 0, /* special_function */
1760 "R_RBR_16", /* name */
b34976b6 1761 TRUE, /* partial_inplace */
cf9ab45b
AM
1762 0xffff, /* src_mask */
1763 0xffff, /* dst_mask */
b34976b6 1764 FALSE), /* pcrel_offset */
1b164155
TR
1765
1766 /* Modifiable branch absolute. */
1767 HOWTO (R_RBA, /* type */
1768 0, /* rightshift */
1769 1, /* size (0 = byte, 1 = short, 2 = long) */
1770 16, /* bitsize */
b34976b6 1771 FALSE, /* pc_relative */
1b164155
TR
1772 0, /* bitpos */
1773 complain_overflow_bitfield, /* complain_on_overflow */
1774 0, /* special_function */
1775 "R_RBA_16", /* name */
b34976b6 1776 TRUE, /* partial_inplace */
a78eab4e 1777 0xffff, /* src_mask */
1b164155 1778 0xffff, /* dst_mask */
b34976b6 1779 FALSE), /* pcrel_offset */
1b164155 1780
beb1bf64
TR
1781};
1782
1783void
1784xcoff64_rtype2howto (relent, internal)
1785 arelent *relent;
1786 struct internal_reloc *internal;
1787{
59862849 1788 if (internal->r_type > R_RBRC)
beb1bf64
TR
1789 abort ();
1790
59862849
TR
1791 /* Default howto layout works most of the time */
1792 relent->howto = &xcoff64_howto_table[internal->r_type];
cf9ab45b 1793
5c4491d3 1794 /* Special case some 16 bit reloc */
59862849
TR
1795 if (15 == (internal->r_size & 0x3f))
1796 {
cf9ab45b 1797 if (R_BA == internal->r_type)
59862849 1798 relent->howto = &xcoff64_howto_table[0x1d];
cf9ab45b 1799 else if (R_RBR == internal->r_type)
59862849 1800 relent->howto = &xcoff64_howto_table[0x1e];
cf9ab45b 1801 else if (R_RBA == internal->r_type)
1b164155 1802 relent->howto = &xcoff64_howto_table[0x1f];
59862849
TR
1803 }
1804 /* Special case 32 bit */
1805 else if (31 == (internal->r_size & 0x3f))
1806 {
cf9ab45b 1807 if (R_POS == internal->r_type)
59862849
TR
1808 relent->howto = &xcoff64_howto_table[0x1c];
1809 }
cf9ab45b 1810
beb1bf64
TR
1811 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1812 relocation, as well as indicating whether it is signed or not.
1813 Doublecheck that the relocation information gathered from the
1814 type matches this information. The bitsize is not significant
1815 for R_REF relocs. */
1816 if (relent->howto->dst_mask != 0
dc810e39 1817 && (relent->howto->bitsize
beb1bf64
TR
1818 != ((unsigned int) internal->r_size & 0x3f) + 1))
1819 abort ();
beb1bf64
TR
1820}
1821
1822reloc_howto_type *
1823xcoff64_reloc_type_lookup (abfd, code)
1824 bfd *abfd ATTRIBUTE_UNUSED;
1825 bfd_reloc_code_real_type code;
1826{
1827 switch (code)
1828 {
1829 case BFD_RELOC_PPC_B26:
1830 return &xcoff64_howto_table[0xa];
ff3a6ee3
TR
1831 case BFD_RELOC_PPC_BA16:
1832 return &xcoff64_howto_table[0x1d];
beb1bf64
TR
1833 case BFD_RELOC_PPC_BA26:
1834 return &xcoff64_howto_table[8];
1835 case BFD_RELOC_PPC_TOC16:
1836 return &xcoff64_howto_table[3];
1837 case BFD_RELOC_32:
1838 case BFD_RELOC_CTOR:
beb1bf64 1839 return &xcoff64_howto_table[0x1c];
59862849
TR
1840 case BFD_RELOC_64:
1841 return &xcoff64_howto_table[0];
beb1bf64
TR
1842 default:
1843 return NULL;
1844 }
1845}
1846
157090f7
AM
1847static reloc_howto_type *
1848xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1849 const char *r_name)
1850{
1851 unsigned int i;
1852
1853 for (i = 0;
1854 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1855 i++)
1856 if (xcoff64_howto_table[i].name != NULL
1857 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1858 return &xcoff64_howto_table[i];
1859
1860 return NULL;
1861}
1862
beb1bf64
TR
1863/* Read in the armap of an XCOFF archive. */
1864
b34976b6 1865static bfd_boolean
beb1bf64
TR
1866xcoff64_slurp_armap (abfd)
1867 bfd *abfd;
1868{
1869 file_ptr off;
1870 size_t namlen;
dc810e39 1871 bfd_size_type sz, amt;
beb1bf64
TR
1872 bfd_byte *contents, *cend;
1873 bfd_vma c, i;
1874 carsym *arsym;
1875 bfd_byte *p;
dc810e39 1876 file_ptr pos;
beb1bf64
TR
1877
1878 /* This is for the new format. */
1879 struct xcoff_ar_hdr_big hdr;
1880
dc810e39
AM
1881 if (xcoff_ardata (abfd) == NULL)
1882 {
b34976b6
AM
1883 bfd_has_map (abfd) = FALSE;
1884 return TRUE;
dc810e39 1885 }
beb1bf64 1886
487e54f2
AM
1887 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1888 (const char **) NULL, 10);
dc810e39
AM
1889 if (off == 0)
1890 {
b34976b6
AM
1891 bfd_has_map (abfd) = FALSE;
1892 return TRUE;
dc810e39 1893 }
beb1bf64
TR
1894
1895 if (bfd_seek (abfd, off, SEEK_SET) != 0)
b34976b6 1896 return FALSE;
beb1bf64
TR
1897
1898 /* The symbol table starts with a normal archive header. */
dc810e39
AM
1899 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1900 != SIZEOF_AR_HDR_BIG)
b34976b6 1901 return FALSE;
beb1bf64
TR
1902
1903 /* Skip the name (normally empty). */
1904 namlen = strtol (hdr.namlen, (char **) NULL, 10);
dc810e39
AM
1905 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1906 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
b34976b6 1907 return FALSE;
beb1bf64 1908
487e54f2 1909 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
beb1bf64
TR
1910
1911 /* Read in the entire symbol table. */
1912 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1913 if (contents == NULL)
b34976b6 1914 return FALSE;
dc810e39 1915 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
b34976b6 1916 return FALSE;
beb1bf64
TR
1917
1918 /* The symbol table starts with an eight byte count. */
dc810e39 1919 c = H_GET_64 (abfd, contents);
beb1bf64 1920
dc810e39
AM
1921 if (c * 8 >= sz)
1922 {
1923 bfd_set_error (bfd_error_bad_value);
b34976b6 1924 return FALSE;
dc810e39
AM
1925 }
1926 amt = c;
1927 amt *= sizeof (carsym);
1928 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
beb1bf64 1929 if (bfd_ardata (abfd)->symdefs == NULL)
b34976b6 1930 return FALSE;
dc810e39 1931
beb1bf64
TR
1932 /* After the count comes a list of eight byte file offsets. */
1933 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1934 i < c;
1935 ++i, ++arsym, p += 8)
dc810e39 1936 arsym->file_offset = H_GET_64 (abfd, p);
beb1bf64
TR
1937
1938 /* After the file offsets come null terminated symbol names. */
1939 cend = contents + sz;
1940 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1941 i < c;
1942 ++i, ++arsym, p += strlen ((char *) p) + 1)
1943 {
1944 if (p >= cend)
1945 {
1946 bfd_set_error (bfd_error_bad_value);
b34976b6 1947 return FALSE;
beb1bf64
TR
1948 }
1949 arsym->name = (char *) p;
1950 }
1951
1952 bfd_ardata (abfd)->symdef_count = c;
b34976b6 1953 bfd_has_map (abfd) = TRUE;
beb1bf64 1954
b34976b6 1955 return TRUE;
beb1bf64
TR
1956}
1957
1958
beb1bf64
TR
1959/* See if this is an NEW XCOFF archive. */
1960
814fa6ab 1961static const bfd_target *
beb1bf64
TR
1962xcoff64_archive_p (abfd)
1963 bfd *abfd;
1964{
487e54f2 1965 struct artdata *tdata_hold;
beb1bf64
TR
1966 char magic[SXCOFFARMAG];
1967 /* This is the new format. */
1968 struct xcoff_ar_file_hdr_big hdr;
dc810e39 1969 bfd_size_type amt = SXCOFFARMAG;
beb1bf64 1970
dc810e39
AM
1971 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
1972 {
1973 if (bfd_get_error () != bfd_error_system_call)
1974 bfd_set_error (bfd_error_wrong_format);
1975 return NULL;
1976 }
1977
1978 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1979 {
1980 bfd_set_error (bfd_error_wrong_format);
1981 return NULL;
1982 }
beb1bf64 1983
beb1bf64
TR
1984 /* Copy over the magic string. */
1985 memcpy (hdr.magic, magic, SXCOFFARMAG);
1986
1987 /* Now read the rest of the file header. */
487e54f2
AM
1988 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1989 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
dc810e39
AM
1990 {
1991 if (bfd_get_error () != bfd_error_system_call)
1992 bfd_set_error (bfd_error_wrong_format);
1993 return NULL;
1994 }
beb1bf64 1995
487e54f2
AM
1996 tdata_hold = bfd_ardata (abfd);
1997
1998 amt = sizeof (struct artdata);
1999 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2000 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2001 goto error_ret_restore;
2002
9e492e05
JJ
2003 /* Already cleared by bfd_zalloc above.
2004 bfd_ardata (abfd)->cache = NULL;
2005 bfd_ardata (abfd)->archive_head = NULL;
2006 bfd_ardata (abfd)->symdefs = NULL;
2007 bfd_ardata (abfd)->extended_names = NULL;
2008 bfd_ardata (abfd)->extended_names_size = 0; */
487e54f2
AM
2009 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2010 (const char **) NULL,
2011 10);
beb1bf64 2012
dc810e39
AM
2013 amt = SIZEOF_AR_FILE_HDR_BIG;
2014 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
beb1bf64 2015 if (bfd_ardata (abfd)->tdata == NULL)
487e54f2 2016 goto error_ret;
dc810e39 2017
beb1bf64
TR
2018 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2019
dc810e39
AM
2020 if (! xcoff64_slurp_armap (abfd))
2021 {
487e54f2 2022 error_ret:
dc810e39 2023 bfd_release (abfd, bfd_ardata (abfd));
487e54f2
AM
2024 error_ret_restore:
2025 bfd_ardata (abfd) = tdata_hold;
dc810e39
AM
2026 return NULL;
2027 }
beb1bf64
TR
2028
2029 return abfd->xvec;
2030}
2031
2032
2033/* Open the next element in an XCOFF archive. */
2034
814fa6ab 2035static bfd *
beb1bf64
TR
2036xcoff64_openr_next_archived_file (archive, last_file)
2037 bfd *archive;
2038 bfd *last_file;
2039{
cf3d882d 2040 bfd_vma filestart;
beb1bf64 2041
dc810e39
AM
2042 if ((xcoff_ardata (archive) == NULL)
2043 || ! xcoff_big_format_p (archive))
2044 {
2045 bfd_set_error (bfd_error_invalid_operation);
2046 return NULL;
2047 }
beb1bf64 2048
dc810e39
AM
2049 if (last_file == NULL)
2050 {
beb1bf64 2051 filestart = bfd_ardata (archive)->first_file_filepos;
dc810e39
AM
2052 }
2053 else
2054 {
487e54f2
AM
2055 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2056 (const char **) NULL, 10);
dc810e39 2057 }
487e54f2 2058
beb1bf64 2059 if (filestart == 0
487e54f2
AM
2060 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2061 (const char **) NULL, 10)
2062 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2063 (const char **) NULL, 10))
dc810e39
AM
2064 {
2065 bfd_set_error (bfd_error_no_more_archived_files);
2066 return NULL;
2067 }
beb1bf64 2068
cf3d882d 2069 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
beb1bf64
TR
2070}
2071
2072/* We can't use the usual coff_sizeof_headers routine, because AIX
2073 always uses an a.out header. */
2074
814fa6ab 2075static int
a6b96beb
AM
2076xcoff64_sizeof_headers (bfd *abfd,
2077 struct bfd_link_info *info ATTRIBUTE_UNUSED)
beb1bf64
TR
2078{
2079 int size;
2080
dc810e39 2081 size = bfd_coff_filhsz (abfd);
beb1bf64 2082
08da05b0 2083 /* Don't think the small aout header can be used since some of the
dc810e39
AM
2084 old elements have been reordered past the end of the old coff
2085 small aout size. */
beb1bf64
TR
2086
2087 if (xcoff_data (abfd)->full_aouthdr)
dc810e39 2088 size += bfd_coff_aoutsz (abfd);
beb1bf64 2089
dc810e39 2090 size += abfd->section_count * bfd_coff_scnhsz (abfd);
beb1bf64
TR
2091 return size;
2092}
2093
2094
2095
2096static asection *
dc810e39 2097xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
beb1bf64
TR
2098 bfd *abfd;
2099 union internal_auxent *aux;
2100 const char *symbol_name;
2101{
2102 asection *return_value = NULL;
2103
dc810e39
AM
2104 /* Changes from 32 :
2105 .sv == 8, is only for 32 bit programs
2106 .ti == 12 and .tb == 13 are now reserved. */
2107 static const char *names[19] =
2108 {
beb1bf64
TR
2109 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2110 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
dc810e39 2111 ".td", ".sv64", ".sv3264"
beb1bf64
TR
2112 };
2113
dc810e39
AM
2114 if ((19 >= aux->x_csect.x_smclas)
2115 && (NULL != names[aux->x_csect.x_smclas]))
2116 {
beb1bf64 2117
dc810e39
AM
2118 return_value = bfd_make_section_anyway
2119 (abfd, names[aux->x_csect.x_smclas]);
beb1bf64 2120
dc810e39
AM
2121 }
2122 else
2123 {
2124 (*_bfd_error_handler)
d003868e
AM
2125 (_("%B: symbol `%s' has unrecognized smclas %d"),
2126 abfd, symbol_name, aux->x_csect.x_smclas);
dc810e39
AM
2127 bfd_set_error (bfd_error_bad_value);
2128 }
beb1bf64
TR
2129
2130 return return_value;
2131}
2132
b34976b6 2133static bfd_boolean
beb1bf64 2134xcoff64_is_lineno_count_overflow (abfd, value)
dc810e39
AM
2135 bfd *abfd ATTRIBUTE_UNUSED;
2136 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2137{
b34976b6 2138 return FALSE;
beb1bf64
TR
2139}
2140
b34976b6 2141static bfd_boolean
beb1bf64 2142xcoff64_is_reloc_count_overflow (abfd, value)
dc810e39
AM
2143 bfd *abfd ATTRIBUTE_UNUSED;
2144 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2145{
b34976b6 2146 return FALSE;
beb1bf64
TR
2147}
2148
814fa6ab 2149static bfd_vma
beb1bf64 2150xcoff64_loader_symbol_offset (abfd, ldhdr)
dc810e39
AM
2151 bfd *abfd ATTRIBUTE_UNUSED;
2152 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2153{
2154 return (ldhdr->l_symoff);
2155}
2156
814fa6ab 2157static bfd_vma
beb1bf64 2158xcoff64_loader_reloc_offset (abfd, ldhdr)
dc810e39
AM
2159 bfd *abfd ATTRIBUTE_UNUSED;
2160 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2161{
2162 return (ldhdr->l_rldoff);
2163}
2164
b34976b6 2165static bfd_boolean
eb1e0e80
NC
2166xcoff64_bad_format_hook (abfd, filehdr)
2167 bfd * abfd;
2168 PTR filehdr;
2169{
2170 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2171
2172 /* Check flavor first. */
2173 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
b34976b6 2174 return FALSE;
eb1e0e80
NC
2175
2176 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
b34976b6 2177 return FALSE;
eb1e0e80 2178
b34976b6 2179 return TRUE;
eb1e0e80
NC
2180}
2181
b34976b6 2182static bfd_boolean
69f284c7 2183xcoff64_generate_rtinit (abfd, init, fini, rtld)
9a4c7f16
TR
2184 bfd *abfd;
2185 const char *init;
2186 const char *fini;
b34976b6 2187 bfd_boolean rtld;
9a4c7f16
TR
2188{
2189 bfd_byte filehdr_ext[FILHSZ];
69f284c7
TR
2190 bfd_byte scnhdr_ext[SCNHSZ * 3];
2191 bfd_byte syment_ext[SYMESZ * 10];
2192 bfd_byte reloc_ext[RELSZ * 3];
9a4c7f16
TR
2193 bfd_byte *data_buffer;
2194 bfd_size_type data_buffer_size;
2195 bfd_byte *string_table, *st_tmp;
2196 bfd_size_type string_table_size;
2197 bfd_vma val;
2198 size_t initsz, finisz;
2199 struct internal_filehdr filehdr;
69f284c7
TR
2200 struct internal_scnhdr text_scnhdr;
2201 struct internal_scnhdr data_scnhdr;
2202 struct internal_scnhdr bss_scnhdr;
9a4c7f16
TR
2203 struct internal_syment syment;
2204 union internal_auxent auxent;
2205 struct internal_reloc reloc;
54327882 2206
69f284c7 2207 char *text_name = ".text";
9a4c7f16 2208 char *data_name = ".data";
69f284c7 2209 char *bss_name = ".bss";
9a4c7f16 2210 char *rtinit_name = "__rtinit";
69f284c7 2211 char *rtld_name = "__rtld";
54327882 2212
69f284c7 2213 if (! bfd_xcoff_rtinit_size (abfd))
b34976b6 2214 return FALSE;
9a4c7f16
TR
2215
2216 initsz = (init == NULL ? 0 : 1 + strlen (init));
2217 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2218
eb1e0e80 2219 /* File header. */
9a4c7f16
TR
2220 memset (filehdr_ext, 0, FILHSZ);
2221 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2222 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
54327882 2223 filehdr.f_nscns = 3;
9a4c7f16
TR
2224 filehdr.f_timdat = 0;
2225 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2226 filehdr.f_symptr = 0; /* set below */
2227 filehdr.f_opthdr = 0;
2228 filehdr.f_flags = 0;
2229
eb1e0e80 2230 /* Section headers. */
69f284c7
TR
2231 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2232
eb1e0e80 2233 /* Text. */
69f284c7
TR
2234 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2235 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2236 text_scnhdr.s_paddr = 0;
2237 text_scnhdr.s_vaddr = 0;
2238 text_scnhdr.s_size = 0;
2239 text_scnhdr.s_scnptr = 0;
2240 text_scnhdr.s_relptr = 0;
2241 text_scnhdr.s_lnnoptr = 0;
2242 text_scnhdr.s_nreloc = 0;
2243 text_scnhdr.s_nlnno = 0;
2244 text_scnhdr.s_flags = STYP_TEXT;
2245
eb1e0e80 2246 /* Data. */
69f284c7
TR
2247 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2248 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2249 data_scnhdr.s_paddr = 0;
2250 data_scnhdr.s_vaddr = 0;
2251 data_scnhdr.s_size = 0; /* set below */
2252 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2253 data_scnhdr.s_relptr = 0; /* set below */
2254 data_scnhdr.s_lnnoptr = 0;
2255 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2256 data_scnhdr.s_nlnno = 0;
2257 data_scnhdr.s_flags = STYP_DATA;
2258
eb1e0e80 2259 /* Bss. */
69f284c7
TR
2260 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2261 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2262 bss_scnhdr.s_paddr = 0; /* set below */
2263 bss_scnhdr.s_vaddr = 0; /* set below */
2264 bss_scnhdr.s_size = 0; /* set below */
2265 bss_scnhdr.s_scnptr = 0;
54327882 2266 bss_scnhdr.s_relptr = 0;
69f284c7
TR
2267 bss_scnhdr.s_lnnoptr = 0;
2268 bss_scnhdr.s_nreloc = 0;
2269 bss_scnhdr.s_nlnno = 0;
2270 bss_scnhdr.s_flags = STYP_BSS;
9a4c7f16 2271
54327882 2272 /* .data
cf9ab45b
AM
2273 0x0000 0x00000000 : rtl
2274 0x0004 0x00000000 :
2275 0x0008 0x00000018 : offset to init, or 0
2276 0x000C 0x00000038 : offset to fini, or 0
2277 0x0010 0x00000010 : size of descriptor
2278 0x0014 0x00000000 : pad
2279 0x0018 0x00000000 : init, needs a reloc
2280 0x001C 0x00000000 :
2281 0x0020 0x00000058 : offset to init name
2282 0x0024 0x00000000 : flags, padded to a word
2283 0x0028 0x00000000 : empty init
2284 0x002C 0x00000000 :
2285 0x0030 0x00000000 :
2286 0x0034 0x00000000 :
2287 0x0038 0x00000000 : fini, needs a reloc
2288 0x003C 0x00000000 :
2289 0x0040 0x00000??? : offset to fini name
2290 0x0044 0x00000000 : flags, padded to a word
2291 0x0048 0x00000000 : empty fini
2292 0x004C 0x00000000 :
2293 0x0050 0x00000000 :
2294 0x0054 0x00000000 :
2295 0x0058 init name
9a4c7f16
TR
2296 0x0058 + initsz fini name */
2297
2298 data_buffer_size = 0x0058 + initsz + finisz;
2a52da53 2299 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
330693f5 2300 data_buffer = NULL;
9bab7074 2301 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
330693f5 2302 if (data_buffer == NULL)
b34976b6 2303 return FALSE;
54327882 2304
54327882 2305 if (initsz)
9a4c7f16
TR
2306 {
2307 val = 0x18;
2308 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2309 val = 0x58;
2310 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2311 memcpy (&data_buffer[val], init, initsz);
2312 }
2313
54327882 2314 if (finisz)
9a4c7f16
TR
2315 {
2316 val = 0x38;
2317 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2318 val = 0x58 + initsz;
2319 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2320 memcpy (&data_buffer[val], fini, finisz);
2321 }
2322
2323 val = 0x10;
2324 bfd_put_32 (abfd, val, &data_buffer[0x10]);
69f284c7
TR
2325 data_scnhdr.s_size = data_buffer_size;
2326 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
9a4c7f16 2327
eb1e0e80 2328 /* String table. */
9a4c7f16
TR
2329 string_table_size = 4;
2330 string_table_size += strlen (data_name) + 1;
2331 string_table_size += strlen (rtinit_name) + 1;
2332 string_table_size += initsz;
2333 string_table_size += finisz;
cf9ab45b 2334 if (rtld)
69f284c7 2335 string_table_size += strlen (rtld_name) + 1;
9a4c7f16 2336
9bab7074
AM
2337 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2338 if (string_table == NULL)
b34976b6 2339 return FALSE;
9bab7074 2340
9a4c7f16
TR
2341 val = string_table_size;
2342 bfd_put_32 (abfd, val, &string_table[0]);
2343 st_tmp = string_table + 4;
54327882
AM
2344
2345 /* symbols
9a4c7f16
TR
2346 0. .data csect
2347 2. __rtinit
54327882
AM
2348 4. init function
2349 6. fini function
69f284c7
TR
2350 8. __rtld */
2351 memset (syment_ext, 0, 10 * SYMESZ);
2352 memset (reloc_ext, 0, 3 * RELSZ);
9a4c7f16
TR
2353
2354 /* .data csect */
2355 memset (&syment, 0, sizeof (struct internal_syment));
2356 memset (&auxent, 0, sizeof (union internal_auxent));
2357
2358 syment._n._n_n._n_offset = st_tmp - string_table;
2359 memcpy (st_tmp, data_name, strlen (data_name));
2360 st_tmp += strlen (data_name) + 1;
2361
69f284c7 2362 syment.n_scnum = 2;
9a4c7f16
TR
2363 syment.n_sclass = C_HIDEXT;
2364 syment.n_numaux = 1;
2365 auxent.x_csect.x_scnlen.l = data_buffer_size;
2366 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2367 auxent.x_csect.x_smclas = XMC_RW;
54327882 2368 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2369 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2370 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2371 syment.n_numaux,
9a4c7f16
TR
2372 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2373 filehdr.f_nsyms += 2;
2374
2375 /* __rtinit */
2376 memset (&syment, 0, sizeof (struct internal_syment));
2377 memset (&auxent, 0, sizeof (union internal_auxent));
2378 syment._n._n_n._n_offset = st_tmp - string_table;
2379 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2380 st_tmp += strlen (rtinit_name) + 1;
54327882 2381
69f284c7 2382 syment.n_scnum = 2;
9a4c7f16
TR
2383 syment.n_sclass = C_EXT;
2384 syment.n_numaux = 1;
2385 auxent.x_csect.x_smtyp = XTY_LD;
2386 auxent.x_csect.x_smclas = XMC_RW;
54327882 2387 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2388 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2389 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2390 syment.n_numaux,
9a4c7f16
TR
2391 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2392 filehdr.f_nsyms += 2;
2393
eb1e0e80 2394 /* Init. */
54327882 2395 if (initsz)
9a4c7f16
TR
2396 {
2397 memset (&syment, 0, sizeof (struct internal_syment));
2398 memset (&auxent, 0, sizeof (union internal_auxent));
2399
2400 syment._n._n_n._n_offset = st_tmp - string_table;
2401 memcpy (st_tmp, init, initsz);
2402 st_tmp += initsz;
2403
2404 syment.n_sclass = C_EXT;
2405 syment.n_numaux = 1;
54327882 2406 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2407 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2408 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2409 syment.n_numaux,
9a4c7f16 2410 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
eb1e0e80 2411 /* Reloc. */
9a4c7f16
TR
2412 memset (&reloc, 0, sizeof (struct internal_reloc));
2413 reloc.r_vaddr = 0x0018;
2414 reloc.r_symndx = filehdr.f_nsyms;
2415 reloc.r_type = R_POS;
2416 reloc.r_size = 63;
2417 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2418
2419 filehdr.f_nsyms += 2;
69f284c7 2420 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2421 }
2422
eb1e0e80 2423 /* Finit. */
54327882 2424 if (finisz)
9a4c7f16
TR
2425 {
2426 memset (&syment, 0, sizeof (struct internal_syment));
2427 memset (&auxent, 0, sizeof (union internal_auxent));
2428
2429 syment._n._n_n._n_offset = st_tmp - string_table;
2430 memcpy (st_tmp, fini, finisz);
2431 st_tmp += finisz;
2432
2433 syment.n_sclass = C_EXT;
2434 syment.n_numaux = 1;
54327882 2435 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2436 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2437 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2438 syment.n_numaux,
9a4c7f16
TR
2439 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2440
eb1e0e80 2441 /* Reloc. */
9a4c7f16
TR
2442 memset (&reloc, 0, sizeof (struct internal_reloc));
2443 reloc.r_vaddr = 0x0038;
2444 reloc.r_symndx = filehdr.f_nsyms;
2445 reloc.r_type = R_POS;
2446 reloc.r_size = 63;
54327882 2447 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7 2448 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
9a4c7f16
TR
2449
2450 filehdr.f_nsyms += 2;
69f284c7 2451 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2452 }
2453
69f284c7
TR
2454 if (rtld)
2455 {
2456 memset (&syment, 0, sizeof (struct internal_syment));
2457 memset (&auxent, 0, sizeof (union internal_auxent));
2458
2459 syment._n._n_n._n_offset = st_tmp - string_table;
2460 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2461 st_tmp += strlen (rtld_name) + 1;
2462
2463 syment.n_sclass = C_EXT;
2464 syment.n_numaux = 1;
54327882 2465 bfd_coff_swap_sym_out (abfd, &syment,
69f284c7 2466 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2467 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2468 syment.n_numaux,
69f284c7
TR
2469 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2470
eb1e0e80 2471 /* Reloc. */
69f284c7
TR
2472 memset (&reloc, 0, sizeof (struct internal_reloc));
2473 reloc.r_vaddr = 0x0000;
2474 reloc.r_symndx = filehdr.f_nsyms;
2475 reloc.r_type = R_POS;
2476 reloc.r_size = 63;
54327882 2477 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7
TR
2478 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2479
2480 filehdr.f_nsyms += 2;
2481 data_scnhdr.s_nreloc += 1;
2482
2483 bss_scnhdr.s_size = 0;
2484 }
2485
2486 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2487 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
9a4c7f16
TR
2488
2489 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2490 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
69f284c7
TR
2491 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2492 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2493 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2494 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
9a4c7f16 2495 bfd_bwrite (data_buffer, data_buffer_size, abfd);
69f284c7 2496 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
9a4c7f16
TR
2497 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2498 bfd_bwrite (string_table, string_table_size, abfd);
2499
330693f5
TR
2500 free (data_buffer);
2501 data_buffer = NULL;
2502
b34976b6 2503 return TRUE;
9a4c7f16
TR
2504}
2505
beb1bf64
TR
2506/* The typical dynamic reloc. */
2507
2508static reloc_howto_type xcoff64_dynamic_reloc =
dc810e39
AM
2509HOWTO (0, /* type */
2510 0, /* rightshift */
2511 4, /* size (0 = byte, 1 = short, 2 = long) */
2512 64, /* bitsize */
b34976b6 2513 FALSE, /* pc_relative */
dc810e39
AM
2514 0, /* bitpos */
2515 complain_overflow_bitfield, /* complain_on_overflow */
2516 0, /* special_function */
2517 "R_POS", /* name */
b34976b6 2518 TRUE, /* partial_inplace */
dc810e39
AM
2519 MINUS_ONE, /* src_mask */
2520 MINUS_ONE, /* dst_mask */
b34976b6 2521 FALSE); /* pcrel_offset */
beb1bf64
TR
2522
2523static unsigned long xcoff64_glink_code[10] =
2524{
54327882
AM
2525 0xe9820000, /* ld r12,0(r2) */
2526 0xf8410028, /* std r2,40(r1) */
2527 0xe80c0000, /* ld r0,0(r12) */
2528 0xe84c0008, /* ld r0,8(r12) */
2529 0x7c0903a6, /* mtctr r0 */
2530 0x4e800420, /* bctr */
2531 0x00000000, /* start of traceback table */
2532 0x000ca000, /* traceback table */
2533 0x00000000, /* traceback table */
2534 0x00000018, /* ??? */
beb1bf64
TR
2535};
2536
dc810e39 2537static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
cf9ab45b
AM
2538 {
2539 { /* COFF backend, defined in libcoff.h. */
2540 _bfd_xcoff64_swap_aux_in,
2541 _bfd_xcoff64_swap_sym_in,
2542 _bfd_xcoff64_swap_lineno_in,
2543 _bfd_xcoff64_swap_aux_out,
2544 _bfd_xcoff64_swap_sym_out,
2545 _bfd_xcoff64_swap_lineno_out,
2546 xcoff64_swap_reloc_out,
2547 coff_swap_filehdr_out,
2548 coff_swap_aouthdr_out,
2549 coff_swap_scnhdr_out,
2550 FILHSZ,
2551 AOUTSZ,
2552 SCNHSZ,
2553 SYMESZ,
2554 AUXESZ,
2555 RELSZ,
2556 LINESZ,
2557 FILNMLEN,
b34976b6
AM
2558 TRUE, /* _bfd_coff_long_filenames */
2559 FALSE, /* _bfd_coff_long_section_names */
cf9ab45b 2560 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2561 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2562 4, /* _bfd_coff_debug_string_prefix_length */
2563 coff_swap_filehdr_in,
2564 coff_swap_aouthdr_in,
2565 coff_swap_scnhdr_in,
2566 xcoff64_swap_reloc_in,
2567 xcoff64_bad_format_hook,
2568 coff_set_arch_mach_hook,
2569 coff_mkobject_hook,
2570 styp_to_sec_flags,
2571 coff_set_alignment_hook,
2572 coff_slurp_symbol_table,
2573 symname_in_debug_hook,
2574 coff_pointerize_aux_hook,
2575 coff_print_aux,
2576 dummy_reloc16_extra_cases,
2577 dummy_reloc16_estimate,
2578 NULL, /* bfd_coff_sym_is_global */
2579 coff_compute_section_file_positions,
2580 NULL, /* _bfd_coff_start_final_link */
2581 xcoff64_ppc_relocate_section,
2582 coff_rtype_to_howto,
2583 NULL, /* _bfd_coff_adjust_symndx */
2584 _bfd_generic_link_add_one_symbol,
2585 coff_link_output_has_begun,
2586 coff_final_link_postscript
2587 },
2588
2589 0x01EF, /* magic number */
2590 bfd_arch_powerpc,
2591 bfd_mach_ppc_620,
2592
2593 /* Function pointers to xcoff specific swap routines. */
2594 xcoff64_swap_ldhdr_in,
2595 xcoff64_swap_ldhdr_out,
2596 xcoff64_swap_ldsym_in,
2597 xcoff64_swap_ldsym_out,
2598 xcoff64_swap_ldrel_in,
2599 xcoff64_swap_ldrel_out,
2600
2601 /* Sizes. */
2602 LDHDRSZ,
2603 LDSYMSZ,
2604 LDRELSZ,
2605 24, /* _xcoff_function_descriptor_size */
2606 0, /* _xcoff_small_aout_header_size */
2607
2608 /* Versions. */
2609 2, /* _xcoff_ldhdr_version */
2610
2611 _bfd_xcoff64_put_symbol_name,
2612 _bfd_xcoff64_put_ldsymbol_name,
2613 &xcoff64_dynamic_reloc,
2614 xcoff64_create_csect_from_smclas,
2615
2616 /* Lineno and reloc count overflow. */
2617 xcoff64_is_lineno_count_overflow,
2618 xcoff64_is_reloc_count_overflow,
2619
2620 xcoff64_loader_symbol_offset,
2621 xcoff64_loader_reloc_offset,
2622
2623 /* glink. */
2624 &xcoff64_glink_code[0],
2625 40, /* _xcoff_glink_size */
2626
2627 /* rtinit. */
2628 88, /* _xcoff_rtinit_size */
2629 xcoff64_generate_rtinit,
2630 };
beb1bf64 2631
eb1e0e80 2632/* The transfer vector that leads the outside world to all of the above. */
beb1bf64 2633const bfd_target rs6000coff64_vec =
cf9ab45b
AM
2634 {
2635 "aixcoff64-rs6000",
2636 bfd_target_xcoff_flavour,
2637 BFD_ENDIAN_BIG, /* data byte order is big */
2638 BFD_ENDIAN_BIG, /* header byte order is big */
2639
2640 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2641 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2642
a7c71b0c 2643 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2644 0, /* leading char */
2645 '/', /* ar_pad_char */
2646 15, /* ar_max_namelen */
2647
2648 /* data */
2649 bfd_getb64,
2650 bfd_getb_signed_64,
2651 bfd_putb64,
2652 bfd_getb32,
2653 bfd_getb_signed_32,
2654 bfd_putb32,
2655 bfd_getb16,
2656 bfd_getb_signed_16,
2657 bfd_putb16,
2658
2659 /* hdrs */
2660 bfd_getb64,
2661 bfd_getb_signed_64,
2662 bfd_putb64,
2663 bfd_getb32,
2664 bfd_getb_signed_32,
2665 bfd_putb32,
2666 bfd_getb16,
2667 bfd_getb_signed_16,
2668 bfd_putb16,
2669
2670 { /* bfd_check_format */
2671 _bfd_dummy_target,
2672 coff_object_p,
2673 xcoff64_archive_p,
2674 CORE_FILE_P
2675 },
2676
2677 { /* bfd_set_format */
2678 bfd_false,
2679 coff_mkobject,
2680 _bfd_generic_mkarchive,
2681 bfd_false
2682 },
2683
2684 {/* bfd_write_contents */
2685 bfd_false,
2686 xcoff64_write_object_contents,
2687 _bfd_xcoff_write_archive_contents,
2688 bfd_false
2689 },
2690
2691 /* Generic */
2692 bfd_true,
2693 bfd_true,
2694 coff_new_section_hook,
2695 _bfd_generic_get_section_contents,
2696 _bfd_generic_get_section_contents_in_window,
2697
2698 /* Copy */
2699 _bfd_xcoff_copy_private_bfd_data,
b34976b6 2700 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
60b48850 2701 _bfd_generic_init_private_section_data,
b34976b6
AM
2702 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2703 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
80fccad2 2704 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
b34976b6
AM
2705 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2706 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
cf9ab45b
AM
2707
2708 /* Core */
2709 coff_core_file_failing_command,
2710 coff_core_file_failing_signal,
2711 coff_core_file_matches_executable_p,
2712
2713 /* Archive */
2714 xcoff64_slurp_armap,
dc810e39 2715 bfd_false,
b34976b6 2716 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
cf9ab45b
AM
2717 bfd_dont_truncate_arname,
2718 _bfd_xcoff_write_armap,
2719 _bfd_xcoff_read_ar_hdr,
2720 xcoff64_openr_next_archived_file,
2721 _bfd_generic_get_elt_at_index,
2722 _bfd_xcoff_stat_arch_elt,
2723 bfd_true,
2724
2725 /* Symbols */
2726 coff_get_symtab_upper_bound,
6cee3f79 2727 coff_canonicalize_symtab,
cf9ab45b
AM
2728 coff_make_empty_symbol,
2729 coff_print_symbol,
2730 coff_get_symbol_info,
2731 _bfd_xcoff_is_local_label_name,
7db6994f 2732 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
2733 coff_get_lineno,
2734 coff_find_nearest_line,
4575b1b5 2735 _bfd_generic_find_line,
4ab527b0 2736 coff_find_inliner_info,
cf9ab45b
AM
2737 coff_bfd_make_debug_symbol,
2738 _bfd_generic_read_minisymbols,
2739 _bfd_generic_minisymbol_to_symbol,
2740
2741 /* Reloc */
2742 coff_get_reloc_upper_bound,
2743 coff_canonicalize_reloc,
2744 xcoff64_reloc_type_lookup,
157090f7 2745 xcoff64_reloc_name_lookup,
cf9ab45b
AM
2746
2747 /* Write */
2748 coff_set_arch_mach,
2749 coff_set_section_contents,
2750
2751 /* Link */
2752 xcoff64_sizeof_headers,
2753 bfd_generic_get_relocated_section_contents,
2754 bfd_generic_relax_section,
2755 _bfd_xcoff_bfd_link_hash_table_create,
2756 _bfd_generic_link_hash_table_free,
2757 _bfd_xcoff_bfd_link_add_symbols,
2758 _bfd_generic_link_just_syms,
2759 _bfd_xcoff_bfd_final_link,
2760 _bfd_generic_link_split_section,
2761 bfd_generic_gc_sections,
2762 bfd_generic_merge_sections,
72adc230 2763 bfd_generic_is_group_section,
cf9ab45b 2764 bfd_generic_discard_group,
082b7297 2765 _bfd_generic_section_already_linked,
cf9ab45b
AM
2766
2767 /* Dynamic */
2768 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2769 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 2770 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
2771 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2772 _bfd_xcoff_canonicalize_dynamic_reloc,
2773
2774 /* Opposite endian version, none exists */
2775 NULL,
2776
2777 (void *) &bfd_xcoff_backend_data,
2778 };
eb1e0e80 2779
b34976b6
AM
2780extern const bfd_target *xcoff64_core_p
2781 PARAMS ((bfd *));
2782extern bfd_boolean xcoff64_core_file_matches_executable_p
2783 PARAMS ((bfd *, bfd *));
2784extern char *xcoff64_core_file_failing_command
2785 PARAMS ((bfd *));
2786extern int xcoff64_core_file_failing_signal
2787 PARAMS ((bfd *));
eb1e0e80
NC
2788
2789/* AIX 5 */
54327882 2790static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
cf9ab45b
AM
2791 {
2792 { /* COFF backend, defined in libcoff.h. */
2793 _bfd_xcoff64_swap_aux_in,
2794 _bfd_xcoff64_swap_sym_in,
2795 _bfd_xcoff64_swap_lineno_in,
2796 _bfd_xcoff64_swap_aux_out,
2797 _bfd_xcoff64_swap_sym_out,
2798 _bfd_xcoff64_swap_lineno_out,
2799 xcoff64_swap_reloc_out,
2800 coff_swap_filehdr_out,
2801 coff_swap_aouthdr_out,
2802 coff_swap_scnhdr_out,
2803 FILHSZ,
2804 AOUTSZ,
2805 SCNHSZ,
2806 SYMESZ,
2807 AUXESZ,
2808 RELSZ,
2809 LINESZ,
2810 FILNMLEN,
b34976b6
AM
2811 TRUE, /* _bfd_coff_long_filenames */
2812 FALSE, /* _bfd_coff_long_section_names */
cf9ab45b 2813 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2814 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2815 4, /* _bfd_coff_debug_string_prefix_length */
2816 coff_swap_filehdr_in,
2817 coff_swap_aouthdr_in,
2818 coff_swap_scnhdr_in,
2819 xcoff64_swap_reloc_in,
2820 xcoff64_bad_format_hook,
2821 coff_set_arch_mach_hook,
2822 coff_mkobject_hook,
2823 styp_to_sec_flags,
2824 coff_set_alignment_hook,
2825 coff_slurp_symbol_table,
2826 symname_in_debug_hook,
2827 coff_pointerize_aux_hook,
2828 coff_print_aux,
2829 dummy_reloc16_extra_cases,
2830 dummy_reloc16_estimate,
2831 NULL, /* bfd_coff_sym_is_global */
2832 coff_compute_section_file_positions,
2833 NULL, /* _bfd_coff_start_final_link */
2834 xcoff64_ppc_relocate_section,
2835 coff_rtype_to_howto,
2836 NULL, /* _bfd_coff_adjust_symndx */
2837 _bfd_generic_link_add_one_symbol,
2838 coff_link_output_has_begun,
2839 coff_final_link_postscript
2840 },
2841
2842 U64_TOCMAGIC, /* magic number */
2843 bfd_arch_powerpc,
2844 bfd_mach_ppc_620,
2845
2846 /* Function pointers to xcoff specific swap routines. */
2847 xcoff64_swap_ldhdr_in,
2848 xcoff64_swap_ldhdr_out,
2849 xcoff64_swap_ldsym_in,
2850 xcoff64_swap_ldsym_out,
2851 xcoff64_swap_ldrel_in,
2852 xcoff64_swap_ldrel_out,
2853
2854 /* Sizes. */
2855 LDHDRSZ,
2856 LDSYMSZ,
2857 LDRELSZ,
2858 24, /* _xcoff_function_descriptor_size */
2859 0, /* _xcoff_small_aout_header_size */
2860 /* Versions. */
2861 2, /* _xcoff_ldhdr_version */
2862
2863 _bfd_xcoff64_put_symbol_name,
2864 _bfd_xcoff64_put_ldsymbol_name,
2865 &xcoff64_dynamic_reloc,
2866 xcoff64_create_csect_from_smclas,
2867
2868 /* Lineno and reloc count overflow. */
2869 xcoff64_is_lineno_count_overflow,
2870 xcoff64_is_reloc_count_overflow,
2871
2872 xcoff64_loader_symbol_offset,
2873 xcoff64_loader_reloc_offset,
2874
2875 /* glink. */
2876 &xcoff64_glink_code[0],
2877 40, /* _xcoff_glink_size */
2878
2879 /* rtinit. */
2880 88, /* _xcoff_rtinit_size */
2881 xcoff64_generate_rtinit,
2882 };
eb1e0e80
NC
2883
2884/* The transfer vector that leads the outside world to all of the above. */
2885const bfd_target aix5coff64_vec =
cf9ab45b
AM
2886 {
2887 "aix5coff64-rs6000",
2888 bfd_target_xcoff_flavour,
2889 BFD_ENDIAN_BIG, /* data byte order is big */
2890 BFD_ENDIAN_BIG, /* header byte order is big */
2891
2892 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2893 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2894
a7c71b0c 2895 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2896 0, /* leading char */
2897 '/', /* ar_pad_char */
2898 15, /* ar_max_namelen */
2899
2900 /* data */
2901 bfd_getb64,
2902 bfd_getb_signed_64,
2903 bfd_putb64,
2904 bfd_getb32,
2905 bfd_getb_signed_32,
2906 bfd_putb32,
2907 bfd_getb16,
2908 bfd_getb_signed_16,
2909 bfd_putb16,
2910
2911 /* hdrs */
2912 bfd_getb64,
2913 bfd_getb_signed_64,
2914 bfd_putb64,
2915 bfd_getb32,
2916 bfd_getb_signed_32,
2917 bfd_putb32,
2918 bfd_getb16,
2919 bfd_getb_signed_16,
2920 bfd_putb16,
2921
2922 { /* bfd_check_format */
2923 _bfd_dummy_target,
2924 coff_object_p,
2925 xcoff64_archive_p,
2926 xcoff64_core_p
2927 },
2928
2929 { /* bfd_set_format */
2930 bfd_false,
2931 coff_mkobject,
2932 _bfd_generic_mkarchive,
2933 bfd_false
2934 },
2935
2936 {/* bfd_write_contents */
2937 bfd_false,
2938 xcoff64_write_object_contents,
2939 _bfd_xcoff_write_archive_contents,
2940 bfd_false
2941 },
2942
2943 /* Generic */
2944 bfd_true,
2945 bfd_true,
2946 coff_new_section_hook,
2947 _bfd_generic_get_section_contents,
2948 _bfd_generic_get_section_contents_in_window,
2949
2950 /* Copy */
2951 _bfd_xcoff_copy_private_bfd_data,
b34976b6 2952 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
60b48850 2953 _bfd_generic_init_private_section_data,
b34976b6
AM
2954 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2955 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
80fccad2 2956 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
b34976b6
AM
2957 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2958 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
cf9ab45b
AM
2959
2960 /* Core */
2961 xcoff64_core_file_failing_command,
2962 xcoff64_core_file_failing_signal,
2963 xcoff64_core_file_matches_executable_p,
2964
2965 /* Archive */
2966 xcoff64_slurp_armap,
54327882 2967 bfd_false,
b34976b6 2968 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
cf9ab45b
AM
2969 bfd_dont_truncate_arname,
2970 _bfd_xcoff_write_armap,
2971 _bfd_xcoff_read_ar_hdr,
2972 xcoff64_openr_next_archived_file,
2973 _bfd_generic_get_elt_at_index,
2974 _bfd_xcoff_stat_arch_elt,
2975 bfd_true,
2976
2977 /* Symbols */
2978 coff_get_symtab_upper_bound,
6cee3f79 2979 coff_canonicalize_symtab,
cf9ab45b
AM
2980 coff_make_empty_symbol,
2981 coff_print_symbol,
2982 coff_get_symbol_info,
2983 _bfd_xcoff_is_local_label_name,
7db6994f 2984 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
2985 coff_get_lineno,
2986 coff_find_nearest_line,
4575b1b5 2987 _bfd_generic_find_line,
4ab527b0 2988 coff_find_inliner_info,
cf9ab45b
AM
2989 coff_bfd_make_debug_symbol,
2990 _bfd_generic_read_minisymbols,
2991 _bfd_generic_minisymbol_to_symbol,
2992
2993 /* Reloc */
2994 coff_get_reloc_upper_bound,
2995 coff_canonicalize_reloc,
2996 xcoff64_reloc_type_lookup,
157090f7 2997 xcoff64_reloc_name_lookup,
cf9ab45b
AM
2998
2999 /* Write */
3000 coff_set_arch_mach,
3001 coff_set_section_contents,
3002
3003 /* Link */
3004 xcoff64_sizeof_headers,
3005 bfd_generic_get_relocated_section_contents,
3006 bfd_generic_relax_section,
3007 _bfd_xcoff_bfd_link_hash_table_create,
3008 _bfd_generic_link_hash_table_free,
3009 _bfd_xcoff_bfd_link_add_symbols,
3010 _bfd_generic_link_just_syms,
3011 _bfd_xcoff_bfd_final_link,
3012 _bfd_generic_link_split_section,
3013 bfd_generic_gc_sections,
3014 bfd_generic_merge_sections,
72adc230 3015 bfd_generic_is_group_section,
cf9ab45b 3016 bfd_generic_discard_group,
082b7297 3017 _bfd_generic_section_already_linked,
cf9ab45b
AM
3018
3019 /* Dynamic */
3020 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3021 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 3022 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
3023 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3024 _bfd_xcoff_canonicalize_dynamic_reloc,
3025
3026 /* Opposite endian version, none exists. */
3027 NULL,
3028
3029 (void *) & bfd_xcoff_aix5_backend_data,
3030 };
This page took 0.479694 seconds and 4 git commands to generate.