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