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