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