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