Properly check undefined symbols when gc_sections is active.
[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
c865e45b 1597 /* Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
38487e5e 1598 HOWTO (R_REF, /* type */
dc810e39 1599 0, /* rightshift */
c865e45b
RS
1600 0, /* size (0 = byte, 1 = short, 2 = long) */
1601 1, /* 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];
c865e45b
RS
1885 case BFD_RELOC_NONE:
1886 return &xcoff64_howto_table[0xf];
beb1bf64
TR
1887 default:
1888 return NULL;
1889 }
1890}
1891
157090f7
AM
1892static reloc_howto_type *
1893xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1894 const char *r_name)
1895{
1896 unsigned int i;
1897
1898 for (i = 0;
1899 i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
1900 i++)
1901 if (xcoff64_howto_table[i].name != NULL
1902 && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
1903 return &xcoff64_howto_table[i];
1904
1905 return NULL;
1906}
1907
beb1bf64
TR
1908/* Read in the armap of an XCOFF archive. */
1909
b34976b6 1910static bfd_boolean
beb1bf64
TR
1911xcoff64_slurp_armap (abfd)
1912 bfd *abfd;
1913{
1914 file_ptr off;
1915 size_t namlen;
dc810e39 1916 bfd_size_type sz, amt;
beb1bf64
TR
1917 bfd_byte *contents, *cend;
1918 bfd_vma c, i;
1919 carsym *arsym;
1920 bfd_byte *p;
dc810e39 1921 file_ptr pos;
beb1bf64
TR
1922
1923 /* This is for the new format. */
1924 struct xcoff_ar_hdr_big hdr;
1925
dc810e39
AM
1926 if (xcoff_ardata (abfd) == NULL)
1927 {
b34976b6
AM
1928 bfd_has_map (abfd) = FALSE;
1929 return TRUE;
dc810e39 1930 }
beb1bf64 1931
487e54f2
AM
1932 off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
1933 (const char **) NULL, 10);
dc810e39
AM
1934 if (off == 0)
1935 {
b34976b6
AM
1936 bfd_has_map (abfd) = FALSE;
1937 return TRUE;
dc810e39 1938 }
beb1bf64
TR
1939
1940 if (bfd_seek (abfd, off, SEEK_SET) != 0)
b34976b6 1941 return FALSE;
beb1bf64
TR
1942
1943 /* The symbol table starts with a normal archive header. */
dc810e39
AM
1944 if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
1945 != SIZEOF_AR_HDR_BIG)
b34976b6 1946 return FALSE;
beb1bf64
TR
1947
1948 /* Skip the name (normally empty). */
1949 namlen = strtol (hdr.namlen, (char **) NULL, 10);
dc810e39
AM
1950 pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
1951 if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
b34976b6 1952 return FALSE;
beb1bf64 1953
487e54f2 1954 sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
beb1bf64
TR
1955
1956 /* Read in the entire symbol table. */
1957 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1958 if (contents == NULL)
b34976b6 1959 return FALSE;
dc810e39 1960 if (bfd_bread ((PTR) contents, sz, abfd) != sz)
b34976b6 1961 return FALSE;
beb1bf64
TR
1962
1963 /* The symbol table starts with an eight byte count. */
dc810e39 1964 c = H_GET_64 (abfd, contents);
beb1bf64 1965
dc810e39
AM
1966 if (c * 8 >= sz)
1967 {
1968 bfd_set_error (bfd_error_bad_value);
b34976b6 1969 return FALSE;
dc810e39
AM
1970 }
1971 amt = c;
1972 amt *= sizeof (carsym);
1973 bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
beb1bf64 1974 if (bfd_ardata (abfd)->symdefs == NULL)
b34976b6 1975 return FALSE;
dc810e39 1976
beb1bf64
TR
1977 /* After the count comes a list of eight byte file offsets. */
1978 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1979 i < c;
1980 ++i, ++arsym, p += 8)
dc810e39 1981 arsym->file_offset = H_GET_64 (abfd, p);
beb1bf64
TR
1982
1983 /* After the file offsets come null terminated symbol names. */
1984 cend = contents + sz;
1985 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1986 i < c;
1987 ++i, ++arsym, p += strlen ((char *) p) + 1)
1988 {
1989 if (p >= cend)
1990 {
1991 bfd_set_error (bfd_error_bad_value);
b34976b6 1992 return FALSE;
beb1bf64
TR
1993 }
1994 arsym->name = (char *) p;
1995 }
1996
1997 bfd_ardata (abfd)->symdef_count = c;
b34976b6 1998 bfd_has_map (abfd) = TRUE;
beb1bf64 1999
b34976b6 2000 return TRUE;
beb1bf64
TR
2001}
2002
2003
beb1bf64
TR
2004/* See if this is an NEW XCOFF archive. */
2005
814fa6ab 2006static const bfd_target *
beb1bf64
TR
2007xcoff64_archive_p (abfd)
2008 bfd *abfd;
2009{
487e54f2 2010 struct artdata *tdata_hold;
beb1bf64
TR
2011 char magic[SXCOFFARMAG];
2012 /* This is the new format. */
2013 struct xcoff_ar_file_hdr_big hdr;
dc810e39 2014 bfd_size_type amt = SXCOFFARMAG;
beb1bf64 2015
dc810e39
AM
2016 if (bfd_bread ((PTR) magic, amt, abfd) != amt)
2017 {
2018 if (bfd_get_error () != bfd_error_system_call)
2019 bfd_set_error (bfd_error_wrong_format);
2020 return NULL;
2021 }
2022
2023 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
2024 {
2025 bfd_set_error (bfd_error_wrong_format);
2026 return NULL;
2027 }
beb1bf64 2028
beb1bf64
TR
2029 /* Copy over the magic string. */
2030 memcpy (hdr.magic, magic, SXCOFFARMAG);
2031
2032 /* Now read the rest of the file header. */
487e54f2
AM
2033 amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
2034 if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
dc810e39
AM
2035 {
2036 if (bfd_get_error () != bfd_error_system_call)
2037 bfd_set_error (bfd_error_wrong_format);
2038 return NULL;
2039 }
beb1bf64 2040
487e54f2
AM
2041 tdata_hold = bfd_ardata (abfd);
2042
2043 amt = sizeof (struct artdata);
2044 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
2045 if (bfd_ardata (abfd) == (struct artdata *) NULL)
2046 goto error_ret_restore;
2047
9e492e05
JJ
2048 /* Already cleared by bfd_zalloc above.
2049 bfd_ardata (abfd)->cache = NULL;
2050 bfd_ardata (abfd)->archive_head = NULL;
2051 bfd_ardata (abfd)->symdefs = NULL;
2052 bfd_ardata (abfd)->extended_names = NULL;
2053 bfd_ardata (abfd)->extended_names_size = 0; */
487e54f2
AM
2054 bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
2055 (const char **) NULL,
2056 10);
beb1bf64 2057
dc810e39
AM
2058 amt = SIZEOF_AR_FILE_HDR_BIG;
2059 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
beb1bf64 2060 if (bfd_ardata (abfd)->tdata == NULL)
487e54f2 2061 goto error_ret;
dc810e39 2062
beb1bf64
TR
2063 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
2064
dc810e39
AM
2065 if (! xcoff64_slurp_armap (abfd))
2066 {
487e54f2 2067 error_ret:
dc810e39 2068 bfd_release (abfd, bfd_ardata (abfd));
487e54f2
AM
2069 error_ret_restore:
2070 bfd_ardata (abfd) = tdata_hold;
dc810e39
AM
2071 return NULL;
2072 }
beb1bf64
TR
2073
2074 return abfd->xvec;
2075}
2076
2077
2078/* Open the next element in an XCOFF archive. */
2079
814fa6ab 2080static bfd *
beb1bf64
TR
2081xcoff64_openr_next_archived_file (archive, last_file)
2082 bfd *archive;
2083 bfd *last_file;
2084{
cf3d882d 2085 bfd_vma filestart;
beb1bf64 2086
dc810e39
AM
2087 if ((xcoff_ardata (archive) == NULL)
2088 || ! xcoff_big_format_p (archive))
2089 {
2090 bfd_set_error (bfd_error_invalid_operation);
2091 return NULL;
2092 }
beb1bf64 2093
dc810e39
AM
2094 if (last_file == NULL)
2095 {
beb1bf64 2096 filestart = bfd_ardata (archive)->first_file_filepos;
dc810e39
AM
2097 }
2098 else
2099 {
487e54f2
AM
2100 filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
2101 (const char **) NULL, 10);
dc810e39 2102 }
487e54f2 2103
beb1bf64 2104 if (filestart == 0
487e54f2
AM
2105 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
2106 (const char **) NULL, 10)
2107 || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
2108 (const char **) NULL, 10))
dc810e39
AM
2109 {
2110 bfd_set_error (bfd_error_no_more_archived_files);
2111 return NULL;
2112 }
beb1bf64 2113
cf3d882d 2114 return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
beb1bf64
TR
2115}
2116
2117/* We can't use the usual coff_sizeof_headers routine, because AIX
2118 always uses an a.out header. */
2119
814fa6ab 2120static int
a6b96beb
AM
2121xcoff64_sizeof_headers (bfd *abfd,
2122 struct bfd_link_info *info ATTRIBUTE_UNUSED)
beb1bf64
TR
2123{
2124 int size;
2125
dc810e39 2126 size = bfd_coff_filhsz (abfd);
beb1bf64 2127
08da05b0 2128 /* Don't think the small aout header can be used since some of the
dc810e39
AM
2129 old elements have been reordered past the end of the old coff
2130 small aout size. */
beb1bf64
TR
2131
2132 if (xcoff_data (abfd)->full_aouthdr)
dc810e39 2133 size += bfd_coff_aoutsz (abfd);
beb1bf64 2134
dc810e39 2135 size += abfd->section_count * bfd_coff_scnhsz (abfd);
beb1bf64
TR
2136 return size;
2137}
2138
2139
2140
2141static asection *
dc810e39 2142xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
beb1bf64
TR
2143 bfd *abfd;
2144 union internal_auxent *aux;
2145 const char *symbol_name;
2146{
2147 asection *return_value = NULL;
2148
dc810e39
AM
2149 /* Changes from 32 :
2150 .sv == 8, is only for 32 bit programs
2151 .ti == 12 and .tb == 13 are now reserved. */
2152 static const char *names[19] =
2153 {
beb1bf64
TR
2154 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
2155 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
dc810e39 2156 ".td", ".sv64", ".sv3264"
beb1bf64
TR
2157 };
2158
dc810e39
AM
2159 if ((19 >= aux->x_csect.x_smclas)
2160 && (NULL != names[aux->x_csect.x_smclas]))
2161 {
beb1bf64 2162
dc810e39
AM
2163 return_value = bfd_make_section_anyway
2164 (abfd, names[aux->x_csect.x_smclas]);
beb1bf64 2165
dc810e39
AM
2166 }
2167 else
2168 {
2169 (*_bfd_error_handler)
d003868e
AM
2170 (_("%B: symbol `%s' has unrecognized smclas %d"),
2171 abfd, symbol_name, aux->x_csect.x_smclas);
dc810e39
AM
2172 bfd_set_error (bfd_error_bad_value);
2173 }
beb1bf64
TR
2174
2175 return return_value;
2176}
2177
b34976b6 2178static bfd_boolean
beb1bf64 2179xcoff64_is_lineno_count_overflow (abfd, value)
dc810e39
AM
2180 bfd *abfd ATTRIBUTE_UNUSED;
2181 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2182{
b34976b6 2183 return FALSE;
beb1bf64
TR
2184}
2185
b34976b6 2186static bfd_boolean
beb1bf64 2187xcoff64_is_reloc_count_overflow (abfd, value)
dc810e39
AM
2188 bfd *abfd ATTRIBUTE_UNUSED;
2189 bfd_vma value ATTRIBUTE_UNUSED;
beb1bf64 2190{
b34976b6 2191 return FALSE;
beb1bf64
TR
2192}
2193
814fa6ab 2194static bfd_vma
beb1bf64 2195xcoff64_loader_symbol_offset (abfd, ldhdr)
dc810e39
AM
2196 bfd *abfd ATTRIBUTE_UNUSED;
2197 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2198{
2199 return (ldhdr->l_symoff);
2200}
2201
814fa6ab 2202static bfd_vma
beb1bf64 2203xcoff64_loader_reloc_offset (abfd, ldhdr)
dc810e39
AM
2204 bfd *abfd ATTRIBUTE_UNUSED;
2205 struct internal_ldhdr *ldhdr;
beb1bf64
TR
2206{
2207 return (ldhdr->l_rldoff);
2208}
2209
b34976b6 2210static bfd_boolean
eb1e0e80
NC
2211xcoff64_bad_format_hook (abfd, filehdr)
2212 bfd * abfd;
2213 PTR filehdr;
2214{
2215 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2216
2217 /* Check flavor first. */
2218 if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
b34976b6 2219 return FALSE;
eb1e0e80
NC
2220
2221 if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
b34976b6 2222 return FALSE;
eb1e0e80 2223
b34976b6 2224 return TRUE;
eb1e0e80
NC
2225}
2226
b34976b6 2227static bfd_boolean
69f284c7 2228xcoff64_generate_rtinit (abfd, init, fini, rtld)
9a4c7f16
TR
2229 bfd *abfd;
2230 const char *init;
2231 const char *fini;
b34976b6 2232 bfd_boolean rtld;
9a4c7f16
TR
2233{
2234 bfd_byte filehdr_ext[FILHSZ];
69f284c7
TR
2235 bfd_byte scnhdr_ext[SCNHSZ * 3];
2236 bfd_byte syment_ext[SYMESZ * 10];
2237 bfd_byte reloc_ext[RELSZ * 3];
9a4c7f16
TR
2238 bfd_byte *data_buffer;
2239 bfd_size_type data_buffer_size;
2240 bfd_byte *string_table, *st_tmp;
2241 bfd_size_type string_table_size;
2242 bfd_vma val;
2243 size_t initsz, finisz;
2244 struct internal_filehdr filehdr;
69f284c7
TR
2245 struct internal_scnhdr text_scnhdr;
2246 struct internal_scnhdr data_scnhdr;
2247 struct internal_scnhdr bss_scnhdr;
9a4c7f16
TR
2248 struct internal_syment syment;
2249 union internal_auxent auxent;
2250 struct internal_reloc reloc;
54327882 2251
69f284c7 2252 char *text_name = ".text";
9a4c7f16 2253 char *data_name = ".data";
69f284c7 2254 char *bss_name = ".bss";
9a4c7f16 2255 char *rtinit_name = "__rtinit";
69f284c7 2256 char *rtld_name = "__rtld";
54327882 2257
69f284c7 2258 if (! bfd_xcoff_rtinit_size (abfd))
b34976b6 2259 return FALSE;
9a4c7f16
TR
2260
2261 initsz = (init == NULL ? 0 : 1 + strlen (init));
2262 finisz = (fini == NULL ? 0 : 1 + strlen (fini));
2263
eb1e0e80 2264 /* File header. */
9a4c7f16
TR
2265 memset (filehdr_ext, 0, FILHSZ);
2266 memset (&filehdr, 0, sizeof (struct internal_filehdr));
2267 filehdr.f_magic = bfd_xcoff_magic_number (abfd);
54327882 2268 filehdr.f_nscns = 3;
9a4c7f16
TR
2269 filehdr.f_timdat = 0;
2270 filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
2271 filehdr.f_symptr = 0; /* set below */
2272 filehdr.f_opthdr = 0;
2273 filehdr.f_flags = 0;
2274
eb1e0e80 2275 /* Section headers. */
69f284c7
TR
2276 memset (scnhdr_ext, 0, 3 * SCNHSZ);
2277
eb1e0e80 2278 /* Text. */
69f284c7
TR
2279 memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
2280 memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
2281 text_scnhdr.s_paddr = 0;
2282 text_scnhdr.s_vaddr = 0;
2283 text_scnhdr.s_size = 0;
2284 text_scnhdr.s_scnptr = 0;
2285 text_scnhdr.s_relptr = 0;
2286 text_scnhdr.s_lnnoptr = 0;
2287 text_scnhdr.s_nreloc = 0;
2288 text_scnhdr.s_nlnno = 0;
2289 text_scnhdr.s_flags = STYP_TEXT;
2290
eb1e0e80 2291 /* Data. */
69f284c7
TR
2292 memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
2293 memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
2294 data_scnhdr.s_paddr = 0;
2295 data_scnhdr.s_vaddr = 0;
2296 data_scnhdr.s_size = 0; /* set below */
2297 data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
2298 data_scnhdr.s_relptr = 0; /* set below */
2299 data_scnhdr.s_lnnoptr = 0;
2300 data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
2301 data_scnhdr.s_nlnno = 0;
2302 data_scnhdr.s_flags = STYP_DATA;
2303
eb1e0e80 2304 /* Bss. */
69f284c7
TR
2305 memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
2306 memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
2307 bss_scnhdr.s_paddr = 0; /* set below */
2308 bss_scnhdr.s_vaddr = 0; /* set below */
2309 bss_scnhdr.s_size = 0; /* set below */
2310 bss_scnhdr.s_scnptr = 0;
54327882 2311 bss_scnhdr.s_relptr = 0;
69f284c7
TR
2312 bss_scnhdr.s_lnnoptr = 0;
2313 bss_scnhdr.s_nreloc = 0;
2314 bss_scnhdr.s_nlnno = 0;
2315 bss_scnhdr.s_flags = STYP_BSS;
9a4c7f16 2316
54327882 2317 /* .data
cf9ab45b
AM
2318 0x0000 0x00000000 : rtl
2319 0x0004 0x00000000 :
2320 0x0008 0x00000018 : offset to init, or 0
2321 0x000C 0x00000038 : offset to fini, or 0
2322 0x0010 0x00000010 : size of descriptor
2323 0x0014 0x00000000 : pad
2324 0x0018 0x00000000 : init, needs a reloc
2325 0x001C 0x00000000 :
2326 0x0020 0x00000058 : offset to init name
2327 0x0024 0x00000000 : flags, padded to a word
2328 0x0028 0x00000000 : empty init
2329 0x002C 0x00000000 :
2330 0x0030 0x00000000 :
2331 0x0034 0x00000000 :
2332 0x0038 0x00000000 : fini, needs a reloc
2333 0x003C 0x00000000 :
2334 0x0040 0x00000??? : offset to fini name
2335 0x0044 0x00000000 : flags, padded to a word
2336 0x0048 0x00000000 : empty fini
2337 0x004C 0x00000000 :
2338 0x0050 0x00000000 :
2339 0x0054 0x00000000 :
2340 0x0058 init name
9a4c7f16
TR
2341 0x0058 + initsz fini name */
2342
2343 data_buffer_size = 0x0058 + initsz + finisz;
2a52da53 2344 data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
330693f5 2345 data_buffer = NULL;
9bab7074 2346 data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
330693f5 2347 if (data_buffer == NULL)
b34976b6 2348 return FALSE;
54327882 2349
54327882 2350 if (initsz)
9a4c7f16
TR
2351 {
2352 val = 0x18;
2353 bfd_put_32 (abfd, val, &data_buffer[0x08]);
2354 val = 0x58;
2355 bfd_put_32 (abfd, val, &data_buffer[0x20]);
2356 memcpy (&data_buffer[val], init, initsz);
2357 }
2358
54327882 2359 if (finisz)
9a4c7f16
TR
2360 {
2361 val = 0x38;
2362 bfd_put_32 (abfd, val, &data_buffer[0x0C]);
2363 val = 0x58 + initsz;
2364 bfd_put_32 (abfd, val, &data_buffer[0x40]);
2365 memcpy (&data_buffer[val], fini, finisz);
2366 }
2367
2368 val = 0x10;
2369 bfd_put_32 (abfd, val, &data_buffer[0x10]);
69f284c7
TR
2370 data_scnhdr.s_size = data_buffer_size;
2371 bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
9a4c7f16 2372
eb1e0e80 2373 /* String table. */
9a4c7f16
TR
2374 string_table_size = 4;
2375 string_table_size += strlen (data_name) + 1;
2376 string_table_size += strlen (rtinit_name) + 1;
2377 string_table_size += initsz;
2378 string_table_size += finisz;
cf9ab45b 2379 if (rtld)
69f284c7 2380 string_table_size += strlen (rtld_name) + 1;
9a4c7f16 2381
9bab7074
AM
2382 string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
2383 if (string_table == NULL)
b34976b6 2384 return FALSE;
9bab7074 2385
9a4c7f16
TR
2386 val = string_table_size;
2387 bfd_put_32 (abfd, val, &string_table[0]);
2388 st_tmp = string_table + 4;
54327882
AM
2389
2390 /* symbols
9a4c7f16
TR
2391 0. .data csect
2392 2. __rtinit
54327882
AM
2393 4. init function
2394 6. fini function
69f284c7
TR
2395 8. __rtld */
2396 memset (syment_ext, 0, 10 * SYMESZ);
2397 memset (reloc_ext, 0, 3 * RELSZ);
9a4c7f16
TR
2398
2399 /* .data csect */
2400 memset (&syment, 0, sizeof (struct internal_syment));
2401 memset (&auxent, 0, sizeof (union internal_auxent));
2402
2403 syment._n._n_n._n_offset = st_tmp - string_table;
2404 memcpy (st_tmp, data_name, strlen (data_name));
2405 st_tmp += strlen (data_name) + 1;
2406
69f284c7 2407 syment.n_scnum = 2;
9a4c7f16
TR
2408 syment.n_sclass = C_HIDEXT;
2409 syment.n_numaux = 1;
2410 auxent.x_csect.x_scnlen.l = data_buffer_size;
2411 auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
2412 auxent.x_csect.x_smclas = XMC_RW;
54327882 2413 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2414 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2415 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2416 syment.n_numaux,
9a4c7f16
TR
2417 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2418 filehdr.f_nsyms += 2;
2419
2420 /* __rtinit */
2421 memset (&syment, 0, sizeof (struct internal_syment));
2422 memset (&auxent, 0, sizeof (union internal_auxent));
2423 syment._n._n_n._n_offset = st_tmp - string_table;
2424 memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
2425 st_tmp += strlen (rtinit_name) + 1;
54327882 2426
69f284c7 2427 syment.n_scnum = 2;
9a4c7f16
TR
2428 syment.n_sclass = C_EXT;
2429 syment.n_numaux = 1;
2430 auxent.x_csect.x_smtyp = XTY_LD;
2431 auxent.x_csect.x_smclas = XMC_RW;
54327882 2432 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2433 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2434 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2435 syment.n_numaux,
9a4c7f16
TR
2436 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2437 filehdr.f_nsyms += 2;
2438
eb1e0e80 2439 /* Init. */
54327882 2440 if (initsz)
9a4c7f16
TR
2441 {
2442 memset (&syment, 0, sizeof (struct internal_syment));
2443 memset (&auxent, 0, sizeof (union internal_auxent));
2444
2445 syment._n._n_n._n_offset = st_tmp - string_table;
2446 memcpy (st_tmp, init, initsz);
2447 st_tmp += initsz;
2448
2449 syment.n_sclass = C_EXT;
2450 syment.n_numaux = 1;
54327882 2451 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2452 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2453 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2454 syment.n_numaux,
9a4c7f16 2455 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
eb1e0e80 2456 /* Reloc. */
9a4c7f16
TR
2457 memset (&reloc, 0, sizeof (struct internal_reloc));
2458 reloc.r_vaddr = 0x0018;
2459 reloc.r_symndx = filehdr.f_nsyms;
2460 reloc.r_type = R_POS;
2461 reloc.r_size = 63;
2462 bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
2463
2464 filehdr.f_nsyms += 2;
69f284c7 2465 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2466 }
2467
eb1e0e80 2468 /* Finit. */
54327882 2469 if (finisz)
9a4c7f16
TR
2470 {
2471 memset (&syment, 0, sizeof (struct internal_syment));
2472 memset (&auxent, 0, sizeof (union internal_auxent));
2473
2474 syment._n._n_n._n_offset = st_tmp - string_table;
2475 memcpy (st_tmp, fini, finisz);
2476 st_tmp += finisz;
2477
2478 syment.n_sclass = C_EXT;
2479 syment.n_numaux = 1;
54327882 2480 bfd_coff_swap_sym_out (abfd, &syment,
9a4c7f16 2481 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2482 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2483 syment.n_numaux,
9a4c7f16
TR
2484 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2485
eb1e0e80 2486 /* Reloc. */
9a4c7f16
TR
2487 memset (&reloc, 0, sizeof (struct internal_reloc));
2488 reloc.r_vaddr = 0x0038;
2489 reloc.r_symndx = filehdr.f_nsyms;
2490 reloc.r_type = R_POS;
2491 reloc.r_size = 63;
54327882 2492 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7 2493 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
9a4c7f16
TR
2494
2495 filehdr.f_nsyms += 2;
69f284c7 2496 data_scnhdr.s_nreloc += 1;
9a4c7f16
TR
2497 }
2498
69f284c7
TR
2499 if (rtld)
2500 {
2501 memset (&syment, 0, sizeof (struct internal_syment));
2502 memset (&auxent, 0, sizeof (union internal_auxent));
2503
2504 syment._n._n_n._n_offset = st_tmp - string_table;
2505 memcpy (st_tmp, rtld_name, strlen (rtld_name));
2506 st_tmp += strlen (rtld_name) + 1;
2507
2508 syment.n_sclass = C_EXT;
2509 syment.n_numaux = 1;
54327882 2510 bfd_coff_swap_sym_out (abfd, &syment,
69f284c7 2511 &syment_ext[filehdr.f_nsyms * SYMESZ]);
54327882
AM
2512 bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
2513 syment.n_numaux,
69f284c7
TR
2514 &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
2515
eb1e0e80 2516 /* Reloc. */
69f284c7
TR
2517 memset (&reloc, 0, sizeof (struct internal_reloc));
2518 reloc.r_vaddr = 0x0000;
2519 reloc.r_symndx = filehdr.f_nsyms;
2520 reloc.r_type = R_POS;
2521 reloc.r_size = 63;
54327882 2522 bfd_coff_swap_reloc_out (abfd, &reloc,
69f284c7
TR
2523 &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
2524
2525 filehdr.f_nsyms += 2;
2526 data_scnhdr.s_nreloc += 1;
2527
2528 bss_scnhdr.s_size = 0;
2529 }
2530
2531 data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
2532 filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
9a4c7f16
TR
2533
2534 bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
2535 bfd_bwrite (filehdr_ext, FILHSZ, abfd);
69f284c7
TR
2536 bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
2537 bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
2538 bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
2539 bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
9a4c7f16 2540 bfd_bwrite (data_buffer, data_buffer_size, abfd);
69f284c7 2541 bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
9a4c7f16
TR
2542 bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
2543 bfd_bwrite (string_table, string_table_size, abfd);
2544
330693f5
TR
2545 free (data_buffer);
2546 data_buffer = NULL;
2547
b34976b6 2548 return TRUE;
9a4c7f16
TR
2549}
2550
beb1bf64
TR
2551/* The typical dynamic reloc. */
2552
2553static reloc_howto_type xcoff64_dynamic_reloc =
dc810e39
AM
2554HOWTO (0, /* type */
2555 0, /* rightshift */
2556 4, /* size (0 = byte, 1 = short, 2 = long) */
2557 64, /* bitsize */
b34976b6 2558 FALSE, /* pc_relative */
dc810e39
AM
2559 0, /* bitpos */
2560 complain_overflow_bitfield, /* complain_on_overflow */
2561 0, /* special_function */
2562 "R_POS", /* name */
b34976b6 2563 TRUE, /* partial_inplace */
dc810e39
AM
2564 MINUS_ONE, /* src_mask */
2565 MINUS_ONE, /* dst_mask */
b34976b6 2566 FALSE); /* pcrel_offset */
beb1bf64
TR
2567
2568static unsigned long xcoff64_glink_code[10] =
2569{
54327882
AM
2570 0xe9820000, /* ld r12,0(r2) */
2571 0xf8410028, /* std r2,40(r1) */
2572 0xe80c0000, /* ld r0,0(r12) */
2573 0xe84c0008, /* ld r0,8(r12) */
2574 0x7c0903a6, /* mtctr r0 */
2575 0x4e800420, /* bctr */
2576 0x00000000, /* start of traceback table */
2577 0x000ca000, /* traceback table */
2578 0x00000000, /* traceback table */
2579 0x00000018, /* ??? */
beb1bf64
TR
2580};
2581
dc810e39 2582static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
cf9ab45b
AM
2583 {
2584 { /* COFF backend, defined in libcoff.h. */
2585 _bfd_xcoff64_swap_aux_in,
2586 _bfd_xcoff64_swap_sym_in,
2587 _bfd_xcoff64_swap_lineno_in,
2588 _bfd_xcoff64_swap_aux_out,
2589 _bfd_xcoff64_swap_sym_out,
2590 _bfd_xcoff64_swap_lineno_out,
2591 xcoff64_swap_reloc_out,
2592 coff_swap_filehdr_out,
2593 coff_swap_aouthdr_out,
2594 coff_swap_scnhdr_out,
2595 FILHSZ,
2596 AOUTSZ,
2597 SCNHSZ,
2598 SYMESZ,
2599 AUXESZ,
2600 RELSZ,
2601 LINESZ,
2602 FILNMLEN,
b34976b6 2603 TRUE, /* _bfd_coff_long_filenames */
88183869 2604 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 2605 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2606 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2607 4, /* _bfd_coff_debug_string_prefix_length */
2608 coff_swap_filehdr_in,
2609 coff_swap_aouthdr_in,
2610 coff_swap_scnhdr_in,
2611 xcoff64_swap_reloc_in,
2612 xcoff64_bad_format_hook,
2613 coff_set_arch_mach_hook,
2614 coff_mkobject_hook,
2615 styp_to_sec_flags,
2616 coff_set_alignment_hook,
2617 coff_slurp_symbol_table,
2618 symname_in_debug_hook,
2619 coff_pointerize_aux_hook,
2620 coff_print_aux,
2621 dummy_reloc16_extra_cases,
2622 dummy_reloc16_estimate,
e144674a 2623 NULL, /* bfd_coff_symbol_classification */
cf9ab45b
AM
2624 coff_compute_section_file_positions,
2625 NULL, /* _bfd_coff_start_final_link */
2626 xcoff64_ppc_relocate_section,
2627 coff_rtype_to_howto,
2628 NULL, /* _bfd_coff_adjust_symndx */
2629 _bfd_generic_link_add_one_symbol,
2630 coff_link_output_has_begun,
2b5c217d
NC
2631 coff_final_link_postscript,
2632 NULL /* print_pdata. */
cf9ab45b
AM
2633 },
2634
2635 0x01EF, /* magic number */
2636 bfd_arch_powerpc,
2637 bfd_mach_ppc_620,
2638
2639 /* Function pointers to xcoff specific swap routines. */
2640 xcoff64_swap_ldhdr_in,
2641 xcoff64_swap_ldhdr_out,
2642 xcoff64_swap_ldsym_in,
2643 xcoff64_swap_ldsym_out,
2644 xcoff64_swap_ldrel_in,
2645 xcoff64_swap_ldrel_out,
2646
2647 /* Sizes. */
2648 LDHDRSZ,
2649 LDSYMSZ,
2650 LDRELSZ,
2651 24, /* _xcoff_function_descriptor_size */
2652 0, /* _xcoff_small_aout_header_size */
2653
2654 /* Versions. */
2655 2, /* _xcoff_ldhdr_version */
2656
2657 _bfd_xcoff64_put_symbol_name,
2658 _bfd_xcoff64_put_ldsymbol_name,
2659 &xcoff64_dynamic_reloc,
2660 xcoff64_create_csect_from_smclas,
2661
2662 /* Lineno and reloc count overflow. */
2663 xcoff64_is_lineno_count_overflow,
2664 xcoff64_is_reloc_count_overflow,
2665
2666 xcoff64_loader_symbol_offset,
2667 xcoff64_loader_reloc_offset,
2668
2669 /* glink. */
2670 &xcoff64_glink_code[0],
2671 40, /* _xcoff_glink_size */
2672
2673 /* rtinit. */
2674 88, /* _xcoff_rtinit_size */
2675 xcoff64_generate_rtinit,
2676 };
beb1bf64 2677
eb1e0e80 2678/* The transfer vector that leads the outside world to all of the above. */
beb1bf64 2679const bfd_target rs6000coff64_vec =
cf9ab45b
AM
2680 {
2681 "aixcoff64-rs6000",
2682 bfd_target_xcoff_flavour,
2683 BFD_ENDIAN_BIG, /* data byte order is big */
2684 BFD_ENDIAN_BIG, /* header byte order is big */
2685
2686 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2687 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2688
a7c71b0c 2689 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2690 0, /* leading char */
2691 '/', /* ar_pad_char */
2692 15, /* ar_max_namelen */
2693
2694 /* data */
2695 bfd_getb64,
2696 bfd_getb_signed_64,
2697 bfd_putb64,
2698 bfd_getb32,
2699 bfd_getb_signed_32,
2700 bfd_putb32,
2701 bfd_getb16,
2702 bfd_getb_signed_16,
2703 bfd_putb16,
2704
2705 /* hdrs */
2706 bfd_getb64,
2707 bfd_getb_signed_64,
2708 bfd_putb64,
2709 bfd_getb32,
2710 bfd_getb_signed_32,
2711 bfd_putb32,
2712 bfd_getb16,
2713 bfd_getb_signed_16,
2714 bfd_putb16,
2715
2716 { /* bfd_check_format */
2717 _bfd_dummy_target,
2718 coff_object_p,
2719 xcoff64_archive_p,
2720 CORE_FILE_P
2721 },
2722
2723 { /* bfd_set_format */
2724 bfd_false,
2725 coff_mkobject,
2726 _bfd_generic_mkarchive,
2727 bfd_false
2728 },
2729
2730 {/* bfd_write_contents */
2731 bfd_false,
2732 xcoff64_write_object_contents,
2733 _bfd_xcoff_write_archive_contents,
2734 bfd_false
2735 },
2736
2737 /* Generic */
2738 bfd_true,
2739 bfd_true,
2740 coff_new_section_hook,
2741 _bfd_generic_get_section_contents,
2742 _bfd_generic_get_section_contents_in_window,
2743
2744 /* Copy */
2745 _bfd_xcoff_copy_private_bfd_data,
ac96f0c7 2746 _bfd_generic_bfd_merge_private_bfd_data,
60b48850 2747 _bfd_generic_init_private_section_data,
ac96f0c7
TG
2748 _bfd_generic_bfd_copy_private_section_data,
2749 _bfd_generic_bfd_copy_private_symbol_data,
2750 _bfd_generic_bfd_copy_private_header_data,
2751 _bfd_generic_bfd_set_private_flags,
2752 _bfd_generic_bfd_print_private_bfd_data,
cf9ab45b
AM
2753
2754 /* Core */
2755 coff_core_file_failing_command,
2756 coff_core_file_failing_signal,
2757 coff_core_file_matches_executable_p,
2758
2759 /* Archive */
2760 xcoff64_slurp_armap,
ac96f0c7
TG
2761 _bfd_noarchive_slurp_extended_name_table,
2762 _bfd_noarchive_construct_extended_name_table,
cf9ab45b
AM
2763 bfd_dont_truncate_arname,
2764 _bfd_xcoff_write_armap,
2765 _bfd_xcoff_read_ar_hdr,
2766 xcoff64_openr_next_archived_file,
2767 _bfd_generic_get_elt_at_index,
2768 _bfd_xcoff_stat_arch_elt,
2769 bfd_true,
2770
2771 /* Symbols */
2772 coff_get_symtab_upper_bound,
6cee3f79 2773 coff_canonicalize_symtab,
cf9ab45b
AM
2774 coff_make_empty_symbol,
2775 coff_print_symbol,
2776 coff_get_symbol_info,
2777 _bfd_xcoff_is_local_label_name,
7db6994f 2778 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
2779 coff_get_lineno,
2780 coff_find_nearest_line,
4575b1b5 2781 _bfd_generic_find_line,
4ab527b0 2782 coff_find_inliner_info,
cf9ab45b
AM
2783 coff_bfd_make_debug_symbol,
2784 _bfd_generic_read_minisymbols,
2785 _bfd_generic_minisymbol_to_symbol,
2786
2787 /* Reloc */
2788 coff_get_reloc_upper_bound,
2789 coff_canonicalize_reloc,
2790 xcoff64_reloc_type_lookup,
157090f7 2791 xcoff64_reloc_name_lookup,
cf9ab45b
AM
2792
2793 /* Write */
2794 coff_set_arch_mach,
2795 coff_set_section_contents,
2796
2797 /* Link */
2798 xcoff64_sizeof_headers,
2799 bfd_generic_get_relocated_section_contents,
2800 bfd_generic_relax_section,
2801 _bfd_xcoff_bfd_link_hash_table_create,
2802 _bfd_generic_link_hash_table_free,
2803 _bfd_xcoff_bfd_link_add_symbols,
2804 _bfd_generic_link_just_syms,
1338dd10 2805 _bfd_generic_copy_link_hash_symbol_type,
cf9ab45b
AM
2806 _bfd_xcoff_bfd_final_link,
2807 _bfd_generic_link_split_section,
2808 bfd_generic_gc_sections,
2809 bfd_generic_merge_sections,
72adc230 2810 bfd_generic_is_group_section,
cf9ab45b 2811 bfd_generic_discard_group,
082b7297 2812 _bfd_generic_section_already_linked,
3023e3f6 2813 _bfd_xcoff_define_common_symbol,
cf9ab45b
AM
2814
2815 /* Dynamic */
2816 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2817 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 2818 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
2819 _bfd_xcoff_get_dynamic_reloc_upper_bound,
2820 _bfd_xcoff_canonicalize_dynamic_reloc,
2821
2822 /* Opposite endian version, none exists */
2823 NULL,
2824
2825 (void *) &bfd_xcoff_backend_data,
2826 };
eb1e0e80 2827
b34976b6
AM
2828extern const bfd_target *xcoff64_core_p
2829 PARAMS ((bfd *));
2830extern bfd_boolean xcoff64_core_file_matches_executable_p
2831 PARAMS ((bfd *, bfd *));
2832extern char *xcoff64_core_file_failing_command
2833 PARAMS ((bfd *));
2834extern int xcoff64_core_file_failing_signal
2835 PARAMS ((bfd *));
eb1e0e80
NC
2836
2837/* AIX 5 */
54327882 2838static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
cf9ab45b
AM
2839 {
2840 { /* COFF backend, defined in libcoff.h. */
2841 _bfd_xcoff64_swap_aux_in,
2842 _bfd_xcoff64_swap_sym_in,
2843 _bfd_xcoff64_swap_lineno_in,
2844 _bfd_xcoff64_swap_aux_out,
2845 _bfd_xcoff64_swap_sym_out,
2846 _bfd_xcoff64_swap_lineno_out,
2847 xcoff64_swap_reloc_out,
2848 coff_swap_filehdr_out,
2849 coff_swap_aouthdr_out,
2850 coff_swap_scnhdr_out,
2851 FILHSZ,
2852 AOUTSZ,
2853 SCNHSZ,
2854 SYMESZ,
2855 AUXESZ,
2856 RELSZ,
2857 LINESZ,
2858 FILNMLEN,
b34976b6 2859 TRUE, /* _bfd_coff_long_filenames */
88183869 2860 XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
cf9ab45b 2861 3, /* _bfd_coff_default_section_alignment_power */
b34976b6 2862 TRUE, /* _bfd_coff_force_symnames_in_strings */
cf9ab45b
AM
2863 4, /* _bfd_coff_debug_string_prefix_length */
2864 coff_swap_filehdr_in,
2865 coff_swap_aouthdr_in,
2866 coff_swap_scnhdr_in,
2867 xcoff64_swap_reloc_in,
2868 xcoff64_bad_format_hook,
2869 coff_set_arch_mach_hook,
2870 coff_mkobject_hook,
2871 styp_to_sec_flags,
2872 coff_set_alignment_hook,
2873 coff_slurp_symbol_table,
2874 symname_in_debug_hook,
2875 coff_pointerize_aux_hook,
2876 coff_print_aux,
2877 dummy_reloc16_extra_cases,
2878 dummy_reloc16_estimate,
2879 NULL, /* bfd_coff_sym_is_global */
2880 coff_compute_section_file_positions,
2881 NULL, /* _bfd_coff_start_final_link */
2882 xcoff64_ppc_relocate_section,
2883 coff_rtype_to_howto,
2884 NULL, /* _bfd_coff_adjust_symndx */
2885 _bfd_generic_link_add_one_symbol,
2886 coff_link_output_has_begun,
2b5c217d
NC
2887 coff_final_link_postscript,
2888 NULL /* print_pdata. */
cf9ab45b
AM
2889 },
2890
2891 U64_TOCMAGIC, /* magic number */
2892 bfd_arch_powerpc,
2893 bfd_mach_ppc_620,
2894
2895 /* Function pointers to xcoff specific swap routines. */
2896 xcoff64_swap_ldhdr_in,
2897 xcoff64_swap_ldhdr_out,
2898 xcoff64_swap_ldsym_in,
2899 xcoff64_swap_ldsym_out,
2900 xcoff64_swap_ldrel_in,
2901 xcoff64_swap_ldrel_out,
2902
2903 /* Sizes. */
2904 LDHDRSZ,
2905 LDSYMSZ,
2906 LDRELSZ,
2907 24, /* _xcoff_function_descriptor_size */
2908 0, /* _xcoff_small_aout_header_size */
2909 /* Versions. */
2910 2, /* _xcoff_ldhdr_version */
2911
2912 _bfd_xcoff64_put_symbol_name,
2913 _bfd_xcoff64_put_ldsymbol_name,
2914 &xcoff64_dynamic_reloc,
2915 xcoff64_create_csect_from_smclas,
2916
2917 /* Lineno and reloc count overflow. */
2918 xcoff64_is_lineno_count_overflow,
2919 xcoff64_is_reloc_count_overflow,
2920
2921 xcoff64_loader_symbol_offset,
2922 xcoff64_loader_reloc_offset,
2923
2924 /* glink. */
2925 &xcoff64_glink_code[0],
2926 40, /* _xcoff_glink_size */
2927
2928 /* rtinit. */
2929 88, /* _xcoff_rtinit_size */
2930 xcoff64_generate_rtinit,
2931 };
eb1e0e80
NC
2932
2933/* The transfer vector that leads the outside world to all of the above. */
2934const bfd_target aix5coff64_vec =
cf9ab45b
AM
2935 {
2936 "aix5coff64-rs6000",
2937 bfd_target_xcoff_flavour,
2938 BFD_ENDIAN_BIG, /* data byte order is big */
2939 BFD_ENDIAN_BIG, /* header byte order is big */
2940
2941 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
2942 | HAS_SYMS | HAS_LOCALS | WP_TEXT),
2943
a7c71b0c 2944 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
cf9ab45b
AM
2945 0, /* leading char */
2946 '/', /* ar_pad_char */
2947 15, /* ar_max_namelen */
2948
2949 /* data */
2950 bfd_getb64,
2951 bfd_getb_signed_64,
2952 bfd_putb64,
2953 bfd_getb32,
2954 bfd_getb_signed_32,
2955 bfd_putb32,
2956 bfd_getb16,
2957 bfd_getb_signed_16,
2958 bfd_putb16,
2959
2960 /* hdrs */
2961 bfd_getb64,
2962 bfd_getb_signed_64,
2963 bfd_putb64,
2964 bfd_getb32,
2965 bfd_getb_signed_32,
2966 bfd_putb32,
2967 bfd_getb16,
2968 bfd_getb_signed_16,
2969 bfd_putb16,
2970
2971 { /* bfd_check_format */
2972 _bfd_dummy_target,
2973 coff_object_p,
2974 xcoff64_archive_p,
2975 xcoff64_core_p
2976 },
2977
2978 { /* bfd_set_format */
2979 bfd_false,
2980 coff_mkobject,
2981 _bfd_generic_mkarchive,
2982 bfd_false
2983 },
2984
2985 {/* bfd_write_contents */
2986 bfd_false,
2987 xcoff64_write_object_contents,
2988 _bfd_xcoff_write_archive_contents,
2989 bfd_false
2990 },
2991
2992 /* Generic */
2993 bfd_true,
2994 bfd_true,
2995 coff_new_section_hook,
2996 _bfd_generic_get_section_contents,
2997 _bfd_generic_get_section_contents_in_window,
2998
2999 /* Copy */
3000 _bfd_xcoff_copy_private_bfd_data,
ac96f0c7 3001 _bfd_generic_bfd_merge_private_bfd_data,
60b48850 3002 _bfd_generic_init_private_section_data,
ac96f0c7
TG
3003 _bfd_generic_bfd_copy_private_section_data,
3004 _bfd_generic_bfd_copy_private_symbol_data,
3005 _bfd_generic_bfd_copy_private_header_data,
3006 _bfd_generic_bfd_set_private_flags,
3007 _bfd_generic_bfd_print_private_bfd_data,
cf9ab45b
AM
3008
3009 /* Core */
3010 xcoff64_core_file_failing_command,
3011 xcoff64_core_file_failing_signal,
3012 xcoff64_core_file_matches_executable_p,
3013
3014 /* Archive */
3015 xcoff64_slurp_armap,
ac96f0c7
TG
3016 _bfd_noarchive_slurp_extended_name_table,
3017 _bfd_noarchive_construct_extended_name_table,
cf9ab45b
AM
3018 bfd_dont_truncate_arname,
3019 _bfd_xcoff_write_armap,
3020 _bfd_xcoff_read_ar_hdr,
3021 xcoff64_openr_next_archived_file,
3022 _bfd_generic_get_elt_at_index,
3023 _bfd_xcoff_stat_arch_elt,
3024 bfd_true,
3025
3026 /* Symbols */
3027 coff_get_symtab_upper_bound,
6cee3f79 3028 coff_canonicalize_symtab,
cf9ab45b
AM
3029 coff_make_empty_symbol,
3030 coff_print_symbol,
3031 coff_get_symbol_info,
3032 _bfd_xcoff_is_local_label_name,
7db6994f 3033 coff_bfd_is_target_special_symbol,
cf9ab45b
AM
3034 coff_get_lineno,
3035 coff_find_nearest_line,
4575b1b5 3036 _bfd_generic_find_line,
4ab527b0 3037 coff_find_inliner_info,
cf9ab45b
AM
3038 coff_bfd_make_debug_symbol,
3039 _bfd_generic_read_minisymbols,
3040 _bfd_generic_minisymbol_to_symbol,
3041
3042 /* Reloc */
3043 coff_get_reloc_upper_bound,
3044 coff_canonicalize_reloc,
3045 xcoff64_reloc_type_lookup,
157090f7 3046 xcoff64_reloc_name_lookup,
cf9ab45b
AM
3047
3048 /* Write */
3049 coff_set_arch_mach,
3050 coff_set_section_contents,
3051
3052 /* Link */
3053 xcoff64_sizeof_headers,
3054 bfd_generic_get_relocated_section_contents,
3055 bfd_generic_relax_section,
3056 _bfd_xcoff_bfd_link_hash_table_create,
3057 _bfd_generic_link_hash_table_free,
3058 _bfd_xcoff_bfd_link_add_symbols,
3059 _bfd_generic_link_just_syms,
1338dd10 3060 _bfd_generic_copy_link_hash_symbol_type,
cf9ab45b
AM
3061 _bfd_xcoff_bfd_final_link,
3062 _bfd_generic_link_split_section,
3063 bfd_generic_gc_sections,
3064 bfd_generic_merge_sections,
72adc230 3065 bfd_generic_is_group_section,
cf9ab45b 3066 bfd_generic_discard_group,
082b7297 3067 _bfd_generic_section_already_linked,
3023e3f6 3068 _bfd_xcoff_define_common_symbol,
cf9ab45b
AM
3069
3070 /* Dynamic */
3071 _bfd_xcoff_get_dynamic_symtab_upper_bound,
3072 _bfd_xcoff_canonicalize_dynamic_symtab,
4c45e5c9 3073 _bfd_nodynamic_get_synthetic_symtab,
cf9ab45b
AM
3074 _bfd_xcoff_get_dynamic_reloc_upper_bound,
3075 _bfd_xcoff_canonicalize_dynamic_reloc,
3076
3077 /* Opposite endian version, none exists. */
3078 NULL,
3079
3080 (void *) & bfd_xcoff_aix5_backend_data,
3081 };
This page took 0.653317 seconds and 4 git commands to generate.