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