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