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