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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [coff64-rs6000.c] - Blame information for rev 199

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

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

powered by: WebSVN 2.1.0

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