* binutils-all/objdump.exp: Add m16c and m32c to the list of
[deliverable/binutils-gdb.git] / bfd / coff64-rs6000.c
CommitLineData
7f6d05e8 1/* BFD back-end for IBM RS/6000 "XCOFF64" files.
88183869 2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
7f6d05e8
CP
3 Free Software Foundation, Inc.
4 Written Clinton Popetz.
5 Contributed by Cygnus Support.
6
eb1e0e80 7 This file is part of BFD, the Binary File Descriptor library.
7f6d05e8 8
eb1e0e80
NC
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
cd123cb7 11 the Free Software Foundation; either version 3 of the License, or
eb1e0e80 12 (at your option) any later version.
7f6d05e8 13
eb1e0e80
NC
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
7f6d05e8 18
eb1e0e80
NC
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
cd123cb7
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
7f6d05e8 23
7f6d05e8 24#include "sysdep.h"
3db64b00 25#include "bfd.h"
beb1bf64 26#include "bfdlink.h"
7f6d05e8
CP
27#include "libbfd.h"
28#include "coff/internal.h"
beb1bf64 29#include "coff/xcoff.h"
7f6d05e8 30#include "coff/rs6k64.h"
dc810e39 31#include "libcoff.h"
beb1bf64 32#include "libxcoff.h"
7f6d05e8 33
dc810e39
AM
34#define GET_FILEHDR_SYMPTR H_GET_64
35#define PUT_FILEHDR_SYMPTR H_PUT_64
36#define GET_AOUTHDR_DATA_START H_GET_64
37#define PUT_AOUTHDR_DATA_START H_PUT_64
38#define GET_AOUTHDR_TEXT_START H_GET_64
39#define PUT_AOUTHDR_TEXT_START H_PUT_64
40#define GET_AOUTHDR_TSIZE H_GET_64
41#define PUT_AOUTHDR_TSIZE H_PUT_64
42#define GET_AOUTHDR_DSIZE H_GET_64
43#define PUT_AOUTHDR_DSIZE H_PUT_64
44#define GET_AOUTHDR_BSIZE H_GET_64
45#define PUT_AOUTHDR_BSIZE H_PUT_64
46#define GET_AOUTHDR_ENTRY H_GET_64
47#define PUT_AOUTHDR_ENTRY H_PUT_64
48#define GET_SCNHDR_PADDR H_GET_64
49#define PUT_SCNHDR_PADDR H_PUT_64
50#define GET_SCNHDR_VADDR H_GET_64
51#define PUT_SCNHDR_VADDR H_PUT_64
52#define GET_SCNHDR_SIZE H_GET_64
53#define PUT_SCNHDR_SIZE H_PUT_64
54#define GET_SCNHDR_SCNPTR H_GET_64
55#define PUT_SCNHDR_SCNPTR H_PUT_64
56#define GET_SCNHDR_RELPTR H_GET_64
57#define PUT_SCNHDR_RELPTR H_PUT_64
58#define GET_SCNHDR_LNNOPTR H_GET_64
59#define PUT_SCNHDR_LNNOPTR H_PUT_64
60#define GET_SCNHDR_NRELOC H_GET_32
7f6d05e8 61#define MAX_SCNHDR_NRELOC 0xffffffff
dc810e39
AM
62#define PUT_SCNHDR_NRELOC H_PUT_32
63#define GET_SCNHDR_NLNNO H_GET_32
7f6d05e8 64#define MAX_SCNHDR_NLNNO 0xffffffff
dc810e39
AM
65#define PUT_SCNHDR_NLNNO H_PUT_32
66#define GET_RELOC_VADDR H_GET_64
67#define PUT_RELOC_VADDR H_PUT_64
7f6d05e8
CP
68
69#define COFF_FORCE_SYMBOLS_IN_STRINGS
70#define COFF_DEBUG_STRING_WIDE_PREFIX
71
beb1bf64 72
dc810e39
AM
73#define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
74 do \
75 { \
76 memset (((SCNHDR *) EXT)->s_pad, 0, \
77 sizeof (((SCNHDR *) EXT)->s_pad)); \
78 } \
79 while (0)
7f6d05e8
CP
80
81#define NO_COFF_LINENOS
82
beb1bf64
TR
83#define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
84#define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
7f6d05e8 85
b34976b6
AM
86static void _bfd_xcoff64_swap_lineno_in
87 PARAMS ((bfd *, PTR, PTR));
88static unsigned int _bfd_xcoff64_swap_lineno_out
89 PARAMS ((bfd *, PTR, PTR));
90static bfd_boolean _bfd_xcoff64_put_symbol_name
54327882
AM
91 PARAMS ((bfd *, struct bfd_strtab_hash *, struct internal_syment *,
92 const char *));
b34976b6 93static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
814fa6ab
AM
94 PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
95 const char *));
b34976b6
AM
96static void _bfd_xcoff64_swap_sym_in
97 PARAMS ((bfd *, PTR, PTR));
98static unsigned int _bfd_xcoff64_swap_sym_out
99 PARAMS ((bfd *, PTR, PTR));
dc810e39
AM
100static void _bfd_xcoff64_swap_aux_in
101 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
102static unsigned int _bfd_xcoff64_swap_aux_out
103 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
b34976b6
AM
104static void xcoff64_swap_reloc_in
105 PARAMS ((bfd *, PTR, PTR));
106static unsigned int xcoff64_swap_reloc_out
107 PARAMS ((bfd *, PTR, PTR));
108extern bfd_boolean _bfd_xcoff_mkobject
109 PARAMS ((bfd *));
110extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
111 PARAMS ((bfd *, bfd *));
112extern bfd_boolean _bfd_xcoff_is_local_label_name
113 PARAMS ((bfd *, const char *));
dc810e39
AM
114extern void xcoff64_rtype2howto
115 PARAMS ((arelent *, struct internal_reloc *));
116extern reloc_howto_type * xcoff64_reloc_type_lookup
117 PARAMS ((bfd *, bfd_reloc_code_real_type));
b34976b6
AM
118extern bfd_boolean _bfd_xcoff_slurp_armap
119 PARAMS ((bfd *));
120extern PTR _bfd_xcoff_read_ar_hdr
121 PARAMS ((bfd *));
122extern bfd *_bfd_xcoff_openr_next_archived_file
123 PARAMS ((bfd *, bfd *));
124extern int _bfd_xcoff_stat_arch_elt
125 PARAMS ((bfd *, struct stat *));
126extern bfd_boolean _bfd_xcoff_write_armap
dc810e39 127 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
b34976b6
AM
128extern bfd_boolean _bfd_xcoff_write_archive_contents
129 PARAMS ((bfd *));
130extern int _bfd_xcoff_sizeof_headers
a6b96beb 131 PARAMS ((bfd *, struct bfd_link_info *));
b34976b6
AM
132extern void _bfd_xcoff_swap_sym_in
133 PARAMS ((bfd *, PTR, PTR));
134extern unsigned int _bfd_xcoff_swap_sym_out
135 PARAMS ((bfd *, PTR, PTR));
dc810e39
AM
136extern void _bfd_xcoff_swap_aux_in
137 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
138extern unsigned int _bfd_xcoff_swap_aux_out
139 PARAMS ((bfd *, PTR, int, int, int, int, PTR));
140static void xcoff64_swap_ldhdr_in
141 PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
142static void xcoff64_swap_ldhdr_out
143 PARAMS ((bfd *, const struct internal_ldhdr *, PTR d));
144static void xcoff64_swap_ldsym_in
145 PARAMS ((bfd *, const PTR, struct internal_ldsym *));
146static void xcoff64_swap_ldsym_out
147 PARAMS ((bfd *, const struct internal_ldsym *, PTR d));
148static void xcoff64_swap_ldrel_in
149 PARAMS ((bfd *, const PTR, struct internal_ldrel *));
150static void xcoff64_swap_ldrel_out
151 PARAMS ((bfd *, const struct internal_ldrel *, PTR d));
b34976b6
AM
152static bfd_boolean xcoff64_write_object_contents
153 PARAMS ((bfd *));
154static bfd_boolean xcoff64_ppc_relocate_section
dc810e39 155 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
54327882
AM
156 struct internal_reloc *, struct internal_syment *,
157 asection **));
b34976b6
AM
158static bfd_boolean xcoff64_slurp_armap
159 PARAMS ((bfd *));
160static const bfd_target *xcoff64_archive_p
161 PARAMS ((bfd *));
162static bfd *xcoff64_openr_next_archived_file
163 PARAMS ((bfd *, bfd *));
164static int xcoff64_sizeof_headers
a6b96beb 165 PARAMS ((bfd *, struct bfd_link_info *));
dc810e39
AM
166static asection *xcoff64_create_csect_from_smclas
167 PARAMS ((bfd *, union internal_auxent *, const char *));
b34976b6
AM
168static bfd_boolean xcoff64_is_lineno_count_overflow
169 PARAMS ((bfd *, bfd_vma));
170static bfd_boolean xcoff64_is_reloc_count_overflow
171 PARAMS ((bfd *, bfd_vma));
dc810e39
AM
172static bfd_vma xcoff64_loader_symbol_offset
173 PARAMS ((bfd *, struct internal_ldhdr *));
174static bfd_vma xcoff64_loader_reloc_offset
175 PARAMS ((bfd *, struct internal_ldhdr *));
b34976b6
AM
176static bfd_boolean xcoff64_generate_rtinit
177 PARAMS ((bfd *, const char *, const char *, bfd_boolean));
178static bfd_boolean xcoff64_bad_format_hook
179 PARAMS ((bfd *, PTR ));
dc810e39 180
f1f0d9ab 181/* Relocation functions */
b34976b6
AM
182static bfd_boolean xcoff64_reloc_type_br
183 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
f1f0d9ab 184
b34976b6 185bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
cf9ab45b 186 PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
f1f0d9ab 187{
cf9ab45b
AM
188 xcoff_reloc_type_pos, /* R_POS (0x00) */
189 xcoff_reloc_type_neg, /* R_NEG (0x01) */
190 xcoff_reloc_type_rel, /* R_REL (0x02) */
191 xcoff_reloc_type_toc, /* R_TOC (0x03) */
f1f0d9ab 192 xcoff_reloc_type_fail, /* R_RTB (0x04) */
cf9ab45b
AM
193 xcoff_reloc_type_toc, /* R_GL (0x05) */
194 xcoff_reloc_type_toc, /* R_TCL (0x06) */
195 xcoff_reloc_type_fail, /* (0x07) */
196 xcoff_reloc_type_ba, /* R_BA (0x08) */
197 xcoff_reloc_type_fail, /* (0x09) */
f1f0d9ab 198 xcoff64_reloc_type_br, /* R_BR (0x0a) */
cf9ab45b
AM
199 xcoff_reloc_type_fail, /* (0x0b) */
200 xcoff_reloc_type_pos, /* R_RL (0x0c) */
201 xcoff_reloc_type_pos, /* R_RLA (0x0d) */
202 xcoff_reloc_type_fail, /* (0x0e) */
f1f0d9ab 203 xcoff_reloc_type_noop, /* R_REF (0x0f) */
cf9ab45b
AM
204 xcoff_reloc_type_fail, /* (0x10) */
205 xcoff_reloc_type_fail, /* (0x11) */
206 xcoff_reloc_type_toc, /* R_TRL (0x12) */
207 xcoff_reloc_type_toc, /* R_TRLA (0x13) */
f1f0d9ab
TR
208 xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
209 xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
cf9ab45b 210 xcoff_reloc_type_ba, /* R_CAI (0x16) */
f1f0d9ab 211 xcoff_reloc_type_crel, /* R_CREL (0x17) */
cf9ab45b
AM
212 xcoff_reloc_type_ba, /* R_RBA (0x18) */
213 xcoff_reloc_type_ba, /* R_RBAC (0x19) */
f1f0d9ab 214 xcoff64_reloc_type_br, /* R_RBR (0x1a) */
cf9ab45b 215 xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
f1f0d9ab
TR
216};
217
eb1e0e80 218/* coffcode.h needs these to be defined. */
dc810e39
AM
219/* Internalcoff.h and coffcode.h modify themselves based on these flags. */
220#define XCOFF64
221#define RS6000COFF_C 1
222
223#define SELECT_RELOC(internal, howto) \
224 { \
225 internal.r_type = howto->type; \
226 internal.r_size = \
227 ((howto->complain_on_overflow == complain_overflow_signed \
228 ? 0x80 \
229 : 0) \
230 | (howto->bitsize - 1)); \
231 }
814fa6ab 232
dc810e39
AM
233#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
234#define COFF_LONG_FILENAMES
235#define NO_COFF_SYMBOLS
236#define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
237#define coff_mkobject _bfd_xcoff_mkobject
238#define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
239#define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
240#define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
157090f7 241#define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
dc810e39 242#ifdef AIX_CORE
b34976b6
AM
243extern const bfd_target * rs6000coff_core_p
244 PARAMS ((bfd *abfd));
245extern bfd_boolean rs6000coff_core_file_matches_executable_p
cf9ab45b 246 PARAMS ((bfd *cbfd, bfd *ebfd));
b34976b6
AM
247extern char *rs6000coff_core_file_failing_command
248 PARAMS ((bfd *abfd));
249extern int rs6000coff_core_file_failing_signal
250 PARAMS ((bfd *abfd));
dc810e39
AM
251#define CORE_FILE_P rs6000coff_core_p
252#define coff_core_file_failing_command \
253 rs6000coff_core_file_failing_command
254#define coff_core_file_failing_signal \
255 rs6000coff_core_file_failing_signal
256#define coff_core_file_matches_executable_p \
257 rs6000coff_core_file_matches_executable_p
258#else
259#define CORE_FILE_P _bfd_dummy_target
260#define coff_core_file_failing_command \
261 _bfd_nocore_core_file_failing_command
262#define coff_core_file_failing_signal \
263 _bfd_nocore_core_file_failing_signal
264#define coff_core_file_matches_executable_p \
265 _bfd_nocore_core_file_matches_executable_p
266#endif
267#define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
268#define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
269#define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
270#define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
59862849
TR
271#define coff_swap_reloc_in xcoff64_swap_reloc_in
272#define coff_swap_reloc_out xcoff64_swap_reloc_out
273#define NO_COFF_RELOCS
dc810e39 274
2b5c217d
NC
275#ifndef bfd_pe_print_pdata
276#define bfd_pe_print_pdata NULL
277#endif
278
dc810e39
AM
279#include "coffcode.h"
280
281/* For XCOFF64, the effective width of symndx changes depending on
7f6d05e8
CP
282 whether we are the first entry. Sigh. */
283static void
beb1bf64 284_bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
dc810e39 285 bfd *abfd;
7f6d05e8
CP
286 PTR ext1;
287 PTR in1;
288{
dc810e39
AM
289 LINENO *ext = (LINENO *) ext1;
290 struct internal_lineno *in = (struct internal_lineno *) in1;
7f6d05e8 291
dc810e39 292 in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
7f6d05e8 293 if (in->l_lnno == 0)
dc810e39 294 in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
7f6d05e8 295 else
dc810e39 296 in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
7f6d05e8
CP
297}
298
299static unsigned int
beb1bf64 300_bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
dc810e39
AM
301 bfd *abfd;
302 PTR inp;
303 PTR outp;
7f6d05e8 304{
dc810e39
AM
305 struct internal_lineno *in = (struct internal_lineno *) inp;
306 struct external_lineno *ext = (struct external_lineno *) outp;
307
308 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
309 H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
7f6d05e8 310
7f6d05e8 311 if (in->l_lnno == 0)
dc810e39 312 H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
7f6d05e8 313 else
dc810e39 314 H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
7f6d05e8
CP
315
316 return bfd_coff_linesz (abfd);
317}
318
7f6d05e8 319static void
beb1bf64 320_bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
dc810e39 321 bfd *abfd;
7f6d05e8
CP
322 PTR ext1;
323 PTR in1;
324{
dc810e39
AM
325 struct external_syment *ext = (struct external_syment *) ext1;
326 struct internal_syment *in = (struct internal_syment *) in1;
7f6d05e8 327
7f6d05e8 328 in->_n._n_n._n_zeroes = 0;
dc810e39
AM
329 in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
330 in->n_value = H_GET_64 (abfd, ext->e_value);
331 in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
332 in->n_type = H_GET_16 (abfd, ext->e_type);
333 in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
334 in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
7f6d05e8
CP
335}
336
337static unsigned int
beb1bf64 338_bfd_xcoff64_swap_sym_out (abfd, inp, extp)
dc810e39
AM
339 bfd *abfd;
340 PTR inp;
341 PTR extp;
7f6d05e8 342{
dc810e39
AM
343 struct internal_syment *in = (struct internal_syment *) inp;
344 struct external_syment *ext = (struct external_syment *) extp;
345
346 H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
347 H_PUT_64 (abfd, in->n_value, ext->e_value);
348 H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
349 H_PUT_16 (abfd, in->n_type, ext->e_type);
350 H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
351 H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
7f6d05e8
CP
352 return bfd_coff_symesz (abfd);
353}
354
355static void
beb1bf64 356_bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
dc810e39
AM
357 bfd *abfd;
358 PTR ext1;
359 int type;
360 int class;
361 int indx;
362 int numaux;
363 PTR in1;
7f6d05e8 364{
dc810e39
AM
365 union external_auxent *ext = (union external_auxent *) ext1;
366 union internal_auxent *in = (union internal_auxent *) in1;
7f6d05e8 367
dc810e39
AM
368 switch (class)
369 {
7f6d05e8 370 case C_FILE:
deeb2cd7 371 if (ext->x_file.x_n.x_zeroes[0] == 0)
dc810e39 372 {
7f6d05e8 373 in->x_file.x_n.x_zeroes = 0;
dc810e39
AM
374 in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
375 }
376 else
377 {
beb1bf64
TR
378 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
379 }
7f6d05e8
CP
380 goto end;
381
382 /* RS/6000 "csect" auxents */
383 case C_EXT:
8602d4fe 384 case C_AIX_WEAKEXT:
7f6d05e8
CP
385 case C_HIDEXT:
386 if (indx + 1 == numaux)
387 {
beb1bf64
TR
388 bfd_signed_vma h = 0;
389 bfd_vma l = 0;
390
dc810e39
AM
391 h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
392 l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
beb1bf64
TR
393
394 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
395
dc810e39
AM
396 in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
397 in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
7f6d05e8
CP
398 /* We don't have to hack bitfields in x_smtyp because it's
399 defined by shifts-and-ands, which are equivalent on all
400 byte orders. */
dc810e39
AM
401 in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
402 in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
7f6d05e8
CP
403 goto end;
404 }
405 break;
406
407 case C_STAT:
408 case C_LEAFSTAT:
409 case C_HIDDEN:
dc810e39
AM
410 if (type == T_NULL)
411 {
7f6d05e8 412 /* PE defines some extra fields; we zero them out for
dc810e39 413 safety. */
7f6d05e8
CP
414 in->x_scn.x_checksum = 0;
415 in->x_scn.x_associated = 0;
416 in->x_scn.x_comdat = 0;
417
418 goto end;
419 }
420 break;
421 }
422
423 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
424 {
dc810e39
AM
425 in->x_sym.x_fcnary.x_fcn.x_lnnoptr
426 = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
427 in->x_sym.x_fcnary.x_fcn.x_endndx.l
428 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
429 }
430 if (ISFCN (type))
431 {
432 in->x_sym.x_misc.x_fsize
433 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
434 }
435 else
436 {
437 in->x_sym.x_misc.x_lnsz.x_lnno
438 = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
439 in->x_sym.x_misc.x_lnsz.x_size
440 = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
7f6d05e8 441 }
7f6d05e8 442
dc810e39 443 end: ;
7f6d05e8
CP
444}
445
7f6d05e8 446static unsigned int
beb1bf64 447_bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
dc810e39
AM
448 bfd *abfd;
449 PTR inp;
450 int type;
451 int class;
452 int indx ATTRIBUTE_UNUSED;
453 int numaux ATTRIBUTE_UNUSED;
454 PTR extp;
7f6d05e8 455{
dc810e39
AM
456 union internal_auxent *in = (union internal_auxent *) inp;
457 union external_auxent *ext = (union external_auxent *) extp;
7f6d05e8 458
dc810e39 459 memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
7f6d05e8
CP
460 switch (class)
461 {
dc810e39 462 case C_FILE:
a58d9c34 463 if (in->x_file.x_n.x_zeroes == 0)
dc810e39
AM
464 {
465 H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
466 H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
467 }
468 else
469 {
470 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
471 }
472 H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
7f6d05e8 473 goto end;
dc810e39
AM
474
475 /* RS/6000 "csect" auxents */
476 case C_EXT:
8602d4fe 477 case C_AIX_WEAKEXT:
dc810e39
AM
478 case C_HIDEXT:
479 if (indx + 1 == numaux)
480 {
481 bfd_vma temp;
482
483 temp = in->x_csect.x_scnlen.l & 0xffffffff;
484 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
485 temp = in->x_csect.x_scnlen.l >> 32;
486 H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
487 H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
488 H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
489 /* We don't have to hack bitfields in x_smtyp because it's
490 defined by shifts-and-ands, which are equivalent on all
491 byte orders. */
492 H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
493 H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
494 H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
495 goto end;
496 }
497 break;
498
499 case C_STAT:
500 case C_LEAFSTAT:
501 case C_HIDDEN:
502 if (type == T_NULL)
503 {
504 goto end;
505 }
506 break;
7f6d05e8 507 }
7f6d05e8
CP
508
509 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
510 {
dc810e39
AM
511 H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
512 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
513 H_PUT_8 (abfd, _AUX_FCN,
514 ext->x_auxtype.x_auxtype);
515 H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
516 ext->x_sym.x_fcnary.x_fcn.x_endndx);
7f6d05e8
CP
517 }
518 if (ISFCN (type))
dc810e39
AM
519 {
520 H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
521 ext->x_sym.x_fcnary.x_fcn.x_fsize);
522 }
7f6d05e8
CP
523 else
524 {
dc810e39
AM
525 H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
526 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
527 H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
528 ext->x_sym.x_fcnary.x_lnsz.x_size);
7f6d05e8
CP
529 }
530
dc810e39 531 end:
beb1bf64 532
7f6d05e8
CP
533 return bfd_coff_auxesz (abfd);
534}
535
b34976b6 536static bfd_boolean
eb1e0e80
NC
537_bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
538 bfd *abfd;
539 struct bfd_strtab_hash *strtab;
540 struct internal_syment *sym;
541 const char *name;
542{
b34976b6 543 bfd_boolean hash;
beb1bf64 544 bfd_size_type indx;
dc810e39 545
b34976b6 546 hash = TRUE;
dc810e39 547
beb1bf64 548 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
b34976b6 549 hash = FALSE;
dc810e39 550
b34976b6 551 indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
dc810e39 552
beb1bf64 553 if (indx == (bfd_size_type) -1)
b34976b6 554 return FALSE;
dc810e39 555
beb1bf64
TR
556 sym->_n._n_n._n_zeroes = 0;
557 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
dc810e39 558
b34976b6 559 return TRUE;
beb1bf64
TR
560}
561
b34976b6 562static bfd_boolean
beb1bf64
TR
563_bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
564 bfd *abfd ATTRIBUTE_UNUSED;
dc810e39
AM
565 struct xcoff_loader_info *ldinfo;
566 struct internal_ldsym *ldsym;
567 const char *name;
beb1bf64 568{
beb1bf64
TR
569 size_t len;
570 len = strlen (name);
571
dc810e39
AM
572 if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
573 {
574 bfd_size_type newalc;
f075ee0c 575 char *newstrings;
dc810e39
AM
576
577 newalc = ldinfo->string_alc * 2;
578 if (newalc == 0)
579 newalc = 32;
580 while (ldinfo->string_size + len + 3 > newalc)
581 newalc *= 2;
582
f075ee0c 583 newstrings = bfd_realloc (ldinfo->strings, newalc);
dc810e39
AM
584 if (newstrings == NULL)
585 {
b34976b6
AM
586 ldinfo->failed = TRUE;
587 return FALSE;
dc810e39
AM
588 }
589 ldinfo->string_alc = newalc;
590 ldinfo->strings = newstrings;
beb1bf64 591 }
dc810e39
AM
592
593 bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
beb1bf64
TR
594 ldinfo->strings + ldinfo->string_size);
595 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
596 ldsym->_l._l_l._l_zeroes = 0;
597 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
598 ldinfo->string_size += len + 3;
dc810e39 599
b34976b6 600 return TRUE;
beb1bf64
TR
601}
602
beb1bf64
TR
603/* Routines to swap information in the XCOFF .loader section. If we
604 ever need to write an XCOFF loader, this stuff will need to be
605 moved to another file shared by the linker (which XCOFF calls the
606 ``binder'') and the loader. */
607
608/* Swap in the ldhdr structure. */
609
610static void
814fa6ab
AM
611xcoff64_swap_ldhdr_in (abfd, s, dst)
612 bfd *abfd;
613 const PTR s;
614 struct internal_ldhdr *dst;
615{
616 const struct external_ldhdr *src = (const struct external_ldhdr *) s;
617
beb1bf64
TR
618 dst->l_version = bfd_get_32 (abfd, src->l_version);
619 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
620 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
621 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
622 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
623 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
624 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
625 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
626 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
627 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
628}
629
630/* Swap out the ldhdr structure. */
631
632static void
814fa6ab 633xcoff64_swap_ldhdr_out (abfd, src, d)
beb1bf64
TR
634 bfd *abfd;
635 const struct internal_ldhdr *src;
814fa6ab 636 PTR d;
beb1bf64 637{
814fa6ab
AM
638 struct external_ldhdr *dst = (struct external_ldhdr *) d;
639
dc810e39 640 bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
beb1bf64
TR
641 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
642 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
643 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
644 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
645 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
646 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
647 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
648 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
649 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
650}
651
652/* Swap in the ldsym structure. */
653
654static void
814fa6ab 655xcoff64_swap_ldsym_in (abfd, s, dst)
beb1bf64 656 bfd *abfd;
814fa6ab 657 const PTR s;
beb1bf64
TR
658 struct internal_ldsym *dst;
659{
814fa6ab 660 const struct external_ldsym *src = (const struct external_ldsym *) s;
dc810e39
AM
661 /* XCOFF64 does not use l_zeroes like XCOFF32
662 Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
663 as an offset into the loader symbol table. */
beb1bf64
TR
664 dst->_l._l_l._l_zeroes = 0;
665 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
666 dst->l_value = bfd_get_64 (abfd, src->l_value);
667 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
668 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
669 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
670 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
671 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
672}
673
674/* Swap out the ldsym structure. */
675
676static void
814fa6ab 677xcoff64_swap_ldsym_out (abfd, src, d)
beb1bf64
TR
678 bfd *abfd;
679 const struct internal_ldsym *src;
814fa6ab 680 PTR d;
beb1bf64 681{
814fa6ab
AM
682 struct external_ldsym *dst = (struct external_ldsym *) d;
683
beb1bf64 684 bfd_put_64 (abfd, src->l_value, dst->l_value);
dc810e39
AM
685 bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
686 bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
beb1bf64
TR
687 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
688 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
689 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
690 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
691}
692
59862849
TR
693static void
694xcoff64_swap_reloc_in (abfd, s, d)
695 bfd *abfd;
696 PTR s;
697 PTR d;
698{
699 struct external_reloc *src = (struct external_reloc *) s;
700 struct internal_reloc *dst = (struct internal_reloc *) d;
701
702 memset (dst, 0, sizeof (struct internal_reloc));
703
704 dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
705 dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
706 dst->r_size = bfd_get_8 (abfd, src->r_size);
707 dst->r_type = bfd_get_8 (abfd, src->r_type);
708}
709
710static unsigned int
711xcoff64_swap_reloc_out (abfd, s, d)
712 bfd *abfd;
713 PTR s;
714 PTR d;
715{
716 struct internal_reloc *src = (struct internal_reloc *) s;
717 struct external_reloc *dst = (struct external_reloc *) d;
718
719 bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
720 bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
721 bfd_put_8 (abfd, src->r_type, dst->r_type);
722 bfd_put_8 (abfd, src->r_size, dst->r_size);
723
724 return bfd_coff_relsz (abfd);
725}
726
beb1bf64
TR
727/* Swap in the ldrel structure. */
728
729static void
814fa6ab 730xcoff64_swap_ldrel_in (abfd, s, dst)
beb1bf64 731 bfd *abfd;
814fa6ab 732 const PTR s;
beb1bf64
TR
733 struct internal_ldrel *dst;
734{
814fa6ab
AM
735 const struct external_ldrel *src = (const struct external_ldrel *) s;
736
beb1bf64
TR
737 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
738 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
739 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
740 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
741}
742
743/* Swap out the ldrel structure. */
744
745static void
814fa6ab 746xcoff64_swap_ldrel_out (abfd, src, d)
beb1bf64
TR
747 bfd *abfd;
748 const struct internal_ldrel *src;
814fa6ab 749 PTR d;
beb1bf64 750{
814fa6ab
AM
751 struct external_ldrel *dst = (struct external_ldrel *) d;
752
beb1bf64 753 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
dc810e39
AM
754 bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
755 bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
beb1bf64
TR
756 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
757}
758
b34976b6 759static bfd_boolean
beb1bf64 760xcoff64_write_object_contents (abfd)
cf9ab45b 761 bfd *abfd;
beb1bf64
TR
762{
763 asection *current;
b34976b6
AM
764 bfd_boolean hasrelocs = FALSE;
765 bfd_boolean haslinno = FALSE;
beb1bf64
TR
766 file_ptr scn_base;
767 file_ptr reloc_base;
768 file_ptr lineno_base;
769 file_ptr sym_base;
770 unsigned long reloc_size = 0;
771 unsigned long lnno_size = 0;
dc810e39
AM
772 asection *text_sec = ((void *) 0);
773 asection *data_sec = ((void *) 0);
774 asection *bss_sec = ((void *) 0);
beb1bf64
TR
775 struct internal_filehdr internal_f;
776 struct internal_aouthdr internal_a;
777
778 bfd_set_error (bfd_error_system_call);
779
82e51918 780 if (! abfd->output_has_begun)
dc810e39
AM
781 {
782 if (! bfd_coff_compute_section_file_positions (abfd))
b34976b6 783 return FALSE;
dc810e39 784 }
beb1bf64 785
eb1e0e80 786 /* Work out the size of the reloc and linno areas. */
beb1bf64
TR
787 reloc_base = obj_relocbase (abfd);
788
dc810e39 789 for (current = abfd->sections; current != NULL; current = current->next)
beb1bf64 790 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
beb1bf64
TR
791
792 lineno_base = reloc_base + reloc_size;
793
794 /* Make a pass through the symbol table to count line number entries and
eb1e0e80 795 put them into the correct asections. */
beb1bf64
TR
796 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
797
798 sym_base = lineno_base + lnno_size;
799
eb1e0e80 800 /* Indicate in each section->line_filepos its actual file address. */
dc810e39
AM
801 for (current = abfd->sections; current != NULL; current = current->next)
802 {
803 if (current->lineno_count)
804 {
805 current->line_filepos = lineno_base;
806 current->moving_line_filepos = lineno_base;
807 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
808 }
809 else
810 {
811 current->line_filepos = 0;
812 }
813
814 if (current->reloc_count)
815 {
816 current->rel_filepos = reloc_base;
817 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
818 }
819 else
820 {
821 current->rel_filepos = 0;
822 }
823 }
824
825 if ((abfd->flags & EXEC_P) != 0)
826 {
827 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
828 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
beb1bf64 829 }
dc810e39
AM
830 else
831 {
832 scn_base = bfd_coff_filhsz (abfd);
833 internal_f.f_opthdr = 0;
beb1bf64 834 }
beb1bf64
TR
835
836 internal_f.f_nscns = 0;
837
838 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
b34976b6 839 return FALSE;
beb1bf64 840
dc810e39
AM
841 for (current = abfd->sections; current != NULL; current = current->next)
842 {
843 struct internal_scnhdr section;
844 struct external_scnhdr buff;
845 bfd_size_type amount;
beb1bf64 846
dc810e39 847 internal_f.f_nscns++;
beb1bf64 848
dc810e39 849 strncpy (section.s_name, current->name, SCNNMLEN);
beb1bf64 850
dc810e39
AM
851 section.s_vaddr = current->vma;
852 section.s_paddr = current->lma;
eea6121a 853 section.s_size = current->size;
beb1bf64 854
dc810e39
AM
855 /* If this section has no size or is unloadable then the scnptr
856 will be 0 too. */
eea6121a 857 if (current->size == 0
dc810e39
AM
858 || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
859 {
860 section.s_scnptr = 0;
861 }
862 else
863 {
864 section.s_scnptr = current->filepos;
865 }
866
867 section.s_relptr = current->rel_filepos;
868 section.s_lnnoptr = current->line_filepos;
869 section.s_nreloc = current->reloc_count;
870
871 section.s_nlnno = current->lineno_count;
872 if (current->reloc_count != 0)
b34976b6 873 hasrelocs = TRUE;
dc810e39 874 if (current->lineno_count != 0)
b34976b6 875 haslinno = TRUE;
beb1bf64 876
dc810e39
AM
877 section.s_flags = sec_to_styp_flags (current->name, current->flags);
878
879 if (!strcmp (current->name, _TEXT))
880 {
881 text_sec = current;
882 }
883 else if (!strcmp (current->name, _DATA))
884 {
885 data_sec = current;
886 }
887 else if (!strcmp (current->name, _BSS))
888 {
889 bss_sec = current;
890 }
891
892 amount = bfd_coff_scnhsz (abfd);
893 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
894 || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
b34976b6 895 return FALSE;
dc810e39 896 }
beb1bf64
TR
897
898 internal_f.f_timdat = 0;
899
900 internal_f.f_flags = 0;
901
902 if (!hasrelocs)
903 internal_f.f_flags |= F_RELFLG;
904 if (!haslinno)
905 internal_f.f_flags |= F_LNNO;
906 if (abfd->flags & EXEC_P)
907 internal_f.f_flags |= F_EXEC;
908
eb1e0e80 909 /* FIXME: this is wrong for PPC_PE! */
beb1bf64
TR
910 if (bfd_little_endian (abfd))
911 internal_f.f_flags |= F_AR32WR;
912 else
913 internal_f.f_flags |= F_AR32W;
914
915 if ((abfd->flags & DYNAMIC) != 0)
916 internal_f.f_flags |= F_SHROBJ;
917 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
918 internal_f.f_flags |= F_DYNLOAD;
919
920 memset (&internal_a, 0, sizeof internal_a);
921
eb1e0e80 922 internal_f.f_magic = bfd_xcoff_magic_number (abfd);
cf9ab45b
AM
923 internal_a.magic = (abfd->flags & D_PAGED
924 ? RS6K_AOUTHDR_ZMAGIC
925 : (abfd->flags & WP_TEXT
926 ? RS6K_AOUTHDR_NMAGIC
927 : RS6K_AOUTHDR_OMAGIC));
beb1bf64
TR
928
929 /* FIXME: Does anybody ever set this to another value? */
930 internal_a.vstamp = 0;
931
eb1e0e80 932 /* Now should write relocs, strings, syms. */
beb1bf64
TR
933 obj_sym_filepos (abfd) = sym_base;
934
935 internal_f.f_symptr = 0;
936 internal_f.f_nsyms = 0;
937
dc810e39
AM
938 /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
939 backend linker, and obj_raw_syment_count is not valid until after
940 coff_write_symbols is called. */
941 if (bfd_get_symcount (abfd) != 0)
942 {
943 int firstundef;
beb1bf64 944
dc810e39 945 if (!coff_renumber_symbols (abfd, &firstundef))
b34976b6 946 return FALSE;
dc810e39
AM
947 coff_mangle_symbols (abfd);
948 if (! coff_write_symbols (abfd))
b34976b6 949 return FALSE;
dc810e39 950 if (! coff_write_linenumbers (abfd))
b34976b6 951 return FALSE;
dc810e39 952 if (! coff_write_relocs (abfd, firstundef))
b34976b6 953 return FALSE;
beb1bf64 954
dc810e39
AM
955 internal_f.f_symptr = sym_base;
956 internal_f.f_nsyms = bfd_get_symcount (abfd);
957 }
958 else if (obj_raw_syment_count (abfd) != 0)
959 {
960 internal_f.f_symptr = sym_base;
961
962 /* AIX appears to require that F_RELFLG not be set if there are
963 local symbols but no relocations. */
964 internal_f.f_flags &=~ F_RELFLG;
965 }
966 else
967 {
968 internal_f.f_flags |= F_LSYMS;
969 }
beb1bf64 970
dc810e39
AM
971 if (text_sec)
972 {
eea6121a 973 internal_a.tsize = text_sec->size;
beb1bf64 974 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
dc810e39 975 }
beb1bf64 976
dc810e39
AM
977 if (data_sec)
978 {
eea6121a 979 internal_a.dsize = data_sec->size;
dc810e39
AM
980 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
981 }
beb1bf64 982
dc810e39
AM
983 if (bss_sec)
984 {
eea6121a 985 internal_a.bsize = bss_sec->size;
dc810e39
AM
986 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
987 internal_a.data_start = bss_sec->vma;
988 }
beb1bf64
TR
989
990 internal_a.entry = bfd_get_start_address (abfd);
991 internal_f.f_nsyms = obj_raw_syment_count (abfd);
992
dc810e39
AM
993 if (xcoff_data (abfd)->full_aouthdr)
994 {
beb1bf64
TR
995 bfd_vma toc;
996 asection *loader_sec;
997
998 internal_a.vstamp = 1;
999
1000 internal_a.o_snentry = xcoff_data (abfd)->snentry;
1001 if (internal_a.o_snentry == 0)
1002 internal_a.entry = (bfd_vma) -1;
1003
dc810e39
AM
1004 if (text_sec != NULL)
1005 {
beb1bf64
TR
1006 internal_a.o_sntext = text_sec->target_index;
1007 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
dc810e39
AM
1008 }
1009 else
1010 {
1011 internal_a.o_sntext = 0;
1012 internal_a.o_algntext = 0;
1013 }
1014
1015 if (data_sec != NULL)
1016 {
1017 internal_a.o_sndata = data_sec->target_index;
1018 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
1019 }
1020 else
1021 {
1022 internal_a.o_sndata = 0;
1023 internal_a.o_algndata = 0;
1024 }
beb1bf64
TR
1025
1026 loader_sec = bfd_get_section_by_name (abfd, ".loader");
1027 if (loader_sec != NULL)
1028 internal_a.o_snloader = loader_sec->target_index;
1029 else
1030 internal_a.o_snloader = 0;
1031 if (bss_sec != NULL)
1032 internal_a.o_snbss = bss_sec->target_index;
1033 else
1034 internal_a.o_snbss = 0;
1035
1036 toc = xcoff_data (abfd)->toc;
1037 internal_a.o_toc = toc;
1038 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
1039
1040 internal_a.o_modtype = xcoff_data (abfd)->modtype;
1041 if (xcoff_data (abfd)->cputype != -1)
1042 internal_a.o_cputype = xcoff_data (abfd)->cputype;
1043 else
1044 {
1045 switch (bfd_get_arch (abfd))
1046 {
1047 case bfd_arch_rs6000:
1048 internal_a.o_cputype = 4;
1049 break;
1050 case bfd_arch_powerpc:
250d94fd 1051 if (bfd_get_mach (abfd) == bfd_mach_ppc)
beb1bf64 1052 internal_a.o_cputype = 3;
d19d97e9
RS
1053 else if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
1054 internal_a.o_cputype = 2;
beb1bf64
TR
1055 else
1056 internal_a.o_cputype = 1;
1057 break;
1058 default:
1059 abort ();
1060 }
1061 }
1062 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
1063 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
dc810e39
AM
1064 }
1065
1066 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
b34976b6 1067 return FALSE;
dc810e39 1068
beb1bf64
TR
1069 {
1070 char * buff;
dc810e39
AM
1071 bfd_size_type amount = bfd_coff_filhsz (abfd);
1072
1073 buff = bfd_malloc (amount);
1074 if (buff == NULL)
b34976b6 1075 return FALSE;
dc810e39
AM
1076
1077 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
1078 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1079
beb1bf64 1080 free (buff);
dc810e39 1081
beb1bf64 1082 if (amount != bfd_coff_filhsz (abfd))
b34976b6 1083 return FALSE;
beb1bf64 1084 }
beb1bf64 1085
dc810e39
AM
1086 if (abfd->flags & EXEC_P)
1087 {
1088 char * buff;
1089 bfd_size_type amount = bfd_coff_aoutsz (abfd);
beb1bf64 1090
dc810e39
AM
1091 buff = bfd_malloc (amount);
1092 if (buff == NULL)
b34976b6 1093 return FALSE;
beb1bf64 1094
cf9ab45b 1095 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
dc810e39
AM
1096 amount = bfd_bwrite ((PTR) buff, amount, abfd);
1097
1098 free (buff);
beb1bf64 1099
dc810e39 1100 if (amount != bfd_coff_aoutsz (abfd))
b34976b6 1101 return FALSE;
dc810e39 1102 }
beb1bf64 1103
b34976b6 1104 return TRUE;
beb1bf64
TR
1105}
1106
b34976b6 1107static bfd_boolean
cf9ab45b 1108xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
f1f0d9ab
TR
1109 val, addend, relocation, contents)
1110 bfd *input_bfd;
1111 asection *input_section;
1112 bfd *output_bfd ATTRIBUTE_UNUSED;
1113 struct internal_reloc *rel;
1114 struct internal_syment *sym ATTRIBUTE_UNUSED;
1115 struct reloc_howto_struct *howto;
1116 bfd_vma val;
1117 bfd_vma addend;
1118 bfd_vma *relocation;
1119 bfd_byte *contents;
1120{
1121 struct xcoff_link_hash_entry *h;
12b2cce9 1122 bfd_vma section_offset;
f1f0d9ab 1123
cf9ab45b 1124 if (0 > rel->r_symndx)
b34976b6 1125 return FALSE;
f1f0d9ab
TR
1126
1127 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
12b2cce9 1128 section_offset = rel->r_vaddr - input_section->vma;
f1f0d9ab
TR
1129
1130 /* If we see an R_BR or R_RBR reloc which is jumping to global
1131 linkage code, and it is followed by an appropriate cror nop
1132 instruction, we replace the cror with ld r2,40(r1). This
1133 restores the TOC after the glink code. Contrariwise, if the
1134 call is followed by a ld r2,40(r1), but the call is not
1135 going to global linkage code, we can replace the load with a
1136 cror. */
cf9ab45b 1137 if (NULL != h
8602d4fe
RS
1138 && (bfd_link_hash_defined == h->root.type
1139 || bfd_link_hash_defweak == h->root.type)
12b2cce9 1140 && section_offset + 8 <= input_section->size)
f1f0d9ab
TR
1141 {
1142 bfd_byte *pnext;
1143 unsigned long next;
cf9ab45b 1144
12b2cce9 1145 pnext = contents + section_offset + 4;
f1f0d9ab 1146 next = bfd_get_32 (input_bfd, pnext);
cf9ab45b
AM
1147
1148 /* The _ptrgl function is magic. It is used by the AIX compiler to call
f1f0d9ab 1149 a function through a pointer. */
cf9ab45b 1150 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
f1f0d9ab 1151 {
cf9ab45b
AM
1152 if (next == 0x4def7b82 /* cror 15,15,15 */
1153 || next == 0x4ffffb82 /* cror 31,31,31 */
1154 || next == 0x60000000) /* ori r0,r0,0 */
1155 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1156 }
1157 else
f1f0d9ab 1158 {
cf9ab45b
AM
1159 if (next == 0xe8410028) /* ld r2,40(r1) */
1160 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
f1f0d9ab 1161 }
cf9ab45b
AM
1162 }
1163 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
f1f0d9ab
TR
1164 {
1165 /* Normally, this relocation is against a defined symbol. In the
1166 case where this is a partial link and the output section offset
cf9ab45b 1167 is greater than 2^25, the linker will return an invalid error
f1f0d9ab 1168 message that the relocation has been truncated. Yes it has been
cf9ab45b 1169 truncated but no it not important. For this case, disable the
f1f0d9ab
TR
1170 overflow checking. */
1171 howto->complain_on_overflow = complain_overflow_dont;
1172 }
cf9ab45b 1173
12b2cce9
RS
1174 /* The original PC-relative relocation is biased by -r_vaddr, so adding
1175 the value below will give the absolute target address. */
1176 *relocation = val + addend + rel->r_vaddr;
1177
a78eab4e
AM
1178 howto->src_mask &= ~3;
1179 howto->dst_mask = howto->src_mask;
cf9ab45b 1180
12b2cce9 1181 if (h != NULL
8602d4fe
RS
1182 && (h->root.type == bfd_link_hash_defined
1183 || h->root.type == bfd_link_hash_defweak)
12b2cce9
RS
1184 && bfd_is_abs_section (h->root.u.def.section)
1185 && section_offset + 4 <= input_section->size)
1186 {
1187 bfd_byte *ptr;
1188 bfd_vma insn;
1189
1190 /* Turn the relative branch into an absolute one by setting the
1191 AA bit. */
1192 ptr = contents + section_offset;
1193 insn = bfd_get_32 (input_bfd, ptr);
1194 insn |= 2;
1195 bfd_put_32 (input_bfd, insn, ptr);
1196
1197 /* Make the howto absolute too. */
1198 howto->pc_relative = FALSE;
1199 howto->complain_on_overflow = complain_overflow_bitfield;
1200 }
1201 else
1202 {
1203 /* Use a PC-relative howto and subtract the instruction's address
1204 from the target address we calculated above. */
1205 howto->pc_relative = TRUE;
1206 *relocation -= (input_section->output_section->vma
1207 + input_section->output_offset
1208 + section_offset);
1209 }
b34976b6 1210 return TRUE;
f1f0d9ab
TR
1211}
1212
dbe341c6
TR
1213/* This is the relocation function for the PowerPC64.
1214 See xcoff_ppc_relocation_section for more information. */
beb1bf64 1215
b34976b6 1216bfd_boolean
beb1bf64
TR
1217xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1218 input_section, contents, relocs, syms,
1219 sections)
1220 bfd *output_bfd;
1221 struct bfd_link_info *info;
1222 bfd *input_bfd;
1223 asection *input_section;
1224 bfd_byte *contents;
1225 struct internal_reloc *relocs;
1226 struct internal_syment *syms;
1227 asection **sections;
1228{
1229 struct internal_reloc *rel;
1230 struct internal_reloc *relend;
1231
1232 rel = relocs;
1233 relend = rel + input_section->reloc_count;
1234 for (; rel < relend; rel++)
1235 {
1236 long symndx;
1237 struct xcoff_link_hash_entry *h;
1238 struct internal_syment *sym;
1239 bfd_vma addend;
1240 bfd_vma val;
1241 struct reloc_howto_struct howto;
dbe341c6
TR
1242 bfd_vma relocation;
1243 bfd_vma value_to_relocate;
1244 bfd_vma address;
1245 bfd_byte *location;
beb1bf64
TR
1246
1247 /* Relocation type R_REF is a special relocation type which is
cf9ab45b
AM
1248 merely used to prevent garbage collection from occurring for
1249 the csect including the symbol which it references. */
beb1bf64
TR
1250 if (rel->r_type == R_REF)
1251 continue;
1252
dbe341c6 1253 /* howto */
beb1bf64
TR
1254 howto.type = rel->r_type;
1255 howto.rightshift = 0;
beb1bf64 1256 howto.bitsize = (rel->r_size & 0x3f) + 1;
dbe341c6 1257 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
b34976b6 1258 howto.pc_relative = FALSE;
beb1bf64 1259 howto.bitpos = 0;
cf9ab45b
AM
1260 howto.complain_on_overflow = (rel->r_size & 0x80
1261 ? complain_overflow_signed
1262 : complain_overflow_bitfield);
beb1bf64
TR
1263 howto.special_function = NULL;
1264 howto.name = "internal";
b34976b6 1265 howto.partial_inplace = TRUE;
cf9ab45b 1266 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
b34976b6 1267 howto.pcrel_offset = FALSE;
beb1bf64 1268
dbe341c6 1269 /* symbol */
beb1bf64 1270 val = 0;
dbe341c6
TR
1271 addend = 0;
1272 h = NULL;
1273 sym = NULL;
cf9ab45b 1274 symndx = rel->r_symndx;
beb1bf64 1275
cf9ab45b 1276 if (-1 != symndx)
dc810e39
AM
1277 {
1278 asection *sec;
cf9ab45b 1279
dbe341c6
TR
1280 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1281 sym = syms + symndx;
1282 addend = - sym->n_value;
cf9ab45b
AM
1283
1284 if (NULL == h)
dc810e39
AM
1285 {
1286 sec = sections[symndx];
1287 /* Hack to make sure we use the right TOC anchor value
1288 if this reloc is against the TOC anchor. */
1289 if (sec->name[3] == '0'
1290 && strcmp (sec->name, ".tc0") == 0)
1291 val = xcoff_data (output_bfd)->toc;
1292 else
1293 val = (sec->output_section->vma
1294 + sec->output_offset
1295 + sym->n_value
1296 - sec->vma);
cf9ab45b
AM
1297 }
1298 else
dc810e39 1299 {
858ef0ce
RS
1300 if (info->unresolved_syms_in_objects != RM_IGNORE
1301 && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
1302 {
1303 if (! ((*info->callbacks->undefined_symbol)
1304 (info, h->root.root.string,
1305 input_bfd, input_section,
1306 rel->r_vaddr - input_section->vma,
1307 (info->unresolved_syms_in_objects
1308 == RM_GENERATE_ERROR))))
1309 return FALSE;
1310 }
cf9ab45b
AM
1311 if (h->root.type == bfd_link_hash_defined
1312 || h->root.type == bfd_link_hash_defweak)
dc810e39 1313 {
dbe341c6
TR
1314 sec = h->root.u.def.section;
1315 val = (h->root.u.def.value
1316 + sec->output_section->vma
1317 + sec->output_offset);
cf9ab45b
AM
1318 }
1319 else if (h->root.type == bfd_link_hash_common)
dbe341c6
TR
1320 {
1321 sec = h->root.u.c.p->section;
1322 val = (sec->output_section->vma
1323 + sec->output_offset);
cf9ab45b 1324 }
858ef0ce 1325 else
dbe341c6 1326 {
858ef0ce
RS
1327 BFD_ASSERT (info->relocatable
1328 || (h->flags & XCOFF_DEF_DYNAMIC) != 0
1329 || (h->flags & XCOFF_IMPORT) != 0);
dc810e39 1330 }
dc810e39 1331 }
dc810e39 1332 }
cf9ab45b
AM
1333
1334 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
213e90f4 1335 || !((*xcoff64_calculate_relocation[rel->r_type])
cf9ab45b
AM
1336 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1337 addend, &relocation, contents)))
b34976b6 1338 return FALSE;
cf9ab45b 1339
dbe341c6
TR
1340 /* address */
1341 address = rel->r_vaddr - input_section->vma;
1342 location = contents + address;
cf9ab45b 1343
eea6121a 1344 if (address > input_section->size)
cf9ab45b
AM
1345 abort ();
1346
dbe341c6
TR
1347 /* Get the value we are going to relocate. */
1348 if (1 == howto.size)
1349 value_to_relocate = bfd_get_16 (input_bfd, location);
1350 else if (2 == howto.size)
1351 value_to_relocate = bfd_get_32 (input_bfd, location);
cf9ab45b 1352 else
dbe341c6 1353 value_to_relocate = bfd_get_64 (input_bfd, location);
cf9ab45b
AM
1354
1355 /* overflow.
1356
dbe341c6
TR
1357 FIXME: We may drop bits during the addition
1358 which we don't check for. We must either check at every single
1359 operation, which would be tedious, or we must do the computations
1360 in a type larger than bfd_vma, which would be inefficient. */
cf9ab45b
AM
1361
1362 if ((unsigned int) howto.complain_on_overflow
1363 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1364 abort ();
1365
1366 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1367 (input_bfd, value_to_relocate, relocation, &howto)))
dc810e39 1368 {
dbe341c6
TR
1369 const char *name;
1370 char buf[SYMNMLEN + 1];
1371 char reloc_type_name[10];
cf9ab45b
AM
1372
1373 if (symndx == -1)
beb1bf64 1374 {
dbe341c6 1375 name = "*ABS*";
cf9ab45b
AM
1376 }
1377 else if (h != NULL)
dbe341c6 1378 {
dfeffb9f 1379 name = NULL;
cf9ab45b
AM
1380 }
1381 else
beb1bf64 1382 {
dbe341c6
TR
1383 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1384 if (name == NULL)
1385 name = "UNKNOWN";
beb1bf64 1386 }
dbe341c6 1387 sprintf (reloc_type_name, "0x%02x", rel->r_type);
cf9ab45b 1388
dbe341c6 1389 if (! ((*info->callbacks->reloc_overflow)
dfeffb9f
L
1390 (info, (h ? &h->root : NULL), name, reloc_type_name,
1391 (bfd_vma) 0, input_bfd, input_section,
1392 rel->r_vaddr - input_section->vma)))
b34976b6 1393 return FALSE;
beb1bf64
TR
1394 }
1395
dbe341c6 1396 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
cf9ab45b
AM
1397 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1398 | (((value_to_relocate & howto.src_mask)
1399 + relocation) & howto.dst_mask));
1400
dbe341c6
TR
1401 /* Put the value back in the object file. */
1402 if (1 == howto.size)
1403 bfd_put_16 (input_bfd, value_to_relocate, location);
1404 else if (2 == howto.size)
1405 bfd_put_32 (input_bfd, value_to_relocate, location);
1406 else
1407 bfd_put_64 (input_bfd, value_to_relocate, location);
cf9ab45b 1408
beb1bf64 1409 }
b34976b6 1410 return TRUE;
beb1bf64
TR
1411}
1412
beb1bf64
TR
1413\f
1414/* The XCOFF reloc table. Actually, XCOFF relocations specify the
1415 bitsize and whether they are signed or not, along with a
1416 conventional type. This table is for the types, which are used for
1417 different algorithms for putting in the reloc. Many of these
1418 relocs need special_function entries, which I have not written. */
1419
beb1bf64
TR
1420reloc_howto_type xcoff64_howto_table[] =
1421{
1422 /* Standard 64 bit relocation. */
38487e5e 1423 HOWTO (R_POS, /* type */
dc810e39
AM
1424 0, /* rightshift */
1425 4, /* size (0 = byte, 1 = short, 2 = long) */
1426 64, /* bitsize */
b34976b6 1427 FALSE, /* pc_relative */
dc810e39 1428 0, /* bitpos */
beb1bf64 1429 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39 1430 0, /* special_function */
59862849 1431 "R_POS_64", /* name */
b34976b6 1432 TRUE, /* partial_inplace */
a78eab4e 1433 MINUS_ONE, /* src_mask */
dc810e39 1434 MINUS_ONE, /* dst_mask */
b34976b6 1435 FALSE), /* pcrel_offset */
beb1bf64
TR
1436
1437 /* 64 bit relocation, but store negative value. */
38487e5e 1438 HOWTO (R_NEG, /* type */
dc810e39
AM
1439 0, /* rightshift */
1440 -4, /* size (0 = byte, 1 = short, 2 = long) */
1441 64, /* bitsize */
b34976b6 1442 FALSE, /* pc_relative */
dc810e39 1443 0, /* bitpos */
beb1bf64 1444 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1445 0, /* special_function */
1446 "R_NEG", /* name */
b34976b6 1447 TRUE, /* partial_inplace */
a78eab4e 1448 MINUS_ONE, /* src_mask */
dc810e39 1449 MINUS_ONE, /* dst_mask */
b34976b6 1450 FALSE), /* pcrel_offset */
beb1bf64
TR
1451
1452 /* 32 bit PC relative relocation. */
38487e5e 1453 HOWTO (R_REL, /* type */
dc810e39
AM
1454 0, /* rightshift */
1455 2, /* size (0 = byte, 1 = short, 2 = long) */
1456 32, /* bitsize */
b34976b6 1457 TRUE, /* pc_relative */
dc810e39 1458 0, /* bitpos */
beb1bf64 1459 complain_overflow_signed, /* complain_on_overflow */
dc810e39
AM
1460 0, /* special_function */
1461 "R_REL", /* name */
b34976b6 1462 TRUE, /* partial_inplace */
a78eab4e 1463 0xffffffff, /* src_mask */
dc810e39 1464 0xffffffff, /* dst_mask */
b34976b6 1465 FALSE), /* pcrel_offset */
beb1bf64
TR
1466
1467 /* 16 bit TOC relative relocation. */
38487e5e 1468 HOWTO (R_TOC, /* type */
dc810e39
AM
1469 0, /* rightshift */
1470 1, /* size (0 = byte, 1 = short, 2 = long) */
1471 16, /* bitsize */
b34976b6 1472 FALSE, /* pc_relative */
dc810e39 1473 0, /* bitpos */
beb1bf64 1474 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1475 0, /* special_function */
1476 "R_TOC", /* name */
b34976b6 1477 TRUE, /* partial_inplace */
a78eab4e 1478 0xffff, /* src_mask */
dc810e39 1479 0xffff, /* dst_mask */
b34976b6 1480 FALSE), /* pcrel_offset */
dc810e39 1481
cf9ab45b 1482 /* I don't really know what this is. */
38487e5e 1483 HOWTO (R_RTB, /* type */
dc810e39
AM
1484 1, /* rightshift */
1485 2, /* size (0 = byte, 1 = short, 2 = long) */
1486 32, /* bitsize */
b34976b6 1487 FALSE, /* pc_relative */
dc810e39 1488 0, /* bitpos */
beb1bf64 1489 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1490 0, /* special_function */
1491 "R_RTB", /* name */
b34976b6 1492 TRUE, /* partial_inplace */
a78eab4e 1493 0xffffffff, /* src_mask */
dc810e39 1494 0xffffffff, /* dst_mask */
b34976b6 1495 FALSE), /* pcrel_offset */
beb1bf64
TR
1496
1497 /* External TOC relative symbol. */
38487e5e 1498 HOWTO (R_GL, /* type */
dc810e39 1499 0, /* rightshift */
48bfecdd 1500 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1501 16, /* bitsize */
b34976b6 1502 FALSE, /* pc_relative */
dc810e39 1503 0, /* bitpos */
beb1bf64 1504 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1505 0, /* special_function */
1506 "R_GL", /* name */
b34976b6 1507 TRUE, /* partial_inplace */
a78eab4e 1508 0xffff, /* src_mask */
dc810e39 1509 0xffff, /* dst_mask */
b34976b6 1510 FALSE), /* pcrel_offset */
dc810e39
AM
1511
1512 /* Local TOC relative symbol. */
38487e5e 1513 HOWTO (R_TCL, /* type */
dc810e39 1514 0, /* rightshift */
48bfecdd 1515 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1516 16, /* bitsize */
b34976b6 1517 FALSE, /* pc_relative */
dc810e39 1518 0, /* bitpos */
beb1bf64 1519 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1520 0, /* special_function */
1521 "R_TCL", /* name */
b34976b6 1522 TRUE, /* partial_inplace */
a78eab4e 1523 0xffff, /* src_mask */
dc810e39 1524 0xffff, /* dst_mask */
b34976b6 1525 FALSE), /* pcrel_offset */
beb1bf64
TR
1526
1527 EMPTY_HOWTO (7),
1528
1529 /* Non modifiable absolute branch. */
38487e5e 1530 HOWTO (R_BA, /* type */
dc810e39
AM
1531 0, /* rightshift */
1532 2, /* size (0 = byte, 1 = short, 2 = long) */
1533 26, /* bitsize */
b34976b6 1534 FALSE, /* pc_relative */
dc810e39 1535 0, /* bitpos */
beb1bf64 1536 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39 1537 0, /* special_function */
59862849 1538 "R_BA_26", /* name */
b34976b6 1539 TRUE, /* partial_inplace */
a78eab4e 1540 0x03fffffc, /* src_mask */
48bfecdd 1541 0x03fffffc, /* dst_mask */
b34976b6 1542 FALSE), /* pcrel_offset */
beb1bf64
TR
1543
1544 EMPTY_HOWTO (9),
1545
1546 /* Non modifiable relative branch. */
38487e5e 1547 HOWTO (R_BR, /* type */
dc810e39
AM
1548 0, /* rightshift */
1549 2, /* size (0 = byte, 1 = short, 2 = long) */
1550 26, /* bitsize */
b34976b6 1551 TRUE, /* pc_relative */
dc810e39 1552 0, /* bitpos */
beb1bf64 1553 complain_overflow_signed, /* complain_on_overflow */
dc810e39
AM
1554 0, /* special_function */
1555 "R_BR", /* name */
b34976b6 1556 TRUE, /* partial_inplace */
a78eab4e 1557 0x03fffffc, /* src_mask */
48bfecdd 1558 0x03fffffc, /* dst_mask */
b34976b6 1559 FALSE), /* pcrel_offset */
beb1bf64
TR
1560
1561 EMPTY_HOWTO (0xb),
1562
1563 /* Indirect load. */
38487e5e 1564 HOWTO (R_RL, /* type */
dc810e39 1565 0, /* rightshift */
48bfecdd 1566 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1567 16, /* bitsize */
b34976b6 1568 FALSE, /* pc_relative */
dc810e39 1569 0, /* bitpos */
beb1bf64 1570 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1571 0, /* special_function */
1572 "R_RL", /* name */
b34976b6 1573 TRUE, /* partial_inplace */
a78eab4e 1574 0xffff, /* src_mask */
dc810e39 1575 0xffff, /* dst_mask */
b34976b6 1576 FALSE), /* pcrel_offset */
beb1bf64
TR
1577
1578 /* Load address. */
38487e5e 1579 HOWTO (R_RLA, /* type */
dc810e39 1580 0, /* rightshift */
48bfecdd 1581 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1582 16, /* bitsize */
b34976b6 1583 FALSE, /* pc_relative */
dc810e39 1584 0, /* bitpos */
beb1bf64 1585 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1586 0, /* special_function */
1587 "R_RLA", /* name */
b34976b6 1588 TRUE, /* partial_inplace */
a78eab4e 1589 0xffff, /* src_mask */
dc810e39 1590 0xffff, /* dst_mask */
b34976b6 1591 FALSE), /* pcrel_offset */
beb1bf64
TR
1592
1593 EMPTY_HOWTO (0xe),
1594
cf9ab45b 1595 /* Non-relocating reference. */
38487e5e 1596 HOWTO (R_REF, /* type */
dc810e39
AM
1597 0, /* rightshift */
1598 2, /* size (0 = byte, 1 = short, 2 = long) */
1599 32, /* bitsize */
b34976b6 1600 FALSE, /* pc_relative */
dc810e39 1601 0, /* bitpos */
a78eab4e 1602 complain_overflow_dont, /* complain_on_overflow */
dc810e39
AM
1603 0, /* special_function */
1604 "R_REF", /* name */
b34976b6 1605 FALSE, /* partial_inplace */
dc810e39
AM
1606 0, /* src_mask */
1607 0, /* dst_mask */
b34976b6 1608 FALSE), /* pcrel_offset */
beb1bf64
TR
1609
1610 EMPTY_HOWTO (0x10),
1611 EMPTY_HOWTO (0x11),
1612
1613 /* TOC relative indirect load. */
38487e5e 1614 HOWTO (R_TRL, /* type */
dc810e39 1615 0, /* rightshift */
48bfecdd 1616 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1617 16, /* bitsize */
b34976b6 1618 FALSE, /* pc_relative */
dc810e39 1619 0, /* bitpos */
beb1bf64 1620 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1621 0, /* special_function */
1622 "R_TRL", /* name */
b34976b6 1623 TRUE, /* partial_inplace */
a78eab4e 1624 0xffff, /* src_mask */
dc810e39 1625 0xffff, /* dst_mask */
b34976b6 1626 FALSE), /* pcrel_offset */
dc810e39
AM
1627
1628 /* TOC relative load address. */
38487e5e 1629 HOWTO (R_TRLA, /* type */
dc810e39 1630 0, /* rightshift */
48bfecdd 1631 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1632 16, /* bitsize */
b34976b6 1633 FALSE, /* pc_relative */
dc810e39 1634 0, /* bitpos */
beb1bf64 1635 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1636 0, /* special_function */
1637 "R_TRLA", /* name */
b34976b6 1638 TRUE, /* partial_inplace */
a78eab4e 1639 0xffff, /* src_mask */
dc810e39 1640 0xffff, /* dst_mask */
b34976b6 1641 FALSE), /* pcrel_offset */
beb1bf64
TR
1642
1643 /* Modifiable relative branch. */
38487e5e 1644 HOWTO (R_RRTBI, /* type */
dc810e39
AM
1645 1, /* rightshift */
1646 2, /* size (0 = byte, 1 = short, 2 = long) */
1647 32, /* bitsize */
b34976b6 1648 FALSE, /* pc_relative */
dc810e39 1649 0, /* bitpos */
beb1bf64 1650 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1651 0, /* special_function */
1652 "R_RRTBI", /* name */
b34976b6 1653 TRUE, /* partial_inplace */
a78eab4e 1654 0xffffffff, /* src_mask */
dc810e39 1655 0xffffffff, /* dst_mask */
b34976b6 1656 FALSE), /* pcrel_offset */
beb1bf64
TR
1657
1658 /* Modifiable absolute branch. */
38487e5e 1659 HOWTO (R_RRTBA, /* type */
dc810e39
AM
1660 1, /* rightshift */
1661 2, /* size (0 = byte, 1 = short, 2 = long) */
1662 32, /* bitsize */
b34976b6 1663 FALSE, /* pc_relative */
dc810e39 1664 0, /* bitpos */
beb1bf64 1665 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1666 0, /* special_function */
1667 "R_RRTBA", /* name */
b34976b6 1668 TRUE, /* partial_inplace */
a78eab4e 1669 0xffffffff, /* src_mask */
dc810e39 1670 0xffffffff, /* dst_mask */
b34976b6 1671 FALSE), /* pcrel_offset */
dc810e39
AM
1672
1673 /* Modifiable call absolute indirect. */
38487e5e 1674 HOWTO (R_CAI, /* type */
dc810e39 1675 0, /* rightshift */
48bfecdd 1676 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1677 16, /* bitsize */
b34976b6 1678 FALSE, /* pc_relative */
dc810e39 1679 0, /* bitpos */
beb1bf64 1680 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1681 0, /* special_function */
1682 "R_CAI", /* name */
b34976b6 1683 TRUE, /* partial_inplace */
a78eab4e 1684 0xffff, /* src_mask */
dc810e39 1685 0xffff, /* dst_mask */
b34976b6 1686 FALSE), /* pcrel_offset */
dc810e39 1687
cf9ab45b 1688 /* Modifiable call relative. */
38487e5e 1689 HOWTO (R_CREL, /* type */
dc810e39 1690 0, /* rightshift */
48bfecdd 1691 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1692 16, /* bitsize */
b34976b6 1693 FALSE, /* pc_relative */
dc810e39 1694 0, /* bitpos */
beb1bf64 1695 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1696 0, /* special_function */
1697 "R_CREL", /* name */
b34976b6 1698 TRUE, /* partial_inplace */
a78eab4e 1699 0xffff, /* src_mask */
dc810e39 1700 0xffff, /* dst_mask */
b34976b6 1701 FALSE), /* pcrel_offset */
beb1bf64
TR
1702
1703 /* Modifiable branch absolute. */
38487e5e 1704 HOWTO (R_RBA, /* type */
dc810e39
AM
1705 0, /* rightshift */
1706 2, /* size (0 = byte, 1 = short, 2 = long) */
1707 26, /* bitsize */
b34976b6 1708 FALSE, /* pc_relative */
dc810e39 1709 0, /* bitpos */
beb1bf64 1710 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1711 0, /* special_function */
1712 "R_RBA", /* name */
b34976b6 1713 TRUE, /* partial_inplace */
a78eab4e 1714 0x03fffffc, /* src_mask */
48bfecdd 1715 0x03fffffc, /* dst_mask */
b34976b6 1716 FALSE), /* pcrel_offset */
beb1bf64
TR
1717
1718 /* Modifiable branch absolute. */
38487e5e 1719 HOWTO (R_RBAC, /* type */
dc810e39
AM
1720 0, /* rightshift */
1721 2, /* size (0 = byte, 1 = short, 2 = long) */
1722 32, /* bitsize */
b34976b6 1723 FALSE, /* pc_relative */
dc810e39 1724 0, /* bitpos */
beb1bf64 1725 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1726 0, /* special_function */
1727 "R_RBAC", /* name */
b34976b6 1728 TRUE, /* partial_inplace */
a78eab4e 1729 0xffffffff, /* src_mask */
48bfecdd 1730 0xffffffff, /* dst_mask */
b34976b6 1731 FALSE), /* pcrel_offset */
beb1bf64
TR
1732
1733 /* Modifiable branch relative. */
38487e5e 1734 HOWTO (R_RBR, /* type */
dc810e39
AM
1735 0, /* rightshift */
1736 2, /* size (0 = byte, 1 = short, 2 = long) */
1737 26, /* bitsize */
b34976b6 1738 FALSE, /* pc_relative */
dc810e39 1739 0, /* bitpos */
beb1bf64 1740 complain_overflow_signed, /* complain_on_overflow */
dc810e39 1741 0, /* special_function */
59862849 1742 "R_RBR_26", /* name */
b34976b6 1743 TRUE, /* partial_inplace */
a78eab4e 1744 0x03fffffc, /* src_mask */
48bfecdd 1745 0x03fffffc, /* dst_mask */
b34976b6 1746 FALSE), /* pcrel_offset */
beb1bf64
TR
1747
1748 /* Modifiable branch absolute. */
38487e5e 1749 HOWTO (R_RBRC, /* type */
dc810e39 1750 0, /* rightshift */
48bfecdd 1751 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1752 16, /* bitsize */
b34976b6 1753 FALSE, /* pc_relative */
dc810e39 1754 0, /* bitpos */
beb1bf64 1755 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1756 0, /* special_function */
1757 "R_RBRC", /* name */
b34976b6 1758 TRUE, /* partial_inplace */
a78eab4e 1759 0xffff, /* src_mask */
dc810e39 1760 0xffff, /* dst_mask */
b34976b6 1761 FALSE), /* pcrel_offset */
dc810e39 1762
38487e5e 1763 HOWTO (R_POS, /* type */
dc810e39 1764 0, /* rightshift */
59862849
TR
1765 2, /* size (0 = byte, 1 = short, 2 = long) */
1766 32, /* bitsize */
b34976b6 1767 FALSE, /* pc_relative */
dc810e39
AM
1768 0, /* bitpos */
1769 complain_overflow_bitfield, /* complain_on_overflow */
1770 0, /* special_function */
59862849 1771 "R_POS_32", /* name */
b34976b6 1772 TRUE, /* partial_inplace */
a78eab4e 1773 0xffffffff, /* src_mask */
59862849 1774 0xffffffff, /* dst_mask */
b34976b6 1775 FALSE), /* pcrel_offset */
ff3a6ee3
TR
1776
1777 /* 16 bit Non modifiable absolute branch. */
54327882
AM
1778 HOWTO (R_BA, /* type */
1779 0, /* rightshift */
59862849 1780 1, /* size (0 = byte, 1 = short, 2 = long) */
54327882 1781 16, /* bitsize */
b34976b6 1782 FALSE, /* pc_relative */
54327882 1783 0, /* bitpos */
ff3a6ee3 1784 complain_overflow_bitfield, /* complain_on_overflow */
54327882 1785 0, /* special_function */
59862849 1786 "R_BA_16", /* name */
b34976b6 1787 TRUE, /* partial_inplace */
a78eab4e 1788 0xfffc, /* src_mask */
54327882 1789 0xfffc, /* dst_mask */
b34976b6 1790 FALSE), /* pcrel_offset */
59862849
TR
1791
1792 /* Modifiable branch relative. */
cf9ab45b
AM
1793 HOWTO (R_RBR, /* type */
1794 0, /* rightshift */
1795 1, /* size (0 = byte, 1 = short, 2 = long) */
1796 16, /* bitsize */
b34976b6 1797 FALSE, /* pc_relative */
cf9ab45b 1798 0, /* bitpos */
59862849 1799 complain_overflow_signed, /* complain_on_overflow */
cf9ab45b
AM
1800 0, /* special_function */
1801 "R_RBR_16", /* name */
b34976b6 1802 TRUE, /* partial_inplace */
cf9ab45b
AM
1803 0xffff, /* src_mask */
1804 0xffff, /* dst_mask */
b34976b6 1805 FALSE), /* pcrel_offset */
1b164155
TR
1806
1807 /* Modifiable branch absolute. */
1808 HOWTO (R_RBA, /* type */
1809 0, /* rightshift */
1810 1, /* size (0 = byte, 1 = short, 2 = long) */
1811 16, /* bitsize */
b34976b6 1812 FALSE, /* pc_relative */
1b164155
TR
1813 0, /* bitpos */
1814 complain_overflow_bitfield, /* complain_on_overflow */
1815 0, /* special_function */
1816 "R_RBA_16", /* name */
b34976b6 1817 TRUE, /* partial_inplace */
a78eab4e 1818 0xffff, /* src_mask */
1b164155 1819 0xffff, /* dst_mask */
b34976b6 1820 FALSE), /* pcrel_offset */
1b164155 1821
beb1bf64
TR
1822};
1823
1824void
1825xcoff64_rtype2howto (relent, internal)
1826 arelent *relent;
1827 struct internal_reloc *internal;
1828{
59862849 1829 if (internal->r_type > R_RBRC)
beb1bf64
TR
1830 abort ();
1831
59862849
TR
1832 /* Default howto layout works most of the time */
1833 relent->howto = &xcoff64_howto_table[internal->r_type];
cf9ab45b 1834
5c4491d3 1835 /* Special case some 16 bit reloc */
59862849
TR
1836 if (15 == (internal->r_size & 0x3f))
1837 {
cf9ab45b 1838 if (R_BA == internal->r_type)
59862849 1839 relent->howto = &xcoff64_howto_table[0x1d];
cf9ab45b 1840 else if (R_RBR == internal->r_type)
59862849 1841 relent->howto = &xcoff64_howto_table[0x1e];
cf9ab45b 1842 else if (R_RBA == internal->r_type)
1b164155 1843 relent->howto = &xcoff64_howto_table[0x1f];
59862849
TR
1844 }
1845 /* Special case 32 bit */
1846 else if (31 == (internal->r_size & 0x3f))
1847 {
cf9ab45b 1848 if (R_POS == internal->r_type)
59862849
TR
1849 relent->howto = &xcoff64_howto_table[0x1c];
1850 }
cf9ab45b 1851
beb1bf64
TR
1852 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1853 relocation, as well as indicating whether it is signed or not.
1854 Doublecheck that the relocation information gathered from the
1855 type matches this information. The bitsize is not significant
1856 for R_REF relocs. */
1857 if (relent->howto->dst_mask != 0
dc810e39 1858 && (relent->howto->bitsize
beb1bf64
TR
1859 != ((unsigned int) internal->r_size & 0x3f) + 1))
1860 abort ();
beb1bf64
TR
1861}
1862
1863reloc_howto_type *
1864xcoff64_reloc_type_lookup (abfd, code)
1865 bfd *abfd ATTRIBUTE_UNUSED;
1866 bfd_reloc_code_real_type code;
1867{
1868 switch (code)
1869 {
1870 case BFD_RELOC_PPC_B26:
1871 return &xcoff64_howto_table[0xa];
ff3a6ee3
TR
1872 case BFD_RELOC_PPC_BA16:
1873 return &xcoff64_howto_table[0x1d];
beb1bf64
TR
1874 case BFD_RELOC_PPC_BA26:
1875 return &xcoff64_howto_table[8];
1876 case BFD_RELOC_PPC_TOC16:
1877 return &xcoff64_howto_table[3];
1878 case BFD_RELOC_32:
1879 case BFD_RELOC_CTOR:
beb1bf64 1880 return &xcoff64_howto_table[0x1c];
59862849
TR
1881 case BFD_RELOC_64:
1882 return &xcoff64_howto_table[0];
beb1bf64
TR
1883 default:
1884 return NULL;
1885 }
1886}
1887
157090f7
AM
1888static reloc_howto_type *
1889xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1890 const char *r_name)
1891{
1892 unsigned int i;
1893
1894 for (i = 0;
1895 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1896 i++)
1897 if (xcoff64_howto_table[i].name != NULL
1898 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1899 return &xcoff64_howto_table[i];
1900
1901 return NULL;
1902}
1903
beb1bf64
TR
1904/* Read in the armap of an XCOFF archive. */
1905
b34976b6 1906static bfd_boolean
beb1bf64
TR
1907xcoff64_slurp_armap (abfd)
1908 bfd *abfd;
1909{
1910 file_ptr off;
1911 size_t namlen;
dc810e39 1912 bfd_size_type sz, amt;
beb1bf64
TR
1913 bfd_byte *contents, *cend;
1914 bfd_vma c, i;
1915 carsym *arsym;
1916 bfd_byte *p;
dc810e39 1917 file_ptr pos;
beb1bf64
TR
1918
1919 /* This is for the new format. */
1920 struct xcoff_ar_hdr_big hdr;
1921
dc810e39
AM
1922 if (xcoff_ardata (abfd) == NULL)
1923 {
b34976b6
AM
1924 bfd_has_map (abfd) = FALSE;
1925 return TRUE;
dc810e39 1926 }
beb1bf64 1927
487e54f2
AM
1928 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1929 (const char **) NULL, 10);
dc810e39
AM
1930 if (off == 0)
1931 {
b34976b6
AM
1932 bfd_has_map (abfd) = FALSE;
1933 return TRUE;
dc810e39 1934 }
beb1bf64
TR
1935
1936 if (bfd_seek (abfd, off, SEEK_SET) != 0)
b34976b6 1937 return FALSE;
beb1bf64
TR
1938
1939 /* The symbol table starts with a normal archive header. */
dc810e39
AM
1940 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1941 != SIZEOF_AR_HDR_BIG)
b34976b6 1942 return FALSE;
beb1bf64
TR
1943
1944 /* Skip the name (normally empty). */
1945 namlen = strtol (hdr.namlen, (char **) NULL, 10);
dc810e39
AM
1946 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1947 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
b34976b6 1948 return FALSE;
beb1bf64 1949
487e54f2 1950 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
beb1bf64
TR
1951
1952 /* Read in the entire symbol table. */
1953 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1954 if (contents == NULL)
b34976b6 1955 return FALSE;
dc810e39 1956 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
b34976b6 1957 return FALSE;
beb1bf64
TR
1958
1959 /* The symbol table starts with an eight byte count. */
dc810e39 1960 c = H_GET_64 (abfd, contents);
beb1bf64 1961
dc810e39
AM
1962 if (c * 8 >= sz)
1963 {
1964 bfd_set_error (bfd_error_bad_value);
b34976b6 1965 return FALSE;
dc810e39
AM
1966 }
1967 amt = c;
1968 amt *= sizeof (carsym);
1969 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
beb1bf64 1970 if (bfd_ardata (abfd)->symdefs == NULL)
b34976b6 1971 return FALSE;
dc810e39 1972
beb1bf64
TR
1973 /* After the count comes a list of eight byte file offsets. */
1974 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1975 i < c;
1976 ++i, ++arsym, p += 8)
dc810e39 1977 arsym->file_offset = H_GET_64 (abfd, p);
beb1bf64
TR
1978
1979 /* After the file offsets come null terminated symbol names. */
1980 cend = contents + sz;
1981 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1982 i < c;
1983 ++i, ++arsym, p += strlen ((char *) p) + 1)
1984 {
1985 if (p >= cend)
1986 {
1987 bfd_set_error (bfd_error_bad_value);
b34976b6 1988 return FALSE;
beb1bf64
TR
1989 }
1990 arsym->name = (char *) p;
1991 }
1992
1993 bfd_ardata (abfd)->symdef_count = c;
b34976b6 1994 bfd_has_map (abfd) = TRUE;
beb1bf64 1995
b34976b6 1996 return TRUE;
beb1bf64
TR
1997}
1998
1999
beb1bf64
TR
2000/* See if this is an NEW XCOFF archive. */
2001
814fa6ab 2002static const bfd_target *
beb1bf64
TR
2003xcoff64_archive_p (abfd)
2004 bfd *abfd;
2005{
487e54f2 2006 struct artdata *tdata_hold;
beb1bf64
TR
2007 char magic[SXCOFFARMAG];
2008 /* This is the new format. */
2009 struct xcoff_ar_file_hdr_big hdr;
dc810e39 2010 bfd_size_type amt = SXCOFFARMAG;
beb1bf64 2011
dc810e39
AM
2012 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2013 {
2014 if (bfd_get_error () != bfd_error_system_call)
2015 bfd_set_error (bfd_error_wrong_format);
2016 return NULL;
2017 }
2018
2019 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2020 {
2021 bfd_set_error (bfd_error_wrong_format);
2022 return NULL;
2023 }
beb1bf64 2024
beb1bf64
TR
2025 /* Copy over the magic string. */
2026 memcpy (hdr.magic, magic, SXCOFFARMAG);
2027
2028 /* Now read the rest of the file header. */
487e54f2
AM
2029 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2030 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
dc810e39
AM
2031 {
2032 if (bfd_get_error () != bfd_error_system_call)
2033 bfd_set_error (bfd_error_wrong_format);
2034 return NULL;
2035 }
beb1bf64 2036
487e54f2
AM
2037 tdata_hold = bfd_ardata (abfd);
2038
2039 amt = sizeof (struct artdata);
2040 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2041 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2042 goto error_ret_restore;
2043
9e492e05
JJ
2044 /* Already cleared by bfd_zalloc above.
2045 bfd_ardata (abfd)->cache = NULL;
2046 bfd_ardata (abfd)->archive_head = NULL;
2047 bfd_ardata (abfd)->symdefs = NULL;
2048 bfd_ardata (abfd)->extended_names = NULL;
2049 bfd_ardata (abfd)->extended_names_size = 0; */
487e54f2
AM
2050 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2051 (const char **) NULL,
2052 10);
beb1bf64 2053
dc810e39
AM
2054 amt = SIZEOF_AR_FILE_HDR_BIG;
2055 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
beb1bf64 2056 if (bfd_ardata (abfd)->tdata == NULL)
487e54f2 2057 goto error_ret;
dc810e39 2058
beb1bf64
TR
2059 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2060
dc810e39
AM
2061 if (! xcoff64_slurp_armap (abfd))
2062 {
487e54f2 2063 error_ret:
dc810e39 2064 bfd_release (abfd, bfd_ardata (abfd));
487e54f2
AM
2065 error_ret_restore:
2066 bfd_ardata (abfd) = tdata_hold;
dc810e39
AM
2067 return NULL;
2068 }
beb1bf64
TR
2069
2070 return abfd->xvec;
2071}
2072
2073
2074/* Open the next element in an XCOFF archive. */
2075
814fa6ab 2076static bfd *
beb1bf64
TR
2077xcoff64_openr_next_archived_file (archive, last_file)
2078 bfd *archive;
2079 bfd *last_file;
2080{
cf3d882d 2081 bfd_vma filestart;
beb1bf64 2082
dc810e39
AM
2083 if ((xcoff_ardata (archive) == NULL)
2084 || ! xcoff_big_format_p (archive))
2085 {
2086 bfd_set_error (bfd_error_invalid_operation);
2087 return NULL;
2088 }
beb1bf64 2089
dc810e39
AM
2090 if (last_file == NULL)
2091 {
beb1bf64 2092 filestart = bfd_ardata (archive)->first_file_filepos;
dc810e39
AM
2093 }
2094 else
2095 {
487e54f2
AM
2096 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2097 (const char **) NULL, 10);
dc810e39 2098 }
487e54f2 2099
beb1bf64 2100 if (filestart == 0
487e54f2
AM
2101 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2102 (const char **) NULL, 10)
2103 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2104 (const char **) NULL, 10))
dc810e39
AM
2105 {
2106 bfd_set_error (bfd_error_no_more_archived_files);
2107 return NULL;
2108 }
beb1bf64 2109
cf3d882d 2110 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
beb1bf64
TR
2111}
2112
2113/* We can't use the usual coff_sizeof_headers routine, because AIX
2114 always uses an a.out header. */
2115
814fa6ab 2116static int
a6b96beb
AM
2117xcoff64_sizeof_headers (bfd *abfd,
2118 struct bfd_link_info *info ATTRIBUTE_UNUSED)
beb1bf64
TR
2119{
2120 int size;
2121
dc810e39 2122 size = bfd_coff_filhsz (abfd);
beb1bf64 2123
08da05b0 2124 /* Don't think the small aout header can be used since some of the
dc810e39
AM
2125 old elements have been reordered past the end of the old coff
2126 small aout size. */
beb1bf64
TR
2127
2128 if (xcoff_data (abfd)->full_aouthdr)
dc810e39 2129 size += bfd_coff_aoutsz (abfd);
beb1bf64 2130
dc810e39 2131 size += abfd->section_count * bfd_coff_scnhsz (abfd);
beb1bf64
TR
2132 return size;
2133}
2134
2135
2136
2137static asection *
dc810e39 2138xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
beb1bf64
TR
2139 bfd *abfd;
2140 union internal_auxent *aux;
2141 const char *symbol_name;
2142{
2143 asection *return_value = NULL;
2144
dc810e39
AM
2145 /* Changes from 32 :
2146 .sv == 8, is only for 32 bit programs
2147 .ti == 12 and .tb == 13 are now reserved. */
2148 static const char *names[19] =
2149 {
beb1bf64
TR
2150 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2151 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
dc810e39 2152 ".td", ".sv64", ".sv3264"
beb1bf64
TR
2153 };
2154
dc810e39
AM
2155 if ((19 >= aux->x_csect.x_smclas)
2156 && (NULL != names[aux->x_csect.x_smclas]))
2157 {
beb1bf64 2158
dc810e39
AM
2159 return_value = bfd_make_section_anyway
2160 (abfd, names[aux->x_csect.x_smclas]);
beb1bf64 2161
dc810e39
AM
2162 }
2163 else
2164 {
2165 (*_bfd_error_handler)
d003868e
AM
2166 (_("%B: symbol `%s' has unrecognized smclas %d"),
2167 abfd, symbol_name, aux->x_csect.x_smclas);
dc810e39
AM
2168 bfd_set_error (bfd_error_bad_value);
2169 }
beb1bf64
TR
2170
2171 return return_value;
2172}
2173
b34976b6 2174static bfd_boolean
beb1bf64 2175xcoff64_is_lineno_count_overflow (abfd, value)
dc810e39
AM
2176 bfd *abfd ATTRIBUTE_UNUSED;
2177 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2178{
b34976b6 2179 return FALSE;
beb1bf64
TR
2180}
2181
b34976b6 2182static bfd_boolean
beb1bf64 2183xcoff64_is_reloc_count_overflow (abfd, value)
dc810e39
AM
2184 bfd *abfd ATTRIBUTE_UNUSED;
2185 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2186{
b34976b6 2187 return FALSE;
beb1bf64
TR
2188}
2189
814fa6ab 2190static bfd_vma
beb1bf64 2191xcoff64_loader_symbol_offset (abfd, ldhdr)
dc810e39
AM
2192 bfd *abfd ATTRIBUTE_UNUSED;
2193 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2194{
2195 return (ldhdr->l_symoff);
2196}
2197
814fa6ab 2198static bfd_vma
beb1bf64 2199xcoff64_loader_reloc_offset (abfd, ldhdr)
dc810e39
AM
2200 bfd *abfd ATTRIBUTE_UNUSED;
2201 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2202{
2203 return (ldhdr->l_rldoff);
2204}
2205
b34976b6 2206static bfd_boolean
eb1e0e80
NC
2207xcoff64_bad_format_hook (abfd, filehdr)
2208 bfd * abfd;
2209 PTR filehdr;
2210{
2211 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2212
2213 /* Check flavor first. */
2214 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
b34976b6 2215 return FALSE;
eb1e0e80
NC
2216
2217 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
b34976b6 2218 return FALSE;
eb1e0e80 2219
b34976b6 2220 return TRUE;
eb1e0e80
NC
2221}
2222
b34976b6 2223static bfd_boolean
69f284c7 2224xcoff64_generate_rtinit (abfd, init, fini, rtld)
9a4c7f16
TR
2225 bfd *abfd;
2226 const char *init;
2227 const char *fini;
b34976b6 2228 bfd_boolean rtld;
9a4c7f16
TR
2229{
2230 bfd_byte filehdr_ext[FILHSZ];
69f284c7
TR
2231 bfd_byte scnhdr_ext[SCNHSZ * 3];
2232 bfd_byte syment_ext[SYMESZ * 10];
2233 bfd_byte reloc_ext[RELSZ * 3];
9a4c7f16
TR
2234 bfd_byte *data_buffer;
2235 bfd_size_type data_buffer_size;
2236 bfd_byte *string_table, *st_tmp;
2237 bfd_size_type string_table_size;
2238 bfd_vma val;
2239 size_t initsz, finisz;
2240 struct internal_filehdr filehdr;
69f284c7
TR
2241 struct internal_scnhdr text_scnhdr;
2242 struct internal_scnhdr data_scnhdr;
2243 struct internal_scnhdr bss_scnhdr;
9a4c7f16
TR
2244 struct internal_syment syment;
2245 union internal_auxent auxent;
2246 struct internal_reloc reloc;
54327882 2247
69f284c7 2248 char *text_name = ".text";
9a4c7f16 2249 char *data_name = ".data";
69f284c7 2250 char *bss_name = ".bss";
9a4c7f16 2251 char *rtinit_name = "__rtinit";
69f284c7 2252 char *rtld_name = "__rtld";
54327882 2253
69f284c7 2254 if (! bfd_xcoff_rtinit_size (abfd))
b34976b6 2255 return FALSE;
9a4c7f16
TR
2256
2257 initsz = (init == NULL ? 0 : 1 + strlen (init));
2258 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2259
eb1e0e80 2260 /* File header. */
9a4c7f16
TR
2261 memset (filehdr_ext, 0, FILHSZ);
2262 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2263 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
54327882 2264 filehdr.f_nscns = 3;
9a4c7f16
TR
2265 filehdr.f_timdat = 0;
2266 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2267 filehdr.f_symptr = 0; /* set below */
2268 filehdr.f_opthdr = 0;
2269 filehdr.f_flags = 0;
2270
eb1e0e80 2271 /* Section headers. */
69f284c7
TR
2272 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2273
eb1e0e80 2274 /* Text. */
69f284c7
TR
2275 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2276 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2277 text_scnhdr.s_paddr = 0;
2278 text_scnhdr.s_vaddr = 0;
2279 text_scnhdr.s_size = 0;
2280 text_scnhdr.s_scnptr = 0;
2281 text_scnhdr.s_relptr = 0;
2282 text_scnhdr.s_lnnoptr = 0;
2283 text_scnhdr.s_nreloc = 0;
2284 text_scnhdr.s_nlnno = 0;
2285 text_scnhdr.s_flags = STYP_TEXT;
2286
eb1e0e80 2287 /* Data. */
69f284c7
TR
2288 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2289 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2290 data_scnhdr.s_paddr = 0;
2291 data_scnhdr.s_vaddr = 0;
2292 data_scnhdr.s_size = 0; /* set below */
2293 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2294 data_scnhdr.s_relptr = 0; /* set below */
2295 data_scnhdr.s_lnnoptr = 0;
2296 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2297 data_scnhdr.s_nlnno = 0;
2298 data_scnhdr.s_flags = STYP_DATA;
2299
eb1e0e80 2300 /* Bss. */
69f284c7
TR
2301 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2302 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2303 bss_scnhdr.s_paddr = 0; /* set below */
2304 bss_scnhdr.s_vaddr = 0; /* set below */
2305 bss_scnhdr.s_size = 0; /* set below */
2306 bss_scnhdr.s_scnptr = 0;
54327882 2307 bss_scnhdr.s_relptr = 0;
69f284c7
TR
2308 bss_scnhdr.s_lnnoptr = 0;
2309 bss_scnhdr.s_nreloc = 0;
2310 bss_scnhdr.s_nlnno = 0;
2311 bss_scnhdr.s_flags = STYP_BSS;
9a4c7f16 2312
54327882 2313 /* .data
cf9ab45b
AM
2314 0x0000 0x00000000 : rtl
2315 0x0004 0x00000000 :
2316 0x0008 0x00000018 : offset to init, or 0
2317 0x000C 0x00000038 : offset to fini, or 0
2318 0x0010 0x00000010 : size of descriptor
2319 0x0014 0x00000000 : pad
2320 0x0018 0x00000000 : init, needs a reloc
2321 0x001C 0x00000000 :
2322 0x0020 0x00000058 : offset to init name
2323 0x0024 0x00000000 : flags, padded to a word
2324 0x0028 0x00000000 : empty init
2325 0x002C 0x00000000 :
2326 0x0030 0x00000000 :
2327 0x0034 0x00000000 :
2328 0x0038 0x00000000 : fini, needs a reloc
2329 0x003C 0x00000000 :
2330 0x0040 0x00000??? : offset to fini name
2331 0x0044 0x00000000 : flags, padded to a word
2332 0x0048 0x00000000 : empty fini
2333 0x004C 0x00000000 :
2334 0x0050 0x00000000 :
2335 0x0054 0x00000000 :
2336 0x0058 init name
9a4c7f16
TR
2337 0x0058 + initsz fini name */
2338
2339 data_buffer_size = 0x0058 + initsz + finisz;
2a52da53 2340 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
330693f5 2341 data_buffer = NULL;
9bab7074 2342 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
330693f5 2343 if (data_buffer == NULL)
b34976b6 2344 return FALSE;
54327882 2345
54327882 2346 if (initsz)
9a4c7f16
TR
2347 {
2348 val = 0x18;
2349 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2350 val = 0x58;
2351 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2352 memcpy (&data_buffer[val], init, initsz);
2353 }
2354
54327882 2355 if (finisz)
9a4c7f16
TR
2356 {
2357 val = 0x38;
2358 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2359 val = 0x58 + initsz;
2360 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2361 memcpy (&data_buffer[val], fini, finisz);
2362 }
2363
2364 val = 0x10;
2365 bfd_put_32 (abfd, val, &data_buffer[0x10]);
69f284c7
TR
2366 data_scnhdr.s_size = data_buffer_size;
2367 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
9a4c7f16 2368
eb1e0e80 2369 /* String table. */
9a4c7f16
TR
2370 string_table_size = 4;
2371 string_table_size += strlen (data_name) + 1;
2372 string_table_size += strlen (rtinit_name) + 1;
2373 string_table_size += initsz;
2374 string_table_size += finisz;
cf9ab45b 2375 if (rtld)
69f284c7 2376 string_table_size += strlen (rtld_name) + 1;
9a4c7f16 2377
9bab7074
AM
2378 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2379 if (string_table == NULL)
b34976b6 2380 return FALSE;
9bab7074 2381
9a4c7f16
TR
2382 val = string_table_size;
2383 bfd_put_32 (abfd, val, &string_table[0]);
2384 st_tmp = string_table + 4;
54327882
AM
2385
2386 /* symbols
9a4c7f16
TR
2387 0. .data csect
2388 2. __rtinit
54327882
AM
2389 4. init function
2390 6. fini function
69f284c7
TR
2391 8. __rtld */
2392 memset (syment_ext, 0, 10 * SYMESZ);
2393 memset (reloc_ext, 0, 3 * RELSZ);
9a4c7f16
TR
2394
2395 /* .data csect */
2396 memset (&syment, 0, sizeof (struct internal_syment));
2397 memset (&auxent, 0, sizeof (union internal_auxent));
2398
2399 syment._n._n_n._n_offset = st_tmp - string_table;
2400 memcpy (st_tmp, data_name, strlen (data_name));
2401 st_tmp += strlen (data_name) + 1;
2402
69f284c7 2403 syment.n_scnum = 2;
9a4c7f16
TR
2404 syment.n_sclass = C_HIDEXT;
2405 syment.n_numaux = 1;
2406 auxent.x_csect.x_scnlen.l = data_buffer_size;
2407 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2408 auxent.x_csect.x_smclas = XMC_RW;
54327882 2409 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2410 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2411 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2412 syment.n_numaux,
9a4c7f16
TR
2413 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2414 filehdr.f_nsyms += 2;
2415
2416 /* __rtinit */
2417 memset (&syment, 0, sizeof (struct internal_syment));
2418 memset (&auxent, 0, sizeof (union internal_auxent));
2419 syment._n._n_n._n_offset = st_tmp - string_table;
2420 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2421 st_tmp += strlen (rtinit_name) + 1;
54327882 2422
69f284c7 2423 syment.n_scnum = 2;
9a4c7f16
TR
2424 syment.n_sclass = C_EXT;
2425 syment.n_numaux = 1;
2426 auxent.x_csect.x_smtyp = XTY_LD;
2427 auxent.x_csect.x_smclas = XMC_RW;
54327882 2428 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2429 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2430 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2431 syment.n_numaux,
9a4c7f16
TR
2432 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2433 filehdr.f_nsyms += 2;
2434
eb1e0e80 2435 /* Init. */
54327882 2436 if (initsz)
9a4c7f16
TR
2437 {
2438 memset (&syment, 0, sizeof (struct internal_syment));
2439 memset (&auxent, 0, sizeof (union internal_auxent));
2440
2441 syment._n._n_n._n_offset = st_tmp - string_table;
2442 memcpy (st_tmp, init, initsz);
2443 st_tmp += initsz;
2444
2445 syment.n_sclass = C_EXT;
2446 syment.n_numaux = 1;
54327882 2447 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2448 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2449 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2450 syment.n_numaux,
9a4c7f16 2451 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
eb1e0e80 2452 /* Reloc. */
9a4c7f16
TR
2453 memset (&reloc, 0, sizeof (struct internal_reloc));
2454 reloc.r_vaddr = 0x0018;
2455 reloc.r_symndx = filehdr.f_nsyms;
2456 reloc.r_type = R_POS;
2457 reloc.r_size = 63;
2458 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2459
2460 filehdr.f_nsyms += 2;
69f284c7 2461 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2462 }
2463
eb1e0e80 2464 /* Finit. */
54327882 2465 if (finisz)
9a4c7f16
TR
2466 {
2467 memset (&syment, 0, sizeof (struct internal_syment));
2468 memset (&auxent, 0, sizeof (union internal_auxent));
2469
2470 syment._n._n_n._n_offset = st_tmp - string_table;
2471 memcpy (st_tmp, fini, finisz);
2472 st_tmp += finisz;
2473
2474 syment.n_sclass = C_EXT;
2475 syment.n_numaux = 1;
54327882 2476 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2477 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2478 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2479 syment.n_numaux,
9a4c7f16
TR
2480 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2481
eb1e0e80 2482 /* Reloc. */
9a4c7f16
TR
2483 memset (&reloc, 0, sizeof (struct internal_reloc));
2484 reloc.r_vaddr = 0x0038;
2485 reloc.r_symndx = filehdr.f_nsyms;
2486 reloc.r_type = R_POS;
2487 reloc.r_size = 63;
54327882 2488 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7 2489 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
9a4c7f16
TR
2490
2491 filehdr.f_nsyms += 2;
69f284c7 2492 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2493 }
2494
69f284c7
TR
2495 if (rtld)
2496 {
2497 memset (&syment, 0, sizeof (struct internal_syment));
2498 memset (&auxent, 0, sizeof (union internal_auxent));
2499
2500 syment._n._n_n._n_offset = st_tmp - string_table;
2501 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2502 st_tmp += strlen (rtld_name) + 1;
2503
2504 syment.n_sclass = C_EXT;
2505 syment.n_numaux = 1;
54327882 2506 bfd_coff_swap_sym_out (abfd, &syment,
69f284c7 2507 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2508 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2509 syment.n_numaux,
69f284c7
TR
2510 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2511
eb1e0e80 2512 /* Reloc. */
69f284c7
TR
2513 memset (&reloc, 0, sizeof (struct internal_reloc));
2514 reloc.r_vaddr = 0x0000;
2515 reloc.r_symndx = filehdr.f_nsyms;
2516 reloc.r_type = R_POS;
2517 reloc.r_size = 63;
54327882 2518 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7
TR
2519 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2520
2521 filehdr.f_nsyms += 2;
2522 data_scnhdr.s_nreloc += 1;
2523
2524 bss_scnhdr.s_size = 0;
2525 }
2526
2527 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2528 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
9a4c7f16
TR
2529
2530 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2531 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
69f284c7
TR
2532 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2533 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2534 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2535 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
9a4c7f16 2536 bfd_bwrite (data_buffer, data_buffer_size, abfd);
69f284c7 2537 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
9a4c7f16
TR
2538 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2539 bfd_bwrite (string_table, string_table_size, abfd);
2540
330693f5
TR
2541 free (data_buffer);
2542 data_buffer = NULL;
2543
b34976b6 2544 return TRUE;
9a4c7f16
TR
2545}
2546
beb1bf64
TR
2547/* The typical dynamic reloc. */
2548
2549static reloc_howto_type xcoff64_dynamic_reloc =
dc810e39
AM
2550HOWTO (0, /* type */
2551 0, /* rightshift */
2552 4, /* size (0 = byte, 1 = short, 2 = long) */
2553 64, /* bitsize */
b34976b6 2554 FALSE, /* pc_relative */
dc810e39
AM
2555 0, /* bitpos */
2556 complain_overflow_bitfield, /* complain_on_overflow */
2557 0, /* special_function */
2558 "R_POS", /* name */
b34976b6 2559 TRUE, /* partial_inplace */
dc810e39
AM
2560 MINUS_ONE, /* src_mask */
2561 MINUS_ONE, /* dst_mask */
b34976b6 2562 FALSE); /* pcrel_offset */
beb1bf64
TR
2563
2564static unsigned long xcoff64_glink_code[10] =
2565{
54327882
AM
2566 0xe9820000, /* ld r12,0(r2) */
2567 0xf8410028, /* std r2,40(r1) */
2568 0xe80c0000, /* ld r0,0(r12) */
2569 0xe84c0008, /* ld r0,8(r12) */
2570 0x7c0903a6, /* mtctr r0 */
2571 0x4e800420, /* bctr */
2572 0x00000000, /* start of traceback table */
2573 0x000ca000, /* traceback table */
2574 0x00000000, /* traceback table */
2575 0x00000018, /* ??? */
beb1bf64
TR
2576};
2577
dc810e39 2578static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
cf9ab45b
AM
2579 {
2580 { /* COFF backend, defined in libcoff.h. */
2581 _bfd_xcoff64_swap_aux_in,
2582 _bfd_xcoff64_swap_sym_in,
2583 _bfd_xcoff64_swap_lineno_in,
2584 _bfd_xcoff64_swap_aux_out,
2585 _bfd_xcoff64_swap_sym_out,
2586 _bfd_xcoff64_swap_lineno_out,
2587 xcoff64_swap_reloc_out,
2588 coff_swap_filehdr_out,
2589 coff_swap_aouthdr_out,
2590 coff_swap_scnhdr_out,
2591 FILHSZ,
2592 AOUTSZ,
2593 SCNHSZ,
2594 SYMESZ,
2595 AUXESZ,
2596 RELSZ,
2597 LINESZ,
2598 FILNMLEN,
b34976b6 2599 TRUE, /* _bfd_coff_long_filenames */
88183869 2600 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 2601 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2602 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2603 4, /* _bfd_coff_debug_string_prefix_length */
2604 coff_swap_filehdr_in,
2605 coff_swap_aouthdr_in,
2606 coff_swap_scnhdr_in,
2607 xcoff64_swap_reloc_in,
2608 xcoff64_bad_format_hook,
2609 coff_set_arch_mach_hook,
2610 coff_mkobject_hook,
2611 styp_to_sec_flags,
2612 coff_set_alignment_hook,
2613 coff_slurp_symbol_table,
2614 symname_in_debug_hook,
2615 coff_pointerize_aux_hook,
2616 coff_print_aux,
2617 dummy_reloc16_extra_cases,
2618 dummy_reloc16_estimate,
e144674a 2619 NULL, /* bfd_coff_symbol_classification */
cf9ab45b
AM
2620 coff_compute_section_file_positions,
2621 NULL, /* _bfd_coff_start_final_link */
2622 xcoff64_ppc_relocate_section,
2623 coff_rtype_to_howto,
2624 NULL, /* _bfd_coff_adjust_symndx */
2625 _bfd_generic_link_add_one_symbol,
2626 coff_link_output_has_begun,
2b5c217d
NC
2627 coff_final_link_postscript,
2628 NULL /* print_pdata. */
cf9ab45b
AM
2629 },
2630
2631 0x01EF, /* magic number */
2632 bfd_arch_powerpc,
2633 bfd_mach_ppc_620,
2634
2635 /* Function pointers to xcoff specific swap routines. */
2636 xcoff64_swap_ldhdr_in,
2637 xcoff64_swap_ldhdr_out,
2638 xcoff64_swap_ldsym_in,
2639 xcoff64_swap_ldsym_out,
2640 xcoff64_swap_ldrel_in,
2641 xcoff64_swap_ldrel_out,
2642
2643 /* Sizes. */
2644 LDHDRSZ,
2645 LDSYMSZ,
2646 LDRELSZ,
2647 24, /* _xcoff_function_descriptor_size */
2648 0, /* _xcoff_small_aout_header_size */
2649
2650 /* Versions. */
2651 2, /* _xcoff_ldhdr_version */
2652
2653 _bfd_xcoff64_put_symbol_name,
2654 _bfd_xcoff64_put_ldsymbol_name,
2655 &xcoff64_dynamic_reloc,
2656 xcoff64_create_csect_from_smclas,
2657
2658 /* Lineno and reloc count overflow. */
2659 xcoff64_is_lineno_count_overflow,
2660 xcoff64_is_reloc_count_overflow,
2661
2662 xcoff64_loader_symbol_offset,
2663 xcoff64_loader_reloc_offset,
2664
2665 /* glink. */
2666 &xcoff64_glink_code[0],
2667 40, /* _xcoff_glink_size */
2668
2669 /* rtinit. */
2670 88, /* _xcoff_rtinit_size */
2671 xcoff64_generate_rtinit,
2672 };
beb1bf64 2673
eb1e0e80 2674/* The transfer vector that leads the outside world to all of the above. */
beb1bf64 2675const bfd_target rs6000coff64_vec =
cf9ab45b
AM
2676 {
2677 "aixcoff64-rs6000",
2678 bfd_target_xcoff_flavour,
2679 BFD_ENDIAN_BIG, /* data byte order is big */
2680 BFD_ENDIAN_BIG, /* header byte order is big */
2681
2682 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2683 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2684
a7c71b0c 2685 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2686 0, /* leading char */
2687 '/', /* ar_pad_char */
2688 15, /* ar_max_namelen */
2689
2690 /* data */
2691 bfd_getb64,
2692 bfd_getb_signed_64,
2693 bfd_putb64,
2694 bfd_getb32,
2695 bfd_getb_signed_32,
2696 bfd_putb32,
2697 bfd_getb16,
2698 bfd_getb_signed_16,
2699 bfd_putb16,
2700
2701 /* hdrs */
2702 bfd_getb64,
2703 bfd_getb_signed_64,
2704 bfd_putb64,
2705 bfd_getb32,
2706 bfd_getb_signed_32,
2707 bfd_putb32,
2708 bfd_getb16,
2709 bfd_getb_signed_16,
2710 bfd_putb16,
2711
2712 { /* bfd_check_format */
2713 _bfd_dummy_target,
2714 coff_object_p,
2715 xcoff64_archive_p,
2716 CORE_FILE_P
2717 },
2718
2719 { /* bfd_set_format */
2720 bfd_false,
2721 coff_mkobject,
2722 _bfd_generic_mkarchive,
2723 bfd_false
2724 },
2725
2726 {/* bfd_write_contents */
2727 bfd_false,
2728 xcoff64_write_object_contents,
2729 _bfd_xcoff_write_archive_contents,
2730 bfd_false
2731 },
2732
2733 /* Generic */
2734 bfd_true,
2735 bfd_true,
2736 coff_new_section_hook,
2737 _bfd_generic_get_section_contents,
2738 _bfd_generic_get_section_contents_in_window,
2739
2740 /* Copy */
2741 _bfd_xcoff_copy_private_bfd_data,
b34976b6 2742 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
60b48850 2743 _bfd_generic_init_private_section_data,
b34976b6
AM
2744 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2745 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
80fccad2 2746 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
b34976b6
AM
2747 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2748 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
cf9ab45b
AM
2749
2750 /* Core */
2751 coff_core_file_failing_command,
2752 coff_core_file_failing_signal,
2753 coff_core_file_matches_executable_p,
2754
2755 /* Archive */
2756 xcoff64_slurp_armap,
dc810e39 2757 bfd_false,
b34976b6 2758 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
cf9ab45b
AM
2759 bfd_dont_truncate_arname,
2760 _bfd_xcoff_write_armap,
2761 _bfd_xcoff_read_ar_hdr,
2762 xcoff64_openr_next_archived_file,
2763 _bfd_generic_get_elt_at_index,
2764 _bfd_xcoff_stat_arch_elt,
2765 bfd_true,
2766
2767 /* Symbols */
2768 coff_get_symtab_upper_bound,
6cee3f79 2769 coff_canonicalize_symtab,
cf9ab45b
AM
2770 coff_make_empty_symbol,
2771 coff_print_symbol,
2772 coff_get_symbol_info,
2773 _bfd_xcoff_is_local_label_name,
7db6994f 2774 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
2775 coff_get_lineno,
2776 coff_find_nearest_line,
4575b1b5 2777 _bfd_generic_find_line,
4ab527b0 2778 coff_find_inliner_info,
cf9ab45b
AM
2779 coff_bfd_make_debug_symbol,
2780 _bfd_generic_read_minisymbols,
2781 _bfd_generic_minisymbol_to_symbol,
2782
2783 /* Reloc */
2784 coff_get_reloc_upper_bound,
2785 coff_canonicalize_reloc,
2786 xcoff64_reloc_type_lookup,
157090f7 2787 xcoff64_reloc_name_lookup,
cf9ab45b
AM
2788
2789 /* Write */
2790 coff_set_arch_mach,
2791 coff_set_section_contents,
2792
2793 /* Link */
2794 xcoff64_sizeof_headers,
2795 bfd_generic_get_relocated_section_contents,
2796 bfd_generic_relax_section,
2797 _bfd_xcoff_bfd_link_hash_table_create,
2798 _bfd_generic_link_hash_table_free,
2799 _bfd_xcoff_bfd_link_add_symbols,
2800 _bfd_generic_link_just_syms,
2801 _bfd_xcoff_bfd_final_link,
2802 _bfd_generic_link_split_section,
2803 bfd_generic_gc_sections,
2804 bfd_generic_merge_sections,
72adc230 2805 bfd_generic_is_group_section,
cf9ab45b 2806 bfd_generic_discard_group,
082b7297 2807 _bfd_generic_section_already_linked,
3023e3f6 2808 _bfd_xcoff_define_common_symbol,
cf9ab45b
AM
2809
2810 /* Dynamic */
2811 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2812 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 2813 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
2814 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2815 _bfd_xcoff_canonicalize_dynamic_reloc,
2816
2817 /* Opposite endian version, none exists */
2818 NULL,
2819
2820 (void *) &bfd_xcoff_backend_data,
2821 };
eb1e0e80 2822
b34976b6
AM
2823extern const bfd_target *xcoff64_core_p
2824 PARAMS ((bfd *));
2825extern bfd_boolean xcoff64_core_file_matches_executable_p
2826 PARAMS ((bfd *, bfd *));
2827extern char *xcoff64_core_file_failing_command
2828 PARAMS ((bfd *));
2829extern int xcoff64_core_file_failing_signal
2830 PARAMS ((bfd *));
eb1e0e80
NC
2831
2832/* AIX 5 */
54327882 2833static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
cf9ab45b
AM
2834 {
2835 { /* COFF backend, defined in libcoff.h. */
2836 _bfd_xcoff64_swap_aux_in,
2837 _bfd_xcoff64_swap_sym_in,
2838 _bfd_xcoff64_swap_lineno_in,
2839 _bfd_xcoff64_swap_aux_out,
2840 _bfd_xcoff64_swap_sym_out,
2841 _bfd_xcoff64_swap_lineno_out,
2842 xcoff64_swap_reloc_out,
2843 coff_swap_filehdr_out,
2844 coff_swap_aouthdr_out,
2845 coff_swap_scnhdr_out,
2846 FILHSZ,
2847 AOUTSZ,
2848 SCNHSZ,
2849 SYMESZ,
2850 AUXESZ,
2851 RELSZ,
2852 LINESZ,
2853 FILNMLEN,
b34976b6 2854 TRUE, /* _bfd_coff_long_filenames */
88183869 2855 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 2856 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2857 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2858 4, /* _bfd_coff_debug_string_prefix_length */
2859 coff_swap_filehdr_in,
2860 coff_swap_aouthdr_in,
2861 coff_swap_scnhdr_in,
2862 xcoff64_swap_reloc_in,
2863 xcoff64_bad_format_hook,
2864 coff_set_arch_mach_hook,
2865 coff_mkobject_hook,
2866 styp_to_sec_flags,
2867 coff_set_alignment_hook,
2868 coff_slurp_symbol_table,
2869 symname_in_debug_hook,
2870 coff_pointerize_aux_hook,
2871 coff_print_aux,
2872 dummy_reloc16_extra_cases,
2873 dummy_reloc16_estimate,
2874 NULL, /* bfd_coff_sym_is_global */
2875 coff_compute_section_file_positions,
2876 NULL, /* _bfd_coff_start_final_link */
2877 xcoff64_ppc_relocate_section,
2878 coff_rtype_to_howto,
2879 NULL, /* _bfd_coff_adjust_symndx */
2880 _bfd_generic_link_add_one_symbol,
2881 coff_link_output_has_begun,
2b5c217d
NC
2882 coff_final_link_postscript,
2883 NULL /* print_pdata. */
cf9ab45b
AM
2884 },
2885
2886 U64_TOCMAGIC, /* magic number */
2887 bfd_arch_powerpc,
2888 bfd_mach_ppc_620,
2889
2890 /* Function pointers to xcoff specific swap routines. */
2891 xcoff64_swap_ldhdr_in,
2892 xcoff64_swap_ldhdr_out,
2893 xcoff64_swap_ldsym_in,
2894 xcoff64_swap_ldsym_out,
2895 xcoff64_swap_ldrel_in,
2896 xcoff64_swap_ldrel_out,
2897
2898 /* Sizes. */
2899 LDHDRSZ,
2900 LDSYMSZ,
2901 LDRELSZ,
2902 24, /* _xcoff_function_descriptor_size */
2903 0, /* _xcoff_small_aout_header_size */
2904 /* Versions. */
2905 2, /* _xcoff_ldhdr_version */
2906
2907 _bfd_xcoff64_put_symbol_name,
2908 _bfd_xcoff64_put_ldsymbol_name,
2909 &xcoff64_dynamic_reloc,
2910 xcoff64_create_csect_from_smclas,
2911
2912 /* Lineno and reloc count overflow. */
2913 xcoff64_is_lineno_count_overflow,
2914 xcoff64_is_reloc_count_overflow,
2915
2916 xcoff64_loader_symbol_offset,
2917 xcoff64_loader_reloc_offset,
2918
2919 /* glink. */
2920 &xcoff64_glink_code[0],
2921 40, /* _xcoff_glink_size */
2922
2923 /* rtinit. */
2924 88, /* _xcoff_rtinit_size */
2925 xcoff64_generate_rtinit,
2926 };
eb1e0e80
NC
2927
2928/* The transfer vector that leads the outside world to all of the above. */
2929const bfd_target aix5coff64_vec =
cf9ab45b
AM
2930 {
2931 "aix5coff64-rs6000",
2932 bfd_target_xcoff_flavour,
2933 BFD_ENDIAN_BIG, /* data byte order is big */
2934 BFD_ENDIAN_BIG, /* header byte order is big */
2935
2936 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2937 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2938
a7c71b0c 2939 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2940 0, /* leading char */
2941 '/', /* ar_pad_char */
2942 15, /* ar_max_namelen */
2943
2944 /* data */
2945 bfd_getb64,
2946 bfd_getb_signed_64,
2947 bfd_putb64,
2948 bfd_getb32,
2949 bfd_getb_signed_32,
2950 bfd_putb32,
2951 bfd_getb16,
2952 bfd_getb_signed_16,
2953 bfd_putb16,
2954
2955 /* hdrs */
2956 bfd_getb64,
2957 bfd_getb_signed_64,
2958 bfd_putb64,
2959 bfd_getb32,
2960 bfd_getb_signed_32,
2961 bfd_putb32,
2962 bfd_getb16,
2963 bfd_getb_signed_16,
2964 bfd_putb16,
2965
2966 { /* bfd_check_format */
2967 _bfd_dummy_target,
2968 coff_object_p,
2969 xcoff64_archive_p,
2970 xcoff64_core_p
2971 },
2972
2973 { /* bfd_set_format */
2974 bfd_false,
2975 coff_mkobject,
2976 _bfd_generic_mkarchive,
2977 bfd_false
2978 },
2979
2980 {/* bfd_write_contents */
2981 bfd_false,
2982 xcoff64_write_object_contents,
2983 _bfd_xcoff_write_archive_contents,
2984 bfd_false
2985 },
2986
2987 /* Generic */
2988 bfd_true,
2989 bfd_true,
2990 coff_new_section_hook,
2991 _bfd_generic_get_section_contents,
2992 _bfd_generic_get_section_contents_in_window,
2993
2994 /* Copy */
2995 _bfd_xcoff_copy_private_bfd_data,
b34976b6 2996 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
60b48850 2997 _bfd_generic_init_private_section_data,
b34976b6
AM
2998 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2999 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
80fccad2 3000 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
b34976b6
AM
3001 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
3002 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
cf9ab45b
AM
3003
3004 /* Core */
3005 xcoff64_core_file_failing_command,
3006 xcoff64_core_file_failing_signal,
3007 xcoff64_core_file_matches_executable_p,
3008
3009 /* Archive */
3010 xcoff64_slurp_armap,
54327882 3011 bfd_false,
b34976b6 3012 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
cf9ab45b
AM
3013 bfd_dont_truncate_arname,
3014 _bfd_xcoff_write_armap,
3015 _bfd_xcoff_read_ar_hdr,
3016 xcoff64_openr_next_archived_file,
3017 _bfd_generic_get_elt_at_index,
3018 _bfd_xcoff_stat_arch_elt,
3019 bfd_true,
3020
3021 /* Symbols */
3022 coff_get_symtab_upper_bound,
6cee3f79 3023 coff_canonicalize_symtab,
cf9ab45b
AM
3024 coff_make_empty_symbol,
3025 coff_print_symbol,
3026 coff_get_symbol_info,
3027 _bfd_xcoff_is_local_label_name,
7db6994f 3028 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
3029 coff_get_lineno,
3030 coff_find_nearest_line,
4575b1b5 3031 _bfd_generic_find_line,
4ab527b0 3032 coff_find_inliner_info,
cf9ab45b
AM
3033 coff_bfd_make_debug_symbol,
3034 _bfd_generic_read_minisymbols,
3035 _bfd_generic_minisymbol_to_symbol,
3036
3037 /* Reloc */
3038 coff_get_reloc_upper_bound,
3039 coff_canonicalize_reloc,
3040 xcoff64_reloc_type_lookup,
157090f7 3041 xcoff64_reloc_name_lookup,
cf9ab45b
AM
3042
3043 /* Write */
3044 coff_set_arch_mach,
3045 coff_set_section_contents,
3046
3047 /* Link */
3048 xcoff64_sizeof_headers,
3049 bfd_generic_get_relocated_section_contents,
3050 bfd_generic_relax_section,
3051 _bfd_xcoff_bfd_link_hash_table_create,
3052 _bfd_generic_link_hash_table_free,
3053 _bfd_xcoff_bfd_link_add_symbols,
3054 _bfd_generic_link_just_syms,
3055 _bfd_xcoff_bfd_final_link,
3056 _bfd_generic_link_split_section,
3057 bfd_generic_gc_sections,
3058 bfd_generic_merge_sections,
72adc230 3059 bfd_generic_is_group_section,
cf9ab45b 3060 bfd_generic_discard_group,
082b7297 3061 _bfd_generic_section_already_linked,
3023e3f6 3062 _bfd_xcoff_define_common_symbol,
cf9ab45b
AM
3063
3064 /* Dynamic */
3065 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3066 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 3067 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
3068 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3069 _bfd_xcoff_canonicalize_dynamic_reloc,
3070
3071 /* Opposite endian version, none exists. */
3072 NULL,
3073
3074 (void *) & bfd_xcoff_aix5_backend_data,
3075 };
This page took 0.589057 seconds and 4 git commands to generate.