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

Subversion Repositories or1k_old

[/] [or1k_old/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [coff-rs6000.c] - Blame information for rev 1765

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

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

powered by: WebSVN 2.1.0

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