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