Mark section in a section group with SHF_GROUP
[deliverable/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
b34976b6 3509static bfd_boolean
417236c0 3510_bfd_xcoff_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8
AM
3511 struct xcoff_loader_info *ldinfo,
3512 struct internal_ldsym *ldsym,
3513 const char *name)
beb1bf64
TR
3514{
3515 size_t len;
3516 len = strlen (name);
3517
3518 if (len <= SYMNMLEN)
3519 strncpy (ldsym->_l._l_name, name, SYMNMLEN);
3520 else
3521 {
3522 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
3523 {
dc810e39 3524 bfd_size_type newalc;
f075ee0c 3525 char *newstrings;
beb1bf64
TR
3526
3527 newalc = ldinfo->string_alc * 2;
3528 if (newalc == 0)
3529 newalc = 32;
3530 while (ldinfo->string_size + len + 3 > newalc)
3531 newalc *= 2;
3532
f075ee0c 3533 newstrings = bfd_realloc (ldinfo->strings, newalc);
beb1bf64
TR
3534 if (newstrings == NULL)
3535 {
b34976b6
AM
3536 ldinfo->failed = TRUE;
3537 return FALSE;
beb1bf64
TR
3538 }
3539 ldinfo->string_alc = newalc;
3540 ldinfo->strings = newstrings;
3541 }
3542
dc810e39
AM
3543 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
3544 ldinfo->strings + ldinfo->string_size);
beb1bf64
TR
3545 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
3546 ldsym->_l._l_l._l_zeroes = 0;
3547 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
3548 ldinfo->string_size += len + 3;
3549 }
3550
b34976b6 3551 return TRUE;
beb1bf64
TR
3552}
3553
b34976b6 3554static bfd_boolean
b560e2ac
AM
3555_bfd_xcoff_put_symbol_name (struct bfd_link_info *info,
3556 struct bfd_strtab_hash *strtab,
beb1bf64 3557 struct internal_syment *sym,
f4ffd778
NC
3558 const char *name)
3559{
3560 if (strlen (name) <= SYMNMLEN)
3561 {
3562 strncpy (sym->_n._n_name, name, SYMNMLEN);
3563 }
3564 else
3565 {
b34976b6 3566 bfd_boolean hash;
f4ffd778
NC
3567 bfd_size_type indx;
3568
b560e2ac 3569 hash = !info->traditional_format;
b34976b6 3570 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
f4ffd778 3571 if (indx == (bfd_size_type) -1)
b34976b6 3572 return FALSE;
f4ffd778
NC
3573 sym->_n._n_n._n_zeroes = 0;
3574 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
3575 }
b34976b6 3576 return TRUE;
beb1bf64
TR
3577}
3578
3579static asection *
417236c0 3580xcoff_create_csect_from_smclas (bfd *abfd,
07d6d2b8
AM
3581 union internal_auxent *aux,
3582 const char *symbol_name)
beb1bf64 3583{
beb1bf64
TR
3584 asection *return_value = NULL;
3585
f4ffd778
NC
3586 /* .sv64 = x_smclas == 17
3587 This is an invalid csect for 32 bit apps. */
9a1ada6c
TG
3588 static const char * const names[] =
3589 {
3590 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo", /* 0 - 7 */
3591 ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0", /* 8 - 15 */
3592 ".td", NULL, ".sv3264", NULL, ".tl", ".ul", ".te"
3593 };
1b786873 3594
9a1ada6c 3595 if ((aux->x_csect.x_smclas < ARRAY_SIZE (names))
cf9ab45b 3596 && (NULL != names[aux->x_csect.x_smclas]))
f4ffd778 3597 {
dc810e39 3598 return_value = bfd_make_section_anyway
f4ffd778
NC
3599 (abfd, names[aux->x_csect.x_smclas]);
3600 }
3601 else
3602 {
4eca0228 3603 _bfd_error_handler
695344c0 3604 /* xgettext: c-format */
871b3ab2 3605 (_("%pB: symbol `%s' has unrecognized smclas %d"),
d003868e 3606 abfd, symbol_name, aux->x_csect.x_smclas);
f4ffd778
NC
3607 bfd_set_error (bfd_error_bad_value);
3608 }
beb1bf64
TR
3609
3610 return return_value;
3611}
3612
b34976b6 3613static bfd_boolean
417236c0 3614xcoff_is_lineno_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma value)
beb1bf64 3615{
f4ffd778 3616 if (0xffff <= value)
b34976b6 3617 return TRUE;
f4ffd778 3618
b34976b6 3619 return FALSE;
beb1bf64
TR
3620}
3621
b34976b6 3622static bfd_boolean
417236c0 3623xcoff_is_reloc_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma value)
beb1bf64 3624{
f4ffd778 3625 if (0xffff <= value)
b34976b6 3626 return TRUE;
f4ffd778 3627
b34976b6 3628 return FALSE;
beb1bf64
TR
3629}
3630
a7b97311 3631static bfd_vma
417236c0 3632xcoff_loader_symbol_offset (bfd *abfd,
07d6d2b8 3633 struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED)
beb1bf64 3634{
cf9ab45b 3635 return bfd_xcoff_ldhdrsz (abfd);
beb1bf64
TR
3636}
3637
a7b97311 3638static bfd_vma
417236c0 3639xcoff_loader_reloc_offset (bfd *abfd, struct internal_ldhdr *ldhdr)
beb1bf64 3640{
cf9ab45b 3641 return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
beb1bf64
TR
3642}
3643
b34976b6 3644static bfd_boolean
417236c0 3645xcoff_generate_rtinit (bfd *abfd, const char *init, const char *fini,
07d6d2b8 3646 bfd_boolean rtld)
9a4c7f16
TR
3647{
3648 bfd_byte filehdr_ext[FILHSZ];
3649 bfd_byte scnhdr_ext[SCNHSZ];
69f284c7
TR
3650 bfd_byte syment_ext[SYMESZ * 10];
3651 bfd_byte reloc_ext[RELSZ * 3];
9a4c7f16
TR
3652 bfd_byte *data_buffer;
3653 bfd_size_type data_buffer_size;
d426c6b0 3654 bfd_byte *string_table = NULL, *st_tmp = NULL;
9a4c7f16
TR
3655 bfd_size_type string_table_size;
3656 bfd_vma val;
3657 size_t initsz, finisz;
3658 struct internal_filehdr filehdr;
3659 struct internal_scnhdr scnhdr;
3660 struct internal_syment syment;
3661 union internal_auxent auxent;
3662 struct internal_reloc reloc;
cf9ab45b 3663
9a4c7f16
TR
3664 char *data_name = ".data";
3665 char *rtinit_name = "__rtinit";
69f284c7 3666 char *rtld_name = "__rtld";
cf9ab45b 3667
69f284c7 3668 if (! bfd_xcoff_rtinit_size (abfd))
b34976b6 3669 return FALSE;
9a4c7f16
TR
3670
3671 initsz = (init == NULL ? 0 : 1 + strlen (init));
3672 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
3673
3674 /* file header */
3675 memset (filehdr_ext, 0, FILHSZ);
3676 memset (&filehdr, 0, sizeof (struct internal_filehdr));
3677 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
cf9ab45b 3678 filehdr.f_nscns = 1;
9a4c7f16 3679 filehdr.f_timdat = 0;
69f284c7 3680 filehdr.f_nsyms = 0; /* at least 6, no more than 10 */
9a4c7f16
TR
3681 filehdr.f_symptr = 0; /* set below */
3682 filehdr.f_opthdr = 0;
3683 filehdr.f_flags = 0;
3684
3685 /* section header */
3686 memset (scnhdr_ext, 0, SCNHSZ);
3687 memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
3688 memcpy (scnhdr.s_name, data_name, strlen (data_name));
3689 scnhdr.s_paddr = 0;
3690 scnhdr.s_vaddr = 0;
3691 scnhdr.s_size = 0; /* set below */
3692 scnhdr.s_scnptr = FILHSZ + SCNHSZ;
3693 scnhdr.s_relptr = 0; /* set below */
3694 scnhdr.s_lnnoptr = 0;
3695 scnhdr.s_nreloc = 0; /* either 1 or 2 */
3696 scnhdr.s_nlnno = 0;
3697 scnhdr.s_flags = STYP_DATA;
3698
cf9ab45b
AM
3699 /* .data
3700 0x0000 0x00000000 : rtl
3701 0x0004 0x00000010 : offset to init, or 0
3702 0x0008 0x00000028 : offset to fini, or 0
3703 0x000C 0x0000000C : size of descriptor
3704 0x0010 0x00000000 : init, needs a reloc
3705 0x0014 0x00000040 : offset to init name
3706 0x0018 0x00000000 : flags, padded to a word
3707 0x001C 0x00000000 : empty init
3708 0x0020 0x00000000 :
3709 0x0024 0x00000000 :
3710 0x0028 0x00000000 : fini, needs a reloc
3711 0x002C 0x00000??? : offset to fini name
3712 0x0030 0x00000000 : flags, padded to a word
3713 0x0034 0x00000000 : empty fini
3714 0x0038 0x00000000 :
3715 0x003C 0x00000000 :
3716 0x0040 init name
9a4c7f16
TR
3717 0x0040 + initsz fini name */
3718
3719 data_buffer_size = 0x0040 + initsz + finisz;
2a52da53 3720 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
330693f5 3721 data_buffer = NULL;
9bab7074 3722 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
330693f5 3723 if (data_buffer == NULL)
b34976b6 3724 return FALSE;
9a4c7f16 3725
cf9ab45b 3726 if (initsz)
9a4c7f16
TR
3727 {
3728 val = 0x10;
3729 bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
3730 val = 0x40;
3731 bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
3732 memcpy (&data_buffer[val], init, initsz);
3733 }
3734
cf9ab45b 3735 if (finisz)
9a4c7f16
TR
3736 {
3737 val = 0x28;
3738 bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
3739 val = 0x40 + initsz;
3740 bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
3741 memcpy (&data_buffer[val], fini, finisz);
3742 }
3743
3744 val = 0x0C;
3745 bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
3746
3747 scnhdr.s_size = data_buffer_size;
3748
3749 /* string table */
3750 string_table_size = 0;
cf9ab45b 3751 if (initsz > 9)
9a4c7f16
TR
3752 string_table_size += initsz;
3753 if (finisz > 9)
3754 string_table_size += finisz;
3755 if (string_table_size)
3756 {
3757 string_table_size += 4;
9bab7074 3758 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
021d6096 3759 if (string_table == NULL)
b34976b6 3760 return FALSE;
9bab7074 3761
9a4c7f16
TR
3762 val = string_table_size;
3763 bfd_h_put_32 (abfd, val, &string_table[0]);
3764 st_tmp = string_table + 4;
3765 }
cf9ab45b
AM
3766
3767 /* symbols
9a4c7f16
TR
3768 0. .data csect
3769 2. __rtinit
cf9ab45b
AM
3770 4. init function
3771 6. fini function
69f284c7
TR
3772 8. __rtld */
3773 memset (syment_ext, 0, 10 * SYMESZ);
3774 memset (reloc_ext, 0, 3 * RELSZ);
9a4c7f16
TR
3775
3776 /* .data csect */
3777 memset (&syment, 0, sizeof (struct internal_syment));
3778 memset (&auxent, 0, sizeof (union internal_auxent));
3779 memcpy (syment._n._n_name, data_name, strlen (data_name));
3780 syment.n_scnum = 1;
3781 syment.n_sclass = C_HIDEXT;
3782 syment.n_numaux = 1;
3783 auxent.x_csect.x_scnlen.l = data_buffer_size;
3784 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
3785 auxent.x_csect.x_smclas = XMC_RW;
cf9ab45b 3786 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 3787 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
3788 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3789 syment.n_numaux,
9a4c7f16
TR
3790 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3791 filehdr.f_nsyms += 2;
3792
3793 /* __rtinit */
3794 memset (&syment, 0, sizeof (struct internal_syment));
3795 memset (&auxent, 0, sizeof (union internal_auxent));
3796 memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
3797 syment.n_scnum = 1;
3798 syment.n_sclass = C_EXT;
3799 syment.n_numaux = 1;
3800 auxent.x_csect.x_smtyp = XTY_LD;
3801 auxent.x_csect.x_smclas = XMC_RW;
cf9ab45b 3802 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 3803 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
3804 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3805 syment.n_numaux,
9a4c7f16
TR
3806 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3807 filehdr.f_nsyms += 2;
3808
3809 /* init */
cf9ab45b 3810 if (initsz)
9a4c7f16
TR
3811 {
3812 memset (&syment, 0, sizeof (struct internal_syment));
3813 memset (&auxent, 0, sizeof (union internal_auxent));
3814
cf9ab45b 3815 if (initsz > 9)
9a4c7f16
TR
3816 {
3817 syment._n._n_n._n_offset = st_tmp - string_table;
3818 memcpy (st_tmp, init, initsz);
3819 st_tmp += initsz;
3820 }
3821 else
3822 memcpy (syment._n._n_name, init, initsz - 1);
3823
3824 syment.n_sclass = C_EXT;
3825 syment.n_numaux = 1;
cf9ab45b 3826 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 3827 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
3828 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3829 syment.n_numaux,
9a4c7f16
TR
3830 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3831
3832 /* reloc */
3833 memset (&reloc, 0, sizeof (struct internal_reloc));
3834 reloc.r_vaddr = 0x0010;
3835 reloc.r_symndx = filehdr.f_nsyms;
3836 reloc.r_type = R_POS;
3837 reloc.r_size = 31;
3838 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
3839
3840 filehdr.f_nsyms += 2;
3841 scnhdr.s_nreloc += 1;
3842 }
cf9ab45b 3843
9a4c7f16 3844 /* fini */
cf9ab45b 3845 if (finisz)
9a4c7f16
TR
3846 {
3847 memset (&syment, 0, sizeof (struct internal_syment));
3848 memset (&auxent, 0, sizeof (union internal_auxent));
3849
cf9ab45b 3850 if (finisz > 9)
9a4c7f16
TR
3851 {
3852 syment._n._n_n._n_offset = st_tmp - string_table;
3853 memcpy (st_tmp, fini, finisz);
3854 st_tmp += finisz;
3855 }
3856 else
3857 memcpy (syment._n._n_name, fini, finisz - 1);
3858
3859 syment.n_sclass = C_EXT;
3860 syment.n_numaux = 1;
cf9ab45b 3861 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 3862 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
3863 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3864 syment.n_numaux,
9a4c7f16
TR
3865 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3866
3867 /* reloc */
3868 memset (&reloc, 0, sizeof (struct internal_reloc));
3869 reloc.r_vaddr = 0x0028;
3870 reloc.r_symndx = filehdr.f_nsyms;
3871 reloc.r_type = R_POS;
3872 reloc.r_size = 31;
cf9ab45b 3873 bfd_coff_swap_reloc_out (abfd, &reloc,
9a4c7f16
TR
3874 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3875
3876 filehdr.f_nsyms += 2;
3877 scnhdr.s_nreloc += 1;
3878 }
3879
69f284c7
TR
3880 if (rtld)
3881 {
3882 memset (&syment, 0, sizeof (struct internal_syment));
3883 memset (&auxent, 0, sizeof (union internal_auxent));
3884 memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
3885 syment.n_sclass = C_EXT;
3886 syment.n_numaux = 1;
cf9ab45b 3887 bfd_coff_swap_sym_out (abfd, &syment,
69f284c7 3888 &syment_ext[filehdr.f_nsyms * SYMESZ]);
cf9ab45b
AM
3889 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
3890 syment.n_numaux,
69f284c7
TR
3891 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
3892
3893 /* reloc */
3894 memset (&reloc, 0, sizeof (struct internal_reloc));
3895 reloc.r_vaddr = 0x0000;
3896 reloc.r_symndx = filehdr.f_nsyms;
3897 reloc.r_type = R_POS;
3898 reloc.r_size = 31;
cf9ab45b 3899 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7
TR
3900 &reloc_ext[scnhdr.s_nreloc * RELSZ]);
3901
3902 filehdr.f_nsyms += 2;
3903 scnhdr.s_nreloc += 1;
3904 }
3905
9a4c7f16
TR
3906 scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
3907 filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
3908
3909 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
3910 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
3911 bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
3912 bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
3913 bfd_bwrite (data_buffer, data_buffer_size, abfd);
3914 bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
3915 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
3916 bfd_bwrite (string_table, string_table_size, abfd);
3917
330693f5
TR
3918 free (data_buffer);
3919 data_buffer = NULL;
3920
b34976b6 3921 return TRUE;
9a4c7f16
TR
3922}
3923
beb1bf64
TR
3924
3925static reloc_howto_type xcoff_dynamic_reloc =
cf9ab45b
AM
3926HOWTO (0, /* type */
3927 0, /* rightshift */
3928 2, /* size (0 = byte, 1 = short, 2 = long) */
3929 32, /* bitsize */
b34976b6 3930 FALSE, /* pc_relative */
cf9ab45b 3931 0, /* bitpos */
beb1bf64 3932 complain_overflow_bitfield, /* complain_on_overflow */
cf9ab45b
AM
3933 0, /* special_function */
3934 "R_POS", /* name */
b34976b6 3935 TRUE, /* partial_inplace */
cf9ab45b
AM
3936 0xffffffff, /* src_mask */
3937 0xffffffff, /* dst_mask */
b34976b6 3938 FALSE); /* pcrel_offset */
beb1bf64 3939
dc810e39
AM
3940/* glink
3941
3942 The first word of global linkage code must be modified by filling in
f4ffd778
NC
3943 the correct TOC offset. */
3944
beb1bf64 3945static unsigned long xcoff_glink_code[9] =
f4ffd778
NC
3946 {
3947 0x81820000, /* lwz r12,0(r2) */
3948 0x90410014, /* stw r2,20(r1) */
3949 0x800c0000, /* lwz r0,0(r12) */
3950 0x804c0004, /* lwz r2,4(r12) */
3951 0x7c0903a6, /* mtctr r0 */
3952 0x4e800420, /* bctr */
3953 0x00000000, /* start of traceback table */
3954 0x000c8000, /* traceback table */
3955 0x00000000, /* traceback table */
3956 };
beb1bf64 3957
85645aed
TG
3958/* Table to convert DWARF flags to section names. */
3959
3960const struct xcoff_dwsect_name xcoff_dwsect_names[] = {
3961 { SSUBTYP_DWINFO, ".dwinfo", TRUE },
3962 { SSUBTYP_DWLINE, ".dwline", TRUE },
3963 { SSUBTYP_DWPBNMS, ".dwpbnms", TRUE },
3964 { SSUBTYP_DWPBTYP, ".dwpbtyp", TRUE },
3965 { SSUBTYP_DWARNGE, ".dwarnge", TRUE },
3966 { SSUBTYP_DWABREV, ".dwabrev", FALSE },
3967 { SSUBTYP_DWSTR, ".dwstr", TRUE },
3968 { SSUBTYP_DWRNGES, ".dwrnges", TRUE }
3969};
beb1bf64 3970
09bf66a8
TG
3971/* For generic entry points. */
3972#define _bfd_xcoff_close_and_cleanup _bfd_archive_close_and_cleanup
d00dd7dc 3973#define _bfd_xcoff_bfd_free_cached_info _bfd_bool_bfd_true
09bf66a8
TG
3974#define _bfd_xcoff_new_section_hook coff_new_section_hook
3975#define _bfd_xcoff_get_section_contents _bfd_generic_get_section_contents
3976#define _bfd_xcoff_get_section_contents_in_window \
3977 _bfd_generic_get_section_contents_in_window
3978
3979/* For copy private data entry points. */
3980#define _bfd_xcoff_bfd_copy_private_bfd_data \
3981 _bfd_xcoff_copy_private_bfd_data
3982#define _bfd_xcoff_bfd_merge_private_bfd_data \
3983 _bfd_generic_bfd_merge_private_bfd_data
3984#define _bfd_xcoff_bfd_copy_private_section_data \
3985 _bfd_generic_bfd_copy_private_section_data
3986#define _bfd_xcoff_bfd_copy_private_symbol_data \
3987 _bfd_generic_bfd_copy_private_symbol_data
3988#define _bfd_xcoff_bfd_copy_private_header_data \
3989 _bfd_generic_bfd_copy_private_header_data
3990#define _bfd_xcoff_bfd_set_private_flags \
3991 _bfd_generic_bfd_set_private_flags
3992#define _bfd_xcoff_bfd_print_private_bfd_data \
3993 _bfd_generic_bfd_print_private_bfd_data
3994
3995/* For archive entry points. */
3996#define _bfd_xcoff_slurp_extended_name_table \
3997 _bfd_noarchive_slurp_extended_name_table
3998#define _bfd_xcoff_construct_extended_name_table \
3999 _bfd_noarchive_construct_extended_name_table
4000#define _bfd_xcoff_truncate_arname bfd_dont_truncate_arname
4001#define _bfd_xcoff_write_ar_hdr _bfd_generic_write_ar_hdr
4002#define _bfd_xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
4003#define _bfd_xcoff_generic_stat_arch_elt _bfd_xcoff_stat_arch_elt
d00dd7dc 4004#define _bfd_xcoff_update_armap_timestamp _bfd_bool_bfd_true
09bf66a8
TG
4005
4006/* For symbols entry points. */
4007#define _bfd_xcoff_get_symtab_upper_bound coff_get_symtab_upper_bound
4008#define _bfd_xcoff_canonicalize_symtab coff_canonicalize_symtab
4009#define _bfd_xcoff_make_empty_symbol coff_make_empty_symbol
4010#define _bfd_xcoff_print_symbol coff_print_symbol
4011#define _bfd_xcoff_get_symbol_info coff_get_symbol_info
60bb06bc
L
4012#define _bfd_xcoff_get_symbol_version_string \
4013 _bfd_nosymbols_get_symbol_version_string
09bf66a8
TG
4014#define _bfd_xcoff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
4015#define _bfd_xcoff_bfd_is_target_special_symbol \
4016 coff_bfd_is_target_special_symbol
4017#define _bfd_xcoff_get_lineno coff_get_lineno
fb167eb2 4018#define _bfd_xcoff_find_nearest_line coff_find_nearest_line
9c461f7d 4019#define _bfd_xcoff_find_line coff_find_line
09bf66a8
TG
4020#define _bfd_xcoff_find_inliner_info coff_find_inliner_info
4021#define _bfd_xcoff_bfd_make_debug_symbol coff_bfd_make_debug_symbol
4022#define _bfd_xcoff_read_minisymbols _bfd_generic_read_minisymbols
4023#define _bfd_xcoff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
4024
4025/* For reloc entry points. */
4026#define _bfd_xcoff_get_reloc_upper_bound coff_get_reloc_upper_bound
4027#define _bfd_xcoff_canonicalize_reloc coff_canonicalize_reloc
23186865 4028#define _bfd_xcoff_set_reloc _bfd_generic_set_reloc
09bf66a8
TG
4029#define _bfd_xcoff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
4030#define _bfd_xcoff_bfd_reloc_name_lookup _bfd_xcoff_reloc_name_lookup
4031
4032/* For link entry points. */
4033#define _bfd_xcoff_bfd_get_relocated_section_contents \
4034 bfd_generic_get_relocated_section_contents
4035#define _bfd_xcoff_bfd_relax_section bfd_generic_relax_section
4036#define _bfd_xcoff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
4037#define _bfd_xcoff_bfd_link_just_syms _bfd_generic_link_just_syms
4038#define _bfd_xcoff_bfd_copy_link_hash_symbol_type \
4039 _bfd_generic_copy_link_hash_symbol_type
4040#define _bfd_xcoff_bfd_link_split_section _bfd_generic_link_split_section
4041#define _bfd_xcoff_bfd_gc_sections bfd_generic_gc_sections
4042#define _bfd_xcoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
4043#define _bfd_xcoff_bfd_merge_sections bfd_generic_merge_sections
4044#define _bfd_xcoff_bfd_is_group_section bfd_generic_is_group_section
4045#define _bfd_xcoff_bfd_discard_group bfd_generic_discard_group
4046#define _bfd_xcoff_section_already_linked _bfd_generic_section_already_linked
4047#define _bfd_xcoff_bfd_define_common_symbol _bfd_xcoff_define_common_symbol
7dba9362 4048#define _bfd_xcoff_bfd_define_start_stop bfd_generic_define_start_stop
4f3b23b3 4049#define _bfd_xcoff_bfd_link_check_relocs _bfd_generic_link_check_relocs
09bf66a8
TG
4050
4051/* For dynamic symbols and relocs entry points. */
4052#define _bfd_xcoff_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
4053
dc810e39 4054static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
f4ffd778
NC
4055 {
4056 { /* COFF backend, defined in libcoff.h. */
cf9ab45b
AM
4057 _bfd_xcoff_swap_aux_in,
4058 _bfd_xcoff_swap_sym_in,
4059 coff_swap_lineno_in,
4060 _bfd_xcoff_swap_aux_out,
4061 _bfd_xcoff_swap_sym_out,
4062 coff_swap_lineno_out,
4063 xcoff_swap_reloc_out,
4064 coff_swap_filehdr_out,
4065 coff_swap_aouthdr_out,
4066 coff_swap_scnhdr_out,
4067 FILHSZ,
4068 AOUTSZ,
4069 SCNHSZ,
4070 SYMESZ,
4071 AUXESZ,
4072 RELSZ,
4073 LINESZ,
4074 FILNMLEN,
b34976b6 4075 TRUE, /* _bfd_coff_long_filenames */
88183869 4076 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 4077 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 4078 FALSE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b 4079 2, /* _bfd_coff_debug_string_prefix_length */
167ad85b 4080 32768, /* _bfd_coff_max_nscns */
cf9ab45b
AM
4081 coff_swap_filehdr_in,
4082 coff_swap_aouthdr_in,
4083 coff_swap_scnhdr_in,
4084 xcoff_swap_reloc_in,
4085 coff_bad_format_hook,
4086 coff_set_arch_mach_hook,
4087 coff_mkobject_hook,
4088 styp_to_sec_flags,
4089 coff_set_alignment_hook,
4090 coff_slurp_symbol_table,
4091 symname_in_debug_hook,
4092 coff_pointerize_aux_hook,
4093 coff_print_aux,
4094 dummy_reloc16_extra_cases,
4095 dummy_reloc16_estimate,
4096 NULL, /* bfd_coff_sym_is_global */
4097 coff_compute_section_file_positions,
4098 NULL, /* _bfd_coff_start_final_link */
4099 xcoff_ppc_relocate_section,
4100 coff_rtype_to_howto,
4101 NULL, /* _bfd_coff_adjust_symndx */
4102 _bfd_generic_link_add_one_symbol,
4103 coff_link_output_has_begun,
2b5c217d
NC
4104 coff_final_link_postscript,
4105 NULL /* print_pdata. */
f4ffd778
NC
4106 },
4107
cf9ab45b
AM
4108 0x01DF, /* magic number */
4109 bfd_arch_rs6000,
4110 bfd_mach_rs6k,
dc810e39 4111
f4ffd778 4112 /* Function pointers to xcoff specific swap routines. */
cf9ab45b
AM
4113 xcoff_swap_ldhdr_in,
4114 xcoff_swap_ldhdr_out,
4115 xcoff_swap_ldsym_in,
4116 xcoff_swap_ldsym_out,
4117 xcoff_swap_ldrel_in,
4118 xcoff_swap_ldrel_out,
f4ffd778
NC
4119
4120 /* Sizes. */
cf9ab45b
AM
4121 LDHDRSZ,
4122 LDSYMSZ,
4123 LDRELSZ,
4124 12, /* _xcoff_function_descriptor_size */
4125 SMALL_AOUTSZ,
f4ffd778 4126
cf9ab45b
AM
4127 /* Versions. */
4128 1, /* _xcoff_ldhdr_version */
f4ffd778 4129
cf9ab45b
AM
4130 _bfd_xcoff_put_symbol_name,
4131 _bfd_xcoff_put_ldsymbol_name,
4132 &xcoff_dynamic_reloc,
4133 xcoff_create_csect_from_smclas,
f4ffd778
NC
4134
4135 /* Lineno and reloc count overflow. */
4136 xcoff_is_lineno_count_overflow,
4137 xcoff_is_reloc_count_overflow,
4138
4139 xcoff_loader_symbol_offset,
4140 xcoff_loader_reloc_offset,
4141
4142 /* glink. */
cf9ab45b
AM
4143 &xcoff_glink_code[0],
4144 36, /* _xcoff_glink_size */
9a4c7f16
TR
4145
4146 /* rtinit */
cf9ab45b
AM
4147 64, /* _xcoff_rtinit_size */
4148 xcoff_generate_rtinit,
4149 };
beb1bf64 4150
eb1e0e80 4151/* The transfer vector that leads the outside world to all of the above. */
6d00b590 4152const bfd_target rs6000_xcoff_vec =
cf9ab45b
AM
4153 {
4154 "aixcoff-rs6000",
4155 bfd_target_xcoff_flavour,
4156 BFD_ENDIAN_BIG, /* data byte order is big */
4157 BFD_ENDIAN_BIG, /* header byte order is big */
4158
4159 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4160 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4161
a7c71b0c 4162 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
4163 0, /* leading char */
4164 '/', /* ar_pad_char */
4165 15, /* ar_max_namelen */
0aabe54e 4166 0, /* match priority. */
cf9ab45b
AM
4167
4168 /* data */
4169 bfd_getb64,
4170 bfd_getb_signed_64,
4171 bfd_putb64,
4172 bfd_getb32,
4173 bfd_getb_signed_32,
4174 bfd_putb32,
4175 bfd_getb16,
4176 bfd_getb_signed_16,
4177 bfd_putb16,
4178
4179 /* hdrs */
4180 bfd_getb64,
4181 bfd_getb_signed_64,
4182 bfd_putb64,
4183 bfd_getb32,
4184 bfd_getb_signed_32,
4185 bfd_putb32,
4186 bfd_getb16,
4187 bfd_getb_signed_16,
4188 bfd_putb16,
4189
4190 { /* bfd_check_format */
4191 _bfd_dummy_target,
4192 coff_object_p,
4193 _bfd_xcoff_archive_p,
4194 CORE_FILE_P
4195 },
dc810e39 4196
cf9ab45b 4197 { /* bfd_set_format */
d00dd7dc 4198 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4199 coff_mkobject,
4200 _bfd_generic_mkarchive,
d00dd7dc 4201 _bfd_bool_bfd_false_error
cf9ab45b
AM
4202 },
4203
4204 {/* bfd_write_contents */
d00dd7dc 4205 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4206 coff_write_object_contents,
4207 _bfd_xcoff_write_archive_contents,
d00dd7dc 4208 _bfd_bool_bfd_false_error
cf9ab45b
AM
4209 },
4210
09bf66a8
TG
4211 BFD_JUMP_TABLE_GENERIC (_bfd_xcoff),
4212 BFD_JUMP_TABLE_COPY (_bfd_xcoff),
261b8d08 4213 BFD_JUMP_TABLE_CORE (coff),
09bf66a8
TG
4214 BFD_JUMP_TABLE_ARCHIVE (_bfd_xcoff),
4215 BFD_JUMP_TABLE_SYMBOLS (_bfd_xcoff),
4216 BFD_JUMP_TABLE_RELOCS (_bfd_xcoff),
4217 BFD_JUMP_TABLE_WRITE (coff),
4218 BFD_JUMP_TABLE_LINK (_bfd_xcoff),
4219 BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
cf9ab45b
AM
4220
4221 /* Opposite endian version, none exists */
4222 NULL,
4223
2c3fc389 4224 & bfd_xcoff_backend_data,
cf9ab45b 4225 };
beb1bf64 4226
cf9ab45b
AM
4227/* xcoff-powermac target
4228 Old target.
4229 Only difference between this target and the rs6000 target is the
4230 the default architecture and machine type used in coffcode.h
4231
4232 PowerPC Macs use the same magic numbers as RS/6000
4233 (because that's how they were bootstrapped originally),
4234 but they are always PowerPC architecture. */
dc810e39 4235static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
cf9ab45b
AM
4236 {
4237 { /* COFF backend, defined in libcoff.h. */
4238 _bfd_xcoff_swap_aux_in,
4239 _bfd_xcoff_swap_sym_in,
4240 coff_swap_lineno_in,
4241 _bfd_xcoff_swap_aux_out,
4242 _bfd_xcoff_swap_sym_out,
4243 coff_swap_lineno_out,
4244 xcoff_swap_reloc_out,
4245 coff_swap_filehdr_out,
4246 coff_swap_aouthdr_out,
4247 coff_swap_scnhdr_out,
4248 FILHSZ,
4249 AOUTSZ,
4250 SCNHSZ,
4251 SYMESZ,
4252 AUXESZ,
4253 RELSZ,
4254 LINESZ,
4255 FILNMLEN,
b34976b6 4256 TRUE, /* _bfd_coff_long_filenames */
88183869 4257 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 4258 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 4259 FALSE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b 4260 2, /* _bfd_coff_debug_string_prefix_length */
167ad85b 4261 32768, /* _bfd_coff_max_nscns */
cf9ab45b
AM
4262 coff_swap_filehdr_in,
4263 coff_swap_aouthdr_in,
4264 coff_swap_scnhdr_in,
4265 xcoff_swap_reloc_in,
4266 coff_bad_format_hook,
4267 coff_set_arch_mach_hook,
4268 coff_mkobject_hook,
4269 styp_to_sec_flags,
4270 coff_set_alignment_hook,
4271 coff_slurp_symbol_table,
4272 symname_in_debug_hook,
4273 coff_pointerize_aux_hook,
4274 coff_print_aux,
4275 dummy_reloc16_extra_cases,
4276 dummy_reloc16_estimate,
4277 NULL, /* bfd_coff_sym_is_global */
4278 coff_compute_section_file_positions,
4279 NULL, /* _bfd_coff_start_final_link */
4280 xcoff_ppc_relocate_section,
4281 coff_rtype_to_howto,
4282 NULL, /* _bfd_coff_adjust_symndx */
4283 _bfd_generic_link_add_one_symbol,
4284 coff_link_output_has_begun,
2b5c217d
NC
4285 coff_final_link_postscript,
4286 NULL /* print_pdata. */
cf9ab45b
AM
4287 },
4288
4289 0x01DF, /* magic number */
4290 bfd_arch_powerpc,
4291 bfd_mach_ppc,
4292
4293 /* Function pointers to xcoff specific swap routines. */
4294 xcoff_swap_ldhdr_in,
4295 xcoff_swap_ldhdr_out,
4296 xcoff_swap_ldsym_in,
4297 xcoff_swap_ldsym_out,
4298 xcoff_swap_ldrel_in,
4299 xcoff_swap_ldrel_out,
4300
4301 /* Sizes. */
4302 LDHDRSZ,
4303 LDSYMSZ,
4304 LDRELSZ,
4305 12, /* _xcoff_function_descriptor_size */
4306 SMALL_AOUTSZ,
4307
4308 /* Versions. */
4309 1, /* _xcoff_ldhdr_version */
4310
4311 _bfd_xcoff_put_symbol_name,
4312 _bfd_xcoff_put_ldsymbol_name,
4313 &xcoff_dynamic_reloc,
4314 xcoff_create_csect_from_smclas,
4315
4316 /* Lineno and reloc count overflow. */
4317 xcoff_is_lineno_count_overflow,
4318 xcoff_is_reloc_count_overflow,
4319
4320 xcoff_loader_symbol_offset,
4321 xcoff_loader_reloc_offset,
beb1bf64 4322
cf9ab45b
AM
4323 /* glink. */
4324 &xcoff_glink_code[0],
4325 36, /* _xcoff_glink_size */
4326
4327 /* rtinit */
4328 0, /* _xcoff_rtinit_size */
4329 xcoff_generate_rtinit,
4330 };
4331
4332/* The transfer vector that leads the outside world to all of the above. */
6d00b590 4333const bfd_target powerpc_xcoff_vec =
cf9ab45b
AM
4334 {
4335 "xcoff-powermac",
4336 bfd_target_xcoff_flavour,
4337 BFD_ENDIAN_BIG, /* data byte order is big */
4338 BFD_ENDIAN_BIG, /* header byte order is big */
4339
4340 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
4341 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
4342
a7c71b0c 4343 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
4344 0, /* leading char */
4345 '/', /* ar_pad_char */
4346 15, /* ar_max_namelen */
0aabe54e 4347 0, /* match priority. */
cf9ab45b
AM
4348
4349 /* data */
4350 bfd_getb64,
4351 bfd_getb_signed_64,
4352 bfd_putb64,
4353 bfd_getb32,
4354 bfd_getb_signed_32,
4355 bfd_putb32,
4356 bfd_getb16,
4357 bfd_getb_signed_16,
4358 bfd_putb16,
4359
4360 /* hdrs */
4361 bfd_getb64,
4362 bfd_getb_signed_64,
4363 bfd_putb64,
4364 bfd_getb32,
4365 bfd_getb_signed_32,
4366 bfd_putb32,
4367 bfd_getb16,
4368 bfd_getb_signed_16,
4369 bfd_putb16,
4370
4371 { /* bfd_check_format */
4372 _bfd_dummy_target,
4373 coff_object_p,
4374 _bfd_xcoff_archive_p,
4375 CORE_FILE_P
4376 },
4377
4378 { /* bfd_set_format */
d00dd7dc 4379 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4380 coff_mkobject,
4381 _bfd_generic_mkarchive,
d00dd7dc 4382 _bfd_bool_bfd_false_error
cf9ab45b
AM
4383 },
4384
4385 {/* bfd_write_contents */
d00dd7dc 4386 _bfd_bool_bfd_false_error,
cf9ab45b
AM
4387 coff_write_object_contents,
4388 _bfd_xcoff_write_archive_contents,
d00dd7dc 4389 _bfd_bool_bfd_false_error
cf9ab45b 4390 },
dc810e39 4391
09bf66a8
TG
4392 BFD_JUMP_TABLE_GENERIC (_bfd_xcoff),
4393 BFD_JUMP_TABLE_COPY (_bfd_xcoff),
261b8d08 4394 BFD_JUMP_TABLE_CORE (coff),
09bf66a8
TG
4395 BFD_JUMP_TABLE_ARCHIVE (_bfd_xcoff),
4396 BFD_JUMP_TABLE_SYMBOLS (_bfd_xcoff),
4397 BFD_JUMP_TABLE_RELOCS (_bfd_xcoff),
4398 BFD_JUMP_TABLE_WRITE (coff),
4399 BFD_JUMP_TABLE_LINK (_bfd_xcoff),
4400 BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
cf9ab45b
AM
4401
4402 /* Opposite endian version, none exists */
4403 NULL,
4404
2c3fc389 4405 & bfd_pmac_xcoff_backend_data,
cf9ab45b 4406 };
This page took 1.403369 seconds and 4 git commands to generate.