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