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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [bfd/] [coff-rs6000.c] - Blame information for rev 179

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

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

powered by: WebSVN 2.1.0

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