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;
12b2cce9 1120 bfd_vma section_offset;
f1f0d9ab 1121
cf9ab45b 1122 if (0 > rel->r_symndx)
b34976b6 1123 return FALSE;
f1f0d9ab
TR
1124
1125 h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
12b2cce9 1126 section_offset = rel->r_vaddr - input_section->vma;
f1f0d9ab
TR
1127
1128 /* If we see an R_BR or R_RBR reloc which is jumping to global
1129 linkage code, and it is followed by an appropriate cror nop
1130 instruction, we replace the cror with ld r2,40(r1). This
1131 restores the TOC after the glink code. Contrariwise, if the
1132 call is followed by a ld r2,40(r1), but the call is not
1133 going to global linkage code, we can replace the load with a
1134 cror. */
cf9ab45b
AM
1135 if (NULL != h
1136 && bfd_link_hash_defined == h->root.type
12b2cce9 1137 && section_offset + 8 <= input_section->size)
f1f0d9ab
TR
1138 {
1139 bfd_byte *pnext;
1140 unsigned long next;
cf9ab45b 1141
12b2cce9 1142 pnext = contents + section_offset + 4;
f1f0d9ab 1143 next = bfd_get_32 (input_bfd, pnext);
cf9ab45b
AM
1144
1145 /* The _ptrgl function is magic. It is used by the AIX compiler to call
f1f0d9ab 1146 a function through a pointer. */
cf9ab45b 1147 if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
f1f0d9ab 1148 {
cf9ab45b
AM
1149 if (next == 0x4def7b82 /* cror 15,15,15 */
1150 || next == 0x4ffffb82 /* cror 31,31,31 */
1151 || next == 0x60000000) /* ori r0,r0,0 */
1152 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1153 }
1154 else
f1f0d9ab 1155 {
cf9ab45b
AM
1156 if (next == 0xe8410028) /* ld r2,40(r1) */
1157 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
f1f0d9ab 1158 }
cf9ab45b
AM
1159 }
1160 else if (NULL != h && bfd_link_hash_undefined == h->root.type)
f1f0d9ab
TR
1161 {
1162 /* Normally, this relocation is against a defined symbol. In the
1163 case where this is a partial link and the output section offset
cf9ab45b 1164 is greater than 2^25, the linker will return an invalid error
f1f0d9ab 1165 message that the relocation has been truncated. Yes it has been
cf9ab45b 1166 truncated but no it not important. For this case, disable the
f1f0d9ab
TR
1167 overflow checking. */
1168 howto->complain_on_overflow = complain_overflow_dont;
1169 }
cf9ab45b 1170
12b2cce9
RS
1171 /* The original PC-relative relocation is biased by -r_vaddr, so adding
1172 the value below will give the absolute target address. */
1173 *relocation = val + addend + rel->r_vaddr;
1174
a78eab4e
AM
1175 howto->src_mask &= ~3;
1176 howto->dst_mask = howto->src_mask;
cf9ab45b 1177
12b2cce9
RS
1178 if (h != NULL
1179 && h->root.type == bfd_link_hash_defined
1180 && bfd_is_abs_section (h->root.u.def.section)
1181 && section_offset + 4 <= input_section->size)
1182 {
1183 bfd_byte *ptr;
1184 bfd_vma insn;
1185
1186 /* Turn the relative branch into an absolute one by setting the
1187 AA bit. */
1188 ptr = contents + section_offset;
1189 insn = bfd_get_32 (input_bfd, ptr);
1190 insn |= 2;
1191 bfd_put_32 (input_bfd, insn, ptr);
1192
1193 /* Make the howto absolute too. */
1194 howto->pc_relative = FALSE;
1195 howto->complain_on_overflow = complain_overflow_bitfield;
1196 }
1197 else
1198 {
1199 /* Use a PC-relative howto and subtract the instruction's address
1200 from the target address we calculated above. */
1201 howto->pc_relative = TRUE;
1202 *relocation -= (input_section->output_section->vma
1203 + input_section->output_offset
1204 + section_offset);
1205 }
b34976b6 1206 return TRUE;
f1f0d9ab
TR
1207}
1208
dbe341c6
TR
1209/* This is the relocation function for the PowerPC64.
1210 See xcoff_ppc_relocation_section for more information. */
beb1bf64 1211
b34976b6 1212bfd_boolean
beb1bf64
TR
1213xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
1214 input_section, contents, relocs, syms,
1215 sections)
1216 bfd *output_bfd;
1217 struct bfd_link_info *info;
1218 bfd *input_bfd;
1219 asection *input_section;
1220 bfd_byte *contents;
1221 struct internal_reloc *relocs;
1222 struct internal_syment *syms;
1223 asection **sections;
1224{
1225 struct internal_reloc *rel;
1226 struct internal_reloc *relend;
1227
1228 rel = relocs;
1229 relend = rel + input_section->reloc_count;
1230 for (; rel < relend; rel++)
1231 {
1232 long symndx;
1233 struct xcoff_link_hash_entry *h;
1234 struct internal_syment *sym;
1235 bfd_vma addend;
1236 bfd_vma val;
1237 struct reloc_howto_struct howto;
dbe341c6
TR
1238 bfd_vma relocation;
1239 bfd_vma value_to_relocate;
1240 bfd_vma address;
1241 bfd_byte *location;
beb1bf64
TR
1242
1243 /* Relocation type R_REF is a special relocation type which is
cf9ab45b
AM
1244 merely used to prevent garbage collection from occurring for
1245 the csect including the symbol which it references. */
beb1bf64
TR
1246 if (rel->r_type == R_REF)
1247 continue;
1248
dbe341c6 1249 /* howto */
beb1bf64
TR
1250 howto.type = rel->r_type;
1251 howto.rightshift = 0;
beb1bf64 1252 howto.bitsize = (rel->r_size & 0x3f) + 1;
dbe341c6 1253 howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
b34976b6 1254 howto.pc_relative = FALSE;
beb1bf64 1255 howto.bitpos = 0;
cf9ab45b
AM
1256 howto.complain_on_overflow = (rel->r_size & 0x80
1257 ? complain_overflow_signed
1258 : complain_overflow_bitfield);
beb1bf64
TR
1259 howto.special_function = NULL;
1260 howto.name = "internal";
b34976b6 1261 howto.partial_inplace = TRUE;
cf9ab45b 1262 howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
b34976b6 1263 howto.pcrel_offset = FALSE;
beb1bf64 1264
dbe341c6 1265 /* symbol */
beb1bf64 1266 val = 0;
dbe341c6
TR
1267 addend = 0;
1268 h = NULL;
1269 sym = NULL;
cf9ab45b 1270 symndx = rel->r_symndx;
beb1bf64 1271
cf9ab45b 1272 if (-1 != symndx)
dc810e39
AM
1273 {
1274 asection *sec;
cf9ab45b 1275
dbe341c6
TR
1276 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
1277 sym = syms + symndx;
1278 addend = - sym->n_value;
cf9ab45b
AM
1279
1280 if (NULL == h)
dc810e39
AM
1281 {
1282 sec = sections[symndx];
1283 /* Hack to make sure we use the right TOC anchor value
1284 if this reloc is against the TOC anchor. */
1285 if (sec->name[3] == '0'
1286 && strcmp (sec->name, ".tc0") == 0)
1287 val = xcoff_data (output_bfd)->toc;
1288 else
1289 val = (sec->output_section->vma
1290 + sec->output_offset
1291 + sym->n_value
1292 - sec->vma);
cf9ab45b
AM
1293 }
1294 else
dc810e39 1295 {
cf9ab45b
AM
1296 if (h->root.type == bfd_link_hash_defined
1297 || h->root.type == bfd_link_hash_defweak)
dc810e39 1298 {
dbe341c6
TR
1299 sec = h->root.u.def.section;
1300 val = (h->root.u.def.value
1301 + sec->output_section->vma
1302 + sec->output_offset);
cf9ab45b
AM
1303 }
1304 else if (h->root.type == bfd_link_hash_common)
dbe341c6
TR
1305 {
1306 sec = h->root.u.c.p->section;
1307 val = (sec->output_section->vma
1308 + sec->output_offset);
cf9ab45b
AM
1309 }
1310 else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
1049f94e 1311 && ! info->relocatable)
dbe341c6
TR
1312 {
1313 if (! ((*info->callbacks->undefined_symbol)
1314 (info, h->root.root.string, input_bfd, input_section,
b34976b6
AM
1315 rel->r_vaddr - input_section->vma, TRUE)))
1316 return FALSE;
cf9ab45b 1317
dbe341c6
TR
1318 /* Don't try to process the reloc. It can't help, and
1319 it may generate another error. */
1320 continue;
dc810e39 1321 }
dc810e39 1322 }
dc810e39 1323 }
cf9ab45b
AM
1324
1325 if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
213e90f4 1326 || !((*xcoff64_calculate_relocation[rel->r_type])
cf9ab45b
AM
1327 (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
1328 addend, &relocation, contents)))
b34976b6 1329 return FALSE;
cf9ab45b 1330
dbe341c6
TR
1331 /* address */
1332 address = rel->r_vaddr - input_section->vma;
1333 location = contents + address;
cf9ab45b 1334
eea6121a 1335 if (address > input_section->size)
cf9ab45b
AM
1336 abort ();
1337
dbe341c6
TR
1338 /* Get the value we are going to relocate. */
1339 if (1 == howto.size)
1340 value_to_relocate = bfd_get_16 (input_bfd, location);
1341 else if (2 == howto.size)
1342 value_to_relocate = bfd_get_32 (input_bfd, location);
cf9ab45b 1343 else
dbe341c6 1344 value_to_relocate = bfd_get_64 (input_bfd, location);
cf9ab45b
AM
1345
1346 /* overflow.
1347
dbe341c6
TR
1348 FIXME: We may drop bits during the addition
1349 which we don't check for. We must either check at every single
1350 operation, which would be tedious, or we must do the computations
1351 in a type larger than bfd_vma, which would be inefficient. */
cf9ab45b
AM
1352
1353 if ((unsigned int) howto.complain_on_overflow
1354 >= XCOFF_MAX_COMPLAIN_OVERFLOW)
1355 abort ();
1356
1357 if (((*xcoff_complain_overflow[howto.complain_on_overflow])
1358 (input_bfd, value_to_relocate, relocation, &howto)))
dc810e39 1359 {
dbe341c6
TR
1360 const char *name;
1361 char buf[SYMNMLEN + 1];
1362 char reloc_type_name[10];
cf9ab45b
AM
1363
1364 if (symndx == -1)
beb1bf64 1365 {
dbe341c6 1366 name = "*ABS*";
cf9ab45b
AM
1367 }
1368 else if (h != NULL)
dbe341c6 1369 {
dfeffb9f 1370 name = NULL;
cf9ab45b
AM
1371 }
1372 else
beb1bf64 1373 {
dbe341c6
TR
1374 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1375 if (name == NULL)
1376 name = "UNKNOWN";
beb1bf64 1377 }
dbe341c6 1378 sprintf (reloc_type_name, "0x%02x", rel->r_type);
cf9ab45b 1379
dbe341c6 1380 if (! ((*info->callbacks->reloc_overflow)
dfeffb9f
L
1381 (info, (h ? &h->root : NULL), name, reloc_type_name,
1382 (bfd_vma) 0, input_bfd, input_section,
1383 rel->r_vaddr - input_section->vma)))
b34976b6 1384 return FALSE;
beb1bf64
TR
1385 }
1386
dbe341c6 1387 /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
cf9ab45b
AM
1388 value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
1389 | (((value_to_relocate & howto.src_mask)
1390 + relocation) & howto.dst_mask));
1391
dbe341c6
TR
1392 /* Put the value back in the object file. */
1393 if (1 == howto.size)
1394 bfd_put_16 (input_bfd, value_to_relocate, location);
1395 else if (2 == howto.size)
1396 bfd_put_32 (input_bfd, value_to_relocate, location);
1397 else
1398 bfd_put_64 (input_bfd, value_to_relocate, location);
cf9ab45b 1399
beb1bf64 1400 }
b34976b6 1401 return TRUE;
beb1bf64
TR
1402}
1403
beb1bf64
TR
1404\f
1405/* The XCOFF reloc table. Actually, XCOFF relocations specify the
1406 bitsize and whether they are signed or not, along with a
1407 conventional type. This table is for the types, which are used for
1408 different algorithms for putting in the reloc. Many of these
1409 relocs need special_function entries, which I have not written. */
1410
beb1bf64
TR
1411reloc_howto_type xcoff64_howto_table[] =
1412{
1413 /* Standard 64 bit relocation. */
38487e5e 1414 HOWTO (R_POS, /* type */
dc810e39
AM
1415 0, /* rightshift */
1416 4, /* size (0 = byte, 1 = short, 2 = long) */
1417 64, /* bitsize */
b34976b6 1418 FALSE, /* pc_relative */
dc810e39 1419 0, /* bitpos */
beb1bf64 1420 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39 1421 0, /* special_function */
59862849 1422 "R_POS_64", /* name */
b34976b6 1423 TRUE, /* partial_inplace */
a78eab4e 1424 MINUS_ONE, /* src_mask */
dc810e39 1425 MINUS_ONE, /* dst_mask */
b34976b6 1426 FALSE), /* pcrel_offset */
beb1bf64
TR
1427
1428 /* 64 bit relocation, but store negative value. */
38487e5e 1429 HOWTO (R_NEG, /* type */
dc810e39
AM
1430 0, /* rightshift */
1431 -4, /* size (0 = byte, 1 = short, 2 = long) */
1432 64, /* bitsize */
b34976b6 1433 FALSE, /* pc_relative */
dc810e39 1434 0, /* bitpos */
beb1bf64 1435 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1436 0, /* special_function */
1437 "R_NEG", /* name */
b34976b6 1438 TRUE, /* partial_inplace */
a78eab4e 1439 MINUS_ONE, /* src_mask */
dc810e39 1440 MINUS_ONE, /* dst_mask */
b34976b6 1441 FALSE), /* pcrel_offset */
beb1bf64
TR
1442
1443 /* 32 bit PC relative relocation. */
38487e5e 1444 HOWTO (R_REL, /* type */
dc810e39
AM
1445 0, /* rightshift */
1446 2, /* size (0 = byte, 1 = short, 2 = long) */
1447 32, /* bitsize */
b34976b6 1448 TRUE, /* pc_relative */
dc810e39 1449 0, /* bitpos */
beb1bf64 1450 complain_overflow_signed, /* complain_on_overflow */
dc810e39
AM
1451 0, /* special_function */
1452 "R_REL", /* name */
b34976b6 1453 TRUE, /* partial_inplace */
a78eab4e 1454 0xffffffff, /* src_mask */
dc810e39 1455 0xffffffff, /* dst_mask */
b34976b6 1456 FALSE), /* pcrel_offset */
beb1bf64
TR
1457
1458 /* 16 bit TOC relative relocation. */
38487e5e 1459 HOWTO (R_TOC, /* type */
dc810e39
AM
1460 0, /* rightshift */
1461 1, /* size (0 = byte, 1 = short, 2 = long) */
1462 16, /* bitsize */
b34976b6 1463 FALSE, /* pc_relative */
dc810e39 1464 0, /* bitpos */
beb1bf64 1465 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1466 0, /* special_function */
1467 "R_TOC", /* name */
b34976b6 1468 TRUE, /* partial_inplace */
a78eab4e 1469 0xffff, /* src_mask */
dc810e39 1470 0xffff, /* dst_mask */
b34976b6 1471 FALSE), /* pcrel_offset */
dc810e39 1472
cf9ab45b 1473 /* I don't really know what this is. */
38487e5e 1474 HOWTO (R_RTB, /* type */
dc810e39
AM
1475 1, /* rightshift */
1476 2, /* size (0 = byte, 1 = short, 2 = long) */
1477 32, /* bitsize */
b34976b6 1478 FALSE, /* pc_relative */
dc810e39 1479 0, /* bitpos */
beb1bf64 1480 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1481 0, /* special_function */
1482 "R_RTB", /* name */
b34976b6 1483 TRUE, /* partial_inplace */
a78eab4e 1484 0xffffffff, /* src_mask */
dc810e39 1485 0xffffffff, /* dst_mask */
b34976b6 1486 FALSE), /* pcrel_offset */
beb1bf64
TR
1487
1488 /* External TOC relative symbol. */
38487e5e 1489 HOWTO (R_GL, /* type */
dc810e39 1490 0, /* rightshift */
48bfecdd 1491 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1492 16, /* bitsize */
b34976b6 1493 FALSE, /* pc_relative */
dc810e39 1494 0, /* bitpos */
beb1bf64 1495 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1496 0, /* special_function */
1497 "R_GL", /* name */
b34976b6 1498 TRUE, /* partial_inplace */
a78eab4e 1499 0xffff, /* src_mask */
dc810e39 1500 0xffff, /* dst_mask */
b34976b6 1501 FALSE), /* pcrel_offset */
dc810e39
AM
1502
1503 /* Local TOC relative symbol. */
38487e5e 1504 HOWTO (R_TCL, /* type */
dc810e39 1505 0, /* rightshift */
48bfecdd 1506 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1507 16, /* bitsize */
b34976b6 1508 FALSE, /* pc_relative */
dc810e39 1509 0, /* bitpos */
beb1bf64 1510 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1511 0, /* special_function */
1512 "R_TCL", /* name */
b34976b6 1513 TRUE, /* partial_inplace */
a78eab4e 1514 0xffff, /* src_mask */
dc810e39 1515 0xffff, /* dst_mask */
b34976b6 1516 FALSE), /* pcrel_offset */
beb1bf64
TR
1517
1518 EMPTY_HOWTO (7),
1519
1520 /* Non modifiable absolute branch. */
38487e5e 1521 HOWTO (R_BA, /* type */
dc810e39
AM
1522 0, /* rightshift */
1523 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 26, /* bitsize */
b34976b6 1525 FALSE, /* pc_relative */
dc810e39 1526 0, /* bitpos */
beb1bf64 1527 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39 1528 0, /* special_function */
59862849 1529 "R_BA_26", /* name */
b34976b6 1530 TRUE, /* partial_inplace */
a78eab4e 1531 0x03fffffc, /* src_mask */
48bfecdd 1532 0x03fffffc, /* dst_mask */
b34976b6 1533 FALSE), /* pcrel_offset */
beb1bf64
TR
1534
1535 EMPTY_HOWTO (9),
1536
1537 /* Non modifiable relative branch. */
38487e5e 1538 HOWTO (R_BR, /* type */
dc810e39
AM
1539 0, /* rightshift */
1540 2, /* size (0 = byte, 1 = short, 2 = long) */
1541 26, /* bitsize */
b34976b6 1542 TRUE, /* pc_relative */
dc810e39 1543 0, /* bitpos */
beb1bf64 1544 complain_overflow_signed, /* complain_on_overflow */
dc810e39
AM
1545 0, /* special_function */
1546 "R_BR", /* name */
b34976b6 1547 TRUE, /* partial_inplace */
a78eab4e 1548 0x03fffffc, /* src_mask */
48bfecdd 1549 0x03fffffc, /* dst_mask */
b34976b6 1550 FALSE), /* pcrel_offset */
beb1bf64
TR
1551
1552 EMPTY_HOWTO (0xb),
1553
1554 /* Indirect load. */
38487e5e 1555 HOWTO (R_RL, /* type */
dc810e39 1556 0, /* rightshift */
48bfecdd 1557 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1558 16, /* bitsize */
b34976b6 1559 FALSE, /* pc_relative */
dc810e39 1560 0, /* bitpos */
beb1bf64 1561 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1562 0, /* special_function */
1563 "R_RL", /* name */
b34976b6 1564 TRUE, /* partial_inplace */
a78eab4e 1565 0xffff, /* src_mask */
dc810e39 1566 0xffff, /* dst_mask */
b34976b6 1567 FALSE), /* pcrel_offset */
beb1bf64
TR
1568
1569 /* Load address. */
38487e5e 1570 HOWTO (R_RLA, /* type */
dc810e39 1571 0, /* rightshift */
48bfecdd 1572 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1573 16, /* bitsize */
b34976b6 1574 FALSE, /* pc_relative */
dc810e39 1575 0, /* bitpos */
beb1bf64 1576 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1577 0, /* special_function */
1578 "R_RLA", /* name */
b34976b6 1579 TRUE, /* partial_inplace */
a78eab4e 1580 0xffff, /* src_mask */
dc810e39 1581 0xffff, /* dst_mask */
b34976b6 1582 FALSE), /* pcrel_offset */
beb1bf64
TR
1583
1584 EMPTY_HOWTO (0xe),
1585
cf9ab45b 1586 /* Non-relocating reference. */
38487e5e 1587 HOWTO (R_REF, /* type */
dc810e39
AM
1588 0, /* rightshift */
1589 2, /* size (0 = byte, 1 = short, 2 = long) */
1590 32, /* bitsize */
b34976b6 1591 FALSE, /* pc_relative */
dc810e39 1592 0, /* bitpos */
a78eab4e 1593 complain_overflow_dont, /* complain_on_overflow */
dc810e39
AM
1594 0, /* special_function */
1595 "R_REF", /* name */
b34976b6 1596 FALSE, /* partial_inplace */
dc810e39
AM
1597 0, /* src_mask */
1598 0, /* dst_mask */
b34976b6 1599 FALSE), /* pcrel_offset */
beb1bf64
TR
1600
1601 EMPTY_HOWTO (0x10),
1602 EMPTY_HOWTO (0x11),
1603
1604 /* TOC relative indirect load. */
38487e5e 1605 HOWTO (R_TRL, /* type */
dc810e39 1606 0, /* rightshift */
48bfecdd 1607 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1608 16, /* bitsize */
b34976b6 1609 FALSE, /* pc_relative */
dc810e39 1610 0, /* bitpos */
beb1bf64 1611 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1612 0, /* special_function */
1613 "R_TRL", /* name */
b34976b6 1614 TRUE, /* partial_inplace */
a78eab4e 1615 0xffff, /* src_mask */
dc810e39 1616 0xffff, /* dst_mask */
b34976b6 1617 FALSE), /* pcrel_offset */
dc810e39
AM
1618
1619 /* TOC relative load address. */
38487e5e 1620 HOWTO (R_TRLA, /* type */
dc810e39 1621 0, /* rightshift */
48bfecdd 1622 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1623 16, /* bitsize */
b34976b6 1624 FALSE, /* pc_relative */
dc810e39 1625 0, /* bitpos */
beb1bf64 1626 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1627 0, /* special_function */
1628 "R_TRLA", /* name */
b34976b6 1629 TRUE, /* partial_inplace */
a78eab4e 1630 0xffff, /* src_mask */
dc810e39 1631 0xffff, /* dst_mask */
b34976b6 1632 FALSE), /* pcrel_offset */
beb1bf64
TR
1633
1634 /* Modifiable relative branch. */
38487e5e 1635 HOWTO (R_RRTBI, /* type */
dc810e39
AM
1636 1, /* rightshift */
1637 2, /* size (0 = byte, 1 = short, 2 = long) */
1638 32, /* bitsize */
b34976b6 1639 FALSE, /* pc_relative */
dc810e39 1640 0, /* bitpos */
beb1bf64 1641 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1642 0, /* special_function */
1643 "R_RRTBI", /* name */
b34976b6 1644 TRUE, /* partial_inplace */
a78eab4e 1645 0xffffffff, /* src_mask */
dc810e39 1646 0xffffffff, /* dst_mask */
b34976b6 1647 FALSE), /* pcrel_offset */
beb1bf64
TR
1648
1649 /* Modifiable absolute branch. */
38487e5e 1650 HOWTO (R_RRTBA, /* type */
dc810e39
AM
1651 1, /* rightshift */
1652 2, /* size (0 = byte, 1 = short, 2 = long) */
1653 32, /* bitsize */
b34976b6 1654 FALSE, /* pc_relative */
dc810e39 1655 0, /* bitpos */
beb1bf64 1656 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1657 0, /* special_function */
1658 "R_RRTBA", /* name */
b34976b6 1659 TRUE, /* partial_inplace */
a78eab4e 1660 0xffffffff, /* src_mask */
dc810e39 1661 0xffffffff, /* dst_mask */
b34976b6 1662 FALSE), /* pcrel_offset */
dc810e39
AM
1663
1664 /* Modifiable call absolute indirect. */
38487e5e 1665 HOWTO (R_CAI, /* type */
dc810e39 1666 0, /* rightshift */
48bfecdd 1667 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1668 16, /* bitsize */
b34976b6 1669 FALSE, /* pc_relative */
dc810e39 1670 0, /* bitpos */
beb1bf64 1671 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1672 0, /* special_function */
1673 "R_CAI", /* name */
b34976b6 1674 TRUE, /* partial_inplace */
a78eab4e 1675 0xffff, /* src_mask */
dc810e39 1676 0xffff, /* dst_mask */
b34976b6 1677 FALSE), /* pcrel_offset */
dc810e39 1678
cf9ab45b 1679 /* Modifiable call relative. */
38487e5e 1680 HOWTO (R_CREL, /* type */
dc810e39 1681 0, /* rightshift */
48bfecdd 1682 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1683 16, /* bitsize */
b34976b6 1684 FALSE, /* pc_relative */
dc810e39 1685 0, /* bitpos */
beb1bf64 1686 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1687 0, /* special_function */
1688 "R_CREL", /* name */
b34976b6 1689 TRUE, /* partial_inplace */
a78eab4e 1690 0xffff, /* src_mask */
dc810e39 1691 0xffff, /* dst_mask */
b34976b6 1692 FALSE), /* pcrel_offset */
beb1bf64
TR
1693
1694 /* Modifiable branch absolute. */
38487e5e 1695 HOWTO (R_RBA, /* type */
dc810e39
AM
1696 0, /* rightshift */
1697 2, /* size (0 = byte, 1 = short, 2 = long) */
1698 26, /* bitsize */
b34976b6 1699 FALSE, /* pc_relative */
dc810e39 1700 0, /* bitpos */
beb1bf64 1701 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1702 0, /* special_function */
1703 "R_RBA", /* name */
b34976b6 1704 TRUE, /* partial_inplace */
a78eab4e 1705 0x03fffffc, /* src_mask */
48bfecdd 1706 0x03fffffc, /* dst_mask */
b34976b6 1707 FALSE), /* pcrel_offset */
beb1bf64
TR
1708
1709 /* Modifiable branch absolute. */
38487e5e 1710 HOWTO (R_RBAC, /* type */
dc810e39
AM
1711 0, /* rightshift */
1712 2, /* size (0 = byte, 1 = short, 2 = long) */
1713 32, /* bitsize */
b34976b6 1714 FALSE, /* pc_relative */
dc810e39 1715 0, /* bitpos */
beb1bf64 1716 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1717 0, /* special_function */
1718 "R_RBAC", /* name */
b34976b6 1719 TRUE, /* partial_inplace */
a78eab4e 1720 0xffffffff, /* src_mask */
48bfecdd 1721 0xffffffff, /* dst_mask */
b34976b6 1722 FALSE), /* pcrel_offset */
beb1bf64
TR
1723
1724 /* Modifiable branch relative. */
38487e5e 1725 HOWTO (R_RBR, /* type */
dc810e39
AM
1726 0, /* rightshift */
1727 2, /* size (0 = byte, 1 = short, 2 = long) */
1728 26, /* bitsize */
b34976b6 1729 FALSE, /* pc_relative */
dc810e39 1730 0, /* bitpos */
beb1bf64 1731 complain_overflow_signed, /* complain_on_overflow */
dc810e39 1732 0, /* special_function */
59862849 1733 "R_RBR_26", /* name */
b34976b6 1734 TRUE, /* partial_inplace */
a78eab4e 1735 0x03fffffc, /* src_mask */
48bfecdd 1736 0x03fffffc, /* dst_mask */
b34976b6 1737 FALSE), /* pcrel_offset */
beb1bf64
TR
1738
1739 /* Modifiable branch absolute. */
38487e5e 1740 HOWTO (R_RBRC, /* type */
dc810e39 1741 0, /* rightshift */
48bfecdd 1742 1, /* size (0 = byte, 1 = short, 2 = long) */
dc810e39 1743 16, /* bitsize */
b34976b6 1744 FALSE, /* pc_relative */
dc810e39 1745 0, /* bitpos */
beb1bf64 1746 complain_overflow_bitfield, /* complain_on_overflow */
dc810e39
AM
1747 0, /* special_function */
1748 "R_RBRC", /* name */
b34976b6 1749 TRUE, /* partial_inplace */
a78eab4e 1750 0xffff, /* src_mask */
dc810e39 1751 0xffff, /* dst_mask */
b34976b6 1752 FALSE), /* pcrel_offset */
dc810e39 1753
38487e5e 1754 HOWTO (R_POS, /* type */
dc810e39 1755 0, /* rightshift */
59862849
TR
1756 2, /* size (0 = byte, 1 = short, 2 = long) */
1757 32, /* bitsize */
b34976b6 1758 FALSE, /* pc_relative */
dc810e39
AM
1759 0, /* bitpos */
1760 complain_overflow_bitfield, /* complain_on_overflow */
1761 0, /* special_function */
59862849 1762 "R_POS_32", /* name */
b34976b6 1763 TRUE, /* partial_inplace */
a78eab4e 1764 0xffffffff, /* src_mask */
59862849 1765 0xffffffff, /* dst_mask */
b34976b6 1766 FALSE), /* pcrel_offset */
ff3a6ee3
TR
1767
1768 /* 16 bit Non modifiable absolute branch. */
54327882
AM
1769 HOWTO (R_BA, /* type */
1770 0, /* rightshift */
59862849 1771 1, /* size (0 = byte, 1 = short, 2 = long) */
54327882 1772 16, /* bitsize */
b34976b6 1773 FALSE, /* pc_relative */
54327882 1774 0, /* bitpos */
ff3a6ee3 1775 complain_overflow_bitfield, /* complain_on_overflow */
54327882 1776 0, /* special_function */
59862849 1777 "R_BA_16", /* name */
b34976b6 1778 TRUE, /* partial_inplace */
a78eab4e 1779 0xfffc, /* src_mask */
54327882 1780 0xfffc, /* dst_mask */
b34976b6 1781 FALSE), /* pcrel_offset */
59862849
TR
1782
1783 /* Modifiable branch relative. */
cf9ab45b
AM
1784 HOWTO (R_RBR, /* type */
1785 0, /* rightshift */
1786 1, /* size (0 = byte, 1 = short, 2 = long) */
1787 16, /* bitsize */
b34976b6 1788 FALSE, /* pc_relative */
cf9ab45b 1789 0, /* bitpos */
59862849 1790 complain_overflow_signed, /* complain_on_overflow */
cf9ab45b
AM
1791 0, /* special_function */
1792 "R_RBR_16", /* name */
b34976b6 1793 TRUE, /* partial_inplace */
cf9ab45b
AM
1794 0xffff, /* src_mask */
1795 0xffff, /* dst_mask */
b34976b6 1796 FALSE), /* pcrel_offset */
1b164155
TR
1797
1798 /* Modifiable branch absolute. */
1799 HOWTO (R_RBA, /* type */
1800 0, /* rightshift */
1801 1, /* size (0 = byte, 1 = short, 2 = long) */
1802 16, /* bitsize */
b34976b6 1803 FALSE, /* pc_relative */
1b164155
TR
1804 0, /* bitpos */
1805 complain_overflow_bitfield, /* complain_on_overflow */
1806 0, /* special_function */
1807 "R_RBA_16", /* name */
b34976b6 1808 TRUE, /* partial_inplace */
a78eab4e 1809 0xffff, /* src_mask */
1b164155 1810 0xffff, /* dst_mask */
b34976b6 1811 FALSE), /* pcrel_offset */
1b164155 1812
beb1bf64
TR
1813};
1814
1815void
1816xcoff64_rtype2howto (relent, internal)
1817 arelent *relent;
1818 struct internal_reloc *internal;
1819{
59862849 1820 if (internal->r_type > R_RBRC)
beb1bf64
TR
1821 abort ();
1822
59862849
TR
1823 /* Default howto layout works most of the time */
1824 relent->howto = &xcoff64_howto_table[internal->r_type];
cf9ab45b 1825
5c4491d3 1826 /* Special case some 16 bit reloc */
59862849
TR
1827 if (15 == (internal->r_size & 0x3f))
1828 {
cf9ab45b 1829 if (R_BA == internal->r_type)
59862849 1830 relent->howto = &xcoff64_howto_table[0x1d];
cf9ab45b 1831 else if (R_RBR == internal->r_type)
59862849 1832 relent->howto = &xcoff64_howto_table[0x1e];
cf9ab45b 1833 else if (R_RBA == internal->r_type)
1b164155 1834 relent->howto = &xcoff64_howto_table[0x1f];
59862849
TR
1835 }
1836 /* Special case 32 bit */
1837 else if (31 == (internal->r_size & 0x3f))
1838 {
cf9ab45b 1839 if (R_POS == internal->r_type)
59862849
TR
1840 relent->howto = &xcoff64_howto_table[0x1c];
1841 }
cf9ab45b 1842
beb1bf64
TR
1843 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1844 relocation, as well as indicating whether it is signed or not.
1845 Doublecheck that the relocation information gathered from the
1846 type matches this information. The bitsize is not significant
1847 for R_REF relocs. */
1848 if (relent->howto->dst_mask != 0
dc810e39 1849 && (relent->howto->bitsize
beb1bf64
TR
1850 != ((unsigned int) internal->r_size & 0x3f) + 1))
1851 abort ();
beb1bf64
TR
1852}
1853
1854reloc_howto_type *
1855xcoff64_reloc_type_lookup (abfd, code)
1856 bfd *abfd ATTRIBUTE_UNUSED;
1857 bfd_reloc_code_real_type code;
1858{
1859 switch (code)
1860 {
1861 case BFD_RELOC_PPC_B26:
1862 return &xcoff64_howto_table[0xa];
ff3a6ee3
TR
1863 case BFD_RELOC_PPC_BA16:
1864 return &xcoff64_howto_table[0x1d];
beb1bf64
TR
1865 case BFD_RELOC_PPC_BA26:
1866 return &xcoff64_howto_table[8];
1867 case BFD_RELOC_PPC_TOC16:
1868 return &xcoff64_howto_table[3];
1869 case BFD_RELOC_32:
1870 case BFD_RELOC_CTOR:
beb1bf64 1871 return &xcoff64_howto_table[0x1c];
59862849
TR
1872 case BFD_RELOC_64:
1873 return &xcoff64_howto_table[0];
beb1bf64
TR
1874 default:
1875 return NULL;
1876 }
1877}
1878
157090f7
AM
1879static reloc_howto_type *
1880xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1881 const char *r_name)
1882{
1883 unsigned int i;
1884
1885 for (i = 0;
1886 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1887 i++)
1888 if (xcoff64_howto_table[i].name != NULL
1889 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1890 return &xcoff64_howto_table[i];
1891
1892 return NULL;
1893}
1894
beb1bf64
TR
1895/* Read in the armap of an XCOFF archive. */
1896
b34976b6 1897static bfd_boolean
beb1bf64
TR
1898xcoff64_slurp_armap (abfd)
1899 bfd *abfd;
1900{
1901 file_ptr off;
1902 size_t namlen;
dc810e39 1903 bfd_size_type sz, amt;
beb1bf64
TR
1904 bfd_byte *contents, *cend;
1905 bfd_vma c, i;
1906 carsym *arsym;
1907 bfd_byte *p;
dc810e39 1908 file_ptr pos;
beb1bf64
TR
1909
1910 /* This is for the new format. */
1911 struct xcoff_ar_hdr_big hdr;
1912
dc810e39
AM
1913 if (xcoff_ardata (abfd) == NULL)
1914 {
b34976b6
AM
1915 bfd_has_map (abfd) = FALSE;
1916 return TRUE;
dc810e39 1917 }
beb1bf64 1918
487e54f2
AM
1919 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1920 (const char **) NULL, 10);
dc810e39
AM
1921 if (off == 0)
1922 {
b34976b6
AM
1923 bfd_has_map (abfd) = FALSE;
1924 return TRUE;
dc810e39 1925 }
beb1bf64
TR
1926
1927 if (bfd_seek (abfd, off, SEEK_SET) != 0)
b34976b6 1928 return FALSE;
beb1bf64
TR
1929
1930 /* The symbol table starts with a normal archive header. */
dc810e39
AM
1931 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1932 != SIZEOF_AR_HDR_BIG)
b34976b6 1933 return FALSE;
beb1bf64
TR
1934
1935 /* Skip the name (normally empty). */
1936 namlen = strtol (hdr.namlen, (char **) NULL, 10);
dc810e39
AM
1937 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1938 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
b34976b6 1939 return FALSE;
beb1bf64 1940
487e54f2 1941 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
beb1bf64
TR
1942
1943 /* Read in the entire symbol table. */
1944 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1945 if (contents == NULL)
b34976b6 1946 return FALSE;
dc810e39 1947 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
b34976b6 1948 return FALSE;
beb1bf64
TR
1949
1950 /* The symbol table starts with an eight byte count. */
dc810e39 1951 c = H_GET_64 (abfd, contents);
beb1bf64 1952
dc810e39
AM
1953 if (c * 8 >= sz)
1954 {
1955 bfd_set_error (bfd_error_bad_value);
b34976b6 1956 return FALSE;
dc810e39
AM
1957 }
1958 amt = c;
1959 amt *= sizeof (carsym);
1960 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
beb1bf64 1961 if (bfd_ardata (abfd)->symdefs == NULL)
b34976b6 1962 return FALSE;
dc810e39 1963
beb1bf64
TR
1964 /* After the count comes a list of eight byte file offsets. */
1965 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1966 i < c;
1967 ++i, ++arsym, p += 8)
dc810e39 1968 arsym->file_offset = H_GET_64 (abfd, p);
beb1bf64
TR
1969
1970 /* After the file offsets come null terminated symbol names. */
1971 cend = contents + sz;
1972 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1973 i < c;
1974 ++i, ++arsym, p += strlen ((char *) p) + 1)
1975 {
1976 if (p >= cend)
1977 {
1978 bfd_set_error (bfd_error_bad_value);
b34976b6 1979 return FALSE;
beb1bf64
TR
1980 }
1981 arsym->name = (char *) p;
1982 }
1983
1984 bfd_ardata (abfd)->symdef_count = c;
b34976b6 1985 bfd_has_map (abfd) = TRUE;
beb1bf64 1986
b34976b6 1987 return TRUE;
beb1bf64
TR
1988}
1989
1990
beb1bf64
TR
1991/* See if this is an NEW XCOFF archive. */
1992
814fa6ab 1993static const bfd_target *
beb1bf64
TR
1994xcoff64_archive_p (abfd)
1995 bfd *abfd;
1996{
487e54f2 1997 struct artdata *tdata_hold;
beb1bf64
TR
1998 char magic[SXCOFFARMAG];
1999 /* This is the new format. */
2000 struct xcoff_ar_file_hdr_big hdr;
dc810e39 2001 bfd_size_type amt = SXCOFFARMAG;
beb1bf64 2002
dc810e39
AM
2003 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2004 {
2005 if (bfd_get_error () != bfd_error_system_call)
2006 bfd_set_error (bfd_error_wrong_format);
2007 return NULL;
2008 }
2009
2010 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2011 {
2012 bfd_set_error (bfd_error_wrong_format);
2013 return NULL;
2014 }
beb1bf64 2015
beb1bf64
TR
2016 /* Copy over the magic string. */
2017 memcpy (hdr.magic, magic, SXCOFFARMAG);
2018
2019 /* Now read the rest of the file header. */
487e54f2
AM
2020 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2021 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
dc810e39
AM
2022 {
2023 if (bfd_get_error () != bfd_error_system_call)
2024 bfd_set_error (bfd_error_wrong_format);
2025 return NULL;
2026 }
beb1bf64 2027
487e54f2
AM
2028 tdata_hold = bfd_ardata (abfd);
2029
2030 amt = sizeof (struct artdata);
2031 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2032 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2033 goto error_ret_restore;
2034
9e492e05
JJ
2035 /* Already cleared by bfd_zalloc above.
2036 bfd_ardata (abfd)->cache = NULL;
2037 bfd_ardata (abfd)->archive_head = NULL;
2038 bfd_ardata (abfd)->symdefs = NULL;
2039 bfd_ardata (abfd)->extended_names = NULL;
2040 bfd_ardata (abfd)->extended_names_size = 0; */
487e54f2
AM
2041 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2042 (const char **) NULL,
2043 10);
beb1bf64 2044
dc810e39
AM
2045 amt = SIZEOF_AR_FILE_HDR_BIG;
2046 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
beb1bf64 2047 if (bfd_ardata (abfd)->tdata == NULL)
487e54f2 2048 goto error_ret;
dc810e39 2049
beb1bf64
TR
2050 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2051
dc810e39
AM
2052 if (! xcoff64_slurp_armap (abfd))
2053 {
487e54f2 2054 error_ret:
dc810e39 2055 bfd_release (abfd, bfd_ardata (abfd));
487e54f2
AM
2056 error_ret_restore:
2057 bfd_ardata (abfd) = tdata_hold;
dc810e39
AM
2058 return NULL;
2059 }
beb1bf64
TR
2060
2061 return abfd->xvec;
2062}
2063
2064
2065/* Open the next element in an XCOFF archive. */
2066
814fa6ab 2067static bfd *
beb1bf64
TR
2068xcoff64_openr_next_archived_file (archive, last_file)
2069 bfd *archive;
2070 bfd *last_file;
2071{
cf3d882d 2072 bfd_vma filestart;
beb1bf64 2073
dc810e39
AM
2074 if ((xcoff_ardata (archive) == NULL)
2075 || ! xcoff_big_format_p (archive))
2076 {
2077 bfd_set_error (bfd_error_invalid_operation);
2078 return NULL;
2079 }
beb1bf64 2080
dc810e39
AM
2081 if (last_file == NULL)
2082 {
beb1bf64 2083 filestart = bfd_ardata (archive)->first_file_filepos;
dc810e39
AM
2084 }
2085 else
2086 {
487e54f2
AM
2087 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2088 (const char **) NULL, 10);
dc810e39 2089 }
487e54f2 2090
beb1bf64 2091 if (filestart == 0
487e54f2
AM
2092 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2093 (const char **) NULL, 10)
2094 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2095 (const char **) NULL, 10))
dc810e39
AM
2096 {
2097 bfd_set_error (bfd_error_no_more_archived_files);
2098 return NULL;
2099 }
beb1bf64 2100
cf3d882d 2101 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
beb1bf64
TR
2102}
2103
2104/* We can't use the usual coff_sizeof_headers routine, because AIX
2105 always uses an a.out header. */
2106
814fa6ab 2107static int
a6b96beb
AM
2108xcoff64_sizeof_headers (bfd *abfd,
2109 struct bfd_link_info *info ATTRIBUTE_UNUSED)
beb1bf64
TR
2110{
2111 int size;
2112
dc810e39 2113 size = bfd_coff_filhsz (abfd);
beb1bf64 2114
08da05b0 2115 /* Don't think the small aout header can be used since some of the
dc810e39
AM
2116 old elements have been reordered past the end of the old coff
2117 small aout size. */
beb1bf64
TR
2118
2119 if (xcoff_data (abfd)->full_aouthdr)
dc810e39 2120 size += bfd_coff_aoutsz (abfd);
beb1bf64 2121
dc810e39 2122 size += abfd->section_count * bfd_coff_scnhsz (abfd);
beb1bf64
TR
2123 return size;
2124}
2125
2126
2127
2128static asection *
dc810e39 2129xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
beb1bf64
TR
2130 bfd *abfd;
2131 union internal_auxent *aux;
2132 const char *symbol_name;
2133{
2134 asection *return_value = NULL;
2135
dc810e39
AM
2136 /* Changes from 32 :
2137 .sv == 8, is only for 32 bit programs
2138 .ti == 12 and .tb == 13 are now reserved. */
2139 static const char *names[19] =
2140 {
beb1bf64
TR
2141 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2142 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
dc810e39 2143 ".td", ".sv64", ".sv3264"
beb1bf64
TR
2144 };
2145
dc810e39
AM
2146 if ((19 >= aux->x_csect.x_smclas)
2147 && (NULL != names[aux->x_csect.x_smclas]))
2148 {
beb1bf64 2149
dc810e39
AM
2150 return_value = bfd_make_section_anyway
2151 (abfd, names[aux->x_csect.x_smclas]);
beb1bf64 2152
dc810e39
AM
2153 }
2154 else
2155 {
2156 (*_bfd_error_handler)
d003868e
AM
2157 (_("%B: symbol `%s' has unrecognized smclas %d"),
2158 abfd, symbol_name, aux->x_csect.x_smclas);
dc810e39
AM
2159 bfd_set_error (bfd_error_bad_value);
2160 }
beb1bf64
TR
2161
2162 return return_value;
2163}
2164
b34976b6 2165static bfd_boolean
beb1bf64 2166xcoff64_is_lineno_count_overflow (abfd, value)
dc810e39
AM
2167 bfd *abfd ATTRIBUTE_UNUSED;
2168 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2169{
b34976b6 2170 return FALSE;
beb1bf64
TR
2171}
2172
b34976b6 2173static bfd_boolean
beb1bf64 2174xcoff64_is_reloc_count_overflow (abfd, value)
dc810e39
AM
2175 bfd *abfd ATTRIBUTE_UNUSED;
2176 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2177{
b34976b6 2178 return FALSE;
beb1bf64
TR
2179}
2180
814fa6ab 2181static bfd_vma
beb1bf64 2182xcoff64_loader_symbol_offset (abfd, ldhdr)
dc810e39
AM
2183 bfd *abfd ATTRIBUTE_UNUSED;
2184 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2185{
2186 return (ldhdr->l_symoff);
2187}
2188
814fa6ab 2189static bfd_vma
beb1bf64 2190xcoff64_loader_reloc_offset (abfd, ldhdr)
dc810e39
AM
2191 bfd *abfd ATTRIBUTE_UNUSED;
2192 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2193{
2194 return (ldhdr->l_rldoff);
2195}
2196
b34976b6 2197static bfd_boolean
eb1e0e80
NC
2198xcoff64_bad_format_hook (abfd, filehdr)
2199 bfd * abfd;
2200 PTR filehdr;
2201{
2202 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2203
2204 /* Check flavor first. */
2205 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
b34976b6 2206 return FALSE;
eb1e0e80
NC
2207
2208 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
b34976b6 2209 return FALSE;
eb1e0e80 2210
b34976b6 2211 return TRUE;
eb1e0e80
NC
2212}
2213
b34976b6 2214static bfd_boolean
69f284c7 2215xcoff64_generate_rtinit (abfd, init, fini, rtld)
9a4c7f16
TR
2216 bfd *abfd;
2217 const char *init;
2218 const char *fini;
b34976b6 2219 bfd_boolean rtld;
9a4c7f16
TR
2220{
2221 bfd_byte filehdr_ext[FILHSZ];
69f284c7
TR
2222 bfd_byte scnhdr_ext[SCNHSZ * 3];
2223 bfd_byte syment_ext[SYMESZ * 10];
2224 bfd_byte reloc_ext[RELSZ * 3];
9a4c7f16
TR
2225 bfd_byte *data_buffer;
2226 bfd_size_type data_buffer_size;
2227 bfd_byte *string_table, *st_tmp;
2228 bfd_size_type string_table_size;
2229 bfd_vma val;
2230 size_t initsz, finisz;
2231 struct internal_filehdr filehdr;
69f284c7
TR
2232 struct internal_scnhdr text_scnhdr;
2233 struct internal_scnhdr data_scnhdr;
2234 struct internal_scnhdr bss_scnhdr;
9a4c7f16
TR
2235 struct internal_syment syment;
2236 union internal_auxent auxent;
2237 struct internal_reloc reloc;
54327882 2238
69f284c7 2239 char *text_name = ".text";
9a4c7f16 2240 char *data_name = ".data";
69f284c7 2241 char *bss_name = ".bss";
9a4c7f16 2242 char *rtinit_name = "__rtinit";
69f284c7 2243 char *rtld_name = "__rtld";
54327882 2244
69f284c7 2245 if (! bfd_xcoff_rtinit_size (abfd))
b34976b6 2246 return FALSE;
9a4c7f16
TR
2247
2248 initsz = (init == NULL ? 0 : 1 + strlen (init));
2249 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2250
eb1e0e80 2251 /* File header. */
9a4c7f16
TR
2252 memset (filehdr_ext, 0, FILHSZ);
2253 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2254 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
54327882 2255 filehdr.f_nscns = 3;
9a4c7f16
TR
2256 filehdr.f_timdat = 0;
2257 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2258 filehdr.f_symptr = 0; /* set below */
2259 filehdr.f_opthdr = 0;
2260 filehdr.f_flags = 0;
2261
eb1e0e80 2262 /* Section headers. */
69f284c7
TR
2263 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2264
eb1e0e80 2265 /* Text. */
69f284c7
TR
2266 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2267 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2268 text_scnhdr.s_paddr = 0;
2269 text_scnhdr.s_vaddr = 0;
2270 text_scnhdr.s_size = 0;
2271 text_scnhdr.s_scnptr = 0;
2272 text_scnhdr.s_relptr = 0;
2273 text_scnhdr.s_lnnoptr = 0;
2274 text_scnhdr.s_nreloc = 0;
2275 text_scnhdr.s_nlnno = 0;
2276 text_scnhdr.s_flags = STYP_TEXT;
2277
eb1e0e80 2278 /* Data. */
69f284c7
TR
2279 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2280 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2281 data_scnhdr.s_paddr = 0;
2282 data_scnhdr.s_vaddr = 0;
2283 data_scnhdr.s_size = 0; /* set below */
2284 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2285 data_scnhdr.s_relptr = 0; /* set below */
2286 data_scnhdr.s_lnnoptr = 0;
2287 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2288 data_scnhdr.s_nlnno = 0;
2289 data_scnhdr.s_flags = STYP_DATA;
2290
eb1e0e80 2291 /* Bss. */
69f284c7
TR
2292 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2293 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2294 bss_scnhdr.s_paddr = 0; /* set below */
2295 bss_scnhdr.s_vaddr = 0; /* set below */
2296 bss_scnhdr.s_size = 0; /* set below */
2297 bss_scnhdr.s_scnptr = 0;
54327882 2298 bss_scnhdr.s_relptr = 0;
69f284c7
TR
2299 bss_scnhdr.s_lnnoptr = 0;
2300 bss_scnhdr.s_nreloc = 0;
2301 bss_scnhdr.s_nlnno = 0;
2302 bss_scnhdr.s_flags = STYP_BSS;
9a4c7f16 2303
54327882 2304 /* .data
cf9ab45b
AM
2305 0x0000 0x00000000 : rtl
2306 0x0004 0x00000000 :
2307 0x0008 0x00000018 : offset to init, or 0
2308 0x000C 0x00000038 : offset to fini, or 0
2309 0x0010 0x00000010 : size of descriptor
2310 0x0014 0x00000000 : pad
2311 0x0018 0x00000000 : init, needs a reloc
2312 0x001C 0x00000000 :
2313 0x0020 0x00000058 : offset to init name
2314 0x0024 0x00000000 : flags, padded to a word
2315 0x0028 0x00000000 : empty init
2316 0x002C 0x00000000 :
2317 0x0030 0x00000000 :
2318 0x0034 0x00000000 :
2319 0x0038 0x00000000 : fini, needs a reloc
2320 0x003C 0x00000000 :
2321 0x0040 0x00000??? : offset to fini name
2322 0x0044 0x00000000 : flags, padded to a word
2323 0x0048 0x00000000 : empty fini
2324 0x004C 0x00000000 :
2325 0x0050 0x00000000 :
2326 0x0054 0x00000000 :
2327 0x0058 init name
9a4c7f16
TR
2328 0x0058 + initsz fini name */
2329
2330 data_buffer_size = 0x0058 + initsz + finisz;
2a52da53 2331 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
330693f5 2332 data_buffer = NULL;
9bab7074 2333 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
330693f5 2334 if (data_buffer == NULL)
b34976b6 2335 return FALSE;
54327882 2336
54327882 2337 if (initsz)
9a4c7f16
TR
2338 {
2339 val = 0x18;
2340 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2341 val = 0x58;
2342 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2343 memcpy (&data_buffer[val], init, initsz);
2344 }
2345
54327882 2346 if (finisz)
9a4c7f16
TR
2347 {
2348 val = 0x38;
2349 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2350 val = 0x58 + initsz;
2351 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2352 memcpy (&data_buffer[val], fini, finisz);
2353 }
2354
2355 val = 0x10;
2356 bfd_put_32 (abfd, val, &data_buffer[0x10]);
69f284c7
TR
2357 data_scnhdr.s_size = data_buffer_size;
2358 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
9a4c7f16 2359
eb1e0e80 2360 /* String table. */
9a4c7f16
TR
2361 string_table_size = 4;
2362 string_table_size += strlen (data_name) + 1;
2363 string_table_size += strlen (rtinit_name) + 1;
2364 string_table_size += initsz;
2365 string_table_size += finisz;
cf9ab45b 2366 if (rtld)
69f284c7 2367 string_table_size += strlen (rtld_name) + 1;
9a4c7f16 2368
9bab7074
AM
2369 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2370 if (string_table == NULL)
b34976b6 2371 return FALSE;
9bab7074 2372
9a4c7f16
TR
2373 val = string_table_size;
2374 bfd_put_32 (abfd, val, &string_table[0]);
2375 st_tmp = string_table + 4;
54327882
AM
2376
2377 /* symbols
9a4c7f16
TR
2378 0. .data csect
2379 2. __rtinit
54327882
AM
2380 4. init function
2381 6. fini function
69f284c7
TR
2382 8. __rtld */
2383 memset (syment_ext, 0, 10 * SYMESZ);
2384 memset (reloc_ext, 0, 3 * RELSZ);
9a4c7f16
TR
2385
2386 /* .data csect */
2387 memset (&syment, 0, sizeof (struct internal_syment));
2388 memset (&auxent, 0, sizeof (union internal_auxent));
2389
2390 syment._n._n_n._n_offset = st_tmp - string_table;
2391 memcpy (st_tmp, data_name, strlen (data_name));
2392 st_tmp += strlen (data_name) + 1;
2393
69f284c7 2394 syment.n_scnum = 2;
9a4c7f16
TR
2395 syment.n_sclass = C_HIDEXT;
2396 syment.n_numaux = 1;
2397 auxent.x_csect.x_scnlen.l = data_buffer_size;
2398 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2399 auxent.x_csect.x_smclas = XMC_RW;
54327882 2400 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2401 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2402 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2403 syment.n_numaux,
9a4c7f16
TR
2404 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2405 filehdr.f_nsyms += 2;
2406
2407 /* __rtinit */
2408 memset (&syment, 0, sizeof (struct internal_syment));
2409 memset (&auxent, 0, sizeof (union internal_auxent));
2410 syment._n._n_n._n_offset = st_tmp - string_table;
2411 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2412 st_tmp += strlen (rtinit_name) + 1;
54327882 2413
69f284c7 2414 syment.n_scnum = 2;
9a4c7f16
TR
2415 syment.n_sclass = C_EXT;
2416 syment.n_numaux = 1;
2417 auxent.x_csect.x_smtyp = XTY_LD;
2418 auxent.x_csect.x_smclas = XMC_RW;
54327882 2419 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2420 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2421 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2422 syment.n_numaux,
9a4c7f16
TR
2423 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2424 filehdr.f_nsyms += 2;
2425
eb1e0e80 2426 /* Init. */
54327882 2427 if (initsz)
9a4c7f16
TR
2428 {
2429 memset (&syment, 0, sizeof (struct internal_syment));
2430 memset (&auxent, 0, sizeof (union internal_auxent));
2431
2432 syment._n._n_n._n_offset = st_tmp - string_table;
2433 memcpy (st_tmp, init, initsz);
2434 st_tmp += initsz;
2435
2436 syment.n_sclass = C_EXT;
2437 syment.n_numaux = 1;
54327882 2438 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2439 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2440 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2441 syment.n_numaux,
9a4c7f16 2442 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
eb1e0e80 2443 /* Reloc. */
9a4c7f16
TR
2444 memset (&reloc, 0, sizeof (struct internal_reloc));
2445 reloc.r_vaddr = 0x0018;
2446 reloc.r_symndx = filehdr.f_nsyms;
2447 reloc.r_type = R_POS;
2448 reloc.r_size = 63;
2449 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2450
2451 filehdr.f_nsyms += 2;
69f284c7 2452 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2453 }
2454
eb1e0e80 2455 /* Finit. */
54327882 2456 if (finisz)
9a4c7f16
TR
2457 {
2458 memset (&syment, 0, sizeof (struct internal_syment));
2459 memset (&auxent, 0, sizeof (union internal_auxent));
2460
2461 syment._n._n_n._n_offset = st_tmp - string_table;
2462 memcpy (st_tmp, fini, finisz);
2463 st_tmp += finisz;
2464
2465 syment.n_sclass = C_EXT;
2466 syment.n_numaux = 1;
54327882 2467 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2468 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2469 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2470 syment.n_numaux,
9a4c7f16
TR
2471 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2472
eb1e0e80 2473 /* Reloc. */
9a4c7f16
TR
2474 memset (&reloc, 0, sizeof (struct internal_reloc));
2475 reloc.r_vaddr = 0x0038;
2476 reloc.r_symndx = filehdr.f_nsyms;
2477 reloc.r_type = R_POS;
2478 reloc.r_size = 63;
54327882 2479 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7 2480 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
9a4c7f16
TR
2481
2482 filehdr.f_nsyms += 2;
69f284c7 2483 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2484 }
2485
69f284c7
TR
2486 if (rtld)
2487 {
2488 memset (&syment, 0, sizeof (struct internal_syment));
2489 memset (&auxent, 0, sizeof (union internal_auxent));
2490
2491 syment._n._n_n._n_offset = st_tmp - string_table;
2492 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2493 st_tmp += strlen (rtld_name) + 1;
2494
2495 syment.n_sclass = C_EXT;
2496 syment.n_numaux = 1;
54327882 2497 bfd_coff_swap_sym_out (abfd, &syment,
69f284c7 2498 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2499 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2500 syment.n_numaux,
69f284c7
TR
2501 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2502
eb1e0e80 2503 /* Reloc. */
69f284c7
TR
2504 memset (&reloc, 0, sizeof (struct internal_reloc));
2505 reloc.r_vaddr = 0x0000;
2506 reloc.r_symndx = filehdr.f_nsyms;
2507 reloc.r_type = R_POS;
2508 reloc.r_size = 63;
54327882 2509 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7
TR
2510 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2511
2512 filehdr.f_nsyms += 2;
2513 data_scnhdr.s_nreloc += 1;
2514
2515 bss_scnhdr.s_size = 0;
2516 }
2517
2518 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2519 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
9a4c7f16
TR
2520
2521 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2522 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
69f284c7
TR
2523 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2524 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2525 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2526 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
9a4c7f16 2527 bfd_bwrite (data_buffer, data_buffer_size, abfd);
69f284c7 2528 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
9a4c7f16
TR
2529 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2530 bfd_bwrite (string_table, string_table_size, abfd);
2531
330693f5
TR
2532 free (data_buffer);
2533 data_buffer = NULL;
2534
b34976b6 2535 return TRUE;
9a4c7f16
TR
2536}
2537
beb1bf64
TR
2538/* The typical dynamic reloc. */
2539
2540static reloc_howto_type xcoff64_dynamic_reloc =
dc810e39
AM
2541HOWTO (0, /* type */
2542 0, /* rightshift */
2543 4, /* size (0 = byte, 1 = short, 2 = long) */
2544 64, /* bitsize */
b34976b6 2545 FALSE, /* pc_relative */
dc810e39
AM
2546 0, /* bitpos */
2547 complain_overflow_bitfield, /* complain_on_overflow */
2548 0, /* special_function */
2549 "R_POS", /* name */
b34976b6 2550 TRUE, /* partial_inplace */
dc810e39
AM
2551 MINUS_ONE, /* src_mask */
2552 MINUS_ONE, /* dst_mask */
b34976b6 2553 FALSE); /* pcrel_offset */
beb1bf64
TR
2554
2555static unsigned long xcoff64_glink_code[10] =
2556{
54327882
AM
2557 0xe9820000, /* ld r12,0(r2) */
2558 0xf8410028, /* std r2,40(r1) */
2559 0xe80c0000, /* ld r0,0(r12) */
2560 0xe84c0008, /* ld r0,8(r12) */
2561 0x7c0903a6, /* mtctr r0 */
2562 0x4e800420, /* bctr */
2563 0x00000000, /* start of traceback table */
2564 0x000ca000, /* traceback table */
2565 0x00000000, /* traceback table */
2566 0x00000018, /* ??? */
beb1bf64
TR
2567};
2568
dc810e39 2569static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
cf9ab45b
AM
2570 {
2571 { /* COFF backend, defined in libcoff.h. */
2572 _bfd_xcoff64_swap_aux_in,
2573 _bfd_xcoff64_swap_sym_in,
2574 _bfd_xcoff64_swap_lineno_in,
2575 _bfd_xcoff64_swap_aux_out,
2576 _bfd_xcoff64_swap_sym_out,
2577 _bfd_xcoff64_swap_lineno_out,
2578 xcoff64_swap_reloc_out,
2579 coff_swap_filehdr_out,
2580 coff_swap_aouthdr_out,
2581 coff_swap_scnhdr_out,
2582 FILHSZ,
2583 AOUTSZ,
2584 SCNHSZ,
2585 SYMESZ,
2586 AUXESZ,
2587 RELSZ,
2588 LINESZ,
2589 FILNMLEN,
b34976b6 2590 TRUE, /* _bfd_coff_long_filenames */
88183869 2591 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 2592 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2593 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2594 4, /* _bfd_coff_debug_string_prefix_length */
2595 coff_swap_filehdr_in,
2596 coff_swap_aouthdr_in,
2597 coff_swap_scnhdr_in,
2598 xcoff64_swap_reloc_in,
2599 xcoff64_bad_format_hook,
2600 coff_set_arch_mach_hook,
2601 coff_mkobject_hook,
2602 styp_to_sec_flags,
2603 coff_set_alignment_hook,
2604 coff_slurp_symbol_table,
2605 symname_in_debug_hook,
2606 coff_pointerize_aux_hook,
2607 coff_print_aux,
2608 dummy_reloc16_extra_cases,
2609 dummy_reloc16_estimate,
e144674a 2610 NULL, /* bfd_coff_symbol_classification */
cf9ab45b
AM
2611 coff_compute_section_file_positions,
2612 NULL, /* _bfd_coff_start_final_link */
2613 xcoff64_ppc_relocate_section,
2614 coff_rtype_to_howto,
2615 NULL, /* _bfd_coff_adjust_symndx */
2616 _bfd_generic_link_add_one_symbol,
2617 coff_link_output_has_begun,
2b5c217d
NC
2618 coff_final_link_postscript,
2619 NULL /* print_pdata. */
cf9ab45b
AM
2620 },
2621
2622 0x01EF, /* magic number */
2623 bfd_arch_powerpc,
2624 bfd_mach_ppc_620,
2625
2626 /* Function pointers to xcoff specific swap routines. */
2627 xcoff64_swap_ldhdr_in,
2628 xcoff64_swap_ldhdr_out,
2629 xcoff64_swap_ldsym_in,
2630 xcoff64_swap_ldsym_out,
2631 xcoff64_swap_ldrel_in,
2632 xcoff64_swap_ldrel_out,
2633
2634 /* Sizes. */
2635 LDHDRSZ,
2636 LDSYMSZ,
2637 LDRELSZ,
2638 24, /* _xcoff_function_descriptor_size */
2639 0, /* _xcoff_small_aout_header_size */
2640
2641 /* Versions. */
2642 2, /* _xcoff_ldhdr_version */
2643
2644 _bfd_xcoff64_put_symbol_name,
2645 _bfd_xcoff64_put_ldsymbol_name,
2646 &xcoff64_dynamic_reloc,
2647 xcoff64_create_csect_from_smclas,
2648
2649 /* Lineno and reloc count overflow. */
2650 xcoff64_is_lineno_count_overflow,
2651 xcoff64_is_reloc_count_overflow,
2652
2653 xcoff64_loader_symbol_offset,
2654 xcoff64_loader_reloc_offset,
2655
2656 /* glink. */
2657 &xcoff64_glink_code[0],
2658 40, /* _xcoff_glink_size */
2659
2660 /* rtinit. */
2661 88, /* _xcoff_rtinit_size */
2662 xcoff64_generate_rtinit,
2663 };
beb1bf64 2664
eb1e0e80 2665/* The transfer vector that leads the outside world to all of the above. */
beb1bf64 2666const bfd_target rs6000coff64_vec =
cf9ab45b
AM
2667 {
2668 "aixcoff64-rs6000",
2669 bfd_target_xcoff_flavour,
2670 BFD_ENDIAN_BIG, /* data byte order is big */
2671 BFD_ENDIAN_BIG, /* header byte order is big */
2672
2673 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2674 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2675
a7c71b0c 2676 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2677 0, /* leading char */
2678 '/', /* ar_pad_char */
2679 15, /* ar_max_namelen */
2680
2681 /* data */
2682 bfd_getb64,
2683 bfd_getb_signed_64,
2684 bfd_putb64,
2685 bfd_getb32,
2686 bfd_getb_signed_32,
2687 bfd_putb32,
2688 bfd_getb16,
2689 bfd_getb_signed_16,
2690 bfd_putb16,
2691
2692 /* hdrs */
2693 bfd_getb64,
2694 bfd_getb_signed_64,
2695 bfd_putb64,
2696 bfd_getb32,
2697 bfd_getb_signed_32,
2698 bfd_putb32,
2699 bfd_getb16,
2700 bfd_getb_signed_16,
2701 bfd_putb16,
2702
2703 { /* bfd_check_format */
2704 _bfd_dummy_target,
2705 coff_object_p,
2706 xcoff64_archive_p,
2707 CORE_FILE_P
2708 },
2709
2710 { /* bfd_set_format */
2711 bfd_false,
2712 coff_mkobject,
2713 _bfd_generic_mkarchive,
2714 bfd_false
2715 },
2716
2717 {/* bfd_write_contents */
2718 bfd_false,
2719 xcoff64_write_object_contents,
2720 _bfd_xcoff_write_archive_contents,
2721 bfd_false
2722 },
2723
2724 /* Generic */
2725 bfd_true,
2726 bfd_true,
2727 coff_new_section_hook,
2728 _bfd_generic_get_section_contents,
2729 _bfd_generic_get_section_contents_in_window,
2730
2731 /* Copy */
2732 _bfd_xcoff_copy_private_bfd_data,
b34976b6 2733 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
60b48850 2734 _bfd_generic_init_private_section_data,
b34976b6
AM
2735 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2736 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
80fccad2 2737 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
b34976b6
AM
2738 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2739 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
cf9ab45b
AM
2740
2741 /* Core */
2742 coff_core_file_failing_command,
2743 coff_core_file_failing_signal,
2744 coff_core_file_matches_executable_p,
2745
2746 /* Archive */
2747 xcoff64_slurp_armap,
dc810e39 2748 bfd_false,
b34976b6 2749 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
cf9ab45b
AM
2750 bfd_dont_truncate_arname,
2751 _bfd_xcoff_write_armap,
2752 _bfd_xcoff_read_ar_hdr,
2753 xcoff64_openr_next_archived_file,
2754 _bfd_generic_get_elt_at_index,
2755 _bfd_xcoff_stat_arch_elt,
2756 bfd_true,
2757
2758 /* Symbols */
2759 coff_get_symtab_upper_bound,
6cee3f79 2760 coff_canonicalize_symtab,
cf9ab45b
AM
2761 coff_make_empty_symbol,
2762 coff_print_symbol,
2763 coff_get_symbol_info,
2764 _bfd_xcoff_is_local_label_name,
7db6994f 2765 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
2766 coff_get_lineno,
2767 coff_find_nearest_line,
4575b1b5 2768 _bfd_generic_find_line,
4ab527b0 2769 coff_find_inliner_info,
cf9ab45b
AM
2770 coff_bfd_make_debug_symbol,
2771 _bfd_generic_read_minisymbols,
2772 _bfd_generic_minisymbol_to_symbol,
2773
2774 /* Reloc */
2775 coff_get_reloc_upper_bound,
2776 coff_canonicalize_reloc,
2777 xcoff64_reloc_type_lookup,
157090f7 2778 xcoff64_reloc_name_lookup,
cf9ab45b
AM
2779
2780 /* Write */
2781 coff_set_arch_mach,
2782 coff_set_section_contents,
2783
2784 /* Link */
2785 xcoff64_sizeof_headers,
2786 bfd_generic_get_relocated_section_contents,
2787 bfd_generic_relax_section,
2788 _bfd_xcoff_bfd_link_hash_table_create,
2789 _bfd_generic_link_hash_table_free,
2790 _bfd_xcoff_bfd_link_add_symbols,
2791 _bfd_generic_link_just_syms,
2792 _bfd_xcoff_bfd_final_link,
2793 _bfd_generic_link_split_section,
2794 bfd_generic_gc_sections,
2795 bfd_generic_merge_sections,
72adc230 2796 bfd_generic_is_group_section,
cf9ab45b 2797 bfd_generic_discard_group,
082b7297 2798 _bfd_generic_section_already_linked,
cf9ab45b
AM
2799
2800 /* Dynamic */
2801 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2802 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 2803 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
2804 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2805 _bfd_xcoff_canonicalize_dynamic_reloc,
2806
2807 /* Opposite endian version, none exists */
2808 NULL,
2809
2810 (void *) &bfd_xcoff_backend_data,
2811 };
eb1e0e80 2812
b34976b6
AM
2813extern const bfd_target *xcoff64_core_p
2814 PARAMS ((bfd *));
2815extern bfd_boolean xcoff64_core_file_matches_executable_p
2816 PARAMS ((bfd *, bfd *));
2817extern char *xcoff64_core_file_failing_command
2818 PARAMS ((bfd *));
2819extern int xcoff64_core_file_failing_signal
2820 PARAMS ((bfd *));
eb1e0e80
NC
2821
2822/* AIX 5 */
54327882 2823static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
cf9ab45b
AM
2824 {
2825 { /* COFF backend, defined in libcoff.h. */
2826 _bfd_xcoff64_swap_aux_in,
2827 _bfd_xcoff64_swap_sym_in,
2828 _bfd_xcoff64_swap_lineno_in,
2829 _bfd_xcoff64_swap_aux_out,
2830 _bfd_xcoff64_swap_sym_out,
2831 _bfd_xcoff64_swap_lineno_out,
2832 xcoff64_swap_reloc_out,
2833 coff_swap_filehdr_out,
2834 coff_swap_aouthdr_out,
2835 coff_swap_scnhdr_out,
2836 FILHSZ,
2837 AOUTSZ,
2838 SCNHSZ,
2839 SYMESZ,
2840 AUXESZ,
2841 RELSZ,
2842 LINESZ,
2843 FILNMLEN,
b34976b6 2844 TRUE, /* _bfd_coff_long_filenames */
88183869 2845 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 2846 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2847 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2848 4, /* _bfd_coff_debug_string_prefix_length */
2849 coff_swap_filehdr_in,
2850 coff_swap_aouthdr_in,
2851 coff_swap_scnhdr_in,
2852 xcoff64_swap_reloc_in,
2853 xcoff64_bad_format_hook,
2854 coff_set_arch_mach_hook,
2855 coff_mkobject_hook,
2856 styp_to_sec_flags,
2857 coff_set_alignment_hook,
2858 coff_slurp_symbol_table,
2859 symname_in_debug_hook,
2860 coff_pointerize_aux_hook,
2861 coff_print_aux,
2862 dummy_reloc16_extra_cases,
2863 dummy_reloc16_estimate,
2864 NULL, /* bfd_coff_sym_is_global */
2865 coff_compute_section_file_positions,
2866 NULL, /* _bfd_coff_start_final_link */
2867 xcoff64_ppc_relocate_section,
2868 coff_rtype_to_howto,
2869 NULL, /* _bfd_coff_adjust_symndx */
2870 _bfd_generic_link_add_one_symbol,
2871 coff_link_output_has_begun,
2b5c217d
NC
2872 coff_final_link_postscript,
2873 NULL /* print_pdata. */
cf9ab45b
AM
2874 },
2875
2876 U64_TOCMAGIC, /* magic number */
2877 bfd_arch_powerpc,
2878 bfd_mach_ppc_620,
2879
2880 /* Function pointers to xcoff specific swap routines. */
2881 xcoff64_swap_ldhdr_in,
2882 xcoff64_swap_ldhdr_out,
2883 xcoff64_swap_ldsym_in,
2884 xcoff64_swap_ldsym_out,
2885 xcoff64_swap_ldrel_in,
2886 xcoff64_swap_ldrel_out,
2887
2888 /* Sizes. */
2889 LDHDRSZ,
2890 LDSYMSZ,
2891 LDRELSZ,
2892 24, /* _xcoff_function_descriptor_size */
2893 0, /* _xcoff_small_aout_header_size */
2894 /* Versions. */
2895 2, /* _xcoff_ldhdr_version */
2896
2897 _bfd_xcoff64_put_symbol_name,
2898 _bfd_xcoff64_put_ldsymbol_name,
2899 &xcoff64_dynamic_reloc,
2900 xcoff64_create_csect_from_smclas,
2901
2902 /* Lineno and reloc count overflow. */
2903 xcoff64_is_lineno_count_overflow,
2904 xcoff64_is_reloc_count_overflow,
2905
2906 xcoff64_loader_symbol_offset,
2907 xcoff64_loader_reloc_offset,
2908
2909 /* glink. */
2910 &xcoff64_glink_code[0],
2911 40, /* _xcoff_glink_size */
2912
2913 /* rtinit. */
2914 88, /* _xcoff_rtinit_size */
2915 xcoff64_generate_rtinit,
2916 };
eb1e0e80
NC
2917
2918/* The transfer vector that leads the outside world to all of the above. */
2919const bfd_target aix5coff64_vec =
cf9ab45b
AM
2920 {
2921 "aix5coff64-rs6000",
2922 bfd_target_xcoff_flavour,
2923 BFD_ENDIAN_BIG, /* data byte order is big */
2924 BFD_ENDIAN_BIG, /* header byte order is big */
2925
2926 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2927 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2928
a7c71b0c 2929 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2930 0, /* leading char */
2931 '/', /* ar_pad_char */
2932 15, /* ar_max_namelen */
2933
2934 /* data */
2935 bfd_getb64,
2936 bfd_getb_signed_64,
2937 bfd_putb64,
2938 bfd_getb32,
2939 bfd_getb_signed_32,
2940 bfd_putb32,
2941 bfd_getb16,
2942 bfd_getb_signed_16,
2943 bfd_putb16,
2944
2945 /* hdrs */
2946 bfd_getb64,
2947 bfd_getb_signed_64,
2948 bfd_putb64,
2949 bfd_getb32,
2950 bfd_getb_signed_32,
2951 bfd_putb32,
2952 bfd_getb16,
2953 bfd_getb_signed_16,
2954 bfd_putb16,
2955
2956 { /* bfd_check_format */
2957 _bfd_dummy_target,
2958 coff_object_p,
2959 xcoff64_archive_p,
2960 xcoff64_core_p
2961 },
2962
2963 { /* bfd_set_format */
2964 bfd_false,
2965 coff_mkobject,
2966 _bfd_generic_mkarchive,
2967 bfd_false
2968 },
2969
2970 {/* bfd_write_contents */
2971 bfd_false,
2972 xcoff64_write_object_contents,
2973 _bfd_xcoff_write_archive_contents,
2974 bfd_false
2975 },
2976
2977 /* Generic */
2978 bfd_true,
2979 bfd_true,
2980 coff_new_section_hook,
2981 _bfd_generic_get_section_contents,
2982 _bfd_generic_get_section_contents_in_window,
2983
2984 /* Copy */
2985 _bfd_xcoff_copy_private_bfd_data,
b34976b6 2986 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
60b48850 2987 _bfd_generic_init_private_section_data,
b34976b6
AM
2988 ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2989 ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
80fccad2 2990 ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
b34976b6
AM
2991 ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
2992 ((bfd_boolean (*) (bfd *, void * )) bfd_true),
cf9ab45b
AM
2993
2994 /* Core */
2995 xcoff64_core_file_failing_command,
2996 xcoff64_core_file_failing_signal,
2997 xcoff64_core_file_matches_executable_p,
2998
2999 /* Archive */
3000 xcoff64_slurp_armap,
54327882 3001 bfd_false,
b34976b6 3002 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
cf9ab45b
AM
3003 bfd_dont_truncate_arname,
3004 _bfd_xcoff_write_armap,
3005 _bfd_xcoff_read_ar_hdr,
3006 xcoff64_openr_next_archived_file,
3007 _bfd_generic_get_elt_at_index,
3008 _bfd_xcoff_stat_arch_elt,
3009 bfd_true,
3010
3011 /* Symbols */
3012 coff_get_symtab_upper_bound,
6cee3f79 3013 coff_canonicalize_symtab,
cf9ab45b
AM
3014 coff_make_empty_symbol,
3015 coff_print_symbol,
3016 coff_get_symbol_info,
3017 _bfd_xcoff_is_local_label_name,
7db6994f 3018 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
3019 coff_get_lineno,
3020 coff_find_nearest_line,
4575b1b5 3021 _bfd_generic_find_line,
4ab527b0 3022 coff_find_inliner_info,
cf9ab45b
AM
3023 coff_bfd_make_debug_symbol,
3024 _bfd_generic_read_minisymbols,
3025 _bfd_generic_minisymbol_to_symbol,
3026
3027 /* Reloc */
3028 coff_get_reloc_upper_bound,
3029 coff_canonicalize_reloc,
3030 xcoff64_reloc_type_lookup,
157090f7 3031 xcoff64_reloc_name_lookup,
cf9ab45b
AM
3032
3033 /* Write */
3034 coff_set_arch_mach,
3035 coff_set_section_contents,
3036
3037 /* Link */
3038 xcoff64_sizeof_headers,
3039 bfd_generic_get_relocated_section_contents,
3040 bfd_generic_relax_section,
3041 _bfd_xcoff_bfd_link_hash_table_create,
3042 _bfd_generic_link_hash_table_free,
3043 _bfd_xcoff_bfd_link_add_symbols,
3044 _bfd_generic_link_just_syms,
3045 _bfd_xcoff_bfd_final_link,
3046 _bfd_generic_link_split_section,
3047 bfd_generic_gc_sections,
3048 bfd_generic_merge_sections,
72adc230 3049 bfd_generic_is_group_section,
cf9ab45b 3050 bfd_generic_discard_group,
082b7297 3051 _bfd_generic_section_already_linked,
cf9ab45b
AM
3052
3053 /* Dynamic */
3054 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3055 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 3056 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
3057 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3058 _bfd_xcoff_canonicalize_dynamic_reloc,
3059
3060 /* Opposite endian version, none exists. */
3061 NULL,
3062
3063 (void *) & bfd_xcoff_aix5_backend_data,
3064 };
This page took 0.792195 seconds and 4 git commands to generate.