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