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

Subversion Repositories openrisc_me

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

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 "XCOFF" files.
2 225 jeremybenn
   Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3
   2008, 2009  Free Software Foundation, Inc.
4 24 jeremybenn
   Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.
5
   Archive support from Damon A. Permezel.
6
   Contributed by IBM Corporation and Cygnus Support.
7
 
8
   This file is part of BFD, the Binary File Descriptor library.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23
   MA 02110-1301, USA.  */
24
 
25
#include "sysdep.h"
26
#include "bfd.h"
27
#include "bfdlink.h"
28
#include "libbfd.h"
29
#include "coff/internal.h"
30
#include "coff/xcoff.h"
31
#include "coff/rs6000.h"
32
#include "libcoff.h"
33
#include "libxcoff.h"
34
 
35
extern bfd_boolean _bfd_xcoff_mkobject
36
  PARAMS ((bfd *));
37
extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
38
  PARAMS ((bfd *, bfd *));
39
extern bfd_boolean _bfd_xcoff_is_local_label_name
40
  PARAMS ((bfd *, const char *));
41
extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
42
  PARAMS ((bfd *, bfd_reloc_code_real_type));
43
extern bfd_boolean _bfd_xcoff_slurp_armap
44
  PARAMS ((bfd *));
45
extern const bfd_target *_bfd_xcoff_archive_p
46
  PARAMS ((bfd *));
47
extern PTR _bfd_xcoff_read_ar_hdr
48
  PARAMS ((bfd *));
49
extern bfd *_bfd_xcoff_openr_next_archived_file
50
  PARAMS ((bfd *, bfd *));
51
extern int _bfd_xcoff_stat_arch_elt
52
  PARAMS ((bfd *, struct stat *));
53
extern bfd_boolean _bfd_xcoff_write_armap
54
  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
55
extern bfd_boolean _bfd_xcoff_write_archive_contents
56
  PARAMS ((bfd *));
57
extern int _bfd_xcoff_sizeof_headers
58
  PARAMS ((bfd *, struct bfd_link_info *));
59
extern void _bfd_xcoff_swap_sym_in
60
  PARAMS ((bfd *, PTR, PTR));
61
extern unsigned int _bfd_xcoff_swap_sym_out
62
  PARAMS ((bfd *, PTR, PTR));
63
extern void _bfd_xcoff_swap_aux_in
64
  PARAMS ((bfd *, PTR, int, int, int, int, PTR));
65
extern unsigned int _bfd_xcoff_swap_aux_out
66
  PARAMS ((bfd *, PTR, int, int, int, int, PTR));
67
static void xcoff_swap_reloc_in
68
  PARAMS ((bfd *, PTR, PTR));
69
static unsigned int xcoff_swap_reloc_out
70
  PARAMS ((bfd *, PTR, PTR));
71
 
72
/* Forward declare xcoff_rtype2howto for coffcode.h macro.  */
73
void xcoff_rtype2howto
74
  PARAMS ((arelent *, struct internal_reloc *));
75
 
76
/* coffcode.h needs these to be defined.  */
77
#define RS6000COFF_C 1
78
 
79
#define SELECT_RELOC(internal, howto)                                   \
80
  {                                                                     \
81
    internal.r_type = howto->type;                                      \
82
    internal.r_size =                                                   \
83
      ((howto->complain_on_overflow == complain_overflow_signed         \
84
        ? 0x80                                                          \
85
        : 0)                                                             \
86
       | (howto->bitsize - 1));                                         \
87
  }
88
 
89
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
90
#define COFF_LONG_FILENAMES
91
#define NO_COFF_SYMBOLS
92
#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
93
#define coff_mkobject _bfd_xcoff_mkobject
94
#define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
95
#define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
96
#define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
97
#define coff_bfd_reloc_name_lookup _bfd_xcoff_reloc_name_lookup
98
#ifdef AIX_CORE
99
extern const bfd_target * rs6000coff_core_p
100
  PARAMS ((bfd *abfd));
101
extern bfd_boolean rs6000coff_core_file_matches_executable_p
102
  PARAMS ((bfd *cbfd, bfd *ebfd));
103
extern char *rs6000coff_core_file_failing_command
104
  PARAMS ((bfd *abfd));
105
extern int rs6000coff_core_file_failing_signal
106
  PARAMS ((bfd *abfd));
107
#define CORE_FILE_P rs6000coff_core_p
108
#define coff_core_file_failing_command \
109
  rs6000coff_core_file_failing_command
110
#define coff_core_file_failing_signal \
111
  rs6000coff_core_file_failing_signal
112
#define coff_core_file_matches_executable_p \
113
  rs6000coff_core_file_matches_executable_p
114
#else
115
#define CORE_FILE_P _bfd_dummy_target
116
#define coff_core_file_failing_command \
117
  _bfd_nocore_core_file_failing_command
118
#define coff_core_file_failing_signal \
119
  _bfd_nocore_core_file_failing_signal
120
#define coff_core_file_matches_executable_p \
121
  _bfd_nocore_core_file_matches_executable_p
122
#endif
123
#define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
124
#define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
125
#define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
126
#define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
127
#define coff_swap_reloc_in xcoff_swap_reloc_in
128
#define coff_swap_reloc_out xcoff_swap_reloc_out
129
#define NO_COFF_RELOCS
130
 
131 225 jeremybenn
#ifndef bfd_pe_print_pdata
132
#define bfd_pe_print_pdata      NULL
133
#endif
134
 
135 24 jeremybenn
#include "coffcode.h"
136
 
137
/* The main body of code is in coffcode.h.  */
138
 
139
static const char *normalize_filename
140
  PARAMS ((bfd *));
141
static bfd_boolean xcoff_write_armap_old
142
  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
143
static bfd_boolean xcoff_write_armap_big
144
  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
145
static bfd_boolean xcoff_write_archive_contents_old
146
  PARAMS ((bfd *));
147
static bfd_boolean xcoff_write_archive_contents_big
148
  PARAMS ((bfd *));
149
static void xcoff_swap_ldhdr_in
150
  PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
151
static void xcoff_swap_ldhdr_out
152
  PARAMS ((bfd *, const struct internal_ldhdr *, PTR));
153
static void xcoff_swap_ldsym_in
154
  PARAMS ((bfd *, const PTR, struct internal_ldsym *));
155
static void xcoff_swap_ldsym_out
156
  PARAMS ((bfd *, const struct internal_ldsym *, PTR));
157
static void xcoff_swap_ldrel_in
158
  PARAMS ((bfd *, const PTR, struct internal_ldrel *));
159
static void xcoff_swap_ldrel_out
160
  PARAMS ((bfd *, const struct internal_ldrel *, PTR));
161
static bfd_boolean xcoff_ppc_relocate_section
162
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
163
           struct internal_reloc *, struct internal_syment *, asection **));
164
static bfd_boolean _bfd_xcoff_put_ldsymbol_name
165
  PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
166
           const char *));
167
static asection *xcoff_create_csect_from_smclas
168
  PARAMS ((bfd *, union internal_auxent *, const char *));
169
static bfd_boolean xcoff_is_lineno_count_overflow
170
  PARAMS ((bfd *, bfd_vma));
171
static bfd_boolean xcoff_is_reloc_count_overflow
172
  PARAMS ((bfd *, bfd_vma));
173
static bfd_vma xcoff_loader_symbol_offset
174
  PARAMS ((bfd *, struct internal_ldhdr *));
175
static bfd_vma xcoff_loader_reloc_offset
176
  PARAMS ((bfd *, struct internal_ldhdr *));
177
static bfd_boolean xcoff_generate_rtinit
178
  PARAMS ((bfd *, const char *, const char *, bfd_boolean));
179
static bfd_boolean do_pad
180
  PARAMS ((bfd *, unsigned int));
181
static bfd_boolean do_copy
182
  PARAMS ((bfd *, bfd *));
183
 
184
/* Relocation functions */
185
static bfd_boolean xcoff_reloc_type_br
186
  PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
187
 
188
static bfd_boolean xcoff_complain_overflow_dont_func
189
  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
190
static bfd_boolean xcoff_complain_overflow_bitfield_func
191
  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
192
static bfd_boolean xcoff_complain_overflow_signed_func
193
  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
194
static bfd_boolean xcoff_complain_overflow_unsigned_func
195
  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
196
 
197
bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
198
  PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
199
{
200
  xcoff_reloc_type_pos,  /* R_POS   (0x00) */
201
  xcoff_reloc_type_neg,  /* R_NEG   (0x01) */
202
  xcoff_reloc_type_rel,  /* R_REL   (0x02) */
203
  xcoff_reloc_type_toc,  /* R_TOC   (0x03) */
204
  xcoff_reloc_type_fail, /* R_RTB   (0x04) */
205
  xcoff_reloc_type_toc,  /* R_GL    (0x05) */
206
  xcoff_reloc_type_toc,  /* R_TCL   (0x06) */
207
  xcoff_reloc_type_fail, /*         (0x07) */
208
  xcoff_reloc_type_ba,   /* R_BA    (0x08) */
209
  xcoff_reloc_type_fail, /*         (0x09) */
210
  xcoff_reloc_type_br,   /* R_BR    (0x0a) */
211
  xcoff_reloc_type_fail, /*         (0x0b) */
212
  xcoff_reloc_type_pos,  /* R_RL    (0x0c) */
213
  xcoff_reloc_type_pos,  /* R_RLA   (0x0d) */
214
  xcoff_reloc_type_fail, /*         (0x0e) */
215
  xcoff_reloc_type_noop, /* R_REF   (0x0f) */
216
  xcoff_reloc_type_fail, /*         (0x10) */
217
  xcoff_reloc_type_fail, /*         (0x11) */
218
  xcoff_reloc_type_toc,  /* R_TRL   (0x12) */
219
  xcoff_reloc_type_toc,  /* R_TRLA  (0x13) */
220
  xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
221
  xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
222
  xcoff_reloc_type_ba,   /* R_CAI   (0x16) */
223
  xcoff_reloc_type_crel, /* R_CREL  (0x17) */
224
  xcoff_reloc_type_ba,   /* R_RBA   (0x18) */
225
  xcoff_reloc_type_ba,   /* R_RBAC  (0x19) */
226
  xcoff_reloc_type_br,   /* R_RBR   (0x1a) */
227
  xcoff_reloc_type_ba,   /* R_RBRC  (0x1b) */
228
};
229
 
230
bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
231
  PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS)) =
232
{
233
  xcoff_complain_overflow_dont_func,
234
  xcoff_complain_overflow_bitfield_func,
235
  xcoff_complain_overflow_signed_func,
236
  xcoff_complain_overflow_unsigned_func,
237
};
238
 
239 225 jeremybenn
/* Information about one member of an archive.  */
240
struct member_layout {
241
  /* The archive member that this structure describes.  */
242
  bfd *member;
243
 
244
  /* The number of bytes of padding that must be inserted before the
245
     start of the member in order to ensure that the section contents
246
     are correctly aligned.  */
247
  unsigned int leading_padding;
248
 
249
  /* The offset of MEMBER from the start of the archive (i.e. the end
250
     of the leading padding).  */
251
  file_ptr offset;
252
 
253
  /* The normalized name of MEMBER.  */
254
  const char *name;
255
 
256
  /* The length of NAME, without padding.  */
257
  bfd_size_type namlen;
258
 
259
  /* The length of NAME, with padding.  */
260
  bfd_size_type padded_namlen;
261
 
262
  /* The size of MEMBER's header, including the name and magic sequence.  */
263
  bfd_size_type header_size;
264
 
265
  /* The size of the MEMBER's contents.  */
266
  bfd_size_type contents_size;
267
 
268
  /* The number of bytes of padding that must be inserted after MEMBER
269
     in order to preserve even alignment.  */
270
  bfd_size_type trailing_padding;
271
};
272
 
273
/* A structure used for iterating over the members of an archive.  */
274
struct archive_iterator {
275
  /* The archive itself.  */
276
  bfd *archive;
277
 
278
  /* Information about the current archive member.  */
279
  struct member_layout current;
280
 
281
  /* Information about the next archive member.  MEMBER is null if there
282
     are no more archive members, in which case OFFSET is the offset of
283
     the first unused byte.  */
284
  struct member_layout next;
285
};
286
 
287
/* Initialize INFO so that it describes member MEMBER of archive ARCHIVE.
288
   OFFSET is the even-padded offset of MEMBER, not including any leading
289
   padding needed for section alignment.  */
290
 
291
static void
292
member_layout_init (struct member_layout *info, bfd *archive,
293
                    bfd *member, file_ptr offset)
294
{
295
  info->member = member;
296
  info->leading_padding = 0;
297
  if (member)
298
    {
299
      info->name = normalize_filename (member);
300
      info->namlen = strlen (info->name);
301
      info->padded_namlen = info->namlen + (info->namlen & 1);
302
      if (xcoff_big_format_p (archive))
303
        info->header_size = SIZEOF_AR_HDR_BIG;
304
      else
305
        info->header_size = SIZEOF_AR_HDR;
306
      info->header_size += info->padded_namlen + SXCOFFARFMAG;
307
      info->contents_size = arelt_size (member);
308
      info->trailing_padding = info->contents_size & 1;
309
 
310
      if (bfd_check_format (member, bfd_object)
311
          && bfd_get_flavour (member) == bfd_target_xcoff_flavour
312
          && (member->flags & DYNAMIC) != 0)
313
        info->leading_padding
314
          = (-(offset + info->header_size)
315
             & ((1 << bfd_xcoff_text_align_power (member)) - 1));
316
    }
317
  info->offset = offset + info->leading_padding;
318
}
319
 
320
/* Set up ITERATOR to iterate through archive ARCHIVE.  */
321
 
322
static void
323
archive_iterator_begin (struct archive_iterator *iterator,
324
                        bfd *archive)
325
{
326
  iterator->archive = archive;
327
  member_layout_init (&iterator->next, archive, archive->archive_head,
328
                      xcoff_big_format_p (archive)
329
                      ? SIZEOF_AR_FILE_HDR_BIG
330
                      : SIZEOF_AR_FILE_HDR);
331
}
332
 
333
/* Make ITERATOR visit the first unvisited archive member.  Return true
334
   on success; return false if all members have been visited.  */
335
 
336
static bfd_boolean
337
archive_iterator_next (struct archive_iterator *iterator)
338
{
339
  if (!iterator->next.member)
340
    return FALSE;
341
 
342
  iterator->current = iterator->next;
343
  member_layout_init (&iterator->next, iterator->archive,
344
                      iterator->current.member->archive_next,
345
                      iterator->current.offset
346
                      + iterator->current.header_size
347
                      + iterator->current.contents_size
348
                      + iterator->current.trailing_padding);
349
  return TRUE;
350
}
351
 
352 24 jeremybenn
/* We use our own tdata type.  Its first field is the COFF tdata type,
353
   so the COFF routines are compatible.  */
354
 
355
bfd_boolean
356
_bfd_xcoff_mkobject (abfd)
357
     bfd *abfd;
358
{
359
  coff_data_type *coff;
360
  bfd_size_type amt = sizeof (struct xcoff_tdata);
361
 
362
  abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
363
  if (abfd->tdata.xcoff_obj_data == NULL)
364
    return FALSE;
365
  coff = coff_data (abfd);
366
  coff->symbols = (coff_symbol_type *) NULL;
367
  coff->conversion_table = (unsigned int *) NULL;
368
  coff->raw_syments = (struct coff_ptr_struct *) NULL;
369
  coff->relocbase = 0;
370
 
371
  xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
372
 
373
  /* We set cputype to -1 to indicate that it has not been
374
     initialized.  */
375
  xcoff_data (abfd)->cputype = -1;
376
 
377
  xcoff_data (abfd)->csects = NULL;
378
  xcoff_data (abfd)->debug_indices = NULL;
379
 
380
  /* text section alignment is different than the default */
381
  bfd_xcoff_text_align_power (abfd) = 2;
382
 
383
  return TRUE;
384
}
385
 
386
/* Copy XCOFF data from one BFD to another.  */
387
 
388
bfd_boolean
389
_bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
390
     bfd *ibfd;
391
     bfd *obfd;
392
{
393
  struct xcoff_tdata *ix, *ox;
394
  asection *sec;
395
 
396
  if (ibfd->xvec != obfd->xvec)
397
    return TRUE;
398
  ix = xcoff_data (ibfd);
399
  ox = xcoff_data (obfd);
400
  ox->full_aouthdr = ix->full_aouthdr;
401
  ox->toc = ix->toc;
402
  if (ix->sntoc == 0)
403
    ox->sntoc = 0;
404
  else
405
    {
406
      sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
407
      if (sec == NULL)
408
        ox->sntoc = 0;
409
      else
410
        ox->sntoc = sec->output_section->target_index;
411
    }
412
  if (ix->snentry == 0)
413
    ox->snentry = 0;
414
  else
415
    {
416
      sec = coff_section_from_bfd_index (ibfd, ix->snentry);
417
      if (sec == NULL)
418
        ox->snentry = 0;
419
      else
420
        ox->snentry = sec->output_section->target_index;
421
    }
422
  bfd_xcoff_text_align_power (obfd) = bfd_xcoff_text_align_power (ibfd);
423
  bfd_xcoff_data_align_power (obfd) = bfd_xcoff_data_align_power (ibfd);
424
  ox->modtype = ix->modtype;
425
  ox->cputype = ix->cputype;
426
  ox->maxdata = ix->maxdata;
427
  ox->maxstack = ix->maxstack;
428
  return TRUE;
429
}
430
 
431
/* I don't think XCOFF really has a notion of local labels based on
432
   name.  This will mean that ld -X doesn't actually strip anything.
433
   The AIX native linker does not have a -X option, and it ignores the
434
   -x option.  */
435
 
436
bfd_boolean
437
_bfd_xcoff_is_local_label_name (abfd, name)
438
     bfd *abfd ATTRIBUTE_UNUSED;
439
     const char *name ATTRIBUTE_UNUSED;
440
{
441
  return FALSE;
442
}
443
 
444
void
445
_bfd_xcoff_swap_sym_in (abfd, ext1, in1)
446
     bfd *abfd;
447
     PTR ext1;
448
     PTR in1;
449
{
450
  SYMENT *ext = (SYMENT *)ext1;
451
  struct internal_syment * in = (struct internal_syment *)in1;
452
 
453
  if (ext->e.e_name[0] != 0)
454
    {
455
      memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
456
    }
457
  else
458
    {
459
      in->_n._n_n._n_zeroes = 0;
460
      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
461
    }
462
 
463
  in->n_value = H_GET_32 (abfd, ext->e_value);
464
  in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
465
  in->n_type = H_GET_16 (abfd, ext->e_type);
466
  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
467
  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
468
}
469
 
470
unsigned int
471
_bfd_xcoff_swap_sym_out (abfd, inp, extp)
472
     bfd *abfd;
473
     PTR inp;
474
     PTR extp;
475
{
476
  struct internal_syment *in = (struct internal_syment *)inp;
477
  SYMENT *ext =(SYMENT *)extp;
478
 
479
  if (in->_n._n_name[0] != 0)
480
    {
481
      memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
482
    }
483
  else
484
    {
485
      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
486
      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
487
    }
488
 
489
  H_PUT_32 (abfd, in->n_value, ext->e_value);
490
  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
491
  H_PUT_16 (abfd, in->n_type, ext->e_type);
492
  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
493
  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
494
  return bfd_coff_symesz (abfd);
495
}
496
 
497
void
498 225 jeremybenn
_bfd_xcoff_swap_aux_in (abfd, ext1, type, in_class, indx, numaux, in1)
499 24 jeremybenn
     bfd *abfd;
500
     PTR ext1;
501
     int type;
502 225 jeremybenn
     int in_class;
503 24 jeremybenn
     int indx;
504
     int numaux;
505
     PTR in1;
506
{
507
  AUXENT * ext = (AUXENT *)ext1;
508
  union internal_auxent *in = (union internal_auxent *)in1;
509
 
510 225 jeremybenn
  switch (in_class)
511 24 jeremybenn
    {
512
    case C_FILE:
513
      if (ext->x_file.x_fname[0] == 0)
514
        {
515
          in->x_file.x_n.x_zeroes = 0;
516
          in->x_file.x_n.x_offset =
517
            H_GET_32 (abfd, ext->x_file.x_n.x_offset);
518
        }
519
      else
520
        {
521
          if (numaux > 1)
522
            {
523
              if (indx == 0)
524
                memcpy (in->x_file.x_fname, ext->x_file.x_fname,
525
                        numaux * sizeof (AUXENT));
526
            }
527
          else
528
            {
529
              memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
530
            }
531
        }
532
      goto end;
533
 
534
      /* RS/6000 "csect" auxents */
535
    case C_EXT:
536 225 jeremybenn
    case C_AIX_WEAKEXT:
537 24 jeremybenn
    case C_HIDEXT:
538
      if (indx + 1 == numaux)
539
        {
540
          in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
541
          in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
542
          in->x_csect.x_snhash   = H_GET_16 (abfd, ext->x_csect.x_snhash);
543
          /* We don't have to hack bitfields in x_smtyp because it's
544
             defined by shifts-and-ands, which are equivalent on all
545
             byte orders.  */
546
          in->x_csect.x_smtyp    = H_GET_8 (abfd, ext->x_csect.x_smtyp);
547
          in->x_csect.x_smclas   = H_GET_8 (abfd, ext->x_csect.x_smclas);
548
          in->x_csect.x_stab     = H_GET_32 (abfd, ext->x_csect.x_stab);
549
          in->x_csect.x_snstab   = H_GET_16 (abfd, ext->x_csect.x_snstab);
550
          goto end;
551
        }
552
      break;
553
 
554
    case C_STAT:
555
    case C_LEAFSTAT:
556
    case C_HIDDEN:
557
      if (type == T_NULL)
558
        {
559
          in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
560
          in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
561
          in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
562
          /* PE defines some extra fields; we zero them out for
563
             safety.  */
564
          in->x_scn.x_checksum = 0;
565
          in->x_scn.x_associated = 0;
566
          in->x_scn.x_comdat = 0;
567
 
568
          goto end;
569
        }
570
      break;
571
    }
572
 
573
  in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
574
  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
575
 
576 225 jeremybenn
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
577
      || ISTAG (in_class))
578 24 jeremybenn
    {
579
      in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
580
        H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
581
      in->x_sym.x_fcnary.x_fcn.x_endndx.l =
582
        H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
583
    }
584
  else
585
    {
586
      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
587
        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
588
      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
589
        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
590
      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
591
        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
592
      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
593
        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
594
    }
595
 
596
  if (ISFCN (type))
597
    {
598
      in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
599
    }
600
  else
601
    {
602
      in->x_sym.x_misc.x_lnsz.x_lnno =
603
        H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
604
      in->x_sym.x_misc.x_lnsz.x_size =
605
        H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
606
    }
607
 
608
 end: ;
609
  /* The semicolon is because MSVC doesn't like labels at
610
     end of block.  */
611
}
612
 
613
 
614
unsigned int _bfd_xcoff_swap_aux_out
615
  PARAMS ((bfd *, PTR, int, int, int, int, PTR));
616
 
617
unsigned int
618 225 jeremybenn
_bfd_xcoff_swap_aux_out (abfd, inp, type, in_class, indx, numaux, extp)
619 24 jeremybenn
     bfd * abfd;
620
     PTR   inp;
621
     int   type;
622 225 jeremybenn
     int   in_class;
623 24 jeremybenn
     int   indx ATTRIBUTE_UNUSED;
624
     int   numaux ATTRIBUTE_UNUSED;
625
     PTR   extp;
626
{
627
  union internal_auxent *in = (union internal_auxent *)inp;
628
  AUXENT *ext = (AUXENT *)extp;
629
 
630
  memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
631 225 jeremybenn
  switch (in_class)
632 24 jeremybenn
    {
633
    case C_FILE:
634
      if (in->x_file.x_fname[0] == 0)
635
        {
636
          H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
637
          H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
638
        }
639
      else
640
        {
641
          memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
642
        }
643
      goto end;
644
 
645
      /* RS/6000 "csect" auxents */
646
    case C_EXT:
647 225 jeremybenn
    case C_AIX_WEAKEXT:
648 24 jeremybenn
    case C_HIDEXT:
649
      if (indx + 1 == numaux)
650
        {
651
          H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
652
          H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
653
          H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
654
          /* We don't have to hack bitfields in x_smtyp because it's
655
             defined by shifts-and-ands, which are equivalent on all
656
             byte orders.  */
657
          H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
658
          H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
659
          H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
660
          H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
661
          goto end;
662
        }
663
      break;
664
 
665
    case C_STAT:
666
    case C_LEAFSTAT:
667
    case C_HIDDEN:
668
      if (type == T_NULL)
669
        {
670
          H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
671
          H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
672
          H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
673
          goto end;
674
        }
675
      break;
676
    }
677
 
678
  H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
679
  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
680
 
681 225 jeremybenn
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
682
      || ISTAG (in_class))
683 24 jeremybenn
    {
684
      H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
685
                ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
686
      H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
687
                ext->x_sym.x_fcnary.x_fcn.x_endndx);
688
    }
689
  else
690
    {
691
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
692
                ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
693
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
694
                ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
695
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
696
                ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
697
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
698
                ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
699
    }
700
 
701
  if (ISFCN (type))
702
    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
703
  else
704
    {
705
      H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
706
                ext->x_sym.x_misc.x_lnsz.x_lnno);
707
      H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
708
                ext->x_sym.x_misc.x_lnsz.x_size);
709
    }
710
 
711
end:
712
  return bfd_coff_auxesz (abfd);
713
}
714
 
715
 
716
 
717
/* The XCOFF reloc table.  Actually, XCOFF relocations specify the
718
   bitsize and whether they are signed or not, along with a
719
   conventional type.  This table is for the types, which are used for
720
   different algorithms for putting in the reloc.  Many of these
721
   relocs need special_function entries, which I have not written.  */
722
 
723
 
724
reloc_howto_type xcoff_howto_table[] =
725
{
726
  /* Standard 32 bit relocation.  */
727
  HOWTO (R_POS,                 /* type */
728
         0,                      /* rightshift */
729
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
730
         32,                    /* bitsize */
731
         FALSE,                 /* pc_relative */
732
         0,                      /* bitpos */
733
         complain_overflow_bitfield, /* complain_on_overflow */
734
         0,                      /* special_function */
735
         "R_POS",               /* name */
736
         TRUE,                  /* partial_inplace */
737
         0xffffffff,            /* src_mask */
738
         0xffffffff,            /* dst_mask */
739
         FALSE),                /* pcrel_offset */
740
 
741
  /* 32 bit relocation, but store negative value.  */
742
  HOWTO (R_NEG,                 /* type */
743
         0,                      /* rightshift */
744
         -2,                    /* size (0 = byte, 1 = short, 2 = long) */
745
         32,                    /* bitsize */
746
         FALSE,                 /* pc_relative */
747
         0,                      /* bitpos */
748
         complain_overflow_bitfield, /* complain_on_overflow */
749
         0,                      /* special_function */
750
         "R_NEG",               /* name */
751
         TRUE,                  /* partial_inplace */
752
         0xffffffff,            /* src_mask */
753
         0xffffffff,            /* dst_mask */
754
         FALSE),                /* pcrel_offset */
755
 
756
  /* 32 bit PC relative relocation.  */
757
  HOWTO (R_REL,                 /* type */
758
         0,                      /* rightshift */
759
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
760
         32,                    /* bitsize */
761
         TRUE,                  /* pc_relative */
762
         0,                      /* bitpos */
763
         complain_overflow_signed, /* complain_on_overflow */
764
         0,                      /* special_function */
765
         "R_REL",               /* name */
766
         TRUE,                  /* partial_inplace */
767
         0xffffffff,            /* src_mask */
768
         0xffffffff,            /* dst_mask */
769
         FALSE),                /* pcrel_offset */
770
 
771
  /* 16 bit TOC relative relocation.  */
772
  HOWTO (R_TOC,                 /* type */
773
         0,                      /* rightshift */
774
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
775
         16,                    /* bitsize */
776
         FALSE,                 /* pc_relative */
777
         0,                      /* bitpos */
778
         complain_overflow_bitfield, /* complain_on_overflow */
779
         0,                      /* special_function */
780
         "R_TOC",               /* name */
781
         TRUE,                  /* partial_inplace */
782
         0xffff,                /* src_mask */
783
         0xffff,                /* dst_mask */
784
         FALSE),                /* pcrel_offset */
785
 
786
  /* I don't really know what this is.  */
787
  HOWTO (R_RTB,                 /* type */
788
         1,                     /* rightshift */
789
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
790
         32,                    /* bitsize */
791
         FALSE,                 /* pc_relative */
792
         0,                      /* bitpos */
793
         complain_overflow_bitfield, /* complain_on_overflow */
794
         0,                      /* special_function */
795
         "R_RTB",               /* name */
796
         TRUE,                  /* partial_inplace */
797
         0xffffffff,            /* src_mask */
798
         0xffffffff,            /* dst_mask */
799
         FALSE),                /* pcrel_offset */
800
 
801
  /* External TOC relative symbol.  */
802
  HOWTO (R_GL,                  /* type */
803
         0,                      /* rightshift */
804
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
805
         16,                    /* bitsize */
806
         FALSE,                 /* pc_relative */
807
         0,                      /* bitpos */
808
         complain_overflow_bitfield, /* complain_on_overflow */
809
         0,                      /* special_function */
810
         "R_GL",                /* name */
811
         TRUE,                  /* partial_inplace */
812
         0xffff,                /* src_mask */
813
         0xffff,                /* dst_mask */
814
         FALSE),                /* pcrel_offset */
815
 
816
  /* Local TOC relative symbol.  */
817
  HOWTO (R_TCL,                 /* type */
818
         0,                      /* rightshift */
819
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
820
         16,                    /* bitsize */
821
         FALSE,                 /* pc_relative */
822
         0,                      /* bitpos */
823
         complain_overflow_bitfield, /* complain_on_overflow */
824
         0,                      /* special_function */
825
         "R_TCL",               /* name */
826
         TRUE,                  /* partial_inplace */
827
         0xffff,                /* src_mask */
828
         0xffff,                /* dst_mask */
829
         FALSE),                /* pcrel_offset */
830
 
831
  EMPTY_HOWTO (7),
832
 
833
  /* Non modifiable absolute branch.  */
834
  HOWTO (R_BA,                  /* type */
835
         0,                      /* rightshift */
836
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
837
         26,                    /* bitsize */
838
         FALSE,                 /* pc_relative */
839
         0,                      /* bitpos */
840
         complain_overflow_bitfield, /* complain_on_overflow */
841
         0,                      /* special_function */
842
         "R_BA_26",             /* name */
843
         TRUE,                  /* partial_inplace */
844
         0x03fffffc,            /* src_mask */
845
         0x03fffffc,            /* dst_mask */
846
         FALSE),                /* pcrel_offset */
847
 
848
  EMPTY_HOWTO (9),
849
 
850
  /* Non modifiable relative branch.  */
851
  HOWTO (R_BR,                  /* type */
852
         0,                      /* rightshift */
853
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
854
         26,                    /* bitsize */
855
         TRUE,                  /* pc_relative */
856
         0,                      /* bitpos */
857
         complain_overflow_signed, /* complain_on_overflow */
858
         0,                      /* special_function */
859
         "R_BR",                /* name */
860
         TRUE,                  /* partial_inplace */
861
         0x03fffffc,            /* src_mask */
862
         0x03fffffc,            /* dst_mask */
863
         FALSE),                /* pcrel_offset */
864
 
865
  EMPTY_HOWTO (0xb),
866
 
867
  /* Indirect load.  */
868
  HOWTO (R_RL,                  /* type */
869
         0,                      /* rightshift */
870
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
871
         16,                    /* bitsize */
872
         FALSE,                 /* pc_relative */
873
         0,                      /* bitpos */
874
         complain_overflow_bitfield, /* complain_on_overflow */
875
         0,                      /* special_function */
876
         "R_RL",                /* name */
877
         TRUE,                  /* partial_inplace */
878
         0xffff,                /* src_mask */
879
         0xffff,                /* dst_mask */
880
         FALSE),                /* pcrel_offset */
881
 
882
  /* Load address.  */
883
  HOWTO (R_RLA,                 /* type */
884
         0,                      /* rightshift */
885
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
886
         16,                    /* bitsize */
887
         FALSE,                 /* pc_relative */
888
         0,                      /* bitpos */
889
         complain_overflow_bitfield, /* complain_on_overflow */
890
         0,                      /* special_function */
891
         "R_RLA",               /* name */
892
         TRUE,                  /* partial_inplace */
893
         0xffff,                /* src_mask */
894
         0xffff,                /* dst_mask */
895
         FALSE),                /* pcrel_offset */
896
 
897
  EMPTY_HOWTO (0xe),
898
 
899 225 jeremybenn
  /* Non-relocating reference.  Bitsize is 1 so that r_rsize is 0.  */
900 24 jeremybenn
  HOWTO (R_REF,                 /* type */
901
         0,                      /* rightshift */
902 225 jeremybenn
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
903
         1,                     /* bitsize */
904 24 jeremybenn
         FALSE,                 /* pc_relative */
905
         0,                      /* bitpos */
906
         complain_overflow_dont, /* complain_on_overflow */
907
         0,                      /* special_function */
908
         "R_REF",               /* name */
909
         FALSE,                 /* partial_inplace */
910
         0,                      /* src_mask */
911
         0,                      /* dst_mask */
912
         FALSE),                /* pcrel_offset */
913
 
914
  EMPTY_HOWTO (0x10),
915
  EMPTY_HOWTO (0x11),
916
 
917
  /* TOC relative indirect load.  */
918
  HOWTO (R_TRL,                 /* type */
919
         0,                      /* rightshift */
920
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
921
         16,                    /* bitsize */
922
         FALSE,                 /* pc_relative */
923
         0,                      /* bitpos */
924
         complain_overflow_bitfield, /* complain_on_overflow */
925
         0,                      /* special_function */
926
         "R_TRL",               /* name */
927
         TRUE,                  /* partial_inplace */
928
         0xffff,                /* src_mask */
929
         0xffff,                /* dst_mask */
930
         FALSE),                /* pcrel_offset */
931
 
932
  /* TOC relative load address.  */
933
  HOWTO (R_TRLA,                /* type */
934
         0,                      /* rightshift */
935
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
936
         16,                    /* bitsize */
937
         FALSE,                 /* pc_relative */
938
         0,                      /* bitpos */
939
         complain_overflow_bitfield, /* complain_on_overflow */
940
         0,                      /* special_function */
941
         "R_TRLA",              /* name */
942
         TRUE,                  /* partial_inplace */
943
         0xffff,                /* src_mask */
944
         0xffff,                /* dst_mask */
945
         FALSE),                /* pcrel_offset */
946
 
947
  /* Modifiable relative branch.  */
948
  HOWTO (R_RRTBI,                /* type */
949
         1,                     /* rightshift */
950
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
951
         32,                    /* bitsize */
952
         FALSE,                 /* pc_relative */
953
         0,                      /* bitpos */
954
         complain_overflow_bitfield, /* complain_on_overflow */
955
         0,                      /* special_function */
956
         "R_RRTBI",             /* name */
957
         TRUE,                  /* partial_inplace */
958
         0xffffffff,            /* src_mask */
959
         0xffffffff,            /* dst_mask */
960
         FALSE),                /* pcrel_offset */
961
 
962
  /* Modifiable absolute branch.  */
963
  HOWTO (R_RRTBA,                /* type */
964
         1,                     /* rightshift */
965
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
966
         32,                    /* bitsize */
967
         FALSE,                 /* pc_relative */
968
         0,                      /* bitpos */
969
         complain_overflow_bitfield, /* complain_on_overflow */
970
         0,                      /* special_function */
971
         "R_RRTBA",             /* name */
972
         TRUE,                  /* partial_inplace */
973
         0xffffffff,            /* src_mask */
974
         0xffffffff,            /* dst_mask */
975
         FALSE),                /* pcrel_offset */
976
 
977
  /* Modifiable call absolute indirect.  */
978
  HOWTO (R_CAI,                 /* type */
979
         0,                      /* rightshift */
980
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
981
         16,                    /* bitsize */
982
         FALSE,                 /* pc_relative */
983
         0,                      /* bitpos */
984
         complain_overflow_bitfield, /* complain_on_overflow */
985
         0,                      /* special_function */
986
         "R_CAI",               /* name */
987
         TRUE,                  /* partial_inplace */
988
         0xffff,                /* src_mask */
989
         0xffff,                /* dst_mask */
990
         FALSE),                /* pcrel_offset */
991
 
992
  /* Modifiable call relative.  */
993
  HOWTO (R_CREL,                /* type */
994
         0,                      /* rightshift */
995
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
996
         16,                    /* bitsize */
997
         FALSE,                 /* pc_relative */
998
         0,                      /* bitpos */
999
         complain_overflow_bitfield, /* complain_on_overflow */
1000
         0,                      /* special_function */
1001
         "R_CREL",              /* name */
1002
         TRUE,                  /* partial_inplace */
1003
         0xffff,                /* src_mask */
1004
         0xffff,                /* dst_mask */
1005
         FALSE),                /* pcrel_offset */
1006
 
1007
  /* Modifiable branch absolute.  */
1008
  HOWTO (R_RBA,                 /* type */
1009
         0,                      /* rightshift */
1010
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1011
         26,                    /* bitsize */
1012
         FALSE,                 /* pc_relative */
1013
         0,                      /* bitpos */
1014
         complain_overflow_bitfield, /* complain_on_overflow */
1015
         0,                      /* special_function */
1016
         "R_RBA",               /* name */
1017
         TRUE,                  /* partial_inplace */
1018
         0x03fffffc,            /* src_mask */
1019
         0x03fffffc,            /* dst_mask */
1020
         FALSE),                /* pcrel_offset */
1021
 
1022
  /* Modifiable branch absolute.  */
1023
  HOWTO (R_RBAC,                /* type */
1024
         0,                      /* rightshift */
1025
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1026
         32,                    /* bitsize */
1027
         FALSE,                 /* pc_relative */
1028
         0,                      /* bitpos */
1029
         complain_overflow_bitfield, /* complain_on_overflow */
1030
         0,                      /* special_function */
1031
         "R_RBAC",              /* name */
1032
         TRUE,                  /* partial_inplace */
1033
         0xffffffff,            /* src_mask */
1034
         0xffffffff,            /* dst_mask */
1035
         FALSE),                /* pcrel_offset */
1036
 
1037
  /* Modifiable branch relative.  */
1038
  HOWTO (R_RBR,                 /* type */
1039
         0,                      /* rightshift */
1040
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1041
         26,                    /* bitsize */
1042
         FALSE,                 /* pc_relative */
1043
         0,                      /* bitpos */
1044
         complain_overflow_signed, /* complain_on_overflow */
1045
         0,                      /* special_function */
1046
         "R_RBR_26",            /* name */
1047
         TRUE,                  /* partial_inplace */
1048
         0x03fffffc,            /* src_mask */
1049
         0x03fffffc,            /* dst_mask */
1050
         FALSE),                /* pcrel_offset */
1051
 
1052
  /* Modifiable branch absolute.  */
1053
  HOWTO (R_RBRC,                /* type */
1054
         0,                      /* rightshift */
1055
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
1056
         16,                    /* bitsize */
1057
         FALSE,                 /* pc_relative */
1058
         0,                      /* bitpos */
1059
         complain_overflow_bitfield, /* complain_on_overflow */
1060
         0,                      /* special_function */
1061
         "R_RBRC",              /* name */
1062
         TRUE,                  /* partial_inplace */
1063
         0xffff,                /* src_mask */
1064
         0xffff,                /* dst_mask */
1065
         FALSE),                /* pcrel_offset */
1066
 
1067
  /* 16 bit Non modifiable absolute branch.  */
1068
  HOWTO (R_BA,                  /* type */
1069
         0,                      /* rightshift */
1070
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
1071
         16,                    /* bitsize */
1072
         FALSE,                 /* pc_relative */
1073
         0,                      /* bitpos */
1074
         complain_overflow_bitfield, /* complain_on_overflow */
1075
         0,                      /* special_function */
1076
         "R_BA_16",             /* name */
1077
         TRUE,                  /* partial_inplace */
1078
         0xfffc,                /* src_mask */
1079
         0xfffc,                /* dst_mask */
1080
         FALSE),                /* pcrel_offset */
1081
 
1082
  /* Modifiable branch relative.  */
1083
  HOWTO (R_RBR,                 /* type */
1084
         0,                      /* rightshift */
1085
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
1086
         16,                    /* bitsize */
1087
         FALSE,                 /* pc_relative */
1088
         0,                      /* bitpos */
1089
         complain_overflow_signed, /* complain_on_overflow */
1090
         0,                      /* special_function */
1091
         "R_RBR_16",            /* name */
1092
         TRUE,                  /* partial_inplace */
1093
         0xffff,                /* src_mask */
1094
         0xffff,                /* dst_mask */
1095
         FALSE),                /* pcrel_offset */
1096
 
1097
  /* Modifiable branch relative.  */
1098
  HOWTO (R_RBA,                 /* type */
1099
         0,                      /* rightshift */
1100
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
1101
         16,                    /* bitsize */
1102
         FALSE,                 /* pc_relative */
1103
         0,                      /* bitpos */
1104
         complain_overflow_signed, /* complain_on_overflow */
1105
         0,                      /* special_function */
1106
         "R_RBA_16",            /* name */
1107
         TRUE,                  /* partial_inplace */
1108
         0xffff,                /* src_mask */
1109
         0xffff,                /* dst_mask */
1110
         FALSE),                /* pcrel_offset */
1111
 
1112
};
1113
 
1114
void
1115
xcoff_rtype2howto (relent, internal)
1116
     arelent *relent;
1117
     struct internal_reloc *internal;
1118
{
1119
  if (internal->r_type > R_RBRC)
1120
    abort ();
1121
 
1122
  /* Default howto layout works most of the time */
1123
  relent->howto = &xcoff_howto_table[internal->r_type];
1124
 
1125
  /* Special case some 16 bit reloc */
1126
  if (15 == (internal->r_size & 0x1f))
1127
    {
1128
      if (R_BA == internal->r_type)
1129
        relent->howto = &xcoff_howto_table[0x1c];
1130
      else if (R_RBR == internal->r_type)
1131
        relent->howto = &xcoff_howto_table[0x1d];
1132
      else if (R_RBA == internal->r_type)
1133
        relent->howto = &xcoff_howto_table[0x1e];
1134
    }
1135
 
1136
  /* The r_size field of an XCOFF reloc encodes the bitsize of the
1137
     relocation, as well as indicating whether it is signed or not.
1138
     Doublecheck that the relocation information gathered from the
1139
     type matches this information.  The bitsize is not significant
1140
     for R_REF relocs.  */
1141
  if (relent->howto->dst_mask != 0
1142
      && (relent->howto->bitsize
1143
          != ((unsigned int) internal->r_size & 0x1f) + 1))
1144
    abort ();
1145
}
1146
 
1147
reloc_howto_type *
1148
_bfd_xcoff_reloc_type_lookup (abfd, code)
1149
     bfd *abfd ATTRIBUTE_UNUSED;
1150
     bfd_reloc_code_real_type code;
1151
{
1152
  switch (code)
1153
    {
1154
    case BFD_RELOC_PPC_B26:
1155
      return &xcoff_howto_table[0xa];
1156
    case BFD_RELOC_PPC_BA16:
1157
      return &xcoff_howto_table[0x1c];
1158
    case BFD_RELOC_PPC_BA26:
1159
      return &xcoff_howto_table[8];
1160
    case BFD_RELOC_PPC_TOC16:
1161
      return &xcoff_howto_table[3];
1162
    case BFD_RELOC_32:
1163
    case BFD_RELOC_CTOR:
1164
      return &xcoff_howto_table[0];
1165 225 jeremybenn
    case BFD_RELOC_NONE:
1166
      return &xcoff_howto_table[0xf];
1167 24 jeremybenn
    default:
1168
      return NULL;
1169
    }
1170
}
1171
 
1172
static reloc_howto_type *
1173
_bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1174
                              const char *r_name)
1175
{
1176
  unsigned int i;
1177
 
1178
  for (i = 0;
1179
       i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]);
1180
       i++)
1181
    if (xcoff_howto_table[i].name != NULL
1182
        && strcasecmp (xcoff_howto_table[i].name, r_name) == 0)
1183
      return &xcoff_howto_table[i];
1184
 
1185
  return NULL;
1186
}
1187
 
1188
/* XCOFF archive support.  The original version of this code was by
1189
   Damon A. Permezel.  It was enhanced to permit cross support, and
1190
   writing archive files, by Ian Lance Taylor, Cygnus Support.
1191
 
1192
   XCOFF uses its own archive format.  Everything is hooked together
1193
   with file offset links, so it is possible to rapidly update an
1194
   archive in place.  Of course, we don't do that.  An XCOFF archive
1195
   has a real file header, not just an ARMAG string.  The structure of
1196
   the file header and of each archive header appear below.
1197
 
1198
   An XCOFF archive also has a member table, which is a list of
1199
   elements in the archive (you can get that by looking through the
1200
   linked list, but you have to read a lot more of the file).  The
1201
   member table has a normal archive header with an empty name.  It is
1202
   normally (and perhaps must be) the second to last entry in the
1203
   archive.  The member table data is almost printable ASCII.  It
1204
   starts with a 12 character decimal string which is the number of
1205
   entries in the table.  For each entry it has a 12 character decimal
1206
   string which is the offset in the archive of that member.  These
1207
   entries are followed by a series of null terminated strings which
1208
   are the member names for each entry.
1209
 
1210
   Finally, an XCOFF archive has a global symbol table, which is what
1211
   we call the armap.  The global symbol table has a normal archive
1212
   header with an empty name.  It is normally (and perhaps must be)
1213
   the last entry in the archive.  The contents start with a four byte
1214
   binary number which is the number of entries.  This is followed by
1215
   a that many four byte binary numbers; each is the file offset of an
1216
   entry in the archive.  These numbers are followed by a series of
1217
   null terminated strings, which are symbol names.
1218
 
1219
   AIX 4.3 introduced a new archive format which can handle larger
1220
   files and also 32- and 64-bit objects in the same archive.  The
1221
   things said above remain true except that there is now more than
1222
   one global symbol table.  The one is used to index 32-bit objects,
1223
   the other for 64-bit objects.
1224
 
1225
   The new archives (recognizable by the new ARMAG string) has larger
1226
   field lengths so that we cannot really share any code.  Also we have
1227
   to take care that we are not generating the new form of archives
1228
   on AIX 4.2 or earlier systems.  */
1229
 
1230
/* XCOFF archives use this as a magic string.  Note that both strings
1231
   have the same length.  */
1232
 
1233
/* Set the magic for archive.  */
1234
 
1235
bfd_boolean
1236
bfd_xcoff_ar_archive_set_magic (abfd, magic)
1237
     bfd *abfd ATTRIBUTE_UNUSED;
1238
     char *magic ATTRIBUTE_UNUSED;
1239
{
1240
  /* Not supported yet.  */
1241
  return FALSE;
1242
 /* bfd_xcoff_archive_set_magic (abfd, magic); */
1243
}
1244
 
1245
/* Read in the armap of an XCOFF archive.  */
1246
 
1247
bfd_boolean
1248
_bfd_xcoff_slurp_armap (abfd)
1249
     bfd *abfd;
1250
{
1251
  file_ptr off;
1252
  size_t namlen;
1253
  bfd_size_type sz;
1254
  bfd_byte *contents, *cend;
1255
  bfd_vma c, i;
1256
  carsym *arsym;
1257
  bfd_byte *p;
1258
 
1259
  if (xcoff_ardata (abfd) == NULL)
1260
    {
1261
      bfd_has_map (abfd) = FALSE;
1262
      return TRUE;
1263
    }
1264
 
1265
  if (! xcoff_big_format_p (abfd))
1266
    {
1267
      /* This is for the old format.  */
1268
      struct xcoff_ar_hdr hdr;
1269
 
1270
      off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
1271
      if (off == 0)
1272
        {
1273
          bfd_has_map (abfd) = FALSE;
1274
          return TRUE;
1275
        }
1276
 
1277
      if (bfd_seek (abfd, off, SEEK_SET) != 0)
1278
        return FALSE;
1279
 
1280
      /* The symbol table starts with a normal archive header.  */
1281
      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1282
          != SIZEOF_AR_HDR)
1283
        return FALSE;
1284
 
1285
      /* Skip the name (normally empty).  */
1286
      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1287
      off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1288
      if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1289
        return FALSE;
1290
 
1291
      sz = strtol (hdr.size, (char **) NULL, 10);
1292
 
1293
      /* Read in the entire symbol table.  */
1294
      contents = (bfd_byte *) bfd_alloc (abfd, sz);
1295
      if (contents == NULL)
1296
        return FALSE;
1297
      if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1298
        return FALSE;
1299
 
1300
      /* The symbol table starts with a four byte count.  */
1301
      c = H_GET_32 (abfd, contents);
1302
 
1303
      if (c * 4 >= sz)
1304
        {
1305
          bfd_set_error (bfd_error_bad_value);
1306
          return FALSE;
1307
        }
1308
 
1309
      bfd_ardata (abfd)->symdefs =
1310
        ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1311
      if (bfd_ardata (abfd)->symdefs == NULL)
1312
        return FALSE;
1313
 
1314
      /* After the count comes a list of four byte file offsets.  */
1315
      for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
1316
           i < c;
1317
           ++i, ++arsym, p += 4)
1318
        arsym->file_offset = H_GET_32 (abfd, p);
1319
    }
1320
  else
1321
    {
1322
      /* This is for the new format.  */
1323
      struct xcoff_ar_hdr_big hdr;
1324
 
1325
      off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
1326
      if (off == 0)
1327
        {
1328
          bfd_has_map (abfd) = FALSE;
1329
          return TRUE;
1330
        }
1331
 
1332
      if (bfd_seek (abfd, off, SEEK_SET) != 0)
1333
        return FALSE;
1334
 
1335
      /* The symbol table starts with a normal archive header.  */
1336
      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1337
          != SIZEOF_AR_HDR_BIG)
1338
        return FALSE;
1339
 
1340
      /* Skip the name (normally empty).  */
1341
      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1342
      off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
1343
      if (bfd_seek (abfd, off, SEEK_CUR) != 0)
1344
        return FALSE;
1345
 
1346
      /* XXX This actually has to be a call to strtoll (at least on 32-bit
1347
         machines) since the field width is 20 and there numbers with more
1348
         than 32 bits can be represented.  */
1349
      sz = strtol (hdr.size, (char **) NULL, 10);
1350
 
1351
      /* Read in the entire symbol table.  */
1352
      contents = (bfd_byte *) bfd_alloc (abfd, sz);
1353
      if (contents == NULL)
1354
        return FALSE;
1355
      if (bfd_bread ((PTR) contents, sz, abfd) != sz)
1356
        return FALSE;
1357
 
1358
      /* The symbol table starts with an eight byte count.  */
1359
      c = H_GET_64 (abfd, contents);
1360
 
1361
      if (c * 8 >= sz)
1362
        {
1363
          bfd_set_error (bfd_error_bad_value);
1364
          return FALSE;
1365
        }
1366
 
1367
      bfd_ardata (abfd)->symdefs =
1368
        ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
1369
      if (bfd_ardata (abfd)->symdefs == NULL)
1370
        return FALSE;
1371
 
1372
      /* After the count comes a list of eight byte file offsets.  */
1373
      for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1374
           i < c;
1375
           ++i, ++arsym, p += 8)
1376
        arsym->file_offset = H_GET_64 (abfd, p);
1377
    }
1378
 
1379
  /* After the file offsets come null terminated symbol names.  */
1380
  cend = contents + sz;
1381
  for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1382
       i < c;
1383
       ++i, ++arsym, p += strlen ((char *) p) + 1)
1384
    {
1385
      if (p >= cend)
1386
        {
1387
          bfd_set_error (bfd_error_bad_value);
1388
          return FALSE;
1389
        }
1390
      arsym->name = (char *) p;
1391
    }
1392
 
1393
  bfd_ardata (abfd)->symdef_count = c;
1394
  bfd_has_map (abfd) = TRUE;
1395
 
1396
  return TRUE;
1397
}
1398
 
1399
/* See if this is an XCOFF archive.  */
1400
 
1401
const bfd_target *
1402
_bfd_xcoff_archive_p (abfd)
1403
     bfd *abfd;
1404
{
1405
  struct artdata *tdata_hold;
1406
  char magic[SXCOFFARMAG];
1407
  bfd_size_type amt = SXCOFFARMAG;
1408
 
1409
  if (bfd_bread ((PTR) magic, amt, abfd) != amt)
1410
    {
1411
      if (bfd_get_error () != bfd_error_system_call)
1412
        bfd_set_error (bfd_error_wrong_format);
1413
      return NULL;
1414
    }
1415
 
1416
  if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
1417
      && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
1418
    {
1419
      bfd_set_error (bfd_error_wrong_format);
1420
      return NULL;
1421
    }
1422
 
1423
  tdata_hold = bfd_ardata (abfd);
1424
 
1425
  amt = sizeof (struct artdata);
1426
  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
1427
  if (bfd_ardata (abfd) == (struct artdata *) NULL)
1428
    goto error_ret_restore;
1429
 
1430
  /* Cleared by bfd_zalloc above.
1431
     bfd_ardata (abfd)->cache = NULL;
1432
     bfd_ardata (abfd)->archive_head = NULL;
1433
     bfd_ardata (abfd)->symdefs = NULL;
1434
     bfd_ardata (abfd)->extended_names = NULL;
1435
     bfd_ardata (abfd)->extended_names_size = 0;  */
1436
 
1437
  /* Now handle the two formats.  */
1438
  if (magic[1] != 'b')
1439
    {
1440
      /* This is the old format.  */
1441
      struct xcoff_ar_file_hdr hdr;
1442
 
1443
      /* Copy over the magic string.  */
1444
      memcpy (hdr.magic, magic, SXCOFFARMAG);
1445
 
1446
      /* Now read the rest of the file header.  */
1447
      amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
1448
      if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1449
        {
1450
          if (bfd_get_error () != bfd_error_system_call)
1451
            bfd_set_error (bfd_error_wrong_format);
1452
          goto error_ret;
1453
        }
1454
 
1455
      bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1456
                                                      (char **) NULL, 10);
1457
 
1458
      amt = SIZEOF_AR_FILE_HDR;
1459
      bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1460
      if (bfd_ardata (abfd)->tdata == NULL)
1461
        goto error_ret;
1462
 
1463
      memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
1464
    }
1465
  else
1466
    {
1467
      /* This is the new format.  */
1468
      struct xcoff_ar_file_hdr_big hdr;
1469
 
1470
      /* Copy over the magic string.  */
1471
      memcpy (hdr.magic, magic, SXCOFFARMAG);
1472
 
1473
      /* Now read the rest of the file header.  */
1474
      amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
1475
      if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
1476
        {
1477
          if (bfd_get_error () != bfd_error_system_call)
1478
            bfd_set_error (bfd_error_wrong_format);
1479
          goto error_ret;
1480
        }
1481
 
1482
      bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
1483
                                                            (const char **) 0,
1484
                                                            10);
1485
 
1486
      amt = SIZEOF_AR_FILE_HDR_BIG;
1487
      bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
1488
      if (bfd_ardata (abfd)->tdata == NULL)
1489
        goto error_ret;
1490
 
1491
      memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1492
    }
1493
 
1494
  if (! _bfd_xcoff_slurp_armap (abfd))
1495
    {
1496
    error_ret:
1497
      bfd_release (abfd, bfd_ardata (abfd));
1498
    error_ret_restore:
1499
      bfd_ardata (abfd) = tdata_hold;
1500
      return NULL;
1501
    }
1502
 
1503
  return abfd->xvec;
1504
}
1505
 
1506
/* Read the archive header in an XCOFF archive.  */
1507
 
1508
PTR
1509
_bfd_xcoff_read_ar_hdr (abfd)
1510
     bfd *abfd;
1511
{
1512
  bfd_size_type namlen;
1513
  struct areltdata *ret;
1514
  bfd_size_type amt = sizeof (struct areltdata);
1515
 
1516
  ret = (struct areltdata *) bfd_alloc (abfd, amt);
1517
  if (ret == NULL)
1518
    return NULL;
1519
 
1520
  if (! xcoff_big_format_p (abfd))
1521
    {
1522
      struct xcoff_ar_hdr hdr;
1523
      struct xcoff_ar_hdr *hdrp;
1524
 
1525
      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1526
          != SIZEOF_AR_HDR)
1527
        {
1528
          free (ret);
1529
          return NULL;
1530
        }
1531
 
1532
      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1533
      amt = SIZEOF_AR_HDR + namlen + 1;
1534
      hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
1535
      if (hdrp == NULL)
1536
        {
1537
          free (ret);
1538
          return NULL;
1539
        }
1540
      memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
1541
      if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
1542
        {
1543
          free (ret);
1544
          return NULL;
1545
        }
1546
      ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
1547
 
1548
      ret->arch_header = (char *) hdrp;
1549
      ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1550
      ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
1551
    }
1552
  else
1553
    {
1554
      struct xcoff_ar_hdr_big hdr;
1555
      struct xcoff_ar_hdr_big *hdrp;
1556
 
1557
      if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1558
          != SIZEOF_AR_HDR_BIG)
1559
        {
1560
          free (ret);
1561
          return NULL;
1562
        }
1563
 
1564
      namlen = strtol (hdr.namlen, (char **) NULL, 10);
1565
      amt = SIZEOF_AR_HDR_BIG + namlen + 1;
1566
      hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
1567
      if (hdrp == NULL)
1568
        {
1569
          free (ret);
1570
          return NULL;
1571
        }
1572
      memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
1573
      if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
1574
        {
1575
          free (ret);
1576
          return NULL;
1577
        }
1578
      ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
1579
 
1580
      ret->arch_header = (char *) hdrp;
1581
      /* XXX This actually has to be a call to strtoll (at least on 32-bit
1582
         machines) since the field width is 20 and there numbers with more
1583
         than 32 bits can be represented.  */
1584
      ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1585
      ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
1586
    }
1587
 
1588
  /* Skip over the XCOFFARFMAG at the end of the file name.  */
1589
  if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
1590
    return NULL;
1591
 
1592
  return (PTR) ret;
1593
}
1594
 
1595
/* Open the next element in an XCOFF archive.  */
1596
 
1597
bfd *
1598
_bfd_xcoff_openr_next_archived_file (archive, last_file)
1599
     bfd *archive;
1600
     bfd *last_file;
1601
{
1602
  file_ptr filestart;
1603
 
1604
  if (xcoff_ardata (archive) == NULL)
1605
    {
1606
      bfd_set_error (bfd_error_invalid_operation);
1607
      return NULL;
1608
    }
1609
 
1610
  if (! xcoff_big_format_p (archive))
1611
    {
1612
      if (last_file == NULL)
1613
        filestart = bfd_ardata (archive)->first_file_filepos;
1614
      else
1615
        filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
1616
                            10);
1617
 
1618
      if (filestart == 0
1619
          || filestart == strtol (xcoff_ardata (archive)->memoff,
1620
                                  (char **) NULL, 10)
1621
          || filestart == strtol (xcoff_ardata (archive)->symoff,
1622
                                  (char **) NULL, 10))
1623
        {
1624
          bfd_set_error (bfd_error_no_more_archived_files);
1625
          return NULL;
1626
        }
1627
    }
1628
  else
1629
    {
1630
      if (last_file == NULL)
1631
        filestart = bfd_ardata (archive)->first_file_filepos;
1632
      else
1633
        /* XXX These actually have to be a calls to strtoll (at least
1634
           on 32-bit machines) since the fields's width is 20 and
1635
           there numbers with more than 32 bits can be represented.  */
1636
        filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
1637
                            10);
1638
 
1639
      /* XXX These actually have to be calls to strtoll (at least on 32-bit
1640
         machines) since the fields's width is 20 and there numbers with more
1641
         than 32 bits can be represented.  */
1642
      if (filestart == 0
1643
          || filestart == strtol (xcoff_ardata_big (archive)->memoff,
1644
                                  (char **) NULL, 10)
1645
          || filestart == strtol (xcoff_ardata_big (archive)->symoff,
1646
                                  (char **) NULL, 10))
1647
        {
1648
          bfd_set_error (bfd_error_no_more_archived_files);
1649
          return NULL;
1650
        }
1651
    }
1652
 
1653
  return _bfd_get_elt_at_filepos (archive, filestart);
1654
}
1655
 
1656
/* Stat an element in an XCOFF archive.  */
1657
 
1658
int
1659
_bfd_xcoff_stat_arch_elt (abfd, s)
1660
     bfd *abfd;
1661
     struct stat *s;
1662
{
1663
  if (abfd->arelt_data == NULL)
1664
    {
1665
      bfd_set_error (bfd_error_invalid_operation);
1666
      return -1;
1667
    }
1668
 
1669
  if (! xcoff_big_format_p (abfd->my_archive))
1670
    {
1671
      struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
1672
 
1673
      s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1674
      s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1675
      s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1676
      s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1677
      s->st_size = arch_eltdata (abfd)->parsed_size;
1678
    }
1679
  else
1680
    {
1681
      struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
1682
 
1683
      s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1684
      s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1685
      s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1686
      s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1687
      s->st_size = arch_eltdata (abfd)->parsed_size;
1688
    }
1689
 
1690
  return 0;
1691
}
1692
 
1693
/* Normalize a file name for inclusion in an archive.  */
1694
 
1695
static const char *
1696
normalize_filename (abfd)
1697
     bfd *abfd;
1698
{
1699
  const char *file;
1700
  const char *filename;
1701
 
1702
  file = bfd_get_filename (abfd);
1703
  filename = strrchr (file, '/');
1704
  if (filename != NULL)
1705
    filename++;
1706
  else
1707
    filename = file;
1708
  return filename;
1709
}
1710
 
1711
/* Write out an XCOFF armap.  */
1712
 
1713
static bfd_boolean
1714
xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
1715
     bfd *abfd;
1716
     unsigned int elength ATTRIBUTE_UNUSED;
1717
     struct orl *map;
1718
     unsigned int orl_count;
1719
     int stridx;
1720
{
1721 225 jeremybenn
  struct archive_iterator iterator;
1722 24 jeremybenn
  struct xcoff_ar_hdr hdr;
1723
  char *p;
1724
  unsigned char buf[4];
1725
  unsigned int i;
1726
 
1727
  memset (&hdr, 0, sizeof hdr);
1728
  sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
1729
  sprintf (hdr.nextoff, "%d", 0);
1730
  memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
1731
  sprintf (hdr.date, "%d", 0);
1732
  sprintf (hdr.uid, "%d", 0);
1733
  sprintf (hdr.gid, "%d", 0);
1734
  sprintf (hdr.mode, "%d", 0);
1735
  sprintf (hdr.namlen, "%d", 0);
1736
 
1737
  /* We need spaces, not null bytes, in the header.  */
1738
  for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
1739
    if (*p == '\0')
1740
      *p = ' ';
1741
 
1742
  if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
1743
      != SIZEOF_AR_HDR
1744
      || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
1745
          != SXCOFFARFMAG))
1746
    return FALSE;
1747
 
1748
  H_PUT_32 (abfd, orl_count, buf);
1749
  if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1750
    return FALSE;
1751
 
1752
  i = 0;
1753 225 jeremybenn
  archive_iterator_begin (&iterator, abfd);
1754
  while (i < orl_count && archive_iterator_next (&iterator))
1755
    while (map[i].u.abfd == iterator.current.member)
1756
      {
1757
        H_PUT_32 (abfd, iterator.current.offset, buf);
1758
        if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1759
          return FALSE;
1760
        ++i;
1761
      }
1762 24 jeremybenn
 
1763
  for (i = 0; i < orl_count; i++)
1764
    {
1765
      const char *name;
1766
      size_t namlen;
1767
 
1768
      name = *map[i].name;
1769
      namlen = strlen (name);
1770
      if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
1771
        return FALSE;
1772
    }
1773
 
1774
  if ((stridx & 1) != 0)
1775
    {
1776
      char b;
1777
 
1778
      b = '\0';
1779
      if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1780
        return FALSE;
1781
    }
1782
 
1783
  return TRUE;
1784
}
1785
 
1786
static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
1787
#define FMT20  "%-20lld"
1788
#define FMT12  "%-12d"
1789
#define FMT12_OCTAL  "%-12o"
1790
#define FMT4  "%-4d"
1791
#define PRINT20(d, v) \
1792
  sprintf (buff20, FMT20, (long long)(v)), \
1793
  memcpy ((void *) (d), buff20, 20)
1794
 
1795
#define PRINT12(d, v) \
1796
  sprintf (buff20, FMT12, (int)(v)), \
1797
  memcpy ((void *) (d), buff20, 12)
1798
 
1799
#define PRINT12_OCTAL(d, v) \
1800
  sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
1801
  memcpy ((void *) (d), buff20, 12)
1802
 
1803
#define PRINT4(d, v) \
1804
  sprintf (buff20, FMT4, (int)(v)), \
1805
  memcpy ((void *) (d), buff20, 4)
1806
 
1807
#define READ20(d, v) \
1808
  buff20[20] = 0, \
1809
  memcpy (buff20, (d), 20), \
1810
  (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
1811
 
1812
static bfd_boolean
1813
do_pad (abfd, number)
1814
     bfd *abfd;
1815
     unsigned int number;
1816
{
1817
  bfd_byte b = 0;
1818
 
1819
  /* Limit pad to <= 4096.  */
1820
  if (number > 4096)
1821
    return FALSE;
1822
 
1823
  while (number--)
1824
    if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
1825
      return FALSE;
1826
 
1827
  return TRUE;
1828
}
1829
 
1830
static bfd_boolean
1831
do_copy (out_bfd, in_bfd)
1832
     bfd *out_bfd;
1833
     bfd *in_bfd;
1834
{
1835
  bfd_size_type remaining;
1836
  bfd_byte buffer[DEFAULT_BUFFERSIZE];
1837
 
1838
  if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
1839
    return FALSE;
1840
 
1841
  remaining = arelt_size (in_bfd);
1842
 
1843
  while (remaining >= DEFAULT_BUFFERSIZE)
1844
    {
1845
      if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
1846
          || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
1847
        return FALSE;
1848
 
1849
      remaining -= DEFAULT_BUFFERSIZE;
1850
    }
1851
 
1852
  if (remaining)
1853
    {
1854
      if (bfd_bread (buffer, remaining, in_bfd) != remaining
1855
          || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
1856
        return FALSE;
1857
    }
1858
 
1859
  return TRUE;
1860
}
1861
 
1862
static bfd_boolean
1863
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
1864
     bfd *abfd;
1865
     unsigned int elength ATTRIBUTE_UNUSED;
1866
     struct orl *map;
1867
     unsigned int orl_count;
1868
     int stridx;
1869
{
1870 225 jeremybenn
  struct archive_iterator iterator;
1871 24 jeremybenn
  struct xcoff_ar_file_hdr_big *fhdr;
1872
  bfd_vma i, sym_32, sym_64, str_32, str_64;
1873 225 jeremybenn
  const bfd_arch_info_type *arch_info;
1874 24 jeremybenn
  bfd *current_bfd;
1875
  size_t string_length;
1876
  file_ptr nextoff, prevoff;
1877
 
1878
  /* First, we look through the symbols and work out which are
1879
     from 32-bit objects and which from 64-bit ones.  */
1880
  sym_32 = sym_64 = str_32 = str_64 = 0;
1881
 
1882 225 jeremybenn
  i = 0;
1883
  for (current_bfd = abfd->archive_head;
1884
       current_bfd != NULL && i < orl_count;
1885
       current_bfd = current_bfd->archive_next)
1886 24 jeremybenn
    {
1887 225 jeremybenn
      arch_info = bfd_get_arch_info (current_bfd);
1888 24 jeremybenn
      while (map[i].u.abfd == current_bfd)
1889
        {
1890
          string_length = strlen (*map[i].name) + 1;
1891
          if (arch_info->bits_per_address == 64)
1892
            {
1893
              sym_64++;
1894
              str_64 += string_length;
1895
            }
1896
          else
1897
            {
1898
              sym_32++;
1899
              str_32 += string_length;
1900
            }
1901
          i++;
1902
        }
1903
    }
1904
 
1905
  /* A quick sanity check... */
1906
  BFD_ASSERT (sym_64 + sym_32 == orl_count);
1907
  /* Explicit cast to int for compiler.  */
1908
  BFD_ASSERT ((int)(str_64 + str_32) == stridx);
1909
 
1910
  fhdr = xcoff_ardata_big (abfd);
1911
 
1912
  /* xcoff_write_archive_contents_big passes nextoff in symoff. */
1913
  READ20 (fhdr->memoff, prevoff);
1914
  READ20 (fhdr->symoff, nextoff);
1915
 
1916
  BFD_ASSERT (nextoff == bfd_tell (abfd));
1917
 
1918
  /* Write out the symbol table.
1919
     Layout :
1920
 
1921
     standard big archive header
1922
     0x0000                   ar_size   [0x14]
1923
     0x0014                   ar_nxtmem [0x14]
1924
     0x0028                   ar_prvmem [0x14]
1925
     0x003C                   ar_date   [0x0C]
1926
     0x0048                   ar_uid    [0x0C]
1927
     0x0054                   ar_gid    [0x0C]
1928
     0x0060                   ar_mod    [0x0C]
1929
     0x006C                   ar_namelen[0x04]
1930
     0x0070                   ar_fmag   [SXCOFFARFMAG]
1931
 
1932
     Symbol table
1933
     0x0072                   num_syms  [0x08], binary
1934
     0x0078                   offsets   [0x08 * num_syms], binary
1935
     0x0086 + 0x08 * num_syms names     [??]
1936
     ??                       pad to even bytes.
1937
  */
1938
 
1939
  if (sym_32)
1940
    {
1941
      struct xcoff_ar_hdr_big *hdr;
1942
      char *symbol_table;
1943
      char *st;
1944
 
1945
      bfd_vma symbol_table_size =
1946
        SIZEOF_AR_HDR_BIG
1947
        + SXCOFFARFMAG
1948
        + 8
1949
        + 8 * sym_32
1950
        + str_32 + (str_32 & 1);
1951
 
1952
      symbol_table = bfd_zmalloc (symbol_table_size);
1953
      if (symbol_table == NULL)
1954
        return FALSE;
1955
 
1956
      hdr = (struct xcoff_ar_hdr_big *) symbol_table;
1957
 
1958
      PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
1959
 
1960
      if (sym_64)
1961
        PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
1962
      else
1963
        PRINT20 (hdr->nextoff, 0);
1964
 
1965
      PRINT20 (hdr->prevoff, prevoff);
1966
      PRINT12 (hdr->date, 0);
1967
      PRINT12 (hdr->uid, 0);
1968
      PRINT12 (hdr->gid, 0);
1969
      PRINT12 (hdr->mode, 0);
1970
      PRINT4 (hdr->namlen, 0) ;
1971
 
1972
      st = symbol_table + SIZEOF_AR_HDR_BIG;
1973
      memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
1974
      st += SXCOFFARFMAG;
1975
 
1976
      bfd_h_put_64 (abfd, sym_32, st);
1977
      st += 8;
1978
 
1979
      /* loop over the 32 bit offsets */
1980
      i = 0;
1981 225 jeremybenn
      archive_iterator_begin (&iterator, abfd);
1982
      while (i < orl_count && archive_iterator_next (&iterator))
1983 24 jeremybenn
        {
1984 225 jeremybenn
          arch_info = bfd_get_arch_info (iterator.current.member);
1985
          while (map[i].u.abfd == iterator.current.member)
1986 24 jeremybenn
            {
1987
              if (arch_info->bits_per_address == 32)
1988
                {
1989 225 jeremybenn
                  bfd_h_put_64 (abfd, iterator.current.offset, st);
1990 24 jeremybenn
                  st += 8;
1991
                }
1992
              i++;
1993
            }
1994
        }
1995
 
1996
      /* loop over the 32 bit symbol names */
1997
      i = 0;
1998 225 jeremybenn
      for (current_bfd = abfd->archive_head;
1999
           current_bfd != NULL && i < orl_count;
2000
           current_bfd = current_bfd->archive_next)
2001 24 jeremybenn
        {
2002 225 jeremybenn
          arch_info = bfd_get_arch_info (current_bfd);
2003 24 jeremybenn
          while (map[i].u.abfd == current_bfd)
2004
            {
2005
              if (arch_info->bits_per_address == 32)
2006
                {
2007
                  string_length = sprintf (st, "%s", *map[i].name);
2008
                  st += string_length + 1;
2009
                }
2010
              i++;
2011
            }
2012
        }
2013
 
2014
      bfd_bwrite (symbol_table, symbol_table_size, abfd);
2015
 
2016
      free (symbol_table);
2017
 
2018
      prevoff = nextoff;
2019
      nextoff = nextoff + symbol_table_size;
2020
    }
2021
  else
2022
    PRINT20 (fhdr->symoff, 0);
2023
 
2024
  if (sym_64)
2025
    {
2026
      struct xcoff_ar_hdr_big *hdr;
2027
      char *symbol_table;
2028
      char *st;
2029
 
2030
      bfd_vma symbol_table_size =
2031
        SIZEOF_AR_HDR_BIG
2032
        + SXCOFFARFMAG
2033
        + 8
2034
        + 8 * sym_64
2035
        + str_64 + (str_64 & 1);
2036
 
2037
      symbol_table = bfd_zmalloc (symbol_table_size);
2038
      if (symbol_table == NULL)
2039
        return FALSE;
2040
 
2041
      hdr = (struct xcoff_ar_hdr_big *) symbol_table;
2042
 
2043
      PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
2044
      PRINT20 (hdr->nextoff, 0);
2045
      PRINT20 (hdr->prevoff, prevoff);
2046
      PRINT12 (hdr->date, 0);
2047
      PRINT12 (hdr->uid, 0);
2048
      PRINT12 (hdr->gid, 0);
2049
      PRINT12 (hdr->mode, 0);
2050
      PRINT4 (hdr->namlen, 0);
2051
 
2052
      st = symbol_table + SIZEOF_AR_HDR_BIG;
2053
      memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
2054
      st += SXCOFFARFMAG;
2055
 
2056
      bfd_h_put_64 (abfd, sym_64, st);
2057
      st += 8;
2058
 
2059
      /* loop over the 64 bit offsets */
2060
      i = 0;
2061 225 jeremybenn
      archive_iterator_begin (&iterator, abfd);
2062
      while (i < orl_count && archive_iterator_next (&iterator))
2063 24 jeremybenn
        {
2064 225 jeremybenn
          arch_info = bfd_get_arch_info (iterator.current.member);
2065
          while (map[i].u.abfd == iterator.current.member)
2066 24 jeremybenn
            {
2067
              if (arch_info->bits_per_address == 64)
2068
                {
2069 225 jeremybenn
                  bfd_h_put_64 (abfd, iterator.current.offset, st);
2070 24 jeremybenn
                  st += 8;
2071
                }
2072
              i++;
2073
            }
2074
        }
2075
 
2076
      /* loop over the 64 bit symbol names */
2077
      i = 0;
2078 225 jeremybenn
      for (current_bfd = abfd->archive_head;
2079
           current_bfd != NULL && i < orl_count;
2080
           current_bfd = current_bfd->archive_next)
2081 24 jeremybenn
        {
2082 225 jeremybenn
          arch_info = bfd_get_arch_info (current_bfd);
2083 24 jeremybenn
          while (map[i].u.abfd == current_bfd)
2084
            {
2085
              if (arch_info->bits_per_address == 64)
2086
                {
2087
                  string_length = sprintf (st, "%s", *map[i].name);
2088
                  st += string_length + 1;
2089
                }
2090
              i++;
2091
            }
2092
        }
2093
 
2094
      bfd_bwrite (symbol_table, symbol_table_size, abfd);
2095
 
2096
      free (symbol_table);
2097
 
2098
      PRINT20 (fhdr->symoff64, nextoff);
2099
    }
2100
  else
2101
    PRINT20 (fhdr->symoff64, 0);
2102
 
2103
  return TRUE;
2104
}
2105
 
2106
bfd_boolean
2107
_bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
2108
     bfd *abfd;
2109
     unsigned int elength ATTRIBUTE_UNUSED;
2110
     struct orl *map;
2111
     unsigned int orl_count;
2112
     int stridx;
2113
{
2114
  if (! xcoff_big_format_p (abfd))
2115
    return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
2116
  else
2117
    return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
2118
}
2119
 
2120
/* Write out an XCOFF archive.  We always write an entire archive,
2121
   rather than fussing with the freelist and so forth.  */
2122
 
2123
static bfd_boolean
2124
xcoff_write_archive_contents_old (abfd)
2125
     bfd *abfd;
2126
{
2127 225 jeremybenn
  struct archive_iterator iterator;
2128 24 jeremybenn
  struct xcoff_ar_file_hdr fhdr;
2129
  bfd_size_type count;
2130
  bfd_size_type total_namlen;
2131
  file_ptr *offsets;
2132
  bfd_boolean makemap;
2133
  bfd_boolean hasobjects;
2134
  file_ptr prevoff, nextoff;
2135
  bfd *sub;
2136
  size_t i;
2137
  struct xcoff_ar_hdr ahdr;
2138
  bfd_size_type size;
2139
  char *p;
2140
  char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
2141
 
2142
  memset (&fhdr, 0, sizeof fhdr);
2143
  (void) strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
2144
  sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
2145
  sprintf (fhdr.freeoff, "%d", 0);
2146
 
2147
  count = 0;
2148
  total_namlen = 0;
2149
  for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
2150
    {
2151
      ++count;
2152
      total_namlen += strlen (normalize_filename (sub)) + 1;
2153 225 jeremybenn
      if (sub->arelt_data == NULL)
2154 24 jeremybenn
        {
2155 225 jeremybenn
          sub->arelt_data = bfd_zalloc (sub, sizeof (struct areltdata));
2156
          if (sub->arelt_data == NULL)
2157
            return FALSE;
2158 24 jeremybenn
        }
2159 225 jeremybenn
      if (arch_xhdr (sub) == NULL)
2160 24 jeremybenn
        {
2161 225 jeremybenn
          struct xcoff_ar_hdr *ahdrp;
2162 24 jeremybenn
          struct stat s;
2163
 
2164
          if (stat (bfd_get_filename (sub), &s) != 0)
2165
            {
2166
              bfd_set_error (bfd_error_system_call);
2167
              return FALSE;
2168
            }
2169
 
2170 225 jeremybenn
          ahdrp = bfd_zalloc (sub, sizeof (*ahdrp));
2171
          if (ahdrp == NULL)
2172
            return FALSE;
2173
 
2174 24 jeremybenn
          sprintf (ahdrp->size, "%ld", (long) s.st_size);
2175
          sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2176
          sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2177
          sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2178
          sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2179
 
2180 225 jeremybenn
          arch_eltdata (sub)->arch_header = (char *) ahdrp;
2181 24 jeremybenn
          arch_eltdata (sub)->parsed_size = s.st_size;
2182
        }
2183 225 jeremybenn
    }
2184
  offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2185
  if (offsets == NULL)
2186
    return FALSE;
2187 24 jeremybenn
 
2188 225 jeremybenn
  if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
2189
    return FALSE;
2190 24 jeremybenn
 
2191 225 jeremybenn
  makemap = bfd_has_map (abfd);
2192
  hasobjects = FALSE;
2193
  prevoff = 0;
2194
  for (archive_iterator_begin (&iterator, abfd), i = 0;
2195
       archive_iterator_next (&iterator);
2196
       i++)
2197
    {
2198
      bfd_size_type namlen;
2199
      struct xcoff_ar_hdr *ahdrp;
2200 24 jeremybenn
 
2201 225 jeremybenn
      if (makemap && ! hasobjects)
2202
        {
2203
          if (bfd_check_format (iterator.current.member, bfd_object))
2204
            hasobjects = TRUE;
2205
        }
2206 24 jeremybenn
 
2207 225 jeremybenn
      ahdrp = arch_xhdr (iterator.current.member);
2208
      sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2209
      sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen);
2210
      sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset);
2211 24 jeremybenn
 
2212
      /* We need spaces, not null bytes, in the header.  */
2213
      for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2214
        if (*p == '\0')
2215
          *p = ' ';
2216
 
2217 225 jeremybenn
      if (!do_pad (abfd, iterator.current.leading_padding))
2218 24 jeremybenn
        return FALSE;
2219
 
2220 225 jeremybenn
      BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
2221
      namlen = iterator.current.padded_namlen;
2222
      if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
2223
          || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
2224
          || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
2225
          || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
2226
          || !do_copy (abfd, iterator.current.member)
2227
          || !do_pad (abfd, iterator.current.trailing_padding))
2228 24 jeremybenn
        return FALSE;
2229
 
2230 225 jeremybenn
      offsets[i] = iterator.current.offset;
2231
      prevoff = iterator.current.offset;
2232 24 jeremybenn
    }
2233
 
2234
  sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2235
 
2236
  /* Write out the member table.  */
2237
 
2238 225 jeremybenn
  nextoff = iterator.next.offset;
2239 24 jeremybenn
  BFD_ASSERT (nextoff == bfd_tell (abfd));
2240
  sprintf (fhdr.memoff, "%ld", (long) nextoff);
2241
 
2242
  memset (&ahdr, 0, sizeof ahdr);
2243
  sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
2244
                                     + count * XCOFFARMAG_ELEMENT_SIZE
2245
                                     + total_namlen));
2246
  sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2247
  sprintf (ahdr.date, "%d", 0);
2248
  sprintf (ahdr.uid, "%d", 0);
2249
  sprintf (ahdr.gid, "%d", 0);
2250
  sprintf (ahdr.mode, "%d", 0);
2251
  sprintf (ahdr.namlen, "%d", 0);
2252
 
2253
  size = (SIZEOF_AR_HDR
2254
          + XCOFFARMAG_ELEMENT_SIZE
2255
          + count * XCOFFARMAG_ELEMENT_SIZE
2256
          + total_namlen
2257
          + SXCOFFARFMAG);
2258
 
2259
  prevoff = nextoff;
2260
  nextoff += size + (size & 1);
2261
 
2262
  if (makemap && hasobjects)
2263
    sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2264
  else
2265
    sprintf (ahdr.nextoff, "%d", 0);
2266
 
2267
  /* We need spaces, not null bytes, in the header.  */
2268
  for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2269
    if (*p == '\0')
2270
      *p = ' ';
2271
 
2272
  if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
2273
       != SIZEOF_AR_HDR)
2274
      || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
2275
          != SXCOFFARFMAG))
2276
    return FALSE;
2277
 
2278
  sprintf (decbuf, "%-12ld", (long) count);
2279
  if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
2280
      != XCOFFARMAG_ELEMENT_SIZE)
2281
    return FALSE;
2282
  for (i = 0; i < (size_t) count; i++)
2283
    {
2284
      sprintf (decbuf, "%-12ld", (long) offsets[i]);
2285
      if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
2286
                      abfd) != XCOFFARMAG_ELEMENT_SIZE)
2287
        return FALSE;
2288
    }
2289
  for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
2290
    {
2291
      const char *name;
2292
      bfd_size_type namlen;
2293
 
2294
      name = normalize_filename (sub);
2295
      namlen = strlen (name);
2296
      if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
2297
        return FALSE;
2298
    }
2299
 
2300
  if (! do_pad (abfd, size & 1))
2301
    return FALSE;
2302
 
2303
  /* Write out the armap, if appropriate.  */
2304
  if (! makemap || ! hasobjects)
2305
    sprintf (fhdr.symoff, "%d", 0);
2306
  else
2307
    {
2308
      BFD_ASSERT (nextoff == bfd_tell (abfd));
2309
      sprintf (fhdr.symoff, "%ld", (long) nextoff);
2310
      bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2311
      if (! _bfd_compute_and_write_armap (abfd, 0))
2312
        return FALSE;
2313
    }
2314
 
2315
  /* Write out the archive file header.  */
2316
 
2317
  /* We need spaces, not null bytes, in the header.  */
2318
  for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2319
    if (*p == '\0')
2320
      *p = ' ';
2321
 
2322
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2323
      || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
2324
          != SIZEOF_AR_FILE_HDR))
2325
    return FALSE;
2326
 
2327
  return TRUE;
2328
}
2329
 
2330
static bfd_boolean
2331
xcoff_write_archive_contents_big (abfd)
2332
     bfd *abfd;
2333
{
2334
  struct xcoff_ar_file_hdr_big fhdr;
2335
  bfd_size_type count;
2336
  bfd_size_type total_namlen;
2337
  file_ptr *offsets;
2338
  bfd_boolean makemap;
2339
  bfd_boolean hasobjects;
2340
  file_ptr prevoff, nextoff;
2341
  bfd *current_bfd;
2342
  size_t i;
2343 225 jeremybenn
  struct xcoff_ar_hdr_big *hdr;
2344 24 jeremybenn
  bfd_size_type size;
2345
  char *member_table, *mt;
2346
  bfd_vma member_table_size;
2347 225 jeremybenn
  struct archive_iterator iterator;
2348 24 jeremybenn
 
2349
  memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
2350
  memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
2351
 
2352
  if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
2353
    return FALSE;
2354
 
2355
  /* Calculate count and total_namlen.  */
2356
  makemap = bfd_has_map (abfd);
2357
  hasobjects = FALSE;
2358
  for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
2359
       current_bfd != NULL;
2360
       current_bfd = current_bfd->archive_next, count++)
2361
    {
2362
      total_namlen += strlen (normalize_filename (current_bfd)) + 1;
2363
 
2364
      if (makemap
2365
          && ! hasobjects
2366
          && bfd_check_format (current_bfd, bfd_object))
2367
        hasobjects = TRUE;
2368
 
2369 225 jeremybenn
      if (current_bfd->arelt_data == NULL)
2370
        {
2371
          size = sizeof (struct areltdata);
2372
          current_bfd->arelt_data = bfd_zalloc (current_bfd, size);
2373
          if (current_bfd->arelt_data == NULL)
2374
            return FALSE;
2375
        }
2376 24 jeremybenn
 
2377 225 jeremybenn
      if (arch_xhdr_big (current_bfd) == NULL)
2378 24 jeremybenn
        {
2379 225 jeremybenn
          struct xcoff_ar_hdr_big *ahdrp;
2380 24 jeremybenn
          struct stat s;
2381
 
2382
          /* XXX This should actually be a call to stat64 (at least on
2383
             32-bit machines).
2384
             XXX This call will fail if the original object is not found.  */
2385
          if (stat (bfd_get_filename (current_bfd), &s) != 0)
2386
            {
2387
              bfd_set_error (bfd_error_system_call);
2388
              return FALSE;
2389
            }
2390
 
2391 225 jeremybenn
          ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp));
2392
          if (ahdrp == NULL)
2393
            return FALSE;
2394
 
2395 24 jeremybenn
          PRINT20 (ahdrp->size, s.st_size);
2396
          PRINT12 (ahdrp->date, s.st_mtime);
2397
          PRINT12 (ahdrp->uid,  s.st_uid);
2398
          PRINT12 (ahdrp->gid,  s.st_gid);
2399
          PRINT12_OCTAL (ahdrp->mode, s.st_mode);
2400
 
2401 225 jeremybenn
          arch_eltdata (current_bfd)->arch_header = (char *) ahdrp;
2402 24 jeremybenn
          arch_eltdata (current_bfd)->parsed_size = s.st_size;
2403
        }
2404 225 jeremybenn
    }
2405 24 jeremybenn
 
2406 225 jeremybenn
  offsets = NULL;
2407
  if (count)
2408
    {
2409
      offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2410
      if (offsets == NULL)
2411 24 jeremybenn
        return FALSE;
2412 225 jeremybenn
    }
2413 24 jeremybenn
 
2414 225 jeremybenn
  prevoff = 0;
2415
  for (archive_iterator_begin (&iterator, abfd), i = 0;
2416
       archive_iterator_next (&iterator);
2417
       i++)
2418
    {
2419
      bfd_size_type namlen;
2420
      struct xcoff_ar_hdr_big *ahdrp;
2421 24 jeremybenn
 
2422 225 jeremybenn
      ahdrp = arch_xhdr_big (iterator.current.member);
2423
      PRINT20 (ahdrp->prevoff, prevoff);
2424
      PRINT4 (ahdrp->namlen, iterator.current.namlen);
2425
      PRINT20 (ahdrp->nextoff, iterator.next.offset);
2426 24 jeremybenn
 
2427 225 jeremybenn
      if (!do_pad (abfd, iterator.current.leading_padding))
2428 24 jeremybenn
        return FALSE;
2429
 
2430 225 jeremybenn
      BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
2431
      namlen = iterator.current.padded_namlen;
2432
      if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
2433
          || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
2434
          || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
2435
          || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
2436
          || !do_copy (abfd, iterator.current.member)
2437
          || !do_pad (abfd, iterator.current.trailing_padding))
2438 24 jeremybenn
        return FALSE;
2439
 
2440 225 jeremybenn
      offsets[i] = iterator.current.offset;
2441
      prevoff = iterator.current.offset;
2442 24 jeremybenn
    }
2443
 
2444
  if (count)
2445
    {
2446
      PRINT20 (fhdr.firstmemoff, offsets[0]);
2447
      PRINT20 (fhdr.lastmemoff, prevoff);
2448
    }
2449
 
2450
  /* Write out the member table.
2451
     Layout :
2452
 
2453
     standard big archive header
2454
     0x0000                   ar_size   [0x14]
2455
     0x0014                   ar_nxtmem [0x14]
2456
     0x0028                   ar_prvmem [0x14]
2457
     0x003C                   ar_date   [0x0C]
2458
     0x0048                   ar_uid    [0x0C]
2459
     0x0054                   ar_gid    [0x0C]
2460
     0x0060                   ar_mod    [0x0C]
2461
     0x006C                   ar_namelen[0x04]
2462
     0x0070                   ar_fmag   [0x02]
2463
 
2464
     Member table
2465
     0x0072                   count     [0x14]
2466
     0x0086                   offsets   [0x14 * counts]
2467
     0x0086 + 0x14 * counts   names     [??]
2468
     ??                       pad to even bytes.
2469
   */
2470
 
2471 225 jeremybenn
  nextoff = iterator.next.offset;
2472 24 jeremybenn
  BFD_ASSERT (nextoff == bfd_tell (abfd));
2473
 
2474
  member_table_size = (SIZEOF_AR_HDR_BIG
2475
                       + SXCOFFARFMAG
2476
                       + XCOFFARMAGBIG_ELEMENT_SIZE
2477
                       + count * XCOFFARMAGBIG_ELEMENT_SIZE
2478
                       + total_namlen);
2479
 
2480
  member_table_size += member_table_size & 1;
2481
  member_table = bfd_zmalloc (member_table_size);
2482
  if (member_table == NULL)
2483
    return FALSE;
2484
 
2485
  hdr = (struct xcoff_ar_hdr_big *) member_table;
2486
 
2487
  PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
2488
                       + count * XCOFFARMAGBIG_ELEMENT_SIZE
2489
                       + total_namlen + (total_namlen & 1)));
2490
  if (makemap && hasobjects)
2491
    PRINT20 (hdr->nextoff, nextoff + member_table_size);
2492
  else
2493
    PRINT20 (hdr->nextoff, 0);
2494
  PRINT20 (hdr->prevoff, prevoff);
2495
  PRINT12 (hdr->date, 0);
2496
  PRINT12 (hdr->uid, 0);
2497
  PRINT12 (hdr->gid, 0);
2498
  PRINT12 (hdr->mode, 0);
2499
  PRINT4 (hdr->namlen, 0);
2500
 
2501
  mt = member_table + SIZEOF_AR_HDR_BIG;
2502
  memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
2503
  mt += SXCOFFARFMAG;
2504
 
2505
  PRINT20 (mt, count);
2506
  mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2507
  for (i = 0; i < (size_t) count; i++)
2508
    {
2509
      PRINT20 (mt, offsets[i]);
2510
      mt += XCOFFARMAGBIG_ELEMENT_SIZE;
2511
    }
2512
 
2513
  if (count)
2514
    {
2515
      free (offsets);
2516
      offsets = NULL;
2517
    }
2518
 
2519
  for (current_bfd = abfd->archive_head;
2520
       current_bfd != NULL;
2521
       current_bfd = current_bfd->archive_next)
2522
    {
2523
      const char *name;
2524
      size_t namlen;
2525
 
2526
      name = normalize_filename (current_bfd);
2527
      namlen = sprintf (mt, "%s", name);
2528
      mt += namlen + 1;
2529
    }
2530
 
2531
  if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
2532
    return FALSE;
2533
 
2534
  free (member_table);
2535
 
2536
  PRINT20 (fhdr.memoff, nextoff);
2537
 
2538
  prevoff = nextoff;
2539
  nextoff += member_table_size;
2540
 
2541
  /* Write out the armap, if appropriate.  */
2542
 
2543
  if (! makemap || ! hasobjects)
2544
    PRINT20 (fhdr.symoff, 0);
2545
  else
2546
    {
2547
      BFD_ASSERT (nextoff == bfd_tell (abfd));
2548
 
2549
      /* Save nextoff in fhdr.symoff so the armap routine can use it.  */
2550
      PRINT20 (fhdr.symoff, nextoff);
2551
 
2552
      bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2553
      if (! _bfd_compute_and_write_armap (abfd, 0))
2554
        return FALSE;
2555
    }
2556
 
2557
  /* Write out the archive file header.  */
2558
 
2559
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2560
      || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
2561
                      abfd) != SIZEOF_AR_FILE_HDR_BIG))
2562
    return FALSE;
2563
 
2564
  return TRUE;
2565
}
2566
 
2567
bfd_boolean
2568
_bfd_xcoff_write_archive_contents (abfd)
2569
     bfd *abfd;
2570
{
2571
  if (! xcoff_big_format_p (abfd))
2572
    return xcoff_write_archive_contents_old (abfd);
2573
  else
2574
    return xcoff_write_archive_contents_big (abfd);
2575
}
2576
 
2577
/* We can't use the usual coff_sizeof_headers routine, because AIX
2578
   always uses an a.out header.  */
2579
 
2580
int
2581
_bfd_xcoff_sizeof_headers (bfd *abfd,
2582
                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
2583
{
2584
  int size;
2585
 
2586
  size = FILHSZ;
2587
  if (xcoff_data (abfd)->full_aouthdr)
2588
    size += AOUTSZ;
2589
  else
2590
    size += SMALL_AOUTSZ;
2591
  size += abfd->section_count * SCNHSZ;
2592
  return size;
2593
}
2594
 
2595
/* Routines to swap information in the XCOFF .loader section.  If we
2596
   ever need to write an XCOFF loader, this stuff will need to be
2597
   moved to another file shared by the linker (which XCOFF calls the
2598
   ``binder'') and the loader.  */
2599
 
2600
/* Swap in the ldhdr structure.  */
2601
 
2602
static void
2603
xcoff_swap_ldhdr_in (abfd, s, dst)
2604
     bfd *abfd;
2605
     const PTR s;
2606
     struct internal_ldhdr *dst;
2607
{
2608
  const struct external_ldhdr *src = (const struct external_ldhdr *) s;
2609
 
2610
  dst->l_version = bfd_get_32 (abfd, src->l_version);
2611
  dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
2612
  dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
2613
  dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
2614
  dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
2615
  dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
2616
  dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
2617
  dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
2618
}
2619
 
2620
/* Swap out the ldhdr structure.  */
2621
 
2622
static void
2623
xcoff_swap_ldhdr_out (abfd, src, d)
2624
     bfd *abfd;
2625
     const struct internal_ldhdr *src;
2626
     PTR d;
2627
{
2628
  struct external_ldhdr *dst = (struct external_ldhdr *) d;
2629
 
2630
  bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
2631
  bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
2632
  bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
2633
  bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
2634
  bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
2635
  bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
2636
  bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
2637
  bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
2638
}
2639
 
2640
/* Swap in the ldsym structure.  */
2641
 
2642
static void
2643
xcoff_swap_ldsym_in (abfd, s, dst)
2644
     bfd *abfd;
2645
     const PTR s;
2646
     struct internal_ldsym *dst;
2647
{
2648
  const struct external_ldsym *src = (const struct external_ldsym *) s;
2649
 
2650
  if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
2651
    memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2652
  } else {
2653
    dst->_l._l_l._l_zeroes = 0;
2654
    dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
2655
  }
2656
  dst->l_value = bfd_get_32 (abfd, src->l_value);
2657
  dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
2658
  dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
2659
  dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
2660
  dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
2661
  dst->l_parm = bfd_get_32 (abfd, src->l_parm);
2662
}
2663
 
2664
/* Swap out the ldsym structure.  */
2665
 
2666
static void
2667
xcoff_swap_ldsym_out (abfd, src, d)
2668
     bfd *abfd;
2669
     const struct internal_ldsym *src;
2670
     PTR d;
2671
{
2672
  struct external_ldsym *dst = (struct external_ldsym *) d;
2673
 
2674
  if (src->_l._l_l._l_zeroes != 0)
2675
    memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2676
  else
2677
    {
2678
      bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
2679
      bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
2680
                  dst->_l._l_l._l_offset);
2681
    }
2682
  bfd_put_32 (abfd, src->l_value, dst->l_value);
2683
  bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
2684
  bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
2685
  bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
2686
  bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
2687
  bfd_put_32 (abfd, src->l_parm, dst->l_parm);
2688
}
2689
 
2690
static void
2691
xcoff_swap_reloc_in (abfd, s, d)
2692
     bfd *abfd;
2693
     PTR s;
2694
     PTR d;
2695
{
2696
  struct external_reloc *src = (struct external_reloc *) s;
2697
  struct internal_reloc *dst = (struct internal_reloc *) d;
2698
 
2699
  memset (dst, 0, sizeof (struct internal_reloc));
2700
 
2701
  dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
2702
  dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
2703
  dst->r_size = bfd_get_8 (abfd, src->r_size);
2704
  dst->r_type = bfd_get_8 (abfd, src->r_type);
2705
}
2706
 
2707
static unsigned int
2708
xcoff_swap_reloc_out (abfd, s, d)
2709
     bfd *abfd;
2710
     PTR s;
2711
     PTR d;
2712
{
2713
  struct internal_reloc *src = (struct internal_reloc *) s;
2714
  struct external_reloc *dst = (struct external_reloc *) d;
2715
 
2716
  bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
2717
  bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
2718
  bfd_put_8 (abfd, src->r_type, dst->r_type);
2719
  bfd_put_8 (abfd, src->r_size, dst->r_size);
2720
 
2721
  return bfd_coff_relsz (abfd);
2722
}
2723
 
2724
/* Swap in the ldrel structure.  */
2725
 
2726
static void
2727
xcoff_swap_ldrel_in (abfd, s, dst)
2728
     bfd *abfd;
2729
     const PTR s;
2730
     struct internal_ldrel *dst;
2731
{
2732
  const struct external_ldrel *src = (const struct external_ldrel *) s;
2733
 
2734
  dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
2735
  dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
2736
  dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
2737
  dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
2738
}
2739
 
2740
/* Swap out the ldrel structure.  */
2741
 
2742
static void
2743
xcoff_swap_ldrel_out (abfd, src, d)
2744
     bfd *abfd;
2745
     const struct internal_ldrel *src;
2746
     PTR d;
2747
{
2748
  struct external_ldrel *dst = (struct external_ldrel *) d;
2749
 
2750
  bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
2751
  bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
2752
  bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
2753
  bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
2754
}
2755
 
2756
 
2757
bfd_boolean
2758
xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
2759
                       val, addend, relocation, contents)
2760
     bfd *input_bfd ATTRIBUTE_UNUSED;
2761
     asection *input_section ATTRIBUTE_UNUSED;
2762
     bfd *output_bfd ATTRIBUTE_UNUSED;
2763
     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2764
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2765
     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2766
     bfd_vma val ATTRIBUTE_UNUSED;
2767
     bfd_vma addend ATTRIBUTE_UNUSED;
2768
     bfd_vma *relocation ATTRIBUTE_UNUSED;
2769
     bfd_byte *contents ATTRIBUTE_UNUSED;
2770
{
2771
  return TRUE;
2772
}
2773
 
2774
bfd_boolean
2775
xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
2776
                       val, addend, relocation, contents)
2777
     bfd *input_bfd;
2778
     asection *input_section ATTRIBUTE_UNUSED;
2779
     bfd *output_bfd ATTRIBUTE_UNUSED;
2780
     struct internal_reloc *rel;
2781
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2782
     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2783
     bfd_vma val ATTRIBUTE_UNUSED;
2784
     bfd_vma addend ATTRIBUTE_UNUSED;
2785
     bfd_vma *relocation ATTRIBUTE_UNUSED;
2786
     bfd_byte *contents ATTRIBUTE_UNUSED;
2787
{
2788
  (*_bfd_error_handler)
2789
    (_("%s: unsupported relocation type 0x%02x"),
2790
     bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
2791
  bfd_set_error (bfd_error_bad_value);
2792
  return FALSE;
2793
}
2794
 
2795
bfd_boolean
2796
xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
2797
                      val, addend, relocation, contents)
2798
     bfd *input_bfd ATTRIBUTE_UNUSED;
2799
     asection *input_section ATTRIBUTE_UNUSED;
2800
     bfd *output_bfd ATTRIBUTE_UNUSED;
2801
     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2802
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2803
     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2804
     bfd_vma val;
2805
     bfd_vma addend;
2806
     bfd_vma *relocation;
2807
     bfd_byte *contents ATTRIBUTE_UNUSED;
2808
{
2809
  *relocation = val + addend;
2810
  return TRUE;
2811
}
2812
 
2813
bfd_boolean
2814
xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
2815
                      val, addend, relocation, contents)
2816
     bfd *input_bfd ATTRIBUTE_UNUSED;
2817
     asection *input_section ATTRIBUTE_UNUSED;
2818
     bfd *output_bfd ATTRIBUTE_UNUSED;
2819
     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2820
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2821
     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2822
     bfd_vma val;
2823
     bfd_vma addend;
2824
     bfd_vma *relocation;
2825
     bfd_byte *contents ATTRIBUTE_UNUSED;
2826
{
2827
  *relocation = addend - val;
2828
  return TRUE;
2829
}
2830
 
2831
bfd_boolean
2832
xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
2833
                      val, addend, relocation, contents)
2834
     bfd *input_bfd ATTRIBUTE_UNUSED;
2835
     asection *input_section;
2836
     bfd *output_bfd ATTRIBUTE_UNUSED;
2837
     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2838
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2839
     struct reloc_howto_struct *howto;
2840
     bfd_vma val;
2841
     bfd_vma addend;
2842
     bfd_vma *relocation;
2843
     bfd_byte *contents ATTRIBUTE_UNUSED;
2844
{
2845
  howto->pc_relative = TRUE;
2846
 
2847
  /* A PC relative reloc includes the section address.  */
2848
  addend += input_section->vma;
2849
 
2850
  *relocation = val + addend;
2851
  *relocation -= (input_section->output_section->vma
2852
                  + input_section->output_offset);
2853
  return TRUE;
2854
}
2855
 
2856
bfd_boolean
2857
xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
2858
                      val, addend, relocation, contents)
2859
     bfd *input_bfd;
2860
     asection *input_section ATTRIBUTE_UNUSED;
2861
     bfd *output_bfd;
2862
     struct internal_reloc *rel;
2863
     struct internal_syment *sym;
2864
     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
2865
     bfd_vma val;
2866
     bfd_vma addend ATTRIBUTE_UNUSED;
2867
     bfd_vma *relocation;
2868
     bfd_byte *contents ATTRIBUTE_UNUSED;
2869
{
2870
  struct xcoff_link_hash_entry *h;
2871
 
2872
  if (0 > rel->r_symndx)
2873
    return FALSE;
2874
 
2875
  h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2876
 
2877
  if (h != NULL && h->smclas != XMC_TD)
2878
    {
2879
      if (h->toc_section == NULL)
2880
        {
2881
          (*_bfd_error_handler)
2882
            (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
2883
             bfd_get_filename (input_bfd), rel->r_vaddr,
2884
             h->root.root.string);
2885
          bfd_set_error (bfd_error_bad_value);
2886
          return FALSE;
2887
        }
2888
 
2889
      BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
2890
      val = (h->toc_section->output_section->vma
2891
              + h->toc_section->output_offset);
2892
    }
2893
 
2894
  *relocation = ((val - xcoff_data (output_bfd)->toc)
2895
                 - (sym->n_value - xcoff_data (input_bfd)->toc));
2896
  return TRUE;
2897
}
2898
 
2899
bfd_boolean
2900
xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto,
2901
                     val, addend, relocation, contents)
2902
     bfd *input_bfd ATTRIBUTE_UNUSED;
2903
     asection *input_section ATTRIBUTE_UNUSED;
2904
     bfd *output_bfd ATTRIBUTE_UNUSED;
2905
     struct internal_reloc *rel ATTRIBUTE_UNUSED;
2906
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2907
     struct reloc_howto_struct *howto;
2908
     bfd_vma val;
2909
     bfd_vma addend;
2910
     bfd_vma *relocation;
2911
     bfd_byte *contents ATTRIBUTE_UNUSED;
2912
{
2913
  howto->src_mask &= ~3;
2914
  howto->dst_mask = howto->src_mask;
2915
 
2916
  *relocation = val + addend;
2917
 
2918
  return TRUE;
2919
}
2920
 
2921
static bfd_boolean
2922
xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
2923
                     val, addend, relocation, contents)
2924
     bfd *input_bfd;
2925
     asection *input_section;
2926
     bfd *output_bfd ATTRIBUTE_UNUSED;
2927
     struct internal_reloc *rel;
2928
     struct internal_syment *sym ATTRIBUTE_UNUSED;
2929
     struct reloc_howto_struct *howto;
2930
     bfd_vma val;
2931
     bfd_vma addend;
2932
     bfd_vma *relocation;
2933
     bfd_byte *contents;
2934
{
2935
  struct xcoff_link_hash_entry *h;
2936 225 jeremybenn
  bfd_vma section_offset;
2937 24 jeremybenn
 
2938
  if (0 > rel->r_symndx)
2939
    return FALSE;
2940
 
2941
  h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2942 225 jeremybenn
  section_offset = rel->r_vaddr - input_section->vma;
2943 24 jeremybenn
 
2944
  /* If we see an R_BR or R_RBR reloc which is jumping to global
2945
     linkage code, and it is followed by an appropriate cror nop
2946
     instruction, we replace the cror with lwz r2,20(r1).  This
2947
     restores the TOC after the glink code.  Contrariwise, if the
2948
     call is followed by a lwz r2,20(r1), but the call is not
2949
     going to global linkage code, we can replace the load with a
2950
     cror.  */
2951
  if (NULL != h
2952 225 jeremybenn
      && (bfd_link_hash_defined == h->root.type
2953
          || bfd_link_hash_defweak == h->root.type)
2954
      && section_offset + 8 <= input_section->size)
2955 24 jeremybenn
    {
2956
      bfd_byte *pnext;
2957
      unsigned long next;
2958
 
2959 225 jeremybenn
      pnext = contents + section_offset + 4;
2960 24 jeremybenn
      next = bfd_get_32 (input_bfd, pnext);
2961
 
2962
      /* The _ptrgl function is magic.  It is used by the AIX
2963
         compiler to call a function through a pointer.  */
2964
      if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
2965
        {
2966
          if (next == 0x4def7b82                        /* cror 15,15,15 */
2967
              || next == 0x4ffffb82                     /* cror 31,31,31 */
2968
              || next == 0x60000000)                    /* ori r0,r0,0 */
2969 225 jeremybenn
            bfd_put_32 (input_bfd, 0x80410014, pnext);  /* lwz r2,20(r1) */
2970 24 jeremybenn
 
2971
        }
2972
      else
2973
        {
2974 225 jeremybenn
          if (next == 0x80410014)                       /* lwz r2,20(r1) */
2975 24 jeremybenn
            bfd_put_32 (input_bfd, 0x60000000, pnext);  /* ori r0,r0,0 */
2976
        }
2977
    }
2978
  else if (NULL != h && bfd_link_hash_undefined == h->root.type)
2979
    {
2980
      /* Normally, this relocation is against a defined symbol.  In the
2981
         case where this is a partial link and the output section offset
2982
         is greater than 2^25, the linker will return an invalid error
2983
         message that the relocation has been truncated.  Yes it has been
2984
         truncated but no it not important.  For this case, disable the
2985
         overflow checking. */
2986
 
2987
      howto->complain_on_overflow = complain_overflow_dont;
2988
    }
2989
 
2990 225 jeremybenn
  /* The original PC-relative relocation is biased by -r_vaddr, so adding
2991
     the value below will give the absolute target address.  */
2992
  *relocation = val + addend + rel->r_vaddr;
2993
 
2994 24 jeremybenn
  howto->src_mask &= ~3;
2995
  howto->dst_mask = howto->src_mask;
2996
 
2997 225 jeremybenn
  if (h != NULL
2998
      && (h->root.type == bfd_link_hash_defined
2999
          || h->root.type == bfd_link_hash_defweak)
3000
      && bfd_is_abs_section (h->root.u.def.section)
3001
      && section_offset + 4 <= input_section->size)
3002
    {
3003
      bfd_byte *ptr;
3004
      bfd_vma insn;
3005 24 jeremybenn
 
3006 225 jeremybenn
      /* Turn the relative branch into an absolute one by setting the
3007
         AA bit.  */
3008
      ptr = contents + section_offset;
3009
      insn = bfd_get_32 (input_bfd, ptr);
3010
      insn |= 2;
3011
      bfd_put_32 (input_bfd, insn, ptr);
3012
 
3013
      /* Make the howto absolute too.  */
3014
      howto->pc_relative = FALSE;
3015
      howto->complain_on_overflow = complain_overflow_bitfield;
3016
    }
3017
  else
3018
    {
3019
      /* Use a PC-relative howto and subtract the instruction's address
3020
         from the target address we calculated above.  */
3021
      howto->pc_relative = TRUE;
3022
      *relocation -= (input_section->output_section->vma
3023
                      + input_section->output_offset
3024
                      + section_offset);
3025
    }
3026 24 jeremybenn
  return TRUE;
3027
}
3028
 
3029
bfd_boolean
3030
xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
3031
                       val, addend, relocation, contents)
3032
     bfd *input_bfd ATTRIBUTE_UNUSED;
3033
     asection *input_section;
3034
     bfd *output_bfd ATTRIBUTE_UNUSED;
3035
     struct internal_reloc *rel ATTRIBUTE_UNUSED;
3036
     struct internal_syment *sym ATTRIBUTE_UNUSED;
3037
     struct reloc_howto_struct *howto;
3038
     bfd_vma val ATTRIBUTE_UNUSED;
3039
     bfd_vma addend;
3040
     bfd_vma *relocation;
3041
     bfd_byte *contents ATTRIBUTE_UNUSED;
3042
{
3043
  howto->pc_relative = TRUE;
3044
  howto->src_mask &= ~3;
3045
  howto->dst_mask = howto->src_mask;
3046
 
3047
  /* A PC relative reloc includes the section address.  */
3048
  addend += input_section->vma;
3049
 
3050
  *relocation = val + addend;
3051
  *relocation -= (input_section->output_section->vma
3052
                  + input_section->output_offset);
3053
  return TRUE;
3054
}
3055
 
3056
static bfd_boolean
3057
xcoff_complain_overflow_dont_func (input_bfd, val, relocation, howto)
3058
     bfd *input_bfd ATTRIBUTE_UNUSED;
3059
     bfd_vma val ATTRIBUTE_UNUSED;
3060
     bfd_vma relocation ATTRIBUTE_UNUSED;
3061
     struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
3062
{
3063
  return FALSE;
3064
}
3065
 
3066
static bfd_boolean
3067
xcoff_complain_overflow_bitfield_func (input_bfd, val, relocation, howto)
3068
     bfd *input_bfd;
3069
     bfd_vma val;
3070
     bfd_vma relocation;
3071
     struct reloc_howto_struct *howto;
3072
{
3073
  bfd_vma addrmask, fieldmask, signmask, ss;
3074
  bfd_vma a, b, sum;
3075
 
3076
  /* Get the values to be added together.  For signed and unsigned
3077
     relocations, we assume that all values should be truncated to
3078
     the size of an address.  For bitfields, all the bits matter.
3079
     See also bfd_check_overflow.  */
3080
  fieldmask = N_ONES (howto->bitsize);
3081
  addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3082
  a = relocation;
3083
  b = val & howto->src_mask;
3084
 
3085
  /* Much like unsigned, except no trimming with addrmask.  In
3086
     addition, the sum overflows if there is a carry out of
3087
     the bfd_vma, i.e., the sum is less than either input
3088
     operand.  */
3089
  a >>= howto->rightshift;
3090
  b >>= howto->bitpos;
3091
 
3092
  /* Bitfields are sometimes used for signed numbers; for
3093
     example, a 13-bit field sometimes represents values in
3094
     0..8191 and sometimes represents values in -4096..4095.
3095
     If the field is signed and a is -4095 (0x1001) and b is
3096
     -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
3097
     0x1fff is 0x3000).  It's not clear how to handle this
3098
     everywhere, since there is not way to know how many bits
3099
     are significant in the relocation, but the original code
3100
     assumed that it was fully sign extended, and we will keep
3101
     that assumption.  */
3102
  signmask = (fieldmask >> 1) + 1;
3103
 
3104
  if ((a & ~ fieldmask) != 0)
3105
    {
3106
      /* Some bits out of the field are set.  This might not
3107
         be a problem: if this is a signed bitfield, it is OK
3108
         iff all the high bits are set, including the sign
3109
         bit.  We'll try setting all but the most significant
3110
         bit in the original relocation value: if this is all
3111
         ones, we are OK, assuming a signed bitfield.  */
3112
      ss = (signmask << howto->rightshift) - 1;
3113
      if ((ss | relocation) != ~ (bfd_vma) 0)
3114
        return TRUE;
3115
      a &= fieldmask;
3116
    }
3117
 
3118
  /* We just assume (b & ~ fieldmask) == 0.  */
3119
 
3120
  /* We explicitly permit wrap around if this relocation
3121
     covers the high bit of an address.  The Linux kernel
3122
     relies on it, and it is the only way to write assembler
3123
     code which can run when loaded at a location 0x80000000
3124
     away from the location at which it is linked.  */
3125
  if (howto->bitsize + howto->rightshift
3126
      == bfd_arch_bits_per_address (input_bfd))
3127
    return FALSE;
3128
 
3129
  sum = a + b;
3130
  if (sum < a || (sum & ~ fieldmask) != 0)
3131
    {
3132
      /* There was a carry out, or the field overflow.  Test
3133
         for signed operands again.  Here is the overflow test
3134
         is as for complain_overflow_signed.  */
3135
      if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3136
        return TRUE;
3137
    }
3138
 
3139
  return FALSE;
3140
}
3141
 
3142
static bfd_boolean
3143
xcoff_complain_overflow_signed_func (input_bfd, val, relocation, howto)
3144
     bfd *input_bfd;
3145
     bfd_vma val;
3146
     bfd_vma relocation;
3147
     struct reloc_howto_struct *howto;
3148
{
3149
  bfd_vma addrmask, fieldmask, signmask, ss;
3150
  bfd_vma a, b, sum;
3151
 
3152
  /* Get the values to be added together.  For signed and unsigned
3153
     relocations, we assume that all values should be truncated to
3154
     the size of an address.  For bitfields, all the bits matter.
3155
     See also bfd_check_overflow.  */
3156
  fieldmask = N_ONES (howto->bitsize);
3157
  addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3158
  a = relocation;
3159
  b = val & howto->src_mask;
3160
 
3161
  a = (a & addrmask) >> howto->rightshift;
3162
 
3163
  /* If any sign bits are set, all sign bits must be set.
3164
     That is, A must be a valid negative address after
3165
     shifting.  */
3166
  signmask = ~ (fieldmask >> 1);
3167
  ss = a & signmask;
3168
  if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
3169
    return TRUE;
3170
 
3171
  /* We only need this next bit of code if the sign bit of B
3172
     is below the sign bit of A.  This would only happen if
3173
     SRC_MASK had fewer bits than BITSIZE.  Note that if
3174
     SRC_MASK has more bits than BITSIZE, we can get into
3175
     trouble; we would need to verify that B is in range, as
3176
     we do for A above.  */
3177
  signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
3178
  if ((b & signmask) != 0)
3179
    {
3180
      /* Set all the bits above the sign bit.  */
3181
      b -= signmask <<= 1;
3182
    }
3183
 
3184
  b = (b & addrmask) >> howto->bitpos;
3185
 
3186
  /* Now we can do the addition.  */
3187
  sum = a + b;
3188
 
3189
  /* See if the result has the correct sign.  Bits above the
3190
     sign bit are junk now; ignore them.  If the sum is
3191
     positive, make sure we did not have all negative inputs;
3192
     if the sum is negative, make sure we did not have all
3193
     positive inputs.  The test below looks only at the sign
3194
     bits, and it really just
3195
     SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
3196
  */
3197
  signmask = (fieldmask >> 1) + 1;
3198
  if (((~ (a ^ b)) & (a ^ sum)) & signmask)
3199
    return TRUE;
3200
 
3201
  return FALSE;
3202
}
3203
 
3204
static bfd_boolean
3205
xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto)
3206
     bfd *input_bfd;
3207
     bfd_vma val;
3208
     bfd_vma relocation;
3209
     struct reloc_howto_struct *howto;
3210
{
3211
  bfd_vma addrmask, fieldmask;
3212
  bfd_vma a, b, sum;
3213
 
3214
  /* Get the values to be added together.  For signed and unsigned
3215
     relocations, we assume that all values should be truncated to
3216
     the size of an address.  For bitfields, all the bits matter.
3217
     See also bfd_check_overflow.  */
3218
  fieldmask = N_ONES (howto->bitsize);
3219
  addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3220
  a = relocation;
3221
  b = val & howto->src_mask;
3222
 
3223
  /* Checking for an unsigned overflow is relatively easy:
3224
     trim the addresses and add, and trim the result as well.
3225
     Overflow is normally indicated when the result does not
3226
     fit in the field.  However, we also need to consider the
3227
     case when, e.g., fieldmask is 0x7fffffff or smaller, an
3228
     input is 0x80000000, and bfd_vma is only 32 bits; then we
3229
     will get sum == 0, but there is an overflow, since the
3230
     inputs did not fit in the field.  Instead of doing a
3231
     separate test, we can check for this by or-ing in the
3232
     operands when testing for the sum overflowing its final
3233
     field.  */
3234
  a = (a & addrmask) >> howto->rightshift;
3235
  b = (b & addrmask) >> howto->bitpos;
3236
  sum = (a + b) & addrmask;
3237
  if ((a | b | sum) & ~ fieldmask)
3238
    return TRUE;
3239
 
3240
  return FALSE;
3241
}
3242
 
3243
/* This is the relocation function for the RS/6000/POWER/PowerPC.
3244
   This is currently the only processor which uses XCOFF; I hope that
3245
   will never change.
3246
 
3247
   I took the relocation type definitions from two documents:
3248
   the PowerPC AIX Version 4 Application Binary Interface, First
3249
   Edition (April 1992), and the PowerOpen ABI, Big-Endian
3250
   32-Bit Hardware Implementation (June 30, 1994).  Differences
3251
   between the documents are noted below.
3252
 
3253
   Unsupported r_type's
3254
 
3255
   R_RTB:
3256
   R_RRTBI:
3257
   R_RRTBA:
3258
 
3259
   These relocs are defined by the PowerPC ABI to be
3260
   relative branches which use half of the difference
3261
   between the symbol and the program counter.  I can't
3262
   quite figure out when this is useful.  These relocs are
3263
   not defined by the PowerOpen ABI.
3264
 
3265
   Supported r_type's
3266
 
3267
   R_POS:
3268
   Simple positive relocation.
3269
 
3270
   R_NEG:
3271
   Simple negative relocation.
3272
 
3273
   R_REL:
3274
   Simple PC relative relocation.
3275
 
3276
   R_TOC:
3277
   TOC relative relocation.  The value in the instruction in
3278
   the input file is the offset from the input file TOC to
3279
   the desired location.  We want the offset from the final
3280
   TOC to the desired location.  We have:
3281
   isym = iTOC + in
3282
   iinsn = in + o
3283
   osym = oTOC + on
3284
   oinsn = on + o
3285
   so we must change insn by on - in.
3286
 
3287
   R_GL:
3288
   GL linkage relocation.  The value of this relocation
3289
   is the address of the entry in the TOC section.
3290
 
3291
   R_TCL:
3292
   Local object TOC address.  I can't figure out the
3293
   difference between this and case R_GL.
3294
 
3295
   R_TRL:
3296
   TOC relative relocation.  A TOC relative load instruction
3297
   which may be changed to a load address instruction.
3298
   FIXME: We don't currently implement this optimization.
3299
 
3300
   R_TRLA:
3301
   TOC relative relocation.  This is a TOC relative load
3302
   address instruction which may be changed to a load
3303
   instruction.  FIXME: I don't know if this is the correct
3304
   implementation.
3305
 
3306
   R_BA:
3307
   Absolute branch.  We don't want to mess with the lower
3308
   two bits of the instruction.
3309
 
3310
   R_CAI:
3311
   The PowerPC ABI defines this as an absolute call which
3312
   may be modified to become a relative call.  The PowerOpen
3313
   ABI does not define this relocation type.
3314
 
3315
   R_RBA:
3316
   Absolute branch which may be modified to become a
3317
   relative branch.
3318
 
3319
   R_RBAC:
3320
   The PowerPC ABI defines this as an absolute branch to a
3321
   fixed address which may be modified to an absolute branch
3322
   to a symbol.  The PowerOpen ABI does not define this
3323
   relocation type.
3324
 
3325
   R_RBRC:
3326
   The PowerPC ABI defines this as an absolute branch to a
3327
   fixed address which may be modified to a relative branch.
3328
   The PowerOpen ABI does not define this relocation type.
3329
 
3330
   R_BR:
3331
   Relative branch.  We don't want to mess with the lower
3332
   two bits of the instruction.
3333
 
3334
   R_CREL:
3335
   The PowerPC ABI defines this as a relative call which may
3336
   be modified to become an absolute call.  The PowerOpen
3337
   ABI does not define this relocation type.
3338
 
3339
   R_RBR:
3340
   A relative branch which may be modified to become an
3341 225 jeremybenn
   absolute branch.
3342 24 jeremybenn
 
3343
   R_RL:
3344
   The PowerPC AIX ABI describes this as a load which may be
3345
   changed to a load address.  The PowerOpen ABI says this
3346
   is the same as case R_POS.
3347
 
3348
   R_RLA:
3349
   The PowerPC AIX ABI describes this as a load address
3350
   which may be changed to a load.  The PowerOpen ABI says
3351
   this is the same as R_POS.
3352
*/
3353
 
3354
bfd_boolean
3355
xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
3356
                            input_section, contents, relocs, syms,
3357
                            sections)
3358
     bfd *output_bfd;
3359
     struct bfd_link_info *info;
3360
     bfd *input_bfd;
3361
     asection *input_section;
3362
     bfd_byte *contents;
3363
     struct internal_reloc *relocs;
3364
     struct internal_syment *syms;
3365
     asection **sections;
3366
{
3367
  struct internal_reloc *rel;
3368
  struct internal_reloc *relend;
3369
 
3370
  rel = relocs;
3371
  relend = rel + input_section->reloc_count;
3372
  for (; rel < relend; rel++)
3373
    {
3374
      long symndx;
3375
      struct xcoff_link_hash_entry *h;
3376
      struct internal_syment *sym;
3377
      bfd_vma addend;
3378
      bfd_vma val;
3379
      struct reloc_howto_struct howto;
3380
      bfd_vma relocation;
3381
      bfd_vma value_to_relocate;
3382
      bfd_vma address;
3383
      bfd_byte *location;
3384
 
3385
      /* Relocation type R_REF is a special relocation type which is
3386
         merely used to prevent garbage collection from occurring for
3387
         the csect including the symbol which it references.  */
3388
      if (rel->r_type == R_REF)
3389
        continue;
3390
 
3391
      /* howto */
3392
      howto.type = rel->r_type;
3393
      howto.rightshift = 0;
3394
      howto.bitsize = (rel->r_size & 0x1f) + 1;
3395
      howto.size = howto.bitsize > 16 ? 2 : 1;
3396
      howto.pc_relative = FALSE;
3397
      howto.bitpos = 0;
3398
      howto.complain_on_overflow = (rel->r_size & 0x80
3399
                                    ? complain_overflow_signed
3400
                                    : complain_overflow_bitfield);
3401
      howto.special_function = NULL;
3402
      howto.name = "internal";
3403
      howto.partial_inplace = TRUE;
3404
      howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
3405
      howto.pcrel_offset = FALSE;
3406
 
3407
      /* symbol */
3408
      val = 0;
3409
      addend = 0;
3410
      h = NULL;
3411
      sym = NULL;
3412
      symndx = rel->r_symndx;
3413
 
3414
      if (-1 != symndx)
3415
        {
3416
          asection *sec;
3417
 
3418
          h = obj_xcoff_sym_hashes (input_bfd)[symndx];
3419
          sym = syms + symndx;
3420
          addend = - sym->n_value;
3421
 
3422
          if (NULL == h)
3423
            {
3424
              sec = sections[symndx];
3425
              /* Hack to make sure we use the right TOC anchor value
3426
                 if this reloc is against the TOC anchor.  */
3427
              if (sec->name[3] == '0'
3428
                  && strcmp (sec->name, ".tc0") == 0)
3429
                val = xcoff_data (output_bfd)->toc;
3430
              else
3431
                val = (sec->output_section->vma
3432
                       + sec->output_offset
3433
                       + sym->n_value
3434
                       - sec->vma);
3435
            }
3436
          else
3437
            {
3438 225 jeremybenn
              if (info->unresolved_syms_in_objects != RM_IGNORE
3439
                  && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
3440
                {
3441
                  if (! ((*info->callbacks->undefined_symbol)
3442
                         (info, h->root.root.string,
3443
                          input_bfd, input_section,
3444
                          rel->r_vaddr - input_section->vma,
3445
                          (info->unresolved_syms_in_objects
3446
                           == RM_GENERATE_ERROR))))
3447
                    return FALSE;
3448
                }
3449 24 jeremybenn
              if (h->root.type == bfd_link_hash_defined
3450
                  || h->root.type == bfd_link_hash_defweak)
3451
                {
3452
                  sec = h->root.u.def.section;
3453
                  val = (h->root.u.def.value
3454
                         + sec->output_section->vma
3455
                         + sec->output_offset);
3456
                }
3457
              else if (h->root.type == bfd_link_hash_common)
3458
                {
3459
                  sec = h->root.u.c.p->section;
3460
                  val = (sec->output_section->vma
3461
                         + sec->output_offset);
3462
 
3463
                }
3464 225 jeremybenn
              else
3465 24 jeremybenn
                {
3466 225 jeremybenn
                  BFD_ASSERT (info->relocatable
3467
                              || (info->static_link
3468
                                  && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
3469
                              || (h->flags & XCOFF_DEF_DYNAMIC) != 0
3470
                              || (h->flags & XCOFF_IMPORT) != 0);
3471 24 jeremybenn
                }
3472
            }
3473
        }
3474
 
3475
      if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
3476
          || !((*xcoff_calculate_relocation[rel->r_type])
3477
               (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
3478
                addend, &relocation, contents)))
3479
        return FALSE;
3480
 
3481
      /* address */
3482
      address = rel->r_vaddr - input_section->vma;
3483
      location = contents + address;
3484
 
3485
      if (address > input_section->size)
3486
        abort ();
3487
 
3488
      /* Get the value we are going to relocate.  */
3489
      if (1 == howto.size)
3490
        value_to_relocate = bfd_get_16 (input_bfd, location);
3491
      else
3492
        value_to_relocate = bfd_get_32 (input_bfd, location);
3493
 
3494
      /* overflow.
3495
 
3496
         FIXME: We may drop bits during the addition
3497
         which we don't check for.  We must either check at every single
3498
         operation, which would be tedious, or we must do the computations
3499
         in a type larger than bfd_vma, which would be inefficient.  */
3500
 
3501
      if ((unsigned int) howto.complain_on_overflow
3502
          >= XCOFF_MAX_COMPLAIN_OVERFLOW)
3503
        abort ();
3504
 
3505
      if (((*xcoff_complain_overflow[howto.complain_on_overflow])
3506
           (input_bfd, value_to_relocate, relocation, &howto)))
3507
        {
3508
          const char *name;
3509
          char buf[SYMNMLEN + 1];
3510
          char reloc_type_name[10];
3511
 
3512
          if (symndx == -1)
3513
            {
3514
              name = "*ABS*";
3515
            }
3516
          else if (h != NULL)
3517
            {
3518
              name = NULL;
3519
            }
3520
          else
3521
            {
3522
              name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
3523
              if (name == NULL)
3524
                name = "UNKNOWN";
3525
            }
3526
          sprintf (reloc_type_name, "0x%02x", rel->r_type);
3527
 
3528
          if (! ((*info->callbacks->reloc_overflow)
3529
                 (info, (h ? &h->root : NULL), name, reloc_type_name,
3530
                  (bfd_vma) 0, input_bfd, input_section,
3531
                  rel->r_vaddr - input_section->vma)))
3532
            return FALSE;
3533
        }
3534
 
3535
      /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE.  */
3536
      value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
3537
                           | (((value_to_relocate & howto.src_mask)
3538
                               + relocation) & howto.dst_mask));
3539
 
3540
      /* Put the value back in the object file.  */
3541
      if (1 == howto.size)
3542
        bfd_put_16 (input_bfd, value_to_relocate, location);
3543
      else
3544
        bfd_put_32 (input_bfd, value_to_relocate, location);
3545
    }
3546
 
3547
  return TRUE;
3548
}
3549
 
3550
static bfd_boolean
3551
_bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
3552
     bfd *abfd ATTRIBUTE_UNUSED;
3553
         struct xcoff_loader_info *ldinfo;
3554
         struct internal_ldsym *ldsym;
3555
         const char *name;
3556
{
3557
  size_t len;
3558
  len = strlen (name);
3559
 
3560
  if (len <= SYMNMLEN)
3561
    strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3562
  else
3563
    {
3564
      if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3565
        {
3566
          bfd_size_type newalc;
3567
          char *newstrings;
3568
 
3569
          newalc = ldinfo->string_alc * 2;
3570
          if (newalc == 0)
3571
            newalc = 32;
3572
          while (ldinfo->string_size + len + 3 > newalc)
3573
            newalc *= 2;
3574
 
3575
          newstrings = bfd_realloc (ldinfo->strings, newalc);
3576
          if (newstrings == NULL)
3577
            {
3578
              ldinfo->failed = TRUE;
3579
              return FALSE;
3580
            }
3581
          ldinfo->string_alc = newalc;
3582
          ldinfo->strings = newstrings;
3583
        }
3584
 
3585
      bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3586
                  ldinfo->strings + ldinfo->string_size);
3587
      strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3588
      ldsym->_l._l_l._l_zeroes = 0;
3589
      ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3590
      ldinfo->string_size += len + 3;
3591
    }
3592
 
3593
  return TRUE;
3594
}
3595
 
3596
static bfd_boolean
3597
_bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
3598
                            struct internal_syment *sym,
3599
                            const char *name)
3600
{
3601
  if (strlen (name) <= SYMNMLEN)
3602
    {
3603
      strncpy (sym->_n._n_name, name, SYMNMLEN);
3604
    }
3605
  else
3606
    {
3607
      bfd_boolean hash;
3608
      bfd_size_type indx;
3609
 
3610
      hash = TRUE;
3611
      if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
3612
        hash = FALSE;
3613
      indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
3614
      if (indx == (bfd_size_type) -1)
3615
        return FALSE;
3616
      sym->_n._n_n._n_zeroes = 0;
3617
      sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3618
    }
3619
  return TRUE;
3620
}
3621
 
3622
static asection *
3623
xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
3624
     bfd *abfd;
3625
     union internal_auxent *aux;
3626
     const char *symbol_name;
3627
{
3628
  asection *return_value = NULL;
3629
 
3630
  /* .sv64 = x_smclas == 17
3631
     This is an invalid csect for 32 bit apps.  */
3632
  static const char *names[19] =
3633
  {
3634
    ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
3635
    ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
3636
    ".td", NULL, ".sv3264"
3637
  };
3638
 
3639
  if ((19 >= aux->x_csect.x_smclas)
3640
      && (NULL != names[aux->x_csect.x_smclas]))
3641
    {
3642
      return_value = bfd_make_section_anyway
3643
        (abfd, names[aux->x_csect.x_smclas]);
3644
    }
3645
  else
3646
    {
3647
      (*_bfd_error_handler)
3648
        (_("%B: symbol `%s' has unrecognized smclas %d"),
3649
         abfd, symbol_name, aux->x_csect.x_smclas);
3650
      bfd_set_error (bfd_error_bad_value);
3651
    }
3652
 
3653
  return return_value;
3654
}
3655
 
3656
static bfd_boolean
3657
xcoff_is_lineno_count_overflow (abfd, value)
3658
    bfd *abfd ATTRIBUTE_UNUSED;
3659
        bfd_vma value;
3660
{
3661
  if (0xffff <= value)
3662
    return TRUE;
3663
 
3664
  return FALSE;
3665
}
3666
 
3667
static bfd_boolean
3668
xcoff_is_reloc_count_overflow (abfd, value)
3669
    bfd *abfd ATTRIBUTE_UNUSED;
3670
        bfd_vma value;
3671
{
3672
  if (0xffff <= value)
3673
    return TRUE;
3674
 
3675
  return FALSE;
3676
}
3677
 
3678
static bfd_vma
3679
xcoff_loader_symbol_offset (abfd, ldhdr)
3680
    bfd *abfd;
3681
    struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
3682
{
3683
  return bfd_xcoff_ldhdrsz (abfd);
3684
}
3685
 
3686
static bfd_vma
3687
xcoff_loader_reloc_offset (abfd, ldhdr)
3688
    bfd *abfd;
3689
    struct internal_ldhdr *ldhdr;
3690
{
3691
  return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
3692
}
3693
 
3694
static bfd_boolean
3695
xcoff_generate_rtinit  (abfd, init, fini, rtld)
3696
     bfd *abfd;
3697
     const char *init;
3698
     const char *fini;
3699
     bfd_boolean rtld;
3700
{
3701
  bfd_byte filehdr_ext[FILHSZ];
3702
  bfd_byte scnhdr_ext[SCNHSZ];
3703
  bfd_byte syment_ext[SYMESZ * 10];
3704
  bfd_byte reloc_ext[RELSZ * 3];
3705
  bfd_byte *data_buffer;
3706
  bfd_size_type data_buffer_size;
3707
  bfd_byte *string_table = NULL, *st_tmp = NULL;
3708
  bfd_size_type string_table_size;
3709
  bfd_vma val;
3710
  size_t initsz, finisz;
3711
  struct internal_filehdr filehdr;
3712
  struct internal_scnhdr scnhdr;
3713
  struct internal_syment syment;
3714
  union internal_auxent auxent;
3715
  struct internal_reloc reloc;
3716
 
3717
  char *data_name = ".data";
3718
  char *rtinit_name = "__rtinit";
3719
  char *rtld_name = "__rtld";
3720
 
3721
  if (! bfd_xcoff_rtinit_size (abfd))
3722
    return FALSE;
3723
 
3724
  initsz = (init == NULL ? 0 : 1 + strlen (init));
3725
  finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3726
 
3727
  /* file header */
3728
  memset (filehdr_ext, 0, FILHSZ);
3729
  memset (&filehdr, 0, sizeof (struct internal_filehdr));
3730
  filehdr.f_magic = bfd_xcoff_magic_number (abfd);
3731
  filehdr.f_nscns = 1;
3732
  filehdr.f_timdat = 0;
3733
  filehdr.f_nsyms = 0;  /* at least 6, no more than 10 */
3734
  filehdr.f_symptr = 0; /* set below */
3735
  filehdr.f_opthdr = 0;
3736
  filehdr.f_flags = 0;
3737
 
3738
  /* section header */
3739
  memset (scnhdr_ext, 0, SCNHSZ);
3740
  memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3741
  memcpy (scnhdr.s_name, data_name, strlen (data_name));
3742
  scnhdr.s_paddr = 0;
3743
  scnhdr.s_vaddr = 0;
3744
  scnhdr.s_size = 0;    /* set below */
3745
  scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3746
  scnhdr.s_relptr = 0;  /* set below */
3747
  scnhdr.s_lnnoptr = 0;
3748
  scnhdr.s_nreloc = 0;  /* either 1 or 2 */
3749
  scnhdr.s_nlnno = 0;
3750
  scnhdr.s_flags = STYP_DATA;
3751
 
3752
  /* .data
3753
     0x0000           0x00000000 : rtl
3754
     0x0004           0x00000010 : offset to init, or 0
3755
     0x0008           0x00000028 : offset to fini, or 0
3756
     0x000C           0x0000000C : size of descriptor
3757
     0x0010           0x00000000 : init, needs a reloc
3758
     0x0014           0x00000040 : offset to init name
3759
     0x0018           0x00000000 : flags, padded to a word
3760
     0x001C           0x00000000 : empty init
3761
     0x0020           0x00000000 :
3762
     0x0024           0x00000000 :
3763
     0x0028           0x00000000 : fini, needs a reloc
3764
     0x002C           0x00000??? : offset to fini name
3765
     0x0030           0x00000000 : flags, padded to a word
3766
     0x0034           0x00000000 : empty fini
3767
     0x0038           0x00000000 :
3768
     0x003C           0x00000000 :
3769
     0x0040           init name
3770
     0x0040 + initsz  fini name */
3771
 
3772
  data_buffer_size = 0x0040 + initsz + finisz;
3773
  data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
3774
  data_buffer = NULL;
3775
  data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
3776
  if (data_buffer == NULL)
3777
    return FALSE;
3778
 
3779
  if (initsz)
3780
    {
3781
      val = 0x10;
3782
      bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
3783
      val = 0x40;
3784
      bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
3785
      memcpy (&data_buffer[val], init, initsz);
3786
    }
3787
 
3788
  if (finisz)
3789
    {
3790
      val = 0x28;
3791
      bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
3792
      val = 0x40 + initsz;
3793
      bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
3794
      memcpy (&data_buffer[val], fini, finisz);
3795
    }
3796
 
3797
  val = 0x0C;
3798
  bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
3799
 
3800
  scnhdr.s_size = data_buffer_size;
3801
 
3802
  /* string table */
3803
  string_table_size = 0;
3804
  if (initsz > 9)
3805
    string_table_size += initsz;
3806
  if (finisz > 9)
3807
    string_table_size += finisz;
3808
  if (string_table_size)
3809
    {
3810
      string_table_size += 4;
3811
      string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
3812
      if (string_table == NULL)
3813
        return FALSE;
3814
 
3815
      val = string_table_size;
3816
      bfd_h_put_32 (abfd, val, &string_table[0]);
3817
      st_tmp = string_table + 4;
3818
    }
3819
 
3820
  /* symbols
3821
     0. .data csect
3822
     2. __rtinit
3823
     4. init function
3824
     6. fini function
3825
     8. __rtld  */
3826
  memset (syment_ext, 0, 10 * SYMESZ);
3827
  memset (reloc_ext, 0, 3 * RELSZ);
3828
 
3829
  /* .data csect */
3830
  memset (&syment, 0, sizeof (struct internal_syment));
3831
  memset (&auxent, 0, sizeof (union internal_auxent));
3832
  memcpy (syment._n._n_name, data_name, strlen (data_name));
3833
  syment.n_scnum = 1;
3834
  syment.n_sclass = C_HIDEXT;
3835
  syment.n_numaux = 1;
3836
  auxent.x_csect.x_scnlen.l = data_buffer_size;
3837
  auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
3838
  auxent.x_csect.x_smclas = XMC_RW;
3839
  bfd_coff_swap_sym_out (abfd, &syment,
3840
                         &syment_ext[filehdr.f_nsyms * SYMESZ]);
3841
  bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3842
                         syment.n_numaux,
3843
                         &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3844
  filehdr.f_nsyms += 2;
3845
 
3846
  /* __rtinit */
3847
  memset (&syment, 0, sizeof (struct internal_syment));
3848
  memset (&auxent, 0, sizeof (union internal_auxent));
3849
  memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
3850
  syment.n_scnum = 1;
3851
  syment.n_sclass = C_EXT;
3852
  syment.n_numaux = 1;
3853
  auxent.x_csect.x_smtyp = XTY_LD;
3854
  auxent.x_csect.x_smclas = XMC_RW;
3855
  bfd_coff_swap_sym_out (abfd, &syment,
3856
                         &syment_ext[filehdr.f_nsyms * SYMESZ]);
3857
  bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3858
                         syment.n_numaux,
3859
                         &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3860
  filehdr.f_nsyms += 2;
3861
 
3862
  /* init */
3863
  if (initsz)
3864
    {
3865
      memset (&syment, 0, sizeof (struct internal_syment));
3866
      memset (&auxent, 0, sizeof (union internal_auxent));
3867
 
3868
      if (initsz > 9)
3869
        {
3870
          syment._n._n_n._n_offset = st_tmp - string_table;
3871
          memcpy (st_tmp, init, initsz);
3872
          st_tmp += initsz;
3873
        }
3874
      else
3875
        memcpy (syment._n._n_name, init, initsz - 1);
3876
 
3877
      syment.n_sclass = C_EXT;
3878
      syment.n_numaux = 1;
3879
      bfd_coff_swap_sym_out (abfd, &syment,
3880
                             &syment_ext[filehdr.f_nsyms * SYMESZ]);
3881
      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3882
                             syment.n_numaux,
3883
                             &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3884
 
3885
      /* reloc */
3886
      memset (&reloc, 0, sizeof (struct internal_reloc));
3887
      reloc.r_vaddr = 0x0010;
3888
      reloc.r_symndx = filehdr.f_nsyms;
3889
      reloc.r_type = R_POS;
3890
      reloc.r_size = 31;
3891
      bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
3892
 
3893
      filehdr.f_nsyms += 2;
3894
      scnhdr.s_nreloc += 1;
3895
    }
3896
 
3897
  /* fini */
3898
  if (finisz)
3899
    {
3900
      memset (&syment, 0, sizeof (struct internal_syment));
3901
      memset (&auxent, 0, sizeof (union internal_auxent));
3902
 
3903
      if (finisz > 9)
3904
        {
3905
          syment._n._n_n._n_offset = st_tmp - string_table;
3906
          memcpy (st_tmp, fini, finisz);
3907
          st_tmp += finisz;
3908
        }
3909
      else
3910
        memcpy (syment._n._n_name, fini, finisz - 1);
3911
 
3912
      syment.n_sclass = C_EXT;
3913
      syment.n_numaux = 1;
3914
      bfd_coff_swap_sym_out (abfd, &syment,
3915
                             &syment_ext[filehdr.f_nsyms * SYMESZ]);
3916
      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3917
                             syment.n_numaux,
3918
                             &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3919
 
3920
      /* reloc */
3921
      memset (&reloc, 0, sizeof (struct internal_reloc));
3922
      reloc.r_vaddr = 0x0028;
3923
      reloc.r_symndx = filehdr.f_nsyms;
3924
      reloc.r_type = R_POS;
3925
      reloc.r_size = 31;
3926
      bfd_coff_swap_reloc_out (abfd, &reloc,
3927
                               &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3928
 
3929
      filehdr.f_nsyms += 2;
3930
      scnhdr.s_nreloc += 1;
3931
    }
3932
 
3933
  if (rtld)
3934
    {
3935
      memset (&syment, 0, sizeof (struct internal_syment));
3936
      memset (&auxent, 0, sizeof (union internal_auxent));
3937
      memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
3938
      syment.n_sclass = C_EXT;
3939
      syment.n_numaux = 1;
3940
      bfd_coff_swap_sym_out (abfd, &syment,
3941
                             &syment_ext[filehdr.f_nsyms * SYMESZ]);
3942
      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3943
                             syment.n_numaux,
3944
                             &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3945
 
3946
      /* reloc */
3947
      memset (&reloc, 0, sizeof (struct internal_reloc));
3948
      reloc.r_vaddr = 0x0000;
3949
      reloc.r_symndx = filehdr.f_nsyms;
3950
      reloc.r_type = R_POS;
3951
      reloc.r_size = 31;
3952
      bfd_coff_swap_reloc_out (abfd, &reloc,
3953
                               &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3954
 
3955
      filehdr.f_nsyms += 2;
3956
      scnhdr.s_nreloc += 1;
3957
    }
3958
 
3959
  scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
3960
  filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
3961
 
3962
  bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
3963
  bfd_bwrite (filehdr_ext, FILHSZ, abfd);
3964
  bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
3965
  bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
3966
  bfd_bwrite (data_buffer, data_buffer_size, abfd);
3967
  bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
3968
  bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
3969
  bfd_bwrite (string_table, string_table_size, abfd);
3970
 
3971
  free (data_buffer);
3972
  data_buffer = NULL;
3973
 
3974
  return TRUE;
3975
}
3976
 
3977
 
3978
static reloc_howto_type xcoff_dynamic_reloc =
3979
HOWTO (0,                        /* type */
3980
       0,                        /* rightshift */
3981
       2,                       /* size (0 = byte, 1 = short, 2 = long) */
3982
       32,                      /* bitsize */
3983
       FALSE,                   /* pc_relative */
3984
       0,                        /* bitpos */
3985
       complain_overflow_bitfield, /* complain_on_overflow */
3986
       0,                        /* special_function */
3987
       "R_POS",                 /* name */
3988
       TRUE,                    /* partial_inplace */
3989
       0xffffffff,              /* src_mask */
3990
       0xffffffff,              /* dst_mask */
3991
       FALSE);                  /* pcrel_offset */
3992
 
3993
/*  glink
3994
 
3995
   The first word of global linkage code must be modified by filling in
3996
   the correct TOC offset.  */
3997
 
3998
static unsigned long xcoff_glink_code[9] =
3999
  {
4000
    0x81820000, /* lwz r12,0(r2) */
4001
    0x90410014, /* stw r2,20(r1) */
4002
    0x800c0000, /* lwz r0,0(r12) */
4003
    0x804c0004, /* lwz r2,4(r12) */
4004
    0x7c0903a6, /* mtctr r0 */
4005
    0x4e800420, /* bctr */
4006
    0x00000000, /* start of traceback table */
4007
    0x000c8000, /* traceback table */
4008
    0x00000000, /* traceback table */
4009
  };
4010
 
4011
 
4012
static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
4013
  {
4014
    { /* COFF backend, defined in libcoff.h.  */
4015
      _bfd_xcoff_swap_aux_in,
4016
      _bfd_xcoff_swap_sym_in,
4017
      coff_swap_lineno_in,
4018
      _bfd_xcoff_swap_aux_out,
4019
      _bfd_xcoff_swap_sym_out,
4020
      coff_swap_lineno_out,
4021
      xcoff_swap_reloc_out,
4022
      coff_swap_filehdr_out,
4023
      coff_swap_aouthdr_out,
4024
      coff_swap_scnhdr_out,
4025
      FILHSZ,
4026
      AOUTSZ,
4027
      SCNHSZ,
4028
      SYMESZ,
4029
      AUXESZ,
4030
      RELSZ,
4031
      LINESZ,
4032
      FILNMLEN,
4033
      TRUE,                     /* _bfd_coff_long_filenames */
4034 225 jeremybenn
      XCOFF_NO_LONG_SECTION_NAMES,  /* _bfd_coff_long_section_names */
4035 24 jeremybenn
      3,                        /* _bfd_coff_default_section_alignment_power */
4036
      FALSE,                    /* _bfd_coff_force_symnames_in_strings */
4037
      2,                        /* _bfd_coff_debug_string_prefix_length */
4038
      coff_swap_filehdr_in,
4039
      coff_swap_aouthdr_in,
4040
      coff_swap_scnhdr_in,
4041
      xcoff_swap_reloc_in,
4042
      coff_bad_format_hook,
4043
      coff_set_arch_mach_hook,
4044
      coff_mkobject_hook,
4045
      styp_to_sec_flags,
4046
      coff_set_alignment_hook,
4047
      coff_slurp_symbol_table,
4048
      symname_in_debug_hook,
4049
      coff_pointerize_aux_hook,
4050
      coff_print_aux,
4051
      dummy_reloc16_extra_cases,
4052
      dummy_reloc16_estimate,
4053
      NULL,                     /* bfd_coff_sym_is_global */
4054
      coff_compute_section_file_positions,
4055
      NULL,                     /* _bfd_coff_start_final_link */
4056
      xcoff_ppc_relocate_section,
4057
      coff_rtype_to_howto,
4058
      NULL,                     /* _bfd_coff_adjust_symndx */
4059
      _bfd_generic_link_add_one_symbol,
4060
      coff_link_output_has_begun,
4061 225 jeremybenn
      coff_final_link_postscript,
4062
      NULL                      /* print_pdata.  */
4063 24 jeremybenn
    },
4064
 
4065
    0x01DF,                     /* magic number */
4066
    bfd_arch_rs6000,
4067
    bfd_mach_rs6k,
4068
 
4069
    /* Function pointers to xcoff specific swap routines.  */
4070
    xcoff_swap_ldhdr_in,
4071
    xcoff_swap_ldhdr_out,
4072
    xcoff_swap_ldsym_in,
4073
    xcoff_swap_ldsym_out,
4074
    xcoff_swap_ldrel_in,
4075
    xcoff_swap_ldrel_out,
4076
 
4077
    /* Sizes.  */
4078
    LDHDRSZ,
4079
    LDSYMSZ,
4080
    LDRELSZ,
4081
    12,                         /* _xcoff_function_descriptor_size */
4082
    SMALL_AOUTSZ,
4083
 
4084
    /* Versions.  */
4085
    1,                          /* _xcoff_ldhdr_version */
4086
 
4087
    _bfd_xcoff_put_symbol_name,
4088
    _bfd_xcoff_put_ldsymbol_name,
4089
    &xcoff_dynamic_reloc,
4090
    xcoff_create_csect_from_smclas,
4091
 
4092
    /* Lineno and reloc count overflow.  */
4093
    xcoff_is_lineno_count_overflow,
4094
    xcoff_is_reloc_count_overflow,
4095
 
4096
    xcoff_loader_symbol_offset,
4097
    xcoff_loader_reloc_offset,
4098
 
4099
    /* glink.  */
4100
    &xcoff_glink_code[0],
4101
    36,                         /* _xcoff_glink_size */
4102
 
4103
    /* rtinit */
4104
    64,                         /* _xcoff_rtinit_size */
4105
    xcoff_generate_rtinit,
4106
  };
4107
 
4108
/* The transfer vector that leads the outside world to all of the above.  */
4109
const bfd_target rs6000coff_vec =
4110
  {
4111
    "aixcoff-rs6000",
4112
    bfd_target_xcoff_flavour,
4113
    BFD_ENDIAN_BIG,             /* data byte order is big */
4114
    BFD_ENDIAN_BIG,             /* header byte order is big */
4115
 
4116
    (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4117
     | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4118
 
4119
    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
4120
    0,                           /* leading char */
4121
    '/',                        /* ar_pad_char */
4122
    15,                         /* ar_max_namelen */
4123
 
4124
    /* data */
4125
    bfd_getb64,
4126
    bfd_getb_signed_64,
4127
    bfd_putb64,
4128
    bfd_getb32,
4129
    bfd_getb_signed_32,
4130
    bfd_putb32,
4131
    bfd_getb16,
4132
    bfd_getb_signed_16,
4133
    bfd_putb16,
4134
 
4135
    /* hdrs */
4136
    bfd_getb64,
4137
    bfd_getb_signed_64,
4138
    bfd_putb64,
4139
    bfd_getb32,
4140
    bfd_getb_signed_32,
4141
    bfd_putb32,
4142
    bfd_getb16,
4143
    bfd_getb_signed_16,
4144
    bfd_putb16,
4145
 
4146
    { /* bfd_check_format */
4147
      _bfd_dummy_target,
4148
      coff_object_p,
4149
      _bfd_xcoff_archive_p,
4150
      CORE_FILE_P
4151
    },
4152
 
4153
    { /* bfd_set_format */
4154
      bfd_false,
4155
      coff_mkobject,
4156
      _bfd_generic_mkarchive,
4157
      bfd_false
4158
    },
4159
 
4160
    {/* bfd_write_contents */
4161
      bfd_false,
4162
      coff_write_object_contents,
4163
      _bfd_xcoff_write_archive_contents,
4164
      bfd_false
4165
    },
4166
 
4167
    /* Generic */
4168
    bfd_true,
4169
    bfd_true,
4170
    coff_new_section_hook,
4171
    _bfd_generic_get_section_contents,
4172
    _bfd_generic_get_section_contents_in_window,
4173
 
4174
    /* Copy */
4175
    _bfd_xcoff_copy_private_bfd_data,
4176
    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4177
    _bfd_generic_init_private_section_data,
4178
    ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4179
    ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4180
    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4181
    ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
4182
    ((bfd_boolean (*) (bfd *, void * )) bfd_true),
4183
 
4184
    /* Core */
4185
    coff_core_file_failing_command,
4186
    coff_core_file_failing_signal,
4187
    coff_core_file_matches_executable_p,
4188
 
4189
    /* Archive */
4190
    _bfd_xcoff_slurp_armap,
4191
    bfd_false,
4192
    ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4193
    bfd_dont_truncate_arname,
4194
    _bfd_xcoff_write_armap,
4195
    _bfd_xcoff_read_ar_hdr,
4196
    _bfd_xcoff_openr_next_archived_file,
4197
    _bfd_generic_get_elt_at_index,
4198
    _bfd_xcoff_stat_arch_elt,
4199
    bfd_true,
4200
 
4201
    /* Symbols */
4202
    coff_get_symtab_upper_bound,
4203
    coff_canonicalize_symtab,
4204
    coff_make_empty_symbol,
4205
    coff_print_symbol,
4206
    coff_get_symbol_info,
4207
    _bfd_xcoff_is_local_label_name,
4208
    coff_bfd_is_target_special_symbol,
4209
    coff_get_lineno,
4210
    coff_find_nearest_line,
4211
    _bfd_generic_find_line,
4212
    coff_find_inliner_info,
4213
    coff_bfd_make_debug_symbol,
4214
    _bfd_generic_read_minisymbols,
4215
    _bfd_generic_minisymbol_to_symbol,
4216
 
4217
    /* Reloc */
4218
    coff_get_reloc_upper_bound,
4219
    coff_canonicalize_reloc,
4220
    _bfd_xcoff_reloc_type_lookup,
4221
    _bfd_xcoff_reloc_name_lookup,
4222
 
4223
    /* Write */
4224
    coff_set_arch_mach,
4225
    coff_set_section_contents,
4226
 
4227
    /* Link */
4228
    _bfd_xcoff_sizeof_headers,
4229
    bfd_generic_get_relocated_section_contents,
4230
    bfd_generic_relax_section,
4231
    _bfd_xcoff_bfd_link_hash_table_create,
4232
    _bfd_generic_link_hash_table_free,
4233
    _bfd_xcoff_bfd_link_add_symbols,
4234
    _bfd_generic_link_just_syms,
4235
    _bfd_xcoff_bfd_final_link,
4236
    _bfd_generic_link_split_section,
4237
    bfd_generic_gc_sections,
4238
    bfd_generic_merge_sections,
4239
    bfd_generic_is_group_section,
4240
    bfd_generic_discard_group,
4241
    _bfd_generic_section_already_linked,
4242 225 jeremybenn
    _bfd_xcoff_define_common_symbol,
4243 24 jeremybenn
 
4244
    /* Dynamic */
4245
    _bfd_xcoff_get_dynamic_symtab_upper_bound,
4246
    _bfd_xcoff_canonicalize_dynamic_symtab,
4247
    _bfd_nodynamic_get_synthetic_symtab,
4248
    _bfd_xcoff_get_dynamic_reloc_upper_bound,
4249
    _bfd_xcoff_canonicalize_dynamic_reloc,
4250
 
4251
    /* Opposite endian version, none exists */
4252
    NULL,
4253
 
4254
    (void *) &bfd_xcoff_backend_data,
4255
  };
4256
 
4257
/* xcoff-powermac target
4258
   Old target.
4259
   Only difference between this target and the rs6000 target is the
4260
   the default architecture and machine type used in coffcode.h
4261
 
4262
   PowerPC Macs use the same magic numbers as RS/6000
4263
   (because that's how they were bootstrapped originally),
4264
   but they are always PowerPC architecture.  */
4265
static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
4266
  {
4267
    { /* COFF backend, defined in libcoff.h.  */
4268
      _bfd_xcoff_swap_aux_in,
4269
      _bfd_xcoff_swap_sym_in,
4270
      coff_swap_lineno_in,
4271
      _bfd_xcoff_swap_aux_out,
4272
      _bfd_xcoff_swap_sym_out,
4273
      coff_swap_lineno_out,
4274
      xcoff_swap_reloc_out,
4275
      coff_swap_filehdr_out,
4276
      coff_swap_aouthdr_out,
4277
      coff_swap_scnhdr_out,
4278
      FILHSZ,
4279
      AOUTSZ,
4280
      SCNHSZ,
4281
      SYMESZ,
4282
      AUXESZ,
4283
      RELSZ,
4284
      LINESZ,
4285
      FILNMLEN,
4286
      TRUE,                     /* _bfd_coff_long_filenames */
4287 225 jeremybenn
      XCOFF_NO_LONG_SECTION_NAMES,  /* _bfd_coff_long_section_names */
4288 24 jeremybenn
      3,                        /* _bfd_coff_default_section_alignment_power */
4289
      FALSE,                    /* _bfd_coff_force_symnames_in_strings */
4290
      2,                        /* _bfd_coff_debug_string_prefix_length */
4291
      coff_swap_filehdr_in,
4292
      coff_swap_aouthdr_in,
4293
      coff_swap_scnhdr_in,
4294
      xcoff_swap_reloc_in,
4295
      coff_bad_format_hook,
4296
      coff_set_arch_mach_hook,
4297
      coff_mkobject_hook,
4298
      styp_to_sec_flags,
4299
      coff_set_alignment_hook,
4300
      coff_slurp_symbol_table,
4301
      symname_in_debug_hook,
4302
      coff_pointerize_aux_hook,
4303
      coff_print_aux,
4304
      dummy_reloc16_extra_cases,
4305
      dummy_reloc16_estimate,
4306
      NULL,                     /* bfd_coff_sym_is_global */
4307
      coff_compute_section_file_positions,
4308
      NULL,                     /* _bfd_coff_start_final_link */
4309
      xcoff_ppc_relocate_section,
4310
      coff_rtype_to_howto,
4311
      NULL,                     /* _bfd_coff_adjust_symndx */
4312
      _bfd_generic_link_add_one_symbol,
4313
      coff_link_output_has_begun,
4314 225 jeremybenn
      coff_final_link_postscript,
4315
      NULL                      /* print_pdata.  */
4316 24 jeremybenn
    },
4317
 
4318
    0x01DF,                     /* magic number */
4319
    bfd_arch_powerpc,
4320
    bfd_mach_ppc,
4321
 
4322
    /* Function pointers to xcoff specific swap routines.  */
4323
    xcoff_swap_ldhdr_in,
4324
    xcoff_swap_ldhdr_out,
4325
    xcoff_swap_ldsym_in,
4326
    xcoff_swap_ldsym_out,
4327
    xcoff_swap_ldrel_in,
4328
    xcoff_swap_ldrel_out,
4329
 
4330
    /* Sizes.  */
4331
    LDHDRSZ,
4332
    LDSYMSZ,
4333
    LDRELSZ,
4334
    12,                         /* _xcoff_function_descriptor_size */
4335
    SMALL_AOUTSZ,
4336
 
4337
    /* Versions.  */
4338
    1,                          /* _xcoff_ldhdr_version */
4339
 
4340
    _bfd_xcoff_put_symbol_name,
4341
    _bfd_xcoff_put_ldsymbol_name,
4342
    &xcoff_dynamic_reloc,
4343
    xcoff_create_csect_from_smclas,
4344
 
4345
    /* Lineno and reloc count overflow.  */
4346
    xcoff_is_lineno_count_overflow,
4347
    xcoff_is_reloc_count_overflow,
4348
 
4349
    xcoff_loader_symbol_offset,
4350
    xcoff_loader_reloc_offset,
4351
 
4352
    /* glink.  */
4353
    &xcoff_glink_code[0],
4354
    36,                         /* _xcoff_glink_size */
4355
 
4356
    /* rtinit */
4357
    0,                           /* _xcoff_rtinit_size */
4358
    xcoff_generate_rtinit,
4359
  };
4360
 
4361
/* The transfer vector that leads the outside world to all of the above.  */
4362
const bfd_target pmac_xcoff_vec =
4363
  {
4364
    "xcoff-powermac",
4365
    bfd_target_xcoff_flavour,
4366
    BFD_ENDIAN_BIG,             /* data byte order is big */
4367
    BFD_ENDIAN_BIG,             /* header byte order is big */
4368
 
4369
    (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4370
     | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4371
 
4372
    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
4373
    0,                           /* leading char */
4374
    '/',                        /* ar_pad_char */
4375
    15,                         /* ar_max_namelen */
4376
 
4377
    /* data */
4378
    bfd_getb64,
4379
    bfd_getb_signed_64,
4380
    bfd_putb64,
4381
    bfd_getb32,
4382
    bfd_getb_signed_32,
4383
    bfd_putb32,
4384
    bfd_getb16,
4385
    bfd_getb_signed_16,
4386
    bfd_putb16,
4387
 
4388
    /* hdrs */
4389
    bfd_getb64,
4390
    bfd_getb_signed_64,
4391
    bfd_putb64,
4392
    bfd_getb32,
4393
    bfd_getb_signed_32,
4394
    bfd_putb32,
4395
    bfd_getb16,
4396
    bfd_getb_signed_16,
4397
    bfd_putb16,
4398
 
4399
    { /* bfd_check_format */
4400
      _bfd_dummy_target,
4401
      coff_object_p,
4402
      _bfd_xcoff_archive_p,
4403
      CORE_FILE_P
4404
    },
4405
 
4406
    { /* bfd_set_format */
4407
      bfd_false,
4408
      coff_mkobject,
4409
      _bfd_generic_mkarchive,
4410
      bfd_false
4411
    },
4412
 
4413
    {/* bfd_write_contents */
4414
      bfd_false,
4415
      coff_write_object_contents,
4416
      _bfd_xcoff_write_archive_contents,
4417
      bfd_false
4418
    },
4419
 
4420
    /* Generic */
4421
    bfd_true,
4422
    bfd_true,
4423
    coff_new_section_hook,
4424
    _bfd_generic_get_section_contents,
4425
    _bfd_generic_get_section_contents_in_window,
4426
 
4427
    /* Copy */
4428
    _bfd_xcoff_copy_private_bfd_data,
4429
    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4430
    _bfd_generic_init_private_section_data,
4431
    ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
4432
    ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
4433
    ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
4434
    ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
4435
    ((bfd_boolean (*) (bfd *, void * )) bfd_true),
4436
 
4437
    /* Core */
4438
    coff_core_file_failing_command,
4439
    coff_core_file_failing_signal,
4440
    coff_core_file_matches_executable_p,
4441
 
4442
    /* Archive */
4443
    _bfd_xcoff_slurp_armap,
4444
    bfd_false,
4445
    ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
4446
    bfd_dont_truncate_arname,
4447
    _bfd_xcoff_write_armap,
4448
    _bfd_xcoff_read_ar_hdr,
4449
    _bfd_xcoff_openr_next_archived_file,
4450
    _bfd_generic_get_elt_at_index,
4451
    _bfd_xcoff_stat_arch_elt,
4452
    bfd_true,
4453
 
4454
    /* Symbols */
4455
    coff_get_symtab_upper_bound,
4456
    coff_canonicalize_symtab,
4457
    coff_make_empty_symbol,
4458
    coff_print_symbol,
4459
    coff_get_symbol_info,
4460
    _bfd_xcoff_is_local_label_name,
4461
    coff_bfd_is_target_special_symbol,
4462
    coff_get_lineno,
4463
    coff_find_nearest_line,
4464
    _bfd_generic_find_line,
4465
    coff_find_inliner_info,
4466
    coff_bfd_make_debug_symbol,
4467
    _bfd_generic_read_minisymbols,
4468
    _bfd_generic_minisymbol_to_symbol,
4469
 
4470
    /* Reloc */
4471
    coff_get_reloc_upper_bound,
4472
    coff_canonicalize_reloc,
4473
    _bfd_xcoff_reloc_type_lookup,
4474
    _bfd_xcoff_reloc_name_lookup,
4475
 
4476
    /* Write */
4477
    coff_set_arch_mach,
4478
    coff_set_section_contents,
4479
 
4480
    /* Link */
4481
    _bfd_xcoff_sizeof_headers,
4482
    bfd_generic_get_relocated_section_contents,
4483
    bfd_generic_relax_section,
4484
    _bfd_xcoff_bfd_link_hash_table_create,
4485
    _bfd_generic_link_hash_table_free,
4486
    _bfd_xcoff_bfd_link_add_symbols,
4487
    _bfd_generic_link_just_syms,
4488
    _bfd_xcoff_bfd_final_link,
4489
    _bfd_generic_link_split_section,
4490
    bfd_generic_gc_sections,
4491
    bfd_generic_merge_sections,
4492
    bfd_generic_is_group_section,
4493
    bfd_generic_discard_group,
4494
    _bfd_generic_section_already_linked,
4495 225 jeremybenn
    _bfd_xcoff_define_common_symbol,
4496 24 jeremybenn
 
4497
    /* Dynamic */
4498
    _bfd_xcoff_get_dynamic_symtab_upper_bound,
4499
    _bfd_xcoff_canonicalize_dynamic_symtab,
4500
    _bfd_nodynamic_get_synthetic_symtab,
4501
    _bfd_xcoff_get_dynamic_reloc_upper_bound,
4502
    _bfd_xcoff_canonicalize_dynamic_reloc,
4503
 
4504
    /* Opposite endian version, none exists */
4505
    NULL,
4506
 
4507
    (void *) &bfd_pmac_xcoff_backend_data,
4508
  };

powered by: WebSVN 2.1.0

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