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