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