Harmonize and improve auxiliary entries support for XCOFF
[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);
05f52dc2
AM
1622 amt = sizeof (struct areltdata) + SIZEOF_AR_HDR + namlen + 1;
1623 ret = (struct areltdata *) bfd_malloc (amt);
1624 if (ret == NULL)
1625 return ret;
1626
1627 hdrp = (struct xcoff_ar_hdr *) (ret + 1);
5ea1af0d 1628 memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
dc810e39 1629 if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
5ea1af0d
GK
1630 {
1631 free (ret);
1632 return NULL;
1633 }
1634 ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
1635
1636 ret->arch_header = (char *) hdrp;
677bd4c6 1637 GET_VALUE_IN_FIELD (ret->parsed_size, hdr.size, 10);
5ea1af0d
GK
1638 ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
1639 }
1640 else
1641 {
1642 struct xcoff_ar_hdr_big hdr;
1643 struct xcoff_ar_hdr_big *hdrp;
1644
05f52dc2
AM
1645 if (bfd_bread (&hdr, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG)
1646 return NULL;
5ea1af0d 1647
677bd4c6 1648 GET_VALUE_IN_FIELD (namlen, hdr.namlen, 10);
05f52dc2
AM
1649 amt = sizeof (struct areltdata) + SIZEOF_AR_HDR_BIG + namlen + 1;
1650 ret = (struct areltdata *) bfd_malloc (amt);
1651 if (ret == NULL)
1652 return ret;
1653
1654 hdrp = (struct xcoff_ar_hdr_big *) (ret + 1);
5ea1af0d 1655 memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
dc810e39 1656 if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
5ea1af0d
GK
1657 {
1658 free (ret);
1659 return NULL;
1660 }
1661 ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
1662
1663 ret->arch_header = (char *) hdrp;
677bd4c6 1664 GET_VALUE_IN_FIELD (ret->parsed_size, hdr.size, 10);
5ea1af0d
GK
1665 ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
1666 }
252b5132
RH
1667
1668 /* Skip over the XCOFFARFMAG at the end of the file name. */
dc810e39 1669 if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
252b5132
RH
1670 return NULL;
1671
2c3fc389 1672 return ret;
252b5132
RH
1673}
1674
1675/* Open the next element in an XCOFF archive. */
1676
7f6d05e8 1677bfd *
417236c0 1678_bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
252b5132
RH
1679{
1680 file_ptr filestart;
1681
1682 if (xcoff_ardata (archive) == NULL)
1683 {
1684 bfd_set_error (bfd_error_invalid_operation);
1685 return NULL;
1686 }
1687
5ea1af0d
GK
1688 if (! xcoff_big_format_p (archive))
1689 {
1690 if (last_file == NULL)
1691 filestart = bfd_ardata (archive)->first_file_filepos;
1692 else
677bd4c6 1693 GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff, 10);
5ea1af0d
GK
1694
1695 if (filestart == 0
677bd4c6
AM
1696 || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->memoff, 10)
1697 || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->symoff, 10))
5ea1af0d
GK
1698 {
1699 bfd_set_error (bfd_error_no_more_archived_files);
1700 return NULL;
1701 }
1702 }
252b5132 1703 else
252b5132 1704 {
5ea1af0d
GK
1705 if (last_file == NULL)
1706 filestart = bfd_ardata (archive)->first_file_filepos;
1707 else
677bd4c6 1708 GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff, 10);
29866fa1 1709
5ea1af0d 1710 if (filestart == 0
677bd4c6
AM
1711 || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->memoff, 10)
1712 || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->symoff, 10))
5ea1af0d
GK
1713 {
1714 bfd_set_error (bfd_error_no_more_archived_files);
1715 return NULL;
1716 }
252b5132
RH
1717 }
1718
1719 return _bfd_get_elt_at_filepos (archive, filestart);
1720}
1721
1722/* Stat an element in an XCOFF archive. */
1723
7f6d05e8 1724int
417236c0 1725_bfd_xcoff_stat_arch_elt (bfd *abfd, struct stat *s)
252b5132 1726{
252b5132
RH
1727 if (abfd->arelt_data == NULL)
1728 {
1729 bfd_set_error (bfd_error_invalid_operation);
1730 return -1;
1731 }
1732
51b9608c 1733 if (! xcoff_big_format_p (abfd->my_archive))
5ea1af0d
GK
1734 {
1735 struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
1736
677bd4c6
AM
1737 GET_VALUE_IN_FIELD (s->st_mtime, hdrp->date, 10);
1738 GET_VALUE_IN_FIELD (s->st_uid, hdrp->uid, 10);
1739 GET_VALUE_IN_FIELD (s->st_gid, hdrp->gid, 10);
1740 GET_VALUE_IN_FIELD (s->st_mode, hdrp->mode, 8);
5ea1af0d
GK
1741 s->st_size = arch_eltdata (abfd)->parsed_size;
1742 }
1743 else
1744 {
1745 struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
252b5132 1746
677bd4c6
AM
1747 GET_VALUE_IN_FIELD (s->st_mtime, hdrp->date, 10);
1748 GET_VALUE_IN_FIELD (s->st_uid, hdrp->uid, 10);
1749 GET_VALUE_IN_FIELD (s->st_gid, hdrp->gid, 10);
1750 GET_VALUE_IN_FIELD (s->st_mode, hdrp->mode, 8);
5ea1af0d
GK
1751 s->st_size = arch_eltdata (abfd)->parsed_size;
1752 }
252b5132
RH
1753
1754 return 0;
1755}
1756
1757/* Normalize a file name for inclusion in an archive. */
1758
1759static const char *
417236c0 1760normalize_filename (bfd *abfd)
252b5132
RH
1761{
1762 const char *file;
1763 const char *filename;
1764
1765 file = bfd_get_filename (abfd);
1766 filename = strrchr (file, '/');
1767 if (filename != NULL)
1768 filename++;
1769 else
1770 filename = file;
1771 return filename;
1772}
1773
1774/* Write out an XCOFF armap. */
1775
0a1b45a2 1776static bool
417236c0 1777xcoff_write_armap_old (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
07d6d2b8 1778 struct orl *map, unsigned int orl_count, int stridx)
252b5132 1779{
2e470849 1780 struct archive_iterator iterator;
252b5132
RH
1781 struct xcoff_ar_hdr hdr;
1782 char *p;
1783 unsigned char buf[4];
252b5132
RH
1784 unsigned int i;
1785
1786 memset (&hdr, 0, sizeof hdr);
1787 sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
1788 sprintf (hdr.nextoff, "%d", 0);
330693f5 1789 memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
252b5132
RH
1790 sprintf (hdr.date, "%d", 0);
1791 sprintf (hdr.uid, "%d", 0);
1792 sprintf (hdr.gid, "%d", 0);
1793 sprintf (hdr.mode, "%d", 0);
1794 sprintf (hdr.namlen, "%d", 0);
1795
1796 /* We need spaces, not null bytes, in the header. */
1797 for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
1798 if (*p == '\0')
1799 *p = ' ';
1800
2c3fc389 1801 if (bfd_bwrite (&hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
dc810e39
AM
1802 != SIZEOF_AR_HDR
1803 || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
1804 != SXCOFFARFMAG))
0a1b45a2 1805 return false;
5ea1af0d 1806
dc810e39
AM
1807 H_PUT_32 (abfd, orl_count, buf);
1808 if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
0a1b45a2 1809 return false;
252b5132 1810
252b5132 1811 i = 0;
2e470849
RS
1812 archive_iterator_begin (&iterator, abfd);
1813 while (i < orl_count && archive_iterator_next (&iterator))
1814 while (map[i].u.abfd == iterator.current.member)
1815 {
1816 H_PUT_32 (abfd, iterator.current.offset, buf);
1817 if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
0a1b45a2 1818 return false;
2e470849
RS
1819 ++i;
1820 }
252b5132
RH
1821
1822 for (i = 0; i < orl_count; i++)
1823 {
1824 const char *name;
1825 size_t namlen;
1826
1827 name = *map[i].name;
1828 namlen = strlen (name);
dc810e39 1829 if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
0a1b45a2 1830 return false;
252b5132
RH
1831 }
1832
1833 if ((stridx & 1) != 0)
1834 {
1835 char b;
1836
1837 b = '\0';
dc810e39 1838 if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
0a1b45a2 1839 return false;
252b5132
RH
1840 }
1841
0a1b45a2 1842 return true;
252b5132
RH
1843}
1844
330693f5 1845static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
ce9116fd
AM
1846#if BFD_HOST_64BIT_LONG
1847#define FMT20 "%-20ld"
1848#elif defined (__MSVCRT__)
1849#define FMT20 "%-20I64d"
1850#else
330693f5 1851#define FMT20 "%-20lld"
ce9116fd 1852#endif
330693f5
TR
1853#define FMT12 "%-12d"
1854#define FMT12_OCTAL "%-12o"
1855#define FMT4 "%-4d"
1856#define PRINT20(d, v) \
ce9116fd 1857 sprintf (buff20, FMT20, (bfd_uint64_t)(v)), \
330693f5
TR
1858 memcpy ((void *) (d), buff20, 20)
1859
1860#define PRINT12(d, v) \
1861 sprintf (buff20, FMT12, (int)(v)), \
cf9ab45b 1862 memcpy ((void *) (d), buff20, 12)
330693f5
TR
1863
1864#define PRINT12_OCTAL(d, v) \
1865 sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
1866 memcpy ((void *) (d), buff20, 12)
1867
1868#define PRINT4(d, v) \
1869 sprintf (buff20, FMT4, (int)(v)), \
cf9ab45b 1870 memcpy ((void *) (d), buff20, 4)
330693f5
TR
1871
1872#define READ20(d, v) \
1873 buff20[20] = 0, \
1874 memcpy (buff20, (d), 20), \
1dba4cb4 1875 (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
f4ffd778 1876
0a1b45a2 1877static bool
417236c0 1878do_pad (bfd *abfd, unsigned int number)
eb1e0e80
NC
1879{
1880 bfd_byte b = 0;
1881
1882 /* Limit pad to <= 4096. */
1883 if (number > 4096)
0a1b45a2 1884 return false;
eb1e0e80
NC
1885
1886 while (number--)
1887 if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
0a1b45a2 1888 return false;
eb1e0e80 1889
0a1b45a2 1890 return true;
eb1e0e80
NC
1891}
1892
0a1b45a2 1893static bool
417236c0 1894do_copy (bfd *out_bfd, bfd *in_bfd)
eb1e0e80
NC
1895{
1896 bfd_size_type remaining;
1897 bfd_byte buffer[DEFAULT_BUFFERSIZE];
1898
1899 if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
0a1b45a2 1900 return false;
eb1e0e80
NC
1901
1902 remaining = arelt_size (in_bfd);
1903
1904 while (remaining >= DEFAULT_BUFFERSIZE)
1905 {
1906 if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
1907 || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
0a1b45a2 1908 return false;
eb1e0e80
NC
1909
1910 remaining -= DEFAULT_BUFFERSIZE;
1911 }
1912
1913 if (remaining)
1914 {
cf9ab45b 1915 if (bfd_bread (buffer, remaining, in_bfd) != remaining
eb1e0e80 1916 || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
0a1b45a2 1917 return false;
eb1e0e80
NC
1918 }
1919
0a1b45a2 1920 return true;
eb1e0e80
NC
1921}
1922
0a1b45a2 1923static bool
417236c0 1924xcoff_write_armap_big (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
07d6d2b8 1925 struct orl *map, unsigned int orl_count, int stridx)
252b5132 1926{
2e470849 1927 struct archive_iterator iterator;
330693f5
TR
1928 struct xcoff_ar_file_hdr_big *fhdr;
1929 bfd_vma i, sym_32, sym_64, str_32, str_64;
2e470849 1930 const bfd_arch_info_type *arch_info;
330693f5
TR
1931 bfd *current_bfd;
1932 size_t string_length;
9dadfa79 1933 file_ptr nextoff, prevoff;
cf9ab45b 1934
330693f5
TR
1935 /* First, we look through the symbols and work out which are
1936 from 32-bit objects and which from 64-bit ones. */
1937 sym_32 = sym_64 = str_32 = str_64 = 0;
252b5132 1938
2e470849
RS
1939 i = 0;
1940 for (current_bfd = abfd->archive_head;
1941 current_bfd != NULL && i < orl_count;
1942 current_bfd = current_bfd->archive_next)
f4ffd778 1943 {
2e470849 1944 arch_info = bfd_get_arch_info (current_bfd);
330693f5
TR
1945 while (map[i].u.abfd == current_bfd)
1946 {
1947 string_length = strlen (*map[i].name) + 1;
330693f5
TR
1948 if (arch_info->bits_per_address == 64)
1949 {
1950 sym_64++;
1951 str_64 += string_length;
1952 }
1953 else
1954 {
1955 sym_32++;
1956 str_32 += string_length;
1957 }
1958 i++;
1959 }
330693f5 1960 }
5ea1af0d 1961
330693f5
TR
1962 /* A quick sanity check... */
1963 BFD_ASSERT (sym_64 + sym_32 == orl_count);
1964 /* Explicit cast to int for compiler. */
1965 BFD_ASSERT ((int)(str_64 + str_32) == stridx);
1a6df346 1966
330693f5 1967 fhdr = xcoff_ardata_big (abfd);
252b5132 1968
330693f5
TR
1969 /* xcoff_write_archive_contents_big passes nextoff in symoff. */
1970 READ20 (fhdr->memoff, prevoff);
1971 READ20 (fhdr->symoff, nextoff);
252b5132 1972
330693f5 1973 BFD_ASSERT (nextoff == bfd_tell (abfd));
5ea1af0d 1974
cf9ab45b
AM
1975 /* Write out the symbol table.
1976 Layout :
1977
330693f5 1978 standard big archive header
cf9ab45b
AM
1979 0x0000 ar_size [0x14]
1980 0x0014 ar_nxtmem [0x14]
1981 0x0028 ar_prvmem [0x14]
1982 0x003C ar_date [0x0C]
1983 0x0048 ar_uid [0x0C]
1984 0x0054 ar_gid [0x0C]
1985 0x0060 ar_mod [0x0C]
1986 0x006C ar_namelen[0x04]
1987 0x0070 ar_fmag [SXCOFFARFMAG]
1988
1989 Symbol table
1990 0x0072 num_syms [0x08], binary
1991 0x0078 offsets [0x08 * num_syms], binary
1992 0x0086 + 0x08 * num_syms names [??]
1993 ?? pad to even bytes.
330693f5
TR
1994 */
1995
cf9ab45b 1996 if (sym_32)
330693f5
TR
1997 {
1998 struct xcoff_ar_hdr_big *hdr;
f075ee0c
AM
1999 char *symbol_table;
2000 char *st;
330693f5 2001
cf9ab45b 2002 bfd_vma symbol_table_size =
330693f5
TR
2003 SIZEOF_AR_HDR_BIG
2004 + SXCOFFARFMAG
cf9ab45b
AM
2005 + 8
2006 + 8 * sym_32
330693f5
TR
2007 + str_32 + (str_32 & 1);
2008
f075ee0c 2009 symbol_table = bfd_zmalloc (symbol_table_size);
330693f5 2010 if (symbol_table == NULL)
0a1b45a2 2011 return false;
330693f5
TR
2012
2013 hdr = (struct xcoff_ar_hdr_big *) symbol_table;
cf9ab45b 2014
330693f5 2015 PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
cf9ab45b 2016
330693f5
TR
2017 if (sym_64)
2018 PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
1a6df346 2019 else
330693f5
TR
2020 PRINT20 (hdr->nextoff, 0);
2021
2022 PRINT20 (hdr->prevoff, prevoff);
2023 PRINT12 (hdr->date, 0);
2024 PRINT12 (hdr->uid, 0);
2025 PRINT12 (hdr->gid, 0);
2026 PRINT12 (hdr->mode, 0);
2027 PRINT4 (hdr->namlen, 0) ;
2028
2029 st = symbol_table + SIZEOF_AR_HDR_BIG;
2030 memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
2031 st += SXCOFFARFMAG;
2032
2033 bfd_h_put_64 (abfd, sym_32, st);
2034 st += 8;
cf9ab45b 2035
330693f5 2036 /* loop over the 32 bit offsets */
330693f5 2037 i = 0;
2e470849
RS
2038 archive_iterator_begin (&iterator, abfd);
2039 while (i < orl_count && archive_iterator_next (&iterator))
330693f5 2040 {
2e470849
RS
2041 arch_info = bfd_get_arch_info (iterator.current.member);
2042 while (map[i].u.abfd == iterator.current.member)
330693f5
TR
2043 {
2044 if (arch_info->bits_per_address == 32)
2045 {
2e470849 2046 bfd_h_put_64 (abfd, iterator.current.offset, st);
330693f5
TR
2047 st += 8;
2048 }
2049 i++;
2050 }
330693f5 2051 }
1a6df346 2052
330693f5 2053 /* loop over the 32 bit symbol names */
330693f5 2054 i = 0;
2e470849
RS
2055 for (current_bfd = abfd->archive_head;
2056 current_bfd != NULL && i < orl_count;
2057 current_bfd = current_bfd->archive_next)
330693f5 2058 {
2e470849 2059 arch_info = bfd_get_arch_info (current_bfd);
330693f5
TR
2060 while (map[i].u.abfd == current_bfd)
2061 {
2062 if (arch_info->bits_per_address == 32)
2063 {
2064 string_length = sprintf (st, "%s", *map[i].name);
2065 st += string_length + 1;
2066 }
2067 i++;
2068 }
330693f5 2069 }
5ea1af0d 2070
330693f5 2071 bfd_bwrite (symbol_table, symbol_table_size, abfd);
1a6df346 2072
330693f5 2073 free (symbol_table);
5ea1af0d 2074
330693f5
TR
2075 prevoff = nextoff;
2076 nextoff = nextoff + symbol_table_size;
5ea1af0d 2077 }
cf9ab45b 2078 else
330693f5 2079 PRINT20 (fhdr->symoff, 0);
cf9ab45b
AM
2080
2081 if (sym_64)
330693f5
TR
2082 {
2083 struct xcoff_ar_hdr_big *hdr;
f075ee0c
AM
2084 char *symbol_table;
2085 char *st;
330693f5 2086
cf9ab45b 2087 bfd_vma symbol_table_size =
330693f5
TR
2088 SIZEOF_AR_HDR_BIG
2089 + SXCOFFARFMAG
cf9ab45b
AM
2090 + 8
2091 + 8 * sym_64
330693f5
TR
2092 + str_64 + (str_64 & 1);
2093
f075ee0c 2094 symbol_table = bfd_zmalloc (symbol_table_size);
330693f5 2095 if (symbol_table == NULL)
0a1b45a2 2096 return false;
330693f5
TR
2097
2098 hdr = (struct xcoff_ar_hdr_big *) symbol_table;
2099
2100 PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
2101 PRINT20 (hdr->nextoff, 0);
2102 PRINT20 (hdr->prevoff, prevoff);
2103 PRINT12 (hdr->date, 0);
2104 PRINT12 (hdr->uid, 0);
2105 PRINT12 (hdr->gid, 0);
2106 PRINT12 (hdr->mode, 0);
2107 PRINT4 (hdr->namlen, 0);
2108
2109 st = symbol_table + SIZEOF_AR_HDR_BIG;
2110 memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
2111 st += SXCOFFARFMAG;
2112
2113 bfd_h_put_64 (abfd, sym_64, st);
2114 st += 8;
cf9ab45b 2115
330693f5 2116 /* loop over the 64 bit offsets */
330693f5 2117 i = 0;
2e470849
RS
2118 archive_iterator_begin (&iterator, abfd);
2119 while (i < orl_count && archive_iterator_next (&iterator))
1a6df346 2120 {
2e470849
RS
2121 arch_info = bfd_get_arch_info (iterator.current.member);
2122 while (map[i].u.abfd == iterator.current.member)
330693f5
TR
2123 {
2124 if (arch_info->bits_per_address == 64)
2125 {
2e470849 2126 bfd_h_put_64 (abfd, iterator.current.offset, st);
330693f5
TR
2127 st += 8;
2128 }
2129 i++;
2130 }
1a6df346 2131 }
330693f5
TR
2132
2133 /* loop over the 64 bit symbol names */
330693f5 2134 i = 0;
2e470849
RS
2135 for (current_bfd = abfd->archive_head;
2136 current_bfd != NULL && i < orl_count;
2137 current_bfd = current_bfd->archive_next)
1a6df346 2138 {
2e470849 2139 arch_info = bfd_get_arch_info (current_bfd);
330693f5
TR
2140 while (map[i].u.abfd == current_bfd)
2141 {
2142 if (arch_info->bits_per_address == 64)
2143 {
2144 string_length = sprintf (st, "%s", *map[i].name);
2145 st += string_length + 1;
2146 }
2147 i++;
2148 }
1a6df346 2149 }
1a6df346 2150
330693f5
TR
2151 bfd_bwrite (symbol_table, symbol_table_size, abfd);
2152
2153 free (symbol_table);
dc810e39 2154
330693f5
TR
2155 PRINT20 (fhdr->symoff64, nextoff);
2156 }
cf9ab45b 2157 else
330693f5 2158 PRINT20 (fhdr->symoff64, 0);
cf9ab45b 2159
0a1b45a2 2160 return true;
1a6df346
GK
2161}
2162
0a1b45a2 2163bool
417236c0 2164_bfd_xcoff_write_armap (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
07d6d2b8 2165 struct orl *map, unsigned int orl_count, int stridx)
5ea1af0d
GK
2166{
2167 if (! xcoff_big_format_p (abfd))
2168 return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
2169 else
2170 return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
2171}
2172
2173/* Write out an XCOFF archive. We always write an entire archive,
2174 rather than fussing with the freelist and so forth. */
2175
0a1b45a2 2176static bool
417236c0 2177xcoff_write_archive_contents_old (bfd *abfd)
5ea1af0d 2178{
2e470849 2179 struct archive_iterator iterator;
5ea1af0d 2180 struct xcoff_ar_file_hdr fhdr;
dc810e39
AM
2181 bfd_size_type count;
2182 bfd_size_type total_namlen;
5ea1af0d 2183 file_ptr *offsets;
0a1b45a2
AM
2184 bool makemap;
2185 bool hasobjects;
9dadfa79 2186 file_ptr prevoff, nextoff;
5ea1af0d 2187 bfd *sub;
dc810e39 2188 size_t i;
5ea1af0d
GK
2189 struct xcoff_ar_hdr ahdr;
2190 bfd_size_type size;
2191 char *p;
330693f5 2192 char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
5ea1af0d
GK
2193
2194 memset (&fhdr, 0, sizeof fhdr);
8278e7ce 2195 (void) memcpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
5ea1af0d
GK
2196 sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
2197 sprintf (fhdr.freeoff, "%d", 0);
2198
2199 count = 0;
2200 total_namlen = 0;
cc481421 2201 for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
5ea1af0d
GK
2202 {
2203 ++count;
2204 total_namlen += strlen (normalize_filename (sub)) + 1;
2e470849 2205 if (sub->arelt_data == NULL)
252b5132 2206 {
06e7acd7 2207 sub->arelt_data = bfd_zmalloc (sizeof (struct areltdata));
2e470849 2208 if (sub->arelt_data == NULL)
0a1b45a2 2209 return false;
252b5132 2210 }
2e470849 2211 if (arch_xhdr (sub) == NULL)
252b5132 2212 {
2e470849 2213 struct xcoff_ar_hdr *ahdrp;
252b5132
RH
2214 struct stat s;
2215
904790e2 2216 if ((sub->flags & BFD_IN_MEMORY) != 0)
252b5132 2217 {
904790e2
AM
2218 /* Assume we just "made" the member, and fake it. */
2219 struct bfd_in_memory *bim
2220 = (struct bfd_in_memory *) sub->iostream;
2221 time (&s.st_mtime);
2222 s.st_uid = getuid ();
2223 s.st_gid = getgid ();
2224 s.st_mode = 0644;
2225 s.st_size = bim->size;
2226 }
2227 else if (stat (bfd_get_filename (sub), &s) != 0)
2228 {
2229 bfd_set_input_error (sub, bfd_error_system_call);
0a1b45a2 2230 return false;
252b5132 2231 }
904790e2 2232
c8001886
AM
2233 if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
2234 {
2235 s.st_mtime = 0;
2236 s.st_uid = 0;
2237 s.st_gid = 0;
2238 s.st_mode = 0644;
2239 }
252b5132 2240
2e470849
RS
2241 ahdrp = bfd_zalloc (sub, sizeof (*ahdrp));
2242 if (ahdrp == NULL)
0a1b45a2 2243 return false;
2e470849 2244
252b5132
RH
2245 sprintf (ahdrp->size, "%ld", (long) s.st_size);
2246 sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2247 sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2248 sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2249 sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2250
2e470849 2251 arch_eltdata (sub)->arch_header = (char *) ahdrp;
252b5132
RH
2252 arch_eltdata (sub)->parsed_size = s.st_size;
2253 }
2e470849
RS
2254 }
2255 offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2256 if (offsets == NULL)
0a1b45a2 2257 return false;
252b5132 2258
2e470849 2259 if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
0a1b45a2 2260 return false;
252b5132 2261
2e470849 2262 makemap = bfd_has_map (abfd);
0a1b45a2 2263 hasobjects = false;
2e470849
RS
2264 prevoff = 0;
2265 for (archive_iterator_begin (&iterator, abfd), i = 0;
2266 archive_iterator_next (&iterator);
2267 i++)
2268 {
2269 bfd_size_type namlen;
2270 struct xcoff_ar_hdr *ahdrp;
252b5132 2271
2e470849
RS
2272 if (makemap && ! hasobjects)
2273 {
2274 if (bfd_check_format (iterator.current.member, bfd_object))
0a1b45a2 2275 hasobjects = true;
2e470849 2276 }
252b5132 2277
2e470849
RS
2278 ahdrp = arch_xhdr (iterator.current.member);
2279 sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2280 sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen);
2281 sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset);
252b5132
RH
2282
2283 /* We need spaces, not null bytes, in the header. */
2284 for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2285 if (*p == '\0')
2286 *p = ' ';
2287
2e470849 2288 if (!do_pad (abfd, iterator.current.leading_padding))
0a1b45a2 2289 return false;
252b5132 2290
2e470849
RS
2291 BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
2292 namlen = iterator.current.padded_namlen;
2293 if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
2294 || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
2295 || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
2296 || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
2297 || !do_copy (abfd, iterator.current.member)
2298 || !do_pad (abfd, iterator.current.trailing_padding))
0a1b45a2 2299 return false;
cf9ab45b 2300
2e470849
RS
2301 offsets[i] = iterator.current.offset;
2302 prevoff = iterator.current.offset;
252b5132
RH
2303 }
2304
2305 sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2306
2307 /* Write out the member table. */
2308
2e470849 2309 nextoff = iterator.next.offset;
252b5132
RH
2310 BFD_ASSERT (nextoff == bfd_tell (abfd));
2311 sprintf (fhdr.memoff, "%ld", (long) nextoff);
2312
2313 memset (&ahdr, 0, sizeof ahdr);
cf9ab45b
AM
2314 sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
2315 + count * XCOFFARMAG_ELEMENT_SIZE
2316 + total_namlen));
252b5132
RH
2317 sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2318 sprintf (ahdr.date, "%d", 0);
2319 sprintf (ahdr.uid, "%d", 0);
2320 sprintf (ahdr.gid, "%d", 0);
2321 sprintf (ahdr.mode, "%d", 0);
2322 sprintf (ahdr.namlen, "%d", 0);
2323
2324 size = (SIZEOF_AR_HDR
330693f5
TR
2325 + XCOFFARMAG_ELEMENT_SIZE
2326 + count * XCOFFARMAG_ELEMENT_SIZE
252b5132
RH
2327 + total_namlen
2328 + SXCOFFARFMAG);
2329
2330 prevoff = nextoff;
2331 nextoff += size + (size & 1);
2332
2333 if (makemap && hasobjects)
2334 sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2335 else
2336 sprintf (ahdr.nextoff, "%d", 0);
2337
2338 /* We need spaces, not null bytes, in the header. */
2339 for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2340 if (*p == '\0')
2341 *p = ' ';
2342
2c3fc389 2343 if ((bfd_bwrite (&ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
dc810e39 2344 != SIZEOF_AR_HDR)
2c3fc389 2345 || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
252b5132 2346 != SXCOFFARFMAG))
0a1b45a2 2347 return false;
252b5132
RH
2348
2349 sprintf (decbuf, "%-12ld", (long) count);
2c3fc389 2350 if (bfd_bwrite (decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
330693f5 2351 != XCOFFARMAG_ELEMENT_SIZE)
0a1b45a2 2352 return false;
dc810e39 2353 for (i = 0; i < (size_t) count; i++)
252b5132
RH
2354 {
2355 sprintf (decbuf, "%-12ld", (long) offsets[i]);
2c3fc389 2356 if (bfd_bwrite (decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
330693f5 2357 abfd) != XCOFFARMAG_ELEMENT_SIZE)
0a1b45a2 2358 return false;
252b5132 2359 }
cc481421 2360 for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
252b5132
RH
2361 {
2362 const char *name;
dc810e39 2363 bfd_size_type namlen;
252b5132
RH
2364
2365 name = normalize_filename (sub);
2366 namlen = strlen (name);
2c3fc389 2367 if (bfd_bwrite (name, namlen + 1, abfd) != namlen + 1)
0a1b45a2 2368 return false;
252b5132 2369 }
252b5132 2370
eb1e0e80 2371 if (! do_pad (abfd, size & 1))
0a1b45a2 2372 return false;
252b5132
RH
2373
2374 /* Write out the armap, if appropriate. */
252b5132
RH
2375 if (! makemap || ! hasobjects)
2376 sprintf (fhdr.symoff, "%d", 0);
2377 else
2378 {
2379 BFD_ASSERT (nextoff == bfd_tell (abfd));
2380 sprintf (fhdr.symoff, "%ld", (long) nextoff);
2c3fc389 2381 bfd_ardata (abfd)->tdata = &fhdr;
252b5132 2382 if (! _bfd_compute_and_write_armap (abfd, 0))
0a1b45a2 2383 return false;
252b5132
RH
2384 }
2385
2386 /* Write out the archive file header. */
2387
2388 /* We need spaces, not null bytes, in the header. */
2389 for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2390 if (*p == '\0')
2391 *p = ' ';
2392
2393 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2c3fc389 2394 || (bfd_bwrite (&fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
dc810e39 2395 != SIZEOF_AR_FILE_HDR))
0a1b45a2 2396 return false;
252b5132 2397
0a1b45a2 2398 return true;
252b5132 2399}
5ea1af0d 2400
0a1b45a2 2401static bool
417236c0 2402xcoff_write_archive_contents_big (bfd *abfd)
5ea1af0d
GK
2403{
2404 struct xcoff_ar_file_hdr_big fhdr;
dc810e39
AM
2405 bfd_size_type count;
2406 bfd_size_type total_namlen;
5ea1af0d 2407 file_ptr *offsets;
0a1b45a2
AM
2408 bool makemap;
2409 bool hasobjects;
9dadfa79 2410 file_ptr prevoff, nextoff;
330693f5 2411 bfd *current_bfd;
dc810e39 2412 size_t i;
2e470849 2413 struct xcoff_ar_hdr_big *hdr;
5ea1af0d 2414 bfd_size_type size;
f075ee0c 2415 char *member_table, *mt;
330693f5 2416 bfd_vma member_table_size;
2e470849 2417 struct archive_iterator iterator;
5ea1af0d 2418
eb1e0e80 2419 memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
330693f5 2420 memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
5ea1af0d 2421
eb1e0e80 2422 if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
0a1b45a2 2423 return false;
cf9ab45b 2424
eb1e0e80
NC
2425 /* Calculate count and total_namlen. */
2426 makemap = bfd_has_map (abfd);
0a1b45a2 2427 hasobjects = false;
cf9ab45b
AM
2428 for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
2429 current_bfd != NULL;
cc481421 2430 current_bfd = current_bfd->archive_next, count++)
eb1e0e80
NC
2431 {
2432 total_namlen += strlen (normalize_filename (current_bfd)) + 1;
2433
2434 if (makemap
2435 && ! hasobjects
2436 && bfd_check_format (current_bfd, bfd_object))
0a1b45a2 2437 hasobjects = true;
330693f5 2438
2e470849
RS
2439 if (current_bfd->arelt_data == NULL)
2440 {
2441 size = sizeof (struct areltdata);
06e7acd7 2442 current_bfd->arelt_data = bfd_zmalloc (size);
2e470849 2443 if (current_bfd->arelt_data == NULL)
0a1b45a2 2444 return false;
2e470849 2445 }
5ea1af0d 2446
2e470849 2447 if (arch_xhdr_big (current_bfd) == NULL)
5ea1af0d 2448 {
2e470849 2449 struct xcoff_ar_hdr_big *ahdrp;
5ea1af0d
GK
2450 struct stat s;
2451
904790e2 2452 if ((current_bfd->flags & BFD_IN_MEMORY) != 0)
5ea1af0d 2453 {
904790e2
AM
2454 /* Assume we just "made" the member, and fake it. */
2455 struct bfd_in_memory *bim
2456 = (struct bfd_in_memory *) current_bfd->iostream;
2457 time (&s.st_mtime);
2458 s.st_uid = getuid ();
2459 s.st_gid = getgid ();
2460 s.st_mode = 0644;
2461 s.st_size = bim->size;
2462 }
2463 else if (stat (bfd_get_filename (current_bfd), &s) != 0)
2464 {
2465 bfd_set_input_error (current_bfd, bfd_error_system_call);
0a1b45a2 2466 return false;
5ea1af0d 2467 }
904790e2 2468
c8001886
AM
2469 if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
2470 {
2471 s.st_mtime = 0;
2472 s.st_uid = 0;
2473 s.st_gid = 0;
2474 s.st_mode = 0644;
2475 }
5ea1af0d 2476
2e470849
RS
2477 ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp));
2478 if (ahdrp == NULL)
0a1b45a2 2479 return false;
2e470849 2480
330693f5
TR
2481 PRINT20 (ahdrp->size, s.st_size);
2482 PRINT12 (ahdrp->date, s.st_mtime);
2483 PRINT12 (ahdrp->uid, s.st_uid);
2484 PRINT12 (ahdrp->gid, s.st_gid);
2485 PRINT12_OCTAL (ahdrp->mode, s.st_mode);
5ea1af0d 2486
2e470849 2487 arch_eltdata (current_bfd)->arch_header = (char *) ahdrp;
330693f5 2488 arch_eltdata (current_bfd)->parsed_size = s.st_size;
5ea1af0d 2489 }
2e470849 2490 }
5ea1af0d 2491
2e470849
RS
2492 offsets = NULL;
2493 if (count)
2494 {
2495 offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2496 if (offsets == NULL)
0a1b45a2 2497 return false;
2e470849 2498 }
eb1e0e80 2499
2e470849
RS
2500 prevoff = 0;
2501 for (archive_iterator_begin (&iterator, abfd), i = 0;
2502 archive_iterator_next (&iterator);
2503 i++)
2504 {
2505 bfd_size_type namlen;
2506 struct xcoff_ar_hdr_big *ahdrp;
5ea1af0d 2507
2e470849
RS
2508 ahdrp = arch_xhdr_big (iterator.current.member);
2509 PRINT20 (ahdrp->prevoff, prevoff);
2510 PRINT4 (ahdrp->namlen, iterator.current.namlen);
2511 PRINT20 (ahdrp->nextoff, iterator.next.offset);
5ea1af0d 2512
2e470849 2513 if (!do_pad (abfd, iterator.current.leading_padding))
2915c55b
JK
2514 {
2515 free (offsets);
0a1b45a2 2516 return false;
2915c55b 2517 }
5ea1af0d 2518
2e470849
RS
2519 BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
2520 namlen = iterator.current.padded_namlen;
2521 if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
2522 || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
2523 || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
2524 || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
2525 || !do_copy (abfd, iterator.current.member)
2526 || !do_pad (abfd, iterator.current.trailing_padding))
2915c55b
JK
2527 {
2528 free (offsets);
0a1b45a2 2529 return false;
2915c55b 2530 }
cf9ab45b 2531
2e470849
RS
2532 offsets[i] = iterator.current.offset;
2533 prevoff = iterator.current.offset;
5ea1af0d
GK
2534 }
2535
eb1e0e80
NC
2536 if (count)
2537 {
2538 PRINT20 (fhdr.firstmemoff, offsets[0]);
2539 PRINT20 (fhdr.lastmemoff, prevoff);
2540 }
5ea1af0d 2541
cf9ab45b
AM
2542 /* Write out the member table.
2543 Layout :
5ea1af0d 2544
330693f5 2545 standard big archive header
cf9ab45b
AM
2546 0x0000 ar_size [0x14]
2547 0x0014 ar_nxtmem [0x14]
2548 0x0028 ar_prvmem [0x14]
2549 0x003C ar_date [0x0C]
2550 0x0048 ar_uid [0x0C]
2551 0x0054 ar_gid [0x0C]
2552 0x0060 ar_mod [0x0C]
2553 0x006C ar_namelen[0x04]
2554 0x0070 ar_fmag [0x02]
2555
2556 Member table
2557 0x0072 count [0x14]
2558 0x0086 offsets [0x14 * counts]
2559 0x0086 + 0x14 * counts names [??]
2560 ?? pad to even bytes.
330693f5 2561 */
5ea1af0d 2562
2e470849 2563 nextoff = iterator.next.offset;
330693f5 2564 BFD_ASSERT (nextoff == bfd_tell (abfd));
5ea1af0d 2565
330693f5
TR
2566 member_table_size = (SIZEOF_AR_HDR_BIG
2567 + SXCOFFARFMAG
2568 + XCOFFARMAGBIG_ELEMENT_SIZE
2569 + count * XCOFFARMAGBIG_ELEMENT_SIZE
2570 + total_namlen);
5ea1af0d 2571
330693f5 2572 member_table_size += member_table_size & 1;
f075ee0c 2573 member_table = bfd_zmalloc (member_table_size);
330693f5 2574 if (member_table == NULL)
2915c55b
JK
2575 {
2576 free (offsets);
0a1b45a2 2577 return false;
2915c55b 2578 }
5ea1af0d 2579
330693f5 2580 hdr = (struct xcoff_ar_hdr_big *) member_table;
5ea1af0d 2581
cf9ab45b
AM
2582 PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
2583 + count * XCOFFARMAGBIG_ELEMENT_SIZE
2584 + total_namlen + (total_namlen & 1)));
2585 if (makemap && hasobjects)
330693f5
TR
2586 PRINT20 (hdr->nextoff, nextoff + member_table_size);
2587 else
2588 PRINT20 (hdr->nextoff, 0);
2589 PRINT20 (hdr->prevoff, prevoff);
2590 PRINT12 (hdr->date, 0);
2591 PRINT12 (hdr->uid, 0);
2592 PRINT12 (hdr->gid, 0);
2593 PRINT12 (hdr->mode, 0);
2594 PRINT4 (hdr->namlen, 0);
cf9ab45b 2595
330693f5
TR
2596 mt = member_table + SIZEOF_AR_HDR_BIG;
2597 memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
2598 mt += SXCOFFARFMAG;
5ea1af0d 2599
330693f5
TR
2600 PRINT20 (mt, count);
2601 mt += XCOFFARMAGBIG_ELEMENT_SIZE;
dc810e39 2602 for (i = 0; i < (size_t) count; i++)
5ea1af0d 2603 {
330693f5
TR
2604 PRINT20 (mt, offsets[i]);
2605 mt += XCOFFARMAGBIG_ELEMENT_SIZE;
5ea1af0d 2606 }
330693f5 2607
cf9ab45b 2608 if (count)
330693f5
TR
2609 {
2610 free (offsets);
2611 offsets = NULL;
2612 }
2613
cc481421
AM
2614 for (current_bfd = abfd->archive_head;
2615 current_bfd != NULL;
2616 current_bfd = current_bfd->archive_next)
5ea1af0d
GK
2617 {
2618 const char *name;
2619 size_t namlen;
2620
330693f5 2621 name = normalize_filename (current_bfd);
cf9ab45b 2622 namlen = sprintf (mt, "%s", name);
330693f5 2623 mt += namlen + 1;
5ea1af0d 2624 }
cf9ab45b 2625
330693f5 2626 if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
0a1b45a2 2627 return false;
5ea1af0d 2628
330693f5 2629 free (member_table);
330693f5
TR
2630
2631 PRINT20 (fhdr.memoff, nextoff);
2632
2633 prevoff = nextoff;
2634 nextoff += member_table_size;
5ea1af0d
GK
2635
2636 /* Write out the armap, if appropriate. */
2637
cf9ab45b 2638 if (! makemap || ! hasobjects)
330693f5 2639 PRINT20 (fhdr.symoff, 0);
5ea1af0d
GK
2640 else
2641 {
2642 BFD_ASSERT (nextoff == bfd_tell (abfd));
330693f5
TR
2643
2644 /* Save nextoff in fhdr.symoff so the armap routine can use it. */
2645 PRINT20 (fhdr.symoff, nextoff);
cf9ab45b 2646
2c3fc389 2647 bfd_ardata (abfd)->tdata = &fhdr;
5ea1af0d 2648 if (! _bfd_compute_and_write_armap (abfd, 0))
0a1b45a2 2649 return false;
5ea1af0d
GK
2650 }
2651
2652 /* Write out the archive file header. */
2653
5ea1af0d 2654 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2c3fc389 2655 || (bfd_bwrite (&fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
330693f5 2656 abfd) != SIZEOF_AR_FILE_HDR_BIG))
0a1b45a2 2657 return false;
cf9ab45b 2658
0a1b45a2 2659 return true;
5ea1af0d
GK
2660}
2661
0a1b45a2 2662bool
417236c0 2663_bfd_xcoff_write_archive_contents (bfd *abfd)
5ea1af0d
GK
2664{
2665 if (! xcoff_big_format_p (abfd))
2666 return xcoff_write_archive_contents_old (abfd);
2667 else
2668 return xcoff_write_archive_contents_big (abfd);
2669}
252b5132
RH
2670\f
2671/* We can't use the usual coff_sizeof_headers routine, because AIX
2672 always uses an a.out header. */
2673
7f6d05e8 2674int
a6b96beb
AM
2675_bfd_xcoff_sizeof_headers (bfd *abfd,
2676 struct bfd_link_info *info ATTRIBUTE_UNUSED)
252b5132
RH
2677{
2678 int size;
2679
2680 size = FILHSZ;
2681 if (xcoff_data (abfd)->full_aouthdr)
2682 size += AOUTSZ;
2683 else
2684 size += SMALL_AOUTSZ;
2685 size += abfd->section_count * SCNHSZ;
2eea2440
TG
2686
2687 if (info->strip != strip_all)
2688 {
2689 /* There can be additional sections just for dealing with overflow in
2690 reloc and lineno counts. But the numbers of relocs and lineno aren't
2691 known when bfd_sizeof_headers is called, so we compute them by
2692 summing the numbers from input sections. */
2693 struct nbr_reloc_lineno
2694 {
2695 unsigned int reloc_count;
2696 unsigned int lineno_count;
2697 };
2698 struct nbr_reloc_lineno *n_rl;
2699 bfd *sub;
7292b3ac 2700 unsigned int max_index;
2eea2440
TG
2701 asection *s;
2702
2703 /* Although the number of sections is known, the maximum value of
2704 section->index isn't (because some sections may have been removed).
2705 Don't try to renumber sections, just compute the upper bound. */
2706 max_index = 0;
2707 for (s = abfd->sections; s != NULL; s = s->next)
2708 if (s->index > max_index)
2709 max_index = s->index;
2710
2711 /* Allocate the per section counters. It could be possible to use a
2712 preallocated array as the number of sections is limited on XCOFF,
2713 but this creates a maintainance issue. */
2714 n_rl = bfd_zmalloc ((max_index + 1) * sizeof (*n_rl));
2715 if (n_rl == NULL)
2716 return -1;
2717
2718 /* Sum. */
c72f2fb2 2719 for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
2eea2440 2720 for (s = sub->sections; s != NULL; s = s->next)
a93ba4c0
AM
2721 if (s->output_section->owner == abfd
2722 && !bfd_section_removed_from_list (abfd, s->output_section))
2723 {
2724 struct nbr_reloc_lineno *e = &n_rl[s->output_section->index];
2725 e->reloc_count += s->reloc_count;
2726 e->lineno_count += s->lineno_count;
2727 }
2eea2440
TG
2728
2729 /* Add the size of a section for each section with an overflow. */
2730 for (s = abfd->sections; s != NULL; s = s->next)
2731 {
2732 struct nbr_reloc_lineno *e = &n_rl[s->index];
2733
2734 if (e->reloc_count >= 0xffff
2735 || (e->lineno_count >= 0xffff && info->strip != strip_debugger))
2736 size += SCNHSZ;
2737 }
2738
2739 free (n_rl);
2740 }
2741
252b5132
RH
2742 return size;
2743}
beb1bf64
TR
2744\f
2745/* Routines to swap information in the XCOFF .loader section. If we
2746 ever need to write an XCOFF loader, this stuff will need to be
2747 moved to another file shared by the linker (which XCOFF calls the
2748 ``binder'') and the loader. */
2749
2750/* Swap in the ldhdr structure. */
2751
2752static void
2c3fc389 2753xcoff_swap_ldhdr_in (bfd *abfd, const void * s, struct internal_ldhdr *dst)
beb1bf64 2754{
814fa6ab
AM
2755 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
2756
beb1bf64
TR
2757 dst->l_version = bfd_get_32 (abfd, src->l_version);
2758 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
2759 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
2760 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
2761 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
2762 dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
2763 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
2764 dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
2765}
2766
2767/* Swap out the ldhdr structure. */
2768
2769static void
2c3fc389 2770xcoff_swap_ldhdr_out (bfd *abfd, const struct internal_ldhdr *src, void * d)
beb1bf64 2771{
814fa6ab
AM
2772 struct external_ldhdr *dst = (struct external_ldhdr *) d;
2773
dc810e39 2774 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
beb1bf64
TR
2775 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
2776 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
2777 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
2778 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
2779 bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
2780 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
2781 bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
2782}
2783
2784/* Swap in the ldsym structure. */
2785
2786static void
2c3fc389 2787xcoff_swap_ldsym_in (bfd *abfd, const void * s, struct internal_ldsym *dst)
beb1bf64 2788{
814fa6ab
AM
2789 const struct external_ldsym *src = (const struct external_ldsym *) s;
2790
beb1bf64
TR
2791 if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
2792 memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2793 } else {
2794 dst->_l._l_l._l_zeroes = 0;
2795 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
2796 }
2797 dst->l_value = bfd_get_32 (abfd, src->l_value);
2798 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
2799 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
2800 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
2801 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
2802 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
2803}
2804
2805/* Swap out the ldsym structure. */
2806
2807static void
2c3fc389 2808xcoff_swap_ldsym_out (bfd *abfd, const struct internal_ldsym *src, void * d)
beb1bf64 2809{
814fa6ab 2810 struct external_ldsym *dst = (struct external_ldsym *) d;
beb1bf64
TR
2811
2812 if (src->_l._l_l._l_zeroes != 0)
2813 memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
2814 else
2815 {
dc810e39
AM
2816 bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
2817 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
2818 dst->_l._l_l._l_offset);
beb1bf64
TR
2819 }
2820 bfd_put_32 (abfd, src->l_value, dst->l_value);
dc810e39 2821 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
beb1bf64
TR
2822 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
2823 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
2824 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
2825 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
2826}
2827
59862849 2828static void
2c3fc389 2829xcoff_swap_reloc_in (bfd *abfd, void * s, void * d)
59862849
TR
2830{
2831 struct external_reloc *src = (struct external_reloc *) s;
2832 struct internal_reloc *dst = (struct internal_reloc *) d;
2833
2834 memset (dst, 0, sizeof (struct internal_reloc));
2835
2836 dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
2837 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
2838 dst->r_size = bfd_get_8 (abfd, src->r_size);
2839 dst->r_type = bfd_get_8 (abfd, src->r_type);
2840}
2841
2842static unsigned int
2c3fc389 2843xcoff_swap_reloc_out (bfd *abfd, void * s, void * d)
59862849
TR
2844{
2845 struct internal_reloc *src = (struct internal_reloc *) s;
2846 struct external_reloc *dst = (struct external_reloc *) d;
2847
2848 bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
2849 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
2850 bfd_put_8 (abfd, src->r_type, dst->r_type);
2851 bfd_put_8 (abfd, src->r_size, dst->r_size);
2852
2853 return bfd_coff_relsz (abfd);
2854}
2855
beb1bf64
TR
2856/* Swap in the ldrel structure. */
2857
2858static void
2c3fc389 2859xcoff_swap_ldrel_in (bfd *abfd, const void * s, struct internal_ldrel *dst)
beb1bf64 2860{
814fa6ab
AM
2861 const struct external_ldrel *src = (const struct external_ldrel *) s;
2862
beb1bf64
TR
2863 dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
2864 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
2865 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
2866 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
2867}
2868
2869/* Swap out the ldrel structure. */
2870
2871static void
2c3fc389 2872xcoff_swap_ldrel_out (bfd *abfd, const struct internal_ldrel *src, void * d)
beb1bf64 2873{
814fa6ab
AM
2874 struct external_ldrel *dst = (struct external_ldrel *) d;
2875
beb1bf64
TR
2876 bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
2877 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
dc810e39
AM
2878 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
2879 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
beb1bf64
TR
2880}
2881\f
2882
0a1b45a2 2883bool
417236c0 2884xcoff_reloc_type_noop (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
2885 asection *input_section ATTRIBUTE_UNUSED,
2886 bfd *output_bfd ATTRIBUTE_UNUSED,
2887 struct internal_reloc *rel ATTRIBUTE_UNUSED,
2888 struct internal_syment *sym ATTRIBUTE_UNUSED,
2889 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
2890 bfd_vma val ATTRIBUTE_UNUSED,
2891 bfd_vma addend ATTRIBUTE_UNUSED,
2892 bfd_vma *relocation ATTRIBUTE_UNUSED,
2893 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6 2894{
0a1b45a2 2895 return true;
dbe341c6
TR
2896}
2897
0a1b45a2 2898bool
417236c0 2899xcoff_reloc_type_fail (bfd *input_bfd,
07d6d2b8
AM
2900 asection *input_section ATTRIBUTE_UNUSED,
2901 bfd *output_bfd ATTRIBUTE_UNUSED,
2902 struct internal_reloc *rel,
2903 struct internal_syment *sym ATTRIBUTE_UNUSED,
2904 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
2905 bfd_vma val ATTRIBUTE_UNUSED,
2906 bfd_vma addend ATTRIBUTE_UNUSED,
2907 bfd_vma *relocation ATTRIBUTE_UNUSED,
2908 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6 2909{
4eca0228 2910 _bfd_error_handler
695344c0 2911 /* xgettext: c-format */
0aa13fee 2912 (_("%pB: unsupported relocation type %#x"),
dae82561 2913 input_bfd, (unsigned int) rel->r_type);
dbe341c6 2914 bfd_set_error (bfd_error_bad_value);
0a1b45a2 2915 return false;
dbe341c6
TR
2916}
2917
0a1b45a2 2918bool
417236c0 2919xcoff_reloc_type_pos (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
2920 asection *input_section ATTRIBUTE_UNUSED,
2921 bfd *output_bfd ATTRIBUTE_UNUSED,
2922 struct internal_reloc *rel ATTRIBUTE_UNUSED,
2923 struct internal_syment *sym ATTRIBUTE_UNUSED,
2924 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
2925 bfd_vma val,
2926 bfd_vma addend,
2927 bfd_vma *relocation,
2928 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6
TR
2929{
2930 *relocation = val + addend;
0a1b45a2 2931 return true;
dbe341c6
TR
2932}
2933
0a1b45a2 2934bool
417236c0 2935xcoff_reloc_type_neg (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
2936 asection *input_section ATTRIBUTE_UNUSED,
2937 bfd *output_bfd ATTRIBUTE_UNUSED,
2938 struct internal_reloc *rel ATTRIBUTE_UNUSED,
2939 struct internal_syment *sym ATTRIBUTE_UNUSED,
2940 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
2941 bfd_vma val,
2942 bfd_vma addend,
2943 bfd_vma *relocation,
2944 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6 2945{
c5df7e44 2946 *relocation = - val - addend;
0a1b45a2 2947 return true;
dbe341c6
TR
2948}
2949
0a1b45a2 2950bool
417236c0 2951xcoff_reloc_type_rel (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
2952 asection *input_section,
2953 bfd *output_bfd ATTRIBUTE_UNUSED,
2954 struct internal_reloc *rel ATTRIBUTE_UNUSED,
2955 struct internal_syment *sym ATTRIBUTE_UNUSED,
2956 struct reloc_howto_struct *howto,
2957 bfd_vma val,
2958 bfd_vma addend,
2959 bfd_vma *relocation,
2960 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6 2961{
0a1b45a2 2962 howto->pc_relative = true;
dbe341c6
TR
2963
2964 /* A PC relative reloc includes the section address. */
2965 addend += input_section->vma;
2966
2967 *relocation = val + addend;
cf9ab45b
AM
2968 *relocation -= (input_section->output_section->vma
2969 + input_section->output_offset);
0a1b45a2 2970 return true;
dbe341c6 2971}
f1f0d9ab 2972
0a1b45a2 2973bool
417236c0 2974xcoff_reloc_type_toc (bfd *input_bfd,
07d6d2b8
AM
2975 asection *input_section ATTRIBUTE_UNUSED,
2976 bfd *output_bfd,
2977 struct internal_reloc *rel,
4a403be0 2978 struct internal_syment *sym ATTRIBUTE_UNUSED,
07d6d2b8
AM
2979 struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
2980 bfd_vma val,
2981 bfd_vma addend ATTRIBUTE_UNUSED,
2982 bfd_vma *relocation,
2983 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6
TR
2984{
2985 struct xcoff_link_hash_entry *h;
2986
cf9ab45b 2987 if (0 > rel->r_symndx)
0a1b45a2 2988 return false;
dbe341c6
TR
2989
2990 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2991
2992 if (h != NULL && h->smclas != XMC_TD)
2993 {
2994 if (h->toc_section == NULL)
2995 {
4eca0228 2996 _bfd_error_handler
695344c0 2997 /* xgettext: c-format */
2dcf00ce
AM
2998 (_("%pB: TOC reloc at %#" PRIx64 " to symbol `%s' with no TOC entry"),
2999 input_bfd, (uint64_t) rel->r_vaddr, h->root.root.string);
dbe341c6 3000 bfd_set_error (bfd_error_bad_value);
0a1b45a2 3001 return false;
dbe341c6 3002 }
cf9ab45b 3003
dbe341c6
TR
3004 BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
3005 val = (h->toc_section->output_section->vma
3006 + h->toc_section->output_offset);
3007 }
cf9ab45b 3008
4a403be0
CC
3009 /* We can't use the preexisting value written down by the
3010 assembly, as R_TOCU needs to be adjusted when the final
3011 R_TOCL value is signed. */
3012 *relocation = val - xcoff_data (output_bfd)->toc;
3013
3014 if (rel->r_type == R_TOCU)
3015 *relocation = ((*relocation + 0x8000) >> 16) & 0xffff;
3016 if (rel->r_type == R_TOCL)
3017 *relocation = *relocation & 0x0000ffff;
3018
0a1b45a2 3019 return true;
dbe341c6 3020}
f1f0d9ab 3021
0a1b45a2 3022bool
417236c0 3023xcoff_reloc_type_ba (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
3024 asection *input_section ATTRIBUTE_UNUSED,
3025 bfd *output_bfd ATTRIBUTE_UNUSED,
3026 struct internal_reloc *rel ATTRIBUTE_UNUSED,
3027 struct internal_syment *sym ATTRIBUTE_UNUSED,
3028 struct reloc_howto_struct *howto,
3029 bfd_vma val,
3030 bfd_vma addend,
3031 bfd_vma *relocation,
3032 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6 3033{
a78eab4e
AM
3034 howto->src_mask &= ~3;
3035 howto->dst_mask = howto->src_mask;
dbe341c6
TR
3036
3037 *relocation = val + addend;
3038
0a1b45a2 3039 return true;
dbe341c6
TR
3040}
3041
0a1b45a2 3042static bool
417236c0 3043xcoff_reloc_type_br (bfd *input_bfd,
07d6d2b8
AM
3044 asection *input_section,
3045 bfd *output_bfd ATTRIBUTE_UNUSED,
3046 struct internal_reloc *rel,
3047 struct internal_syment *sym ATTRIBUTE_UNUSED,
3048 struct reloc_howto_struct *howto,
3049 bfd_vma val,
3050 bfd_vma addend,
3051 bfd_vma *relocation,
3052 bfd_byte *contents)
dbe341c6
TR
3053{
3054 struct xcoff_link_hash_entry *h;
12b2cce9 3055 bfd_vma section_offset;
dbe341c6 3056
cf9ab45b 3057 if (0 > rel->r_symndx)
0a1b45a2 3058 return false;
dbe341c6
TR
3059
3060 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
12b2cce9 3061 section_offset = rel->r_vaddr - input_section->vma;
dbe341c6
TR
3062
3063 /* If we see an R_BR or R_RBR reloc which is jumping to global
3064 linkage code, and it is followed by an appropriate cror nop
3065 instruction, we replace the cror with lwz r2,20(r1). This
3066 restores the TOC after the glink code. Contrariwise, if the
3067 call is followed by a lwz r2,20(r1), but the call is not
3068 going to global linkage code, we can replace the load with a
3069 cror. */
cf9ab45b 3070 if (NULL != h
8602d4fe
RS
3071 && (bfd_link_hash_defined == h->root.type
3072 || bfd_link_hash_defweak == h->root.type)
12b2cce9 3073 && section_offset + 8 <= input_section->size)
dbe341c6
TR
3074 {
3075 bfd_byte *pnext;
3076 unsigned long next;
cf9ab45b 3077
12b2cce9 3078 pnext = contents + section_offset + 4;
dbe341c6 3079 next = bfd_get_32 (input_bfd, pnext);
cf9ab45b 3080
dbe341c6
TR
3081 /* The _ptrgl function is magic. It is used by the AIX
3082 compiler to call a function through a pointer. */
3083 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
3084 {
cf9ab45b
AM
3085 if (next == 0x4def7b82 /* cror 15,15,15 */
3086 || next == 0x4ffffb82 /* cror 31,31,31 */
3087 || next == 0x60000000) /* ori r0,r0,0 */
12b2cce9 3088 bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r2,20(r1) */
cf9ab45b
AM
3089
3090 }
3091 else
3092 {
12b2cce9 3093 if (next == 0x80410014) /* lwz r2,20(r1) */
cf9ab45b
AM
3094 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
3095 }
3096 }
3097 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
dbe341c6
TR
3098 {
3099 /* Normally, this relocation is against a defined symbol. In the
3100 case where this is a partial link and the output section offset
cf9ab45b 3101 is greater than 2^25, the linker will return an invalid error
dbe341c6 3102 message that the relocation has been truncated. Yes it has been
cf9ab45b 3103 truncated but no it not important. For this case, disable the
dbe341c6 3104 overflow checking. */
cf9ab45b 3105
dbe341c6
TR
3106 howto->complain_on_overflow = complain_overflow_dont;
3107 }
cf9ab45b 3108
12b2cce9
RS
3109 /* The original PC-relative relocation is biased by -r_vaddr, so adding
3110 the value below will give the absolute target address. */
3111 *relocation = val + addend + rel->r_vaddr;
3112
a78eab4e
AM
3113 howto->src_mask &= ~3;
3114 howto->dst_mask = howto->src_mask;
dbe341c6 3115
12b2cce9 3116 if (h != NULL
8602d4fe
RS
3117 && (h->root.type == bfd_link_hash_defined
3118 || h->root.type == bfd_link_hash_defweak)
12b2cce9
RS
3119 && bfd_is_abs_section (h->root.u.def.section)
3120 && section_offset + 4 <= input_section->size)
3121 {
3122 bfd_byte *ptr;
3123 bfd_vma insn;
cf9ab45b 3124
12b2cce9
RS
3125 /* Turn the relative branch into an absolute one by setting the
3126 AA bit. */
3127 ptr = contents + section_offset;
3128 insn = bfd_get_32 (input_bfd, ptr);
3129 insn |= 2;
3130 bfd_put_32 (input_bfd, insn, ptr);
3131
3132 /* Make the howto absolute too. */
0a1b45a2 3133 howto->pc_relative = false;
12b2cce9
RS
3134 howto->complain_on_overflow = complain_overflow_bitfield;
3135 }
3136 else
3137 {
3138 /* Use a PC-relative howto and subtract the instruction's address
3139 from the target address we calculated above. */
0a1b45a2 3140 howto->pc_relative = true;
12b2cce9
RS
3141 *relocation -= (input_section->output_section->vma
3142 + input_section->output_offset
3143 + section_offset);
3144 }
0a1b45a2 3145 return true;
dbe341c6
TR
3146}
3147
0a1b45a2 3148bool
417236c0 3149xcoff_reloc_type_crel (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
3150 asection *input_section,
3151 bfd *output_bfd ATTRIBUTE_UNUSED,
3152 struct internal_reloc *rel ATTRIBUTE_UNUSED,
3153 struct internal_syment *sym ATTRIBUTE_UNUSED,
3154 struct reloc_howto_struct *howto,
3155 bfd_vma val ATTRIBUTE_UNUSED,
3156 bfd_vma addend,
3157 bfd_vma *relocation,
3158 bfd_byte *contents ATTRIBUTE_UNUSED)
dbe341c6 3159{
0a1b45a2 3160 howto->pc_relative = true;
a78eab4e
AM
3161 howto->src_mask &= ~3;
3162 howto->dst_mask = howto->src_mask;
dbe341c6
TR
3163
3164 /* A PC relative reloc includes the section address. */
3165 addend += input_section->vma;
3166
3167 *relocation = val + addend;
cf9ab45b
AM
3168 *relocation -= (input_section->output_section->vma
3169 + input_section->output_offset);
0a1b45a2 3170 return true;
dbe341c6
TR
3171}
3172
0a1b45a2 3173bool
1b2cb8e2
CC
3174xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED,
3175 asection *input_section ATTRIBUTE_UNUSED,
3176 bfd *output_bfd ATTRIBUTE_UNUSED,
3177 struct internal_reloc *rel ATTRIBUTE_UNUSED,
3178 struct internal_syment *sym ATTRIBUTE_UNUSED,
3179 struct reloc_howto_struct *howto,
3180 bfd_vma val,
3181 bfd_vma addend,
3182 bfd_vma *relocation,
3183 bfd_byte *contents ATTRIBUTE_UNUSED)
3184{
3185 struct xcoff_link_hash_entry *h;
3186
3187 if (0 > rel->r_symndx)
0a1b45a2 3188 return false;
1b2cb8e2
CC
3189
3190 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
3191
3192 /* FIXME: R_TLSML is targeting a internal TOC symbol, which will
3193 make the following checks failing. It should be moved with
3194 R_TLSM bellow once it works. */
3195 if (howto->type == R_TLSML)
3196 {
3197 *relocation = 0;
0a1b45a2 3198 return true;
1b2cb8e2
CC
3199 }
3200
3201 /* FIXME: h is sometimes null, if the TLS symbol is not exported. */
3202 if (!h)
3203 {
3204 _bfd_error_handler
3205 (_("%pB: TLS relocation at (0x%" BFD_VMA_FMT "x) over "
3206 "internal symbols (C_HIDEXT) not yet possible\n"),
3207 input_bfd, rel->r_vaddr);
0a1b45a2 3208 return false;
1b2cb8e2
CC
3209 }
3210
3211
3212 /* TLS relocations must target a TLS symbol. */
3213 if (h->smclas != XMC_TL && h->smclas != XMC_UL)
3214 {
3215 _bfd_error_handler
3216 (_("%pB: TLS relocation at (0x%" BFD_VMA_FMT "x) over "
3217 "non-TLS symbol %s (0x%x)\n"),
3218 input_bfd, rel->r_vaddr, h->root.root.string, h->smclas);
0a1b45a2 3219 return false;
1b2cb8e2
CC
3220 }
3221
3222 /* Local TLS relocations must target a local symbol, ie
3223 non-imported. */
3224 if ((rel->r_type == R_TLS_LD || rel->r_type == R_TLS_LE)
3225 && (((h->flags & XCOFF_DEF_REGULAR) == 0
3226 && (h->flags & XCOFF_DEF_DYNAMIC) != 0)
3227 || (h->flags & XCOFF_IMPORT) != 0))
3228 {
3229 _bfd_error_handler
3230 (_("%pB: TLS local relocation at (0x%" BFD_VMA_FMT "x) over "
3231 "imported symbol %s\n"),
3232 input_bfd, rel->r_vaddr, h->root.root.string);
0a1b45a2 3233 return false;
1b2cb8e2
CC
3234 }
3235
3236 /* R_TLSM and R_TLSML are relocations used by the loader.
3237 The value must be 0.
3238 FIXME: move R_TLSML here. */
3239 if (howto->type == R_TLSM)
3240 {
3241 *relocation = 0;
0a1b45a2 3242 return true;
1b2cb8e2
CC
3243 }
3244
3245 /* Other TLS relocations aims to put offsets from TLS pointers
3246 starting at -0x7c00 (or -0x7800 in XCOFF64). It becomes a
3247 simple R_POS relocation as long as .tdata and .tbss addresses
3248 start at the same value. This is done in aix ld scripts.
3249 TODO: implement optimization when tls size is < 62K. */
3250 *relocation = val + addend;
3251
0a1b45a2 3252 return true;
1b2cb8e2
CC
3253}
3254
0a1b45a2 3255static bool
417236c0 3256xcoff_complain_overflow_dont_func (bfd *input_bfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
3257 bfd_vma val ATTRIBUTE_UNUSED,
3258 bfd_vma relocation ATTRIBUTE_UNUSED,
3259 struct reloc_howto_struct *
3260 howto ATTRIBUTE_UNUSED)
dbe341c6 3261{
0a1b45a2 3262 return false;
dbe341c6
TR
3263}
3264
0a1b45a2 3265static bool
417236c0 3266xcoff_complain_overflow_bitfield_func (bfd *input_bfd,
07d6d2b8
AM
3267 bfd_vma val,
3268 bfd_vma relocation,
3269 struct reloc_howto_struct *howto)
dbe341c6 3270{
c7e2358a 3271 bfd_vma fieldmask, signmask, ss;
dbe341c6 3272 bfd_vma a, b, sum;
cf9ab45b 3273
dbe341c6
TR
3274 /* Get the values to be added together. For signed and unsigned
3275 relocations, we assume that all values should be truncated to
3276 the size of an address. For bitfields, all the bits matter.
3277 See also bfd_check_overflow. */
3278 fieldmask = N_ONES (howto->bitsize);
dbe341c6
TR
3279 a = relocation;
3280 b = val & howto->src_mask;
3281
3282 /* Much like unsigned, except no trimming with addrmask. In
3283 addition, the sum overflows if there is a carry out of
3284 the bfd_vma, i.e., the sum is less than either input
3285 operand. */
3286 a >>= howto->rightshift;
3287 b >>= howto->bitpos;
cf9ab45b 3288
dbe341c6
TR
3289 /* Bitfields are sometimes used for signed numbers; for
3290 example, a 13-bit field sometimes represents values in
3291 0..8191 and sometimes represents values in -4096..4095.
3292 If the field is signed and a is -4095 (0x1001) and b is
3293 -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
3294 0x1fff is 0x3000). It's not clear how to handle this
3295 everywhere, since there is not way to know how many bits
3296 are significant in the relocation, but the original code
3297 assumed that it was fully sign extended, and we will keep
3298 that assumption. */
3299 signmask = (fieldmask >> 1) + 1;
cf9ab45b 3300
dbe341c6
TR
3301 if ((a & ~ fieldmask) != 0)
3302 {
3303 /* Some bits out of the field are set. This might not
3304 be a problem: if this is a signed bitfield, it is OK
3305 iff all the high bits are set, including the sign
3306 bit. We'll try setting all but the most significant
3307 bit in the original relocation value: if this is all
3308 ones, we are OK, assuming a signed bitfield. */
3309 ss = (signmask << howto->rightshift) - 1;
3310 if ((ss | relocation) != ~ (bfd_vma) 0)
0a1b45a2 3311 return true;
dbe341c6
TR
3312 a &= fieldmask;
3313 }
cf9ab45b 3314
dbe341c6 3315 /* We just assume (b & ~ fieldmask) == 0. */
cf9ab45b 3316
dbe341c6
TR
3317 /* We explicitly permit wrap around if this relocation
3318 covers the high bit of an address. The Linux kernel
3319 relies on it, and it is the only way to write assembler
3320 code which can run when loaded at a location 0x80000000
3321 away from the location at which it is linked. */
706704c8 3322 if ((unsigned) howto->bitsize + howto->rightshift
dbe341c6 3323 == bfd_arch_bits_per_address (input_bfd))
0a1b45a2 3324 return false;
cf9ab45b 3325
dbe341c6
TR
3326 sum = a + b;
3327 if (sum < a || (sum & ~ fieldmask) != 0)
3328 {
3329 /* There was a carry out, or the field overflow. Test
3330 for signed operands again. Here is the overflow test
3331 is as for complain_overflow_signed. */
3332 if (((~ (a ^ b)) & (a ^ sum)) & signmask)
0a1b45a2 3333 return true;
dbe341c6 3334 }
cf9ab45b 3335
0a1b45a2 3336 return false;
dbe341c6
TR
3337}
3338
0a1b45a2 3339static bool
417236c0 3340xcoff_complain_overflow_signed_func (bfd *input_bfd,
07d6d2b8
AM
3341 bfd_vma val,
3342 bfd_vma relocation,
3343 struct reloc_howto_struct *howto)
dbe341c6
TR
3344{
3345 bfd_vma addrmask, fieldmask, signmask, ss;
3346 bfd_vma a, b, sum;
cf9ab45b 3347
dbe341c6
TR
3348 /* Get the values to be added together. For signed and unsigned
3349 relocations, we assume that all values should be truncated to
3350 the size of an address. For bitfields, all the bits matter.
3351 See also bfd_check_overflow. */
3352 fieldmask = N_ONES (howto->bitsize);
3353 addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3354 a = relocation;
3355 b = val & howto->src_mask;
3356
3357 a = (a & addrmask) >> howto->rightshift;
cf9ab45b 3358
dbe341c6
TR
3359 /* If any sign bits are set, all sign bits must be set.
3360 That is, A must be a valid negative address after
3361 shifting. */
3362 signmask = ~ (fieldmask >> 1);
3363 ss = a & signmask;
3364 if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
0a1b45a2 3365 return true;
cf9ab45b 3366
dbe341c6
TR
3367 /* We only need this next bit of code if the sign bit of B
3368 is below the sign bit of A. This would only happen if
3369 SRC_MASK had fewer bits than BITSIZE. Note that if
3370 SRC_MASK has more bits than BITSIZE, we can get into
3371 trouble; we would need to verify that B is in range, as
3372 we do for A above. */
3373 signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
3374 if ((b & signmask) != 0)
3375 {
3376 /* Set all the bits above the sign bit. */
3377 b -= signmask <<= 1;
3378 }
cf9ab45b 3379
dbe341c6 3380 b = (b & addrmask) >> howto->bitpos;
cf9ab45b 3381
dbe341c6
TR
3382 /* Now we can do the addition. */
3383 sum = a + b;
cf9ab45b 3384
dbe341c6
TR
3385 /* See if the result has the correct sign. Bits above the
3386 sign bit are junk now; ignore them. If the sum is
3387 positive, make sure we did not have all negative inputs;
3388 if the sum is negative, make sure we did not have all
3389 positive inputs. The test below looks only at the sign
3390 bits, and it really just
3391 SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
3392 */
3393 signmask = (fieldmask >> 1) + 1;
3394 if (((~ (a ^ b)) & (a ^ sum)) & signmask)
0a1b45a2 3395 return true;
cf9ab45b 3396
0a1b45a2 3397 return false;
dbe341c6
TR
3398}
3399
0a1b45a2 3400static bool
417236c0 3401xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
07d6d2b8
AM
3402 bfd_vma val,
3403 bfd_vma relocation,
3404 struct reloc_howto_struct *howto)
dbe341c6
TR
3405{
3406 bfd_vma addrmask, fieldmask;
3407 bfd_vma a, b, sum;
cf9ab45b 3408
dbe341c6
TR
3409 /* Get the values to be added together. For signed and unsigned
3410 relocations, we assume that all values should be truncated to
3411 the size of an address. For bitfields, all the bits matter.
3412 See also bfd_check_overflow. */
3413 fieldmask = N_ONES (howto->bitsize);
3414 addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
3415 a = relocation;
3416 b = val & howto->src_mask;
3417
3418 /* Checking for an unsigned overflow is relatively easy:
3419 trim the addresses and add, and trim the result as well.
3420 Overflow is normally indicated when the result does not
3421 fit in the field. However, we also need to consider the
3422 case when, e.g., fieldmask is 0x7fffffff or smaller, an
3423 input is 0x80000000, and bfd_vma is only 32 bits; then we
3424 will get sum == 0, but there is an overflow, since the
3425 inputs did not fit in the field. Instead of doing a
3426 separate test, we can check for this by or-ing in the
3427 operands when testing for the sum overflowing its final
3428 field. */
3429 a = (a & addrmask) >> howto->rightshift;
3430 b = (b & addrmask) >> howto->bitpos;
3431 sum = (a + b) & addrmask;
3432 if ((a | b | sum) & ~ fieldmask)
0a1b45a2 3433 return true;
cf9ab45b 3434
0a1b45a2 3435 return false;
dbe341c6 3436}
beb1bf64
TR
3437
3438/* This is the relocation function for the RS/6000/POWER/PowerPC.
3439 This is currently the only processor which uses XCOFF; I hope that
cf9ab45b 3440 will never change.
beb1bf64 3441
2c1bef53 3442 The original version was based on two documents:
dbe341c6
TR
3443 the PowerPC AIX Version 4 Application Binary Interface, First
3444 Edition (April 1992), and the PowerOpen ABI, Big-Endian
3445 32-Bit Hardware Implementation (June 30, 1994). Differences
cf9ab45b 3446 between the documents are noted below.
2c1bef53
CC
3447 Now, IBM has released an official documentation about XCOFF
3448 format:
3449 https://www.ibm.com/support/knowledgecenter/ssw_aix_72/filesreference/XCOFF.html
dbe341c6 3450
cf9ab45b 3451 Unsupported r_type's
dbe341c6
TR
3452
3453 R_RTB:
3454 R_RRTBI:
3455 R_RRTBA:
cf9ab45b 3456
dbe341c6
TR
3457 These relocs are defined by the PowerPC ABI to be
3458 relative branches which use half of the difference
3459 between the symbol and the program counter. I can't
3460 quite figure out when this is useful. These relocs are
cf9ab45b 3461 not defined by the PowerOpen ABI.
dbe341c6
TR
3462
3463 Supported r_type's
3464
3465 R_POS:
3466 Simple positive relocation.
3467
3468 R_NEG:
cf9ab45b 3469 Simple negative relocation.
dbe341c6
TR
3470
3471 R_REL:
3472 Simple PC relative relocation.
3473
3474 R_TOC:
3475 TOC relative relocation. The value in the instruction in
3476 the input file is the offset from the input file TOC to
3477 the desired location. We want the offset from the final
3478 TOC to the desired location. We have:
3479 isym = iTOC + in
3480 iinsn = in + o
3481 osym = oTOC + on
3482 oinsn = on + o
3483 so we must change insn by on - in.
2c1bef53
CC
3484 This relocation allows the linker to perform optimizations
3485 by transforming a load instruction into a add-immediate
3486 when possible. The relocation is, then, changed to R_TRLA
3487 in the output file.
3488 TODO: Currently, the optimisation isn't implemented.
3489
3490 R_TRL:
3491 TOC relative relocation. Same as R_TOC, except that
3492 the optimization isn't allowed
3493
3494 R_TRLA:
3495 TOC relative relocation. This is a TOC relative load
3496 address instruction which have been changed to an add-
3497 immediate instruction.
dbe341c6
TR
3498
3499 R_GL:
3500 GL linkage relocation. The value of this relocation
2c1bef53
CC
3501 is the address of the external symbol in the TOC
3502 section.
dbe341c6
TR
3503
3504 R_TCL:
3505 Local object TOC address. I can't figure out the
cf9ab45b 3506 difference between this and case R_GL.
dbe341c6 3507
2c1bef53
CC
3508 R_RL:
3509 The PowerPC AIX ABI describes this as a load which may be
3510 changed to a load address. The PowerOpen ABI says this
3511 is the same as case R_POS.
dbe341c6 3512
2c1bef53
CC
3513 R_RLA:
3514 The PowerPC AIX ABI describes this as a load address
3515 which may be changed to a load. The PowerOpen ABI says
3516 this is the same as R_POS.
3517
3518 R_REF:
3519 Not a relocation but a way to prevent the garbage
3520 collector of AIX linker to remove symbols.
3521 This is not needed in our case.
dbe341c6
TR
3522
3523 R_BA:
2c1bef53
CC
3524 The PowerOpen ABI says this is the same as R_RBA.
3525
3526 R_RBA:
3527 Absolute branch which may be modified to become a
3528 relative branch.
3529
3530 R_BR:
3531 The PowerOpen ABI says this is the same as R_RBR.
3532
3533 R_RBR:
3534 A relative branch which may be modified to become an
3535 absolute branch.
dbe341c6
TR
3536
3537 R_CAI:
3538 The PowerPC ABI defines this as an absolute call which
3539 may be modified to become a relative call. The PowerOpen
cf9ab45b
AM
3540 ABI does not define this relocation type.
3541
2c1bef53
CC
3542 R_CREL:
3543 The PowerPC ABI defines this as a relative call which may
3544 be modified to become an absolute call. The PowerOpen
3545 ABI does not define this relocation type.
dbe341c6
TR
3546
3547 R_RBAC:
3548 The PowerPC ABI defines this as an absolute branch to a
3549 fixed address which may be modified to an absolute branch
3550 to a symbol. The PowerOpen ABI does not define this
cf9ab45b 3551 relocation type.
dbe341c6
TR
3552
3553 R_RBRC:
3554 The PowerPC ABI defines this as an absolute branch to a
3555 fixed address which may be modified to a relative branch.
cf9ab45b 3556 The PowerOpen ABI does not define this relocation type.
4a403be0 3557
1b2cb8e2
CC
3558 R_TLS:
3559 Thread-local storage relocation using general-dynamic
3560 model.
3561
3562 R_TLS_IE:
3563 Thread-local storage relocation using initial-exec model.
3564
3565 R_TLS_LD:
3566 Thread-local storage relocation using local-dynamic model.
3567
3568 R_TLS_LE:
3569 Thread-local storage relocation using local-exec model.
3570
3571 R_TLS:
3572 Tread-local storage relocation used by the loader.
3573
3574 R_TLSM:
3575 Tread-local storage relocation used by the loader.
3576
4a403be0
CC
3577 R_TOCU:
3578 Upper TOC relative relocation. The value is the
3579 high-order 16 bit of a TOC relative relocation.
3580
3581 R_TOCL:
3582 Lower TOC relative relocation. The value is the
3583 low-order 16 bit of a TOC relative relocation.
dbe341c6
TR
3584*/
3585
0a1b45a2 3586bool
417236c0 3587xcoff_ppc_relocate_section (bfd *output_bfd,
07d6d2b8
AM
3588 struct bfd_link_info *info,
3589 bfd *input_bfd,
3590 asection *input_section,
3591 bfd_byte *contents,
3592 struct internal_reloc *relocs,
3593 struct internal_syment *syms,
3594 asection **sections)
beb1bf64
TR
3595{
3596 struct internal_reloc *rel;
3597 struct internal_reloc *relend;
3598
3599 rel = relocs;
3600 relend = rel + input_section->reloc_count;
beb1bf64
TR
3601 for (; rel < relend; rel++)
3602 {
3603 long symndx;
3604 struct xcoff_link_hash_entry *h;
3605 struct internal_syment *sym;
3606 bfd_vma addend;
3607 bfd_vma val;
3608 struct reloc_howto_struct howto;
dbe341c6
TR
3609 bfd_vma relocation;
3610 bfd_vma value_to_relocate;
3611 bfd_vma address;
3612 bfd_byte *location;
beb1bf64
TR
3613
3614 /* Relocation type R_REF is a special relocation type which is
cf9ab45b
AM
3615 merely used to prevent garbage collection from occurring for
3616 the csect including the symbol which it references. */
beb1bf64
TR
3617 if (rel->r_type == R_REF)
3618 continue;
3619
2c1bef53
CC
3620 /* Retrieve default value in HOWTO table and fix up according
3621 to r_size field, if it can be different.
3622 This should be made during relocation reading but the algorithms
3623 are expecting constant howtos. */
3624 memcpy (&howto, &xcoff_howto_table[rel->r_type], sizeof (howto));
3625 if (howto.bitsize != (rel->r_size & 0x1f) + 1)
3626 {
3627 switch (rel->r_type)
3628 {
3629 case R_POS:
3630 case R_NEG:
3631 howto.bitsize = (rel->r_size & 0x1f) + 1;
3632 howto.size = howto.bitsize > 16 ? 2 : 1;
3633 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
3634 break;
3635
3636 default:
3637 _bfd_error_handler
3638 (_("%pB: relocatation (%d) at (0x%" BFD_VMA_FMT "x) has wrong"
3639 " r_rsize (0x%x)\n"),
3640 input_bfd, rel->r_type, rel->r_vaddr, rel->r_size);
0a1b45a2 3641 return false;
2c1bef53
CC
3642 }
3643 }
3644
cf9ab45b
AM
3645 howto.complain_on_overflow = (rel->r_size & 0x80
3646 ? complain_overflow_signed
3647 : complain_overflow_bitfield);
beb1bf64 3648
dbe341c6 3649 /* symbol */
beb1bf64 3650 val = 0;
dbe341c6
TR
3651 addend = 0;
3652 h = NULL;
3653 sym = NULL;
cf9ab45b 3654 symndx = rel->r_symndx;
beb1bf64 3655
cf9ab45b 3656 if (-1 != symndx)
beb1bf64
TR
3657 {
3658 asection *sec;
cf9ab45b 3659
dbe341c6
TR
3660 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
3661 sym = syms + symndx;
3662 addend = - sym->n_value;
cf9ab45b
AM
3663
3664 if (NULL == h)
beb1bf64
TR
3665 {
3666 sec = sections[symndx];
3667 /* Hack to make sure we use the right TOC anchor value
dbe341c6 3668 if this reloc is against the TOC anchor. */
beb1bf64 3669 if (sec->name[3] == '0'
dbe341c6
TR
3670 && strcmp (sec->name, ".tc0") == 0)
3671 val = xcoff_data (output_bfd)->toc;
f4ffd778 3672 else
dbe341c6
TR
3673 val = (sec->output_section->vma
3674 + sec->output_offset
3675 + sym->n_value
3676 - sec->vma);
cf9ab45b
AM
3677 }
3678 else
dbe341c6 3679 {
858ef0ce
RS
3680 if (info->unresolved_syms_in_objects != RM_IGNORE
3681 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
1a72702b
AM
3682 (*info->callbacks->undefined_symbol)
3683 (info, h->root.root.string,
3684 input_bfd, input_section,
3685 rel->r_vaddr - input_section->vma,
95a51568
FS
3686 info->unresolved_syms_in_objects == RM_DIAGNOSE &&
3687 !info->warn_unresolved_syms);
1a72702b 3688
cf9ab45b
AM
3689 if (h->root.type == bfd_link_hash_defined
3690 || h->root.type == bfd_link_hash_defweak)
dbe341c6
TR
3691 {
3692 sec = h->root.u.def.section;
3693 val = (h->root.u.def.value
3694 + sec->output_section->vma
3695 + sec->output_offset);
cf9ab45b
AM
3696 }
3697 else if (h->root.type == bfd_link_hash_common)
f4ffd778 3698 {
dbe341c6 3699 sec = h->root.u.c.p->section;
f4ffd778 3700 val = (sec->output_section->vma
dbe341c6 3701 + sec->output_offset);
cf9ab45b
AM
3702
3703 }
858ef0ce 3704 else
dbe341c6 3705 {
0e1862bb 3706 BFD_ASSERT (bfd_link_relocatable (info)
94313f36
RS
3707 || (info->static_link
3708 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
858ef0ce
RS
3709 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
3710 || (h->flags & XCOFF_IMPORT) != 0);
f4ffd778 3711 }
beb1bf64
TR
3712 }
3713 }
beb1bf64 3714
cf9ab45b
AM
3715 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
3716 || !((*xcoff_calculate_relocation[rel->r_type])
3717 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
3718 addend, &relocation, contents)))
0a1b45a2 3719 return false;
cf9ab45b 3720
dbe341c6
TR
3721 /* address */
3722 address = rel->r_vaddr - input_section->vma;
3723 location = contents + address;
cf9ab45b 3724
eea6121a 3725 if (address > input_section->size)
cf9ab45b 3726 abort ();
dbe341c6
TR
3727
3728 /* Get the value we are going to relocate. */
3729 if (1 == howto.size)
3730 value_to_relocate = bfd_get_16 (input_bfd, location);
cf9ab45b 3731 else
dbe341c6 3732 value_to_relocate = bfd_get_32 (input_bfd, location);
cf9ab45b
AM
3733
3734 /* overflow.
3735
dbe341c6
TR
3736 FIXME: We may drop bits during the addition
3737 which we don't check for. We must either check at every single
3738 operation, which would be tedious, or we must do the computations
3739 in a type larger than bfd_vma, which would be inefficient. */
beb1bf64 3740
cf9ab45b
AM
3741 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
3742 (input_bfd, value_to_relocate, relocation, &howto)))
beb1bf64 3743 {
dbe341c6
TR
3744 const char *name;
3745 char buf[SYMNMLEN + 1];
3746 char reloc_type_name[10];
cf9ab45b
AM
3747
3748 if (symndx == -1)
beb1bf64 3749 {
dbe341c6 3750 name = "*ABS*";
cf9ab45b
AM
3751 }
3752 else if (h != NULL)
beb1bf64 3753 {
dfeffb9f 3754 name = NULL;
cf9ab45b
AM
3755 }
3756 else
beb1bf64 3757 {
dbe341c6
TR
3758 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
3759 if (name == NULL)
3760 name = "UNKNOWN";
beb1bf64 3761 }
dbe341c6 3762 sprintf (reloc_type_name, "0x%02x", rel->r_type);
cf9ab45b 3763
1a72702b
AM
3764 (*info->callbacks->reloc_overflow)
3765 (info, (h ? &h->root : NULL), name, reloc_type_name,
3766 (bfd_vma) 0, input_bfd, input_section,
3767 rel->r_vaddr - input_section->vma);
beb1bf64 3768 }
cf9ab45b 3769
dbe341c6 3770 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
cf9ab45b
AM
3771 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
3772 | (((value_to_relocate & howto.src_mask)
3773 + relocation) & howto.dst_mask));
3774
dbe341c6
TR
3775 /* Put the value back in the object file. */
3776 if (1 == howto.size)
3777 bfd_put_16 (input_bfd, value_to_relocate, location);
cf9ab45b 3778 else
dbe341c6 3779 bfd_put_32 (input_bfd, value_to_relocate, location);
beb1bf64
TR
3780 }
3781
0a1b45a2 3782 return true;
beb1bf64
TR
3783}
3784
c25179e7
NC
3785/* gcc-8 warns (*) on all the strncpy calls in this function about
3786 possible string truncation. The "truncation" is not a bug. We
3787 have an external representation of structs with fields that are not
3788 necessarily NULL terminated and corresponding internal
3789 representation fields that are one larger so that they can always
3790 be NULL terminated.
3791 gcc versions between 4.2 and 4.6 do not allow pragma control of
3792 diagnostics inside functions, giving a hard error if you try to use
3793 the finer control available with later versions.
3794 gcc prior to 4.2 warns about diagnostic push and pop.
3795 gcc-5, gcc-6 and gcc-7 warn that -Wstringop-truncation is unknown,
3796 unless you also add #pragma GCC diagnostic ignored "-Wpragma".
3797 (*) Depending on your system header files! */
3798#if GCC_VERSION >= 8000
3799# pragma GCC diagnostic push
3800# pragma GCC diagnostic ignored "-Wstringop-truncation"
3801#endif
0a1b45a2 3802static bool
417236c0 3803_bfd_xcoff_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
3804 struct xcoff_loader_info *ldinfo,
3805 struct internal_ldsym *ldsym,
3806 const char *name)
beb1bf64
TR
3807{
3808 size_t len;
3809 len = strlen (name);
3810
3811 if (len <= SYMNMLEN)
3812 strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3813 else
3814 {
3815 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3816 {
dc810e39 3817 bfd_size_type newalc;
f075ee0c 3818 char *newstrings;
beb1bf64
TR
3819
3820 newalc = ldinfo->string_alc * 2;
3821 if (newalc == 0)
3822 newalc = 32;
3823 while (ldinfo->string_size + len + 3 > newalc)
3824 newalc *= 2;
3825
f075ee0c 3826 newstrings = bfd_realloc (ldinfo->strings, newalc);
beb1bf64
TR
3827 if (newstrings == NULL)
3828 {
0a1b45a2
AM
3829 ldinfo->failed = true;
3830 return false;
beb1bf64
TR
3831 }
3832 ldinfo->string_alc = newalc;
3833 ldinfo->strings = newstrings;
3834 }
3835
dc810e39
AM
3836 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3837 ldinfo->strings + ldinfo->string_size);
beb1bf64
TR
3838 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3839 ldsym->_l._l_l._l_zeroes = 0;
3840 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3841 ldinfo->string_size += len + 3;
3842 }
3843
0a1b45a2 3844 return true;
beb1bf64
TR
3845}
3846
0a1b45a2 3847static bool
b560e2ac
AM
3848_bfd_xcoff_put_symbol_name (struct bfd_link_info *info,
3849 struct bfd_strtab_hash *strtab,
beb1bf64 3850 struct internal_syment *sym,
f4ffd778
NC
3851 const char *name)
3852{
3853 if (strlen (name) <= SYMNMLEN)
3854 {
3855 strncpy (sym->_n._n_name, name, SYMNMLEN);
3856 }
3857 else
3858 {
0a1b45a2 3859 bool hash;
f4ffd778
NC
3860 bfd_size_type indx;
3861
b560e2ac 3862 hash = !info->traditional_format;
0a1b45a2 3863 indx = _bfd_stringtab_add (strtab, name, hash, false);
f4ffd778 3864 if (indx == (bfd_size_type) -1)
0a1b45a2 3865 return false;
f4ffd778
NC
3866 sym->_n._n_n._n_zeroes = 0;
3867 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3868 }
0a1b45a2 3869 return true;
beb1bf64 3870}
c25179e7
NC
3871#if GCC_VERSION >= 8000
3872# pragma GCC diagnostic pop
3873#endif
beb1bf64
TR
3874
3875static asection *
417236c0 3876xcoff_create_csect_from_smclas (bfd *abfd,
07d6d2b8
AM
3877 union internal_auxent *aux,
3878 const char *symbol_name)
beb1bf64 3879{
beb1bf64
TR
3880 asection *return_value = NULL;
3881
f4ffd778
NC
3882 /* .sv64 = x_smclas == 17
3883 This is an invalid csect for 32 bit apps. */
9a1ada6c
TG
3884 static const char * const names[] =
3885 {
3886 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo", /* 0 - 7 */
3887 ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0", /* 8 - 15 */
3888 ".td", NULL, ".sv3264", NULL, ".tl", ".ul", ".te"
3889 };
1b786873 3890
9a1ada6c 3891 if ((aux->x_csect.x_smclas < ARRAY_SIZE (names))
cf9ab45b 3892 && (NULL != names[aux->x_csect.x_smclas]))
f4ffd778 3893 {
dc810e39 3894 return_value = bfd_make_section_anyway
f4ffd778
NC
3895 (abfd, names[aux->x_csect.x_smclas]);
3896 }
3897 else
3898 {
4eca0228 3899 _bfd_error_handler
695344c0 3900 /* xgettext: c-format */
871b3ab2 3901 (_("%pB: symbol `%s' has unrecognized smclas %d"),
d003868e 3902 abfd, symbol_name, aux->x_csect.x_smclas);
f4ffd778
NC
3903 bfd_set_error (bfd_error_bad_value);
3904 }
beb1bf64
TR
3905
3906 return return_value;
3907}
3908
0a1b45a2 3909static bool
417236c0 3910xcoff_is_lineno_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma value)
beb1bf64 3911{
f4ffd778 3912 if (0xffff <= value)
0a1b45a2 3913 return true;
f4ffd778 3914
0a1b45a2 3915 return false;
beb1bf64
TR
3916}
3917
0a1b45a2 3918static bool
417236c0 3919xcoff_is_reloc_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma value)
beb1bf64 3920{
f4ffd778 3921 if (0xffff <= value)
0a1b45a2 3922 return true;
f4ffd778 3923
0a1b45a2 3924 return false;
beb1bf64
TR
3925}
3926
a7b97311 3927static bfd_vma
417236c0 3928xcoff_loader_symbol_offset (bfd *abfd,
07d6d2b8 3929 struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED)
beb1bf64 3930{
cf9ab45b 3931 return bfd_xcoff_ldhdrsz (abfd);
beb1bf64
TR
3932}
3933
a7b97311 3934static bfd_vma
417236c0 3935xcoff_loader_reloc_offset (bfd *abfd, struct internal_ldhdr *ldhdr)
beb1bf64 3936{
cf9ab45b 3937 return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
beb1bf64
TR
3938}
3939
0a1b45a2 3940static bool
417236c0 3941xcoff_generate_rtinit (bfd *abfd, const char *init, const char *fini,
0a1b45a2 3942 bool rtld)
9a4c7f16
TR
3943{
3944 bfd_byte filehdr_ext[FILHSZ];
3945 bfd_byte scnhdr_ext[SCNHSZ];
69f284c7
TR
3946 bfd_byte syment_ext[SYMESZ * 10];
3947 bfd_byte reloc_ext[RELSZ * 3];
9a4c7f16
TR
3948 bfd_byte *data_buffer;
3949 bfd_size_type data_buffer_size;
d426c6b0 3950 bfd_byte *string_table = NULL, *st_tmp = NULL;
9a4c7f16
TR
3951 bfd_size_type string_table_size;
3952 bfd_vma val;
3953 size_t initsz, finisz;
3954 struct internal_filehdr filehdr;
3955 struct internal_scnhdr scnhdr;
3956 struct internal_syment syment;
3957 union internal_auxent auxent;
3958 struct internal_reloc reloc;
cf9ab45b 3959
9a4c7f16
TR
3960 char *data_name = ".data";
3961 char *rtinit_name = "__rtinit";
69f284c7 3962 char *rtld_name = "__rtld";
cf9ab45b 3963
69f284c7 3964 if (! bfd_xcoff_rtinit_size (abfd))
0a1b45a2 3965 return false;
9a4c7f16
TR
3966
3967 initsz = (init == NULL ? 0 : 1 + strlen (init));
3968 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3969
3970 /* file header */
3971 memset (filehdr_ext, 0, FILHSZ);
3972 memset (&filehdr, 0, sizeof (struct internal_filehdr));
3973 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
cf9ab45b 3974 filehdr.f_nscns = 1;
9a4c7f16 3975 filehdr.f_timdat = 0;
69f284c7 3976 filehdr.f_nsyms = 0; /* at least 6, no more than 10 */
9a4c7f16
TR
3977 filehdr.f_symptr = 0; /* set below */
3978 filehdr.f_opthdr = 0;
3979 filehdr.f_flags = 0;
3980
3981 /* section header */
3982 memset (scnhdr_ext, 0, SCNHSZ);
3983 memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3984 memcpy (scnhdr.s_name, data_name, strlen (data_name));
3985 scnhdr.s_paddr = 0;
3986 scnhdr.s_vaddr = 0;
3987 scnhdr.s_size = 0; /* set below */
3988 scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3989 scnhdr.s_relptr = 0; /* set below */
3990 scnhdr.s_lnnoptr = 0;
3991 scnhdr.s_nreloc = 0; /* either 1 or 2 */
3992 scnhdr.s_nlnno = 0;
3993 scnhdr.s_flags = STYP_DATA;
3994
cf9ab45b
AM
3995 /* .data
3996 0x0000 0x00000000 : rtl
3997 0x0004 0x00000010 : offset to init, or 0
3998 0x0008 0x00000028 : offset to fini, or 0
3999 0x000C 0x0000000C : size of descriptor
4000 0x0010 0x00000000 : init, needs a reloc
4001 0x0014 0x00000040 : offset to init name
4002 0x0018 0x00000000 : flags, padded to a word
4003 0x001C 0x00000000 : empty init
4004 0x0020 0x00000000 :
4005 0x0024 0x00000000 :
4006 0x0028 0x00000000 : fini, needs a reloc
4007 0x002C 0x00000??? : offset to fini name
4008 0x0030 0x00000000 : flags, padded to a word
4009 0x0034 0x00000000 : empty fini
4010 0x0038 0x00000000 :
4011 0x003C 0x00000000 :
4012 0x0040 init name
9a4c7f16
TR
4013 0x0040 + initsz fini name */
4014
4015 data_buffer_size = 0x0040 + initsz + finisz;
2a52da53 4016 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
330693f5 4017 data_buffer = NULL;
9bab7074 4018 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
330693f5 4019 if (data_buffer == NULL)
0a1b45a2 4020 return false;
9a4c7f16 4021
cf9ab45b 4022 if (initsz)
9a4c7f16
TR
4023 {
4024 val = 0x10;
4025 bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
4026 val = 0x40;
4027 bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
4028 memcpy (&data_buffer[val], init, initsz);
4029 }
4030
cf9ab45b 4031 if (finisz)
9a4c7f16
TR
4032 {
4033 val = 0x28;
4034 bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
4035 val = 0x40 + initsz;
4036 bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
4037 memcpy (&data_buffer[val], fini, finisz);
4038 }
4039
4040 val = 0x0C;
4041 bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
4042
4043 scnhdr.s_size = data_buffer_size;
4044
4045 /* string table */
4046 string_table_size = 0;
cf9ab45b 4047 if (initsz > 9)
9a4c7f16
TR
4048 string_table_size += initsz;
4049 if (finisz > 9)
4050 string_table_size += finisz;
4051 if (string_table_size)
4052 {
4053 string_table_size += 4;
9bab7074 4054 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
021d6096 4055 if (string_table == NULL)
0a1b45a2 4056 return false;
9bab7074 4057
9a4c7f16
TR
4058 val = string_table_size;
4059 bfd_h_put_32 (abfd, val, &string_table[0]);
4060 st_tmp = string_table + 4;
4061 }
cf9ab45b
AM
4062
4063 /* symbols
9a4c7f16
TR
4064 0. .data csect
4065 2. __rtinit
cf9ab45b
AM
4066 4. init function
4067 6. fini function
69f284c7
TR
4068 8. __rtld */
4069 memset (syment_ext, 0, 10 * SYMESZ);
4070 memset (reloc_ext, 0, 3 * RELSZ);
9a4c7f16
TR
4071
4072 /* .data csect */
4073 memset (&syment, 0, sizeof (struct internal_syment));
4074 memset (&auxent, 0, sizeof (union internal_auxent));
4075 memcpy (syment._n._n_name, data_name, strlen (data_name));
4076 syment.n_scnum = 1;
4077 syment.n_sclass = C_HIDEXT;
4078 syment.n_numaux = 1;
4079 auxent.x_csect.x_scnlen.l = data_buffer_size;
4080 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
4081 auxent.x_csect.x_smclas = XMC_RW;
cf9ab45b 4082 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 4083 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
4084 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
4085 syment.n_numaux,
9a4c7f16
TR
4086 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
4087 filehdr.f_nsyms += 2;
4088
4089 /* __rtinit */
4090 memset (&syment, 0, sizeof (struct internal_syment));
4091 memset (&auxent, 0, sizeof (union internal_auxent));
4092 memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
4093 syment.n_scnum = 1;
4094 syment.n_sclass = C_EXT;
4095 syment.n_numaux = 1;
4096 auxent.x_csect.x_smtyp = XTY_LD;
4097 auxent.x_csect.x_smclas = XMC_RW;
cf9ab45b 4098 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 4099 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
4100 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
4101 syment.n_numaux,
9a4c7f16
TR
4102 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
4103 filehdr.f_nsyms += 2;
4104
4105 /* init */
cf9ab45b 4106 if (initsz)
9a4c7f16
TR
4107 {
4108 memset (&syment, 0, sizeof (struct internal_syment));
4109 memset (&auxent, 0, sizeof (union internal_auxent));
4110
cf9ab45b 4111 if (initsz > 9)
9a4c7f16
TR
4112 {
4113 syment._n._n_n._n_offset = st_tmp - string_table;
4114 memcpy (st_tmp, init, initsz);
4115 st_tmp += initsz;
4116 }
4117 else
4118 memcpy (syment._n._n_name, init, initsz - 1);
4119
4120 syment.n_sclass = C_EXT;
4121 syment.n_numaux = 1;
cf9ab45b 4122 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 4123 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
4124 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
4125 syment.n_numaux,
9a4c7f16
TR
4126 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
4127
4128 /* reloc */
4129 memset (&reloc, 0, sizeof (struct internal_reloc));
4130 reloc.r_vaddr = 0x0010;
4131 reloc.r_symndx = filehdr.f_nsyms;
4132 reloc.r_type = R_POS;
4133 reloc.r_size = 31;
4134 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
4135
4136 filehdr.f_nsyms += 2;
4137 scnhdr.s_nreloc += 1;
4138 }
cf9ab45b 4139
9a4c7f16 4140 /* fini */
cf9ab45b 4141 if (finisz)
9a4c7f16
TR
4142 {
4143 memset (&syment, 0, sizeof (struct internal_syment));
4144 memset (&auxent, 0, sizeof (union internal_auxent));
4145
cf9ab45b 4146 if (finisz > 9)
9a4c7f16
TR
4147 {
4148 syment._n._n_n._n_offset = st_tmp - string_table;
4149 memcpy (st_tmp, fini, finisz);
4150 st_tmp += finisz;
4151 }
4152 else
4153 memcpy (syment._n._n_name, fini, finisz - 1);
4154
4155 syment.n_sclass = C_EXT;
4156 syment.n_numaux = 1;
cf9ab45b 4157 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 4158 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
4159 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
4160 syment.n_numaux,
9a4c7f16
TR
4161 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
4162
4163 /* reloc */
4164 memset (&reloc, 0, sizeof (struct internal_reloc));
4165 reloc.r_vaddr = 0x0028;
4166 reloc.r_symndx = filehdr.f_nsyms;
4167 reloc.r_type = R_POS;
4168 reloc.r_size = 31;
cf9ab45b 4169 bfd_coff_swap_reloc_out (abfd, &reloc,
9a4c7f16
TR
4170 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
4171
4172 filehdr.f_nsyms += 2;
4173 scnhdr.s_nreloc += 1;
4174 }
4175
69f284c7
TR
4176 if (rtld)
4177 {
4178 memset (&syment, 0, sizeof (struct internal_syment));
4179 memset (&auxent, 0, sizeof (union internal_auxent));
4180 memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
4181 syment.n_sclass = C_EXT;
4182 syment.n_numaux = 1;
cf9ab45b 4183 bfd_coff_swap_sym_out (abfd, &syment,
69f284c7 4184 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
4185 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
4186 syment.n_numaux,
69f284c7
TR
4187 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
4188
4189 /* reloc */
4190 memset (&reloc, 0, sizeof (struct internal_reloc));
4191 reloc.r_vaddr = 0x0000;
4192 reloc.r_symndx = filehdr.f_nsyms;
4193 reloc.r_type = R_POS;
4194 reloc.r_size = 31;
cf9ab45b 4195 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7
TR
4196 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
4197
4198 filehdr.f_nsyms += 2;
4199 scnhdr.s_nreloc += 1;
4200 }
4201
9a4c7f16
TR
4202 scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
4203 filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
4204
4205 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
4206 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
4207 bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
4208 bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
4209 bfd_bwrite (data_buffer, data_buffer_size, abfd);
4210 bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
4211 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
4212 bfd_bwrite (string_table, string_table_size, abfd);
4213
330693f5
TR
4214 free (data_buffer);
4215 data_buffer = NULL;
4216
0a1b45a2 4217 return true;
9a4c7f16
TR
4218}
4219
beb1bf64
TR
4220
4221static reloc_howto_type xcoff_dynamic_reloc =
cf9ab45b
AM
4222HOWTO (0, /* type */
4223 0, /* rightshift */
4224 2, /* size (0 = byte, 1 = short, 2 = long) */
4225 32, /* bitsize */
0a1b45a2 4226 false, /* pc_relative */
cf9ab45b 4227 0, /* bitpos */
beb1bf64 4228 complain_overflow_bitfield, /* complain_on_overflow */
cf9ab45b
AM
4229 0, /* special_function */
4230 "R_POS", /* name */
0a1b45a2 4231 true, /* partial_inplace */
cf9ab45b
AM
4232 0xffffffff, /* src_mask */
4233 0xffffffff, /* dst_mask */
0a1b45a2 4234 false); /* pcrel_offset */
beb1bf64 4235
dc810e39
AM
4236/* glink
4237
4238 The first word of global linkage code must be modified by filling in
f4ffd778
NC
4239 the correct TOC offset. */
4240
342371d5 4241static const unsigned long xcoff_glink_code[9] =
f4ffd778
NC
4242 {
4243 0x81820000, /* lwz r12,0(r2) */
4244 0x90410014, /* stw r2,20(r1) */
4245 0x800c0000, /* lwz r0,0(r12) */
4246 0x804c0004, /* lwz r2,4(r12) */
4247 0x7c0903a6, /* mtctr r0 */
4248 0x4e800420, /* bctr */
4249 0x00000000, /* start of traceback table */
4250 0x000c8000, /* traceback table */
4251 0x00000000, /* traceback table */
4252 };
beb1bf64 4253
85645aed
TG
4254/* Table to convert DWARF flags to section names. */
4255
4256const struct xcoff_dwsect_name xcoff_dwsect_names[] = {
0a1b45a2
AM
4257 { SSUBTYP_DWINFO, ".dwinfo", true },
4258 { SSUBTYP_DWLINE, ".dwline", true },
4259 { SSUBTYP_DWPBNMS, ".dwpbnms", true },
4260 { SSUBTYP_DWPBTYP, ".dwpbtyp", true },
4261 { SSUBTYP_DWARNGE, ".dwarnge", true },
4262 { SSUBTYP_DWABREV, ".dwabrev", false },
4263 { SSUBTYP_DWSTR, ".dwstr", true },
4264 { SSUBTYP_DWRNGES, ".dwrnges", true }
85645aed 4265};
beb1bf64 4266
09bf66a8
TG
4267/* For generic entry points. */
4268#define _bfd_xcoff_close_and_cleanup _bfd_archive_close_and_cleanup
d00dd7dc 4269#define _bfd_xcoff_bfd_free_cached_info _bfd_bool_bfd_true
09bf66a8
TG
4270#define _bfd_xcoff_new_section_hook coff_new_section_hook
4271#define _bfd_xcoff_get_section_contents _bfd_generic_get_section_contents
4272#define _bfd_xcoff_get_section_contents_in_window \
4273 _bfd_generic_get_section_contents_in_window
4274
4275/* For copy private data entry points. */
4276#define _bfd_xcoff_bfd_copy_private_bfd_data \
4277 _bfd_xcoff_copy_private_bfd_data
4278#define _bfd_xcoff_bfd_merge_private_bfd_data \
4279 _bfd_generic_bfd_merge_private_bfd_data
4280#define _bfd_xcoff_bfd_copy_private_section_data \
4281 _bfd_generic_bfd_copy_private_section_data
4282#define _bfd_xcoff_bfd_copy_private_symbol_data \
4283 _bfd_generic_bfd_copy_private_symbol_data
4284#define _bfd_xcoff_bfd_copy_private_header_data \
4285 _bfd_generic_bfd_copy_private_header_data
4286#define _bfd_xcoff_bfd_set_private_flags \
4287 _bfd_generic_bfd_set_private_flags
4288#define _bfd_xcoff_bfd_print_private_bfd_data \
4289 _bfd_generic_bfd_print_private_bfd_data
4290
4291/* For archive entry points. */
4292#define _bfd_xcoff_slurp_extended_name_table \
4293 _bfd_noarchive_slurp_extended_name_table
4294#define _bfd_xcoff_construct_extended_name_table \
4295 _bfd_noarchive_construct_extended_name_table
4296#define _bfd_xcoff_truncate_arname bfd_dont_truncate_arname
4297#define _bfd_xcoff_write_ar_hdr _bfd_generic_write_ar_hdr
4298#define _bfd_xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
4299#define _bfd_xcoff_generic_stat_arch_elt _bfd_xcoff_stat_arch_elt
d00dd7dc 4300#define _bfd_xcoff_update_armap_timestamp _bfd_bool_bfd_true
09bf66a8
TG
4301
4302/* For symbols entry points. */
4303#define _bfd_xcoff_get_symtab_upper_bound coff_get_symtab_upper_bound
4304#define _bfd_xcoff_canonicalize_symtab coff_canonicalize_symtab
4305#define _bfd_xcoff_make_empty_symbol coff_make_empty_symbol
4306#define _bfd_xcoff_print_symbol coff_print_symbol
4307#define _bfd_xcoff_get_symbol_info coff_get_symbol_info
60bb06bc
L
4308#define _bfd_xcoff_get_symbol_version_string \
4309 _bfd_nosymbols_get_symbol_version_string
09bf66a8
TG
4310#define _bfd_xcoff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
4311#define _bfd_xcoff_bfd_is_target_special_symbol \
4312 coff_bfd_is_target_special_symbol
4313#define _bfd_xcoff_get_lineno coff_get_lineno
fb167eb2 4314#define _bfd_xcoff_find_nearest_line coff_find_nearest_line
9c461f7d 4315#define _bfd_xcoff_find_line coff_find_line
09bf66a8
TG
4316#define _bfd_xcoff_find_inliner_info coff_find_inliner_info
4317#define _bfd_xcoff_bfd_make_debug_symbol coff_bfd_make_debug_symbol
4318#define _bfd_xcoff_read_minisymbols _bfd_generic_read_minisymbols
4319#define _bfd_xcoff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
4320
4321/* For reloc entry points. */
4322#define _bfd_xcoff_get_reloc_upper_bound coff_get_reloc_upper_bound
4323#define _bfd_xcoff_canonicalize_reloc coff_canonicalize_reloc
23186865 4324#define _bfd_xcoff_set_reloc _bfd_generic_set_reloc
09bf66a8
TG
4325#define _bfd_xcoff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
4326#define _bfd_xcoff_bfd_reloc_name_lookup _bfd_xcoff_reloc_name_lookup
4327
4328/* For link entry points. */
4329#define _bfd_xcoff_bfd_get_relocated_section_contents \
4330 bfd_generic_get_relocated_section_contents
4331#define _bfd_xcoff_bfd_relax_section bfd_generic_relax_section
4332#define _bfd_xcoff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
4333#define _bfd_xcoff_bfd_link_just_syms _bfd_generic_link_just_syms
4334#define _bfd_xcoff_bfd_copy_link_hash_symbol_type \
4335 _bfd_generic_copy_link_hash_symbol_type
4336#define _bfd_xcoff_bfd_link_split_section _bfd_generic_link_split_section
4337#define _bfd_xcoff_bfd_gc_sections bfd_generic_gc_sections
4338#define _bfd_xcoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
4339#define _bfd_xcoff_bfd_merge_sections bfd_generic_merge_sections
4340#define _bfd_xcoff_bfd_is_group_section bfd_generic_is_group_section
cb7f4b29 4341#define _bfd_xcoff_bfd_group_name bfd_generic_group_name
09bf66a8
TG
4342#define _bfd_xcoff_bfd_discard_group bfd_generic_discard_group
4343#define _bfd_xcoff_section_already_linked _bfd_generic_section_already_linked
4344#define _bfd_xcoff_bfd_define_common_symbol _bfd_xcoff_define_common_symbol
34a87bb0 4345#define _bfd_xcoff_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
7dba9362 4346#define _bfd_xcoff_bfd_define_start_stop bfd_generic_define_start_stop
4f3b23b3 4347#define _bfd_xcoff_bfd_link_check_relocs _bfd_generic_link_check_relocs
09bf66a8
TG
4348
4349/* For dynamic symbols and relocs entry points. */
4350#define _bfd_xcoff_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
4351
dc810e39 4352static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
f4ffd778
NC
4353 {
4354 { /* COFF backend, defined in libcoff.h. */
cf9ab45b
AM
4355 _bfd_xcoff_swap_aux_in,
4356 _bfd_xcoff_swap_sym_in,
4357 coff_swap_lineno_in,
4358 _bfd_xcoff_swap_aux_out,
4359 _bfd_xcoff_swap_sym_out,
4360 coff_swap_lineno_out,
4361 xcoff_swap_reloc_out,
4362 coff_swap_filehdr_out,
4363 coff_swap_aouthdr_out,
4364 coff_swap_scnhdr_out,
4365 FILHSZ,
4366 AOUTSZ,
4367 SCNHSZ,
4368 SYMESZ,
4369 AUXESZ,
4370 RELSZ,
4371 LINESZ,
4372 FILNMLEN,
0a1b45a2 4373 true, /* _bfd_coff_long_filenames */
88183869 4374 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 4375 3, /* _bfd_coff_default_section_alignment_power */
0a1b45a2 4376 false, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b 4377 2, /* _bfd_coff_debug_string_prefix_length */
167ad85b 4378 32768, /* _bfd_coff_max_nscns */
cf9ab45b
AM
4379 coff_swap_filehdr_in,
4380 coff_swap_aouthdr_in,
4381 coff_swap_scnhdr_in,
4382 xcoff_swap_reloc_in,
4383 coff_bad_format_hook,
4384 coff_set_arch_mach_hook,
4385 coff_mkobject_hook,
4386 styp_to_sec_flags,
4387 coff_set_alignment_hook,
4388 coff_slurp_symbol_table,
4389 symname_in_debug_hook,
4390 coff_pointerize_aux_hook,
4391 coff_print_aux,
4392 dummy_reloc16_extra_cases,
4393 dummy_reloc16_estimate,
4394 NULL, /* bfd_coff_sym_is_global */
4395 coff_compute_section_file_positions,
4396 NULL, /* _bfd_coff_start_final_link */
4397 xcoff_ppc_relocate_section,
4398 coff_rtype_to_howto,
4399 NULL, /* _bfd_coff_adjust_symndx */
4400 _bfd_generic_link_add_one_symbol,
4401 coff_link_output_has_begun,
2b5c217d
NC
4402 coff_final_link_postscript,
4403 NULL /* print_pdata. */
f4ffd778
NC
4404 },
4405
cf9ab45b
AM
4406 0x01DF, /* magic number */
4407 bfd_arch_rs6000,
4408 bfd_mach_rs6k,
dc810e39 4409
f4ffd778 4410 /* Function pointers to xcoff specific swap routines. */
cf9ab45b
AM
4411 xcoff_swap_ldhdr_in,
4412 xcoff_swap_ldhdr_out,
4413 xcoff_swap_ldsym_in,
4414 xcoff_swap_ldsym_out,
4415 xcoff_swap_ldrel_in,
4416 xcoff_swap_ldrel_out,
f4ffd778
NC
4417
4418 /* Sizes. */
cf9ab45b
AM
4419 LDHDRSZ,
4420 LDSYMSZ,
4421 LDRELSZ,
4422 12, /* _xcoff_function_descriptor_size */
4423 SMALL_AOUTSZ,
f4ffd778 4424
cf9ab45b
AM
4425 /* Versions. */
4426 1, /* _xcoff_ldhdr_version */
f4ffd778 4427
cf9ab45b
AM
4428 _bfd_xcoff_put_symbol_name,
4429 _bfd_xcoff_put_ldsymbol_name,
4430 &xcoff_dynamic_reloc,
4431 xcoff_create_csect_from_smclas,
f4ffd778
NC
4432
4433 /* Lineno and reloc count overflow. */
4434 xcoff_is_lineno_count_overflow,
4435 xcoff_is_reloc_count_overflow,
4436
4437 xcoff_loader_symbol_offset,
4438 xcoff_loader_reloc_offset,
4439
4440 /* glink. */
cf9ab45b
AM
4441 &xcoff_glink_code[0],
4442 36, /* _xcoff_glink_size */
9a4c7f16
TR
4443
4444 /* rtinit */
cf9ab45b
AM
4445 64, /* _xcoff_rtinit_size */
4446 xcoff_generate_rtinit,
4447 };
beb1bf64 4448
eb1e0e80 4449/* The transfer vector that leads the outside world to all of the above. */
6d00b590 4450const bfd_target rs6000_xcoff_vec =
cf9ab45b
AM
4451 {
4452 "aixcoff-rs6000",
4453 bfd_target_xcoff_flavour,
4454 BFD_ENDIAN_BIG, /* data byte order is big */
4455 BFD_ENDIAN_BIG, /* header byte order is big */
4456
4457 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4458 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4459
a7c71b0c 4460 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
4461 0, /* leading char */
4462 '/', /* ar_pad_char */
4463 15, /* ar_max_namelen */
0aabe54e 4464 0, /* match priority. */
d1bcae83 4465 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
cf9ab45b
AM
4466
4467 /* data */
4468 bfd_getb64,
4469 bfd_getb_signed_64,
4470 bfd_putb64,
4471 bfd_getb32,
4472 bfd_getb_signed_32,
4473 bfd_putb32,
4474 bfd_getb16,
4475 bfd_getb_signed_16,
4476 bfd_putb16,
4477
4478 /* hdrs */
4479 bfd_getb64,
4480 bfd_getb_signed_64,
4481 bfd_putb64,
4482 bfd_getb32,
4483 bfd_getb_signed_32,
4484 bfd_putb32,
4485 bfd_getb16,
4486 bfd_getb_signed_16,
4487 bfd_putb16,
4488
4489 { /* bfd_check_format */
4490 _bfd_dummy_target,
4491 coff_object_p,
4492 _bfd_xcoff_archive_p,
4493 CORE_FILE_P
4494 },
dc810e39 4495
cf9ab45b 4496 { /* bfd_set_format */
d00dd7dc 4497 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4498 coff_mkobject,
4499 _bfd_generic_mkarchive,
d00dd7dc 4500 _bfd_bool_bfd_false_error
cf9ab45b
AM
4501 },
4502
4503 {/* bfd_write_contents */
d00dd7dc 4504 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4505 coff_write_object_contents,
4506 _bfd_xcoff_write_archive_contents,
d00dd7dc 4507 _bfd_bool_bfd_false_error
cf9ab45b
AM
4508 },
4509
09bf66a8
TG
4510 BFD_JUMP_TABLE_GENERIC (_bfd_xcoff),
4511 BFD_JUMP_TABLE_COPY (_bfd_xcoff),
261b8d08 4512 BFD_JUMP_TABLE_CORE (coff),
09bf66a8
TG
4513 BFD_JUMP_TABLE_ARCHIVE (_bfd_xcoff),
4514 BFD_JUMP_TABLE_SYMBOLS (_bfd_xcoff),
4515 BFD_JUMP_TABLE_RELOCS (_bfd_xcoff),
4516 BFD_JUMP_TABLE_WRITE (coff),
4517 BFD_JUMP_TABLE_LINK (_bfd_xcoff),
4518 BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
cf9ab45b
AM
4519
4520 /* Opposite endian version, none exists */
4521 NULL,
4522
2c3fc389 4523 & bfd_xcoff_backend_data,
cf9ab45b 4524 };
beb1bf64 4525
cf9ab45b
AM
4526/* xcoff-powermac target
4527 Old target.
4528 Only difference between this target and the rs6000 target is the
4529 the default architecture and machine type used in coffcode.h
4530
4531 PowerPC Macs use the same magic numbers as RS/6000
4532 (because that's how they were bootstrapped originally),
4533 but they are always PowerPC architecture. */
dc810e39 4534static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
cf9ab45b
AM
4535 {
4536 { /* COFF backend, defined in libcoff.h. */
4537 _bfd_xcoff_swap_aux_in,
4538 _bfd_xcoff_swap_sym_in,
4539 coff_swap_lineno_in,
4540 _bfd_xcoff_swap_aux_out,
4541 _bfd_xcoff_swap_sym_out,
4542 coff_swap_lineno_out,
4543 xcoff_swap_reloc_out,
4544 coff_swap_filehdr_out,
4545 coff_swap_aouthdr_out,
4546 coff_swap_scnhdr_out,
4547 FILHSZ,
4548 AOUTSZ,
4549 SCNHSZ,
4550 SYMESZ,
4551 AUXESZ,
4552 RELSZ,
4553 LINESZ,
4554 FILNMLEN,
0a1b45a2 4555 true, /* _bfd_coff_long_filenames */
88183869 4556 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 4557 3, /* _bfd_coff_default_section_alignment_power */
0a1b45a2 4558 false, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b 4559 2, /* _bfd_coff_debug_string_prefix_length */
167ad85b 4560 32768, /* _bfd_coff_max_nscns */
cf9ab45b
AM
4561 coff_swap_filehdr_in,
4562 coff_swap_aouthdr_in,
4563 coff_swap_scnhdr_in,
4564 xcoff_swap_reloc_in,
4565 coff_bad_format_hook,
4566 coff_set_arch_mach_hook,
4567 coff_mkobject_hook,
4568 styp_to_sec_flags,
4569 coff_set_alignment_hook,
4570 coff_slurp_symbol_table,
4571 symname_in_debug_hook,
4572 coff_pointerize_aux_hook,
4573 coff_print_aux,
4574 dummy_reloc16_extra_cases,
4575 dummy_reloc16_estimate,
4576 NULL, /* bfd_coff_sym_is_global */
4577 coff_compute_section_file_positions,
4578 NULL, /* _bfd_coff_start_final_link */
4579 xcoff_ppc_relocate_section,
4580 coff_rtype_to_howto,
4581 NULL, /* _bfd_coff_adjust_symndx */
4582 _bfd_generic_link_add_one_symbol,
4583 coff_link_output_has_begun,
2b5c217d
NC
4584 coff_final_link_postscript,
4585 NULL /* print_pdata. */
cf9ab45b
AM
4586 },
4587
4588 0x01DF, /* magic number */
4589 bfd_arch_powerpc,
4590 bfd_mach_ppc,
4591
4592 /* Function pointers to xcoff specific swap routines. */
4593 xcoff_swap_ldhdr_in,
4594 xcoff_swap_ldhdr_out,
4595 xcoff_swap_ldsym_in,
4596 xcoff_swap_ldsym_out,
4597 xcoff_swap_ldrel_in,
4598 xcoff_swap_ldrel_out,
4599
4600 /* Sizes. */
4601 LDHDRSZ,
4602 LDSYMSZ,
4603 LDRELSZ,
4604 12, /* _xcoff_function_descriptor_size */
4605 SMALL_AOUTSZ,
4606
4607 /* Versions. */
4608 1, /* _xcoff_ldhdr_version */
4609
4610 _bfd_xcoff_put_symbol_name,
4611 _bfd_xcoff_put_ldsymbol_name,
4612 &xcoff_dynamic_reloc,
4613 xcoff_create_csect_from_smclas,
4614
4615 /* Lineno and reloc count overflow. */
4616 xcoff_is_lineno_count_overflow,
4617 xcoff_is_reloc_count_overflow,
4618
4619 xcoff_loader_symbol_offset,
4620 xcoff_loader_reloc_offset,
beb1bf64 4621
cf9ab45b
AM
4622 /* glink. */
4623 &xcoff_glink_code[0],
4624 36, /* _xcoff_glink_size */
4625
4626 /* rtinit */
4627 0, /* _xcoff_rtinit_size */
4628 xcoff_generate_rtinit,
4629 };
4630
4631/* The transfer vector that leads the outside world to all of the above. */
6d00b590 4632const bfd_target powerpc_xcoff_vec =
cf9ab45b
AM
4633 {
4634 "xcoff-powermac",
4635 bfd_target_xcoff_flavour,
4636 BFD_ENDIAN_BIG, /* data byte order is big */
4637 BFD_ENDIAN_BIG, /* header byte order is big */
4638
4639 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4640 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4641
a7c71b0c 4642 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
4643 0, /* leading char */
4644 '/', /* ar_pad_char */
4645 15, /* ar_max_namelen */
0aabe54e 4646 0, /* match priority. */
d1bcae83 4647 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
cf9ab45b
AM
4648
4649 /* data */
4650 bfd_getb64,
4651 bfd_getb_signed_64,
4652 bfd_putb64,
4653 bfd_getb32,
4654 bfd_getb_signed_32,
4655 bfd_putb32,
4656 bfd_getb16,
4657 bfd_getb_signed_16,
4658 bfd_putb16,
4659
4660 /* hdrs */
4661 bfd_getb64,
4662 bfd_getb_signed_64,
4663 bfd_putb64,
4664 bfd_getb32,
4665 bfd_getb_signed_32,
4666 bfd_putb32,
4667 bfd_getb16,
4668 bfd_getb_signed_16,
4669 bfd_putb16,
4670
4671 { /* bfd_check_format */
4672 _bfd_dummy_target,
4673 coff_object_p,
4674 _bfd_xcoff_archive_p,
4675 CORE_FILE_P
4676 },
4677
4678 { /* bfd_set_format */
d00dd7dc 4679 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4680 coff_mkobject,
4681 _bfd_generic_mkarchive,
d00dd7dc 4682 _bfd_bool_bfd_false_error
cf9ab45b
AM
4683 },
4684
4685 {/* bfd_write_contents */
d00dd7dc 4686 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4687 coff_write_object_contents,
4688 _bfd_xcoff_write_archive_contents,
d00dd7dc 4689 _bfd_bool_bfd_false_error
cf9ab45b 4690 },
dc810e39 4691
09bf66a8
TG
4692 BFD_JUMP_TABLE_GENERIC (_bfd_xcoff),
4693 BFD_JUMP_TABLE_COPY (_bfd_xcoff),
261b8d08 4694 BFD_JUMP_TABLE_CORE (coff),
09bf66a8
TG
4695 BFD_JUMP_TABLE_ARCHIVE (_bfd_xcoff),
4696 BFD_JUMP_TABLE_SYMBOLS (_bfd_xcoff),
4697 BFD_JUMP_TABLE_RELOCS (_bfd_xcoff),
4698 BFD_JUMP_TABLE_WRITE (coff),
4699 BFD_JUMP_TABLE_LINK (_bfd_xcoff),
4700 BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
cf9ab45b
AM
4701
4702 /* Opposite endian version, none exists */
4703 NULL,
4704
2c3fc389 4705 & bfd_pmac_xcoff_backend_data,
cf9ab45b 4706 };
This page took 1.347458 seconds and 4 git commands to generate.