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