Coverage Report

Created: 2026-04-04 08:16

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