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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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