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