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