Coverage Report

Created: 2025-06-24 06:45

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