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