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