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