OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [coff64-rs6000.c] - Blame information for rev 279

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.