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