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