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