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