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