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