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