* output-file.c (output_file_create): Don't try to open using
[binutils.git] / bfd / coff64-rs6000.c
blob61b4dd3837de10ffda091b816f19c90e2c5a8d40
1 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
2 Copyright 2000, 2001
3 Free Software Foundation, Inc.
4 Written Clinton Popetz.
5 Contributed by Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "coff/internal.h"
28 #include "coff/xcoff.h"
29 #include "coff/rs6k64.h"
30 #include "libcoff.h"
31 #include "libxcoff.h"
33 #define GET_FILEHDR_SYMPTR bfd_h_get_64
34 #define PUT_FILEHDR_SYMPTR bfd_h_put_64
35 #define GET_AOUTHDR_DATA_START bfd_h_get_64
36 #define PUT_AOUTHDR_DATA_START bfd_h_put_64
37 #define GET_AOUTHDR_TEXT_START bfd_h_get_64
38 #define PUT_AOUTHDR_TEXT_START bfd_h_put_64
39 #define GET_AOUTHDR_TSIZE bfd_h_get_64
40 #define PUT_AOUTHDR_TSIZE bfd_h_put_64
41 #define GET_AOUTHDR_DSIZE bfd_h_get_64
42 #define PUT_AOUTHDR_DSIZE bfd_h_put_64
43 #define GET_AOUTHDR_BSIZE bfd_h_get_64
44 #define PUT_AOUTHDR_BSIZE bfd_h_put_64
45 #define GET_AOUTHDR_ENTRY bfd_h_get_64
46 #define PUT_AOUTHDR_ENTRY bfd_h_put_64
47 #define GET_SCNHDR_PADDR bfd_h_get_64
48 #define PUT_SCNHDR_PADDR bfd_h_put_64
49 #define GET_SCNHDR_VADDR bfd_h_get_64
50 #define PUT_SCNHDR_VADDR bfd_h_put_64
51 #define GET_SCNHDR_SIZE bfd_h_get_64
52 #define PUT_SCNHDR_SIZE bfd_h_put_64
53 #define GET_SCNHDR_SCNPTR bfd_h_get_64
54 #define PUT_SCNHDR_SCNPTR bfd_h_put_64
55 #define GET_SCNHDR_RELPTR bfd_h_get_64
56 #define PUT_SCNHDR_RELPTR bfd_h_put_64
57 #define GET_SCNHDR_LNNOPTR bfd_h_get_64
58 #define PUT_SCNHDR_LNNOPTR bfd_h_put_64
59 #define GET_SCNHDR_NRELOC bfd_h_get_32
60 #define MAX_SCNHDR_NRELOC 0xffffffff
61 #define PUT_SCNHDR_NRELOC bfd_h_put_32
62 #define GET_SCNHDR_NLNNO bfd_h_get_32
63 #define MAX_SCNHDR_NLNNO 0xffffffff
64 #define PUT_SCNHDR_NLNNO bfd_h_put_32
65 #define GET_RELOC_VADDR bfd_h_get_64
66 #define PUT_RELOC_VADDR bfd_h_put_64
68 #define COFF_FORCE_SYMBOLS_IN_STRINGS
69 #define COFF_DEBUG_STRING_WIDE_PREFIX
72 #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD,INT,EXT) \
73 do { \
74 memset (((SCNHDR *)EXT)->s_pad, 0, sizeof (((SCNHDR *)EXT)->s_pad));\
75 } while(0)
77 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
78 from smaller values. Start with zero, widen, *then* decrement. */
79 #define MINUS_ONE (((bfd_vma)0) - 1)
82 #define NO_COFF_LINENOS
84 #define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
85 #define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
87 #define PUTWORD bfd_h_put_32
88 #define PUTHALF bfd_h_put_16
89 #define PUTBYTE bfd_h_put_8
90 #define GETWORD bfd_h_get_32
91 #define GETHALF bfd_h_get_16
92 #define GETBYTE bfd_h_get_8
95 /* For XCOFF64, the effective width of symndx changes depending on
96 whether we are the first entry. Sigh. */
97 static void
98 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
99 bfd *abfd;
100 PTR ext1;
101 PTR in1;
103 LINENO *ext = (LINENO *)ext1;
104 struct internal_lineno *in = (struct internal_lineno *)in1;
106 in->l_lnno = bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
107 if (in->l_lnno == 0)
108 in->l_addr.l_symndx =
109 bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
110 else
111 in->l_addr.l_paddr =
112 bfd_h_get_64(abfd, (bfd_byte *) ext->l_addr.l_paddr);
115 static unsigned int
116 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
117 bfd *abfd;
118 PTR inp;
119 PTR outp;
121 struct internal_lineno *in = (struct internal_lineno *)inp;
122 struct external_lineno *ext = (struct external_lineno *)outp;
123 PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *)
124 ext->l_addr.l_symndx);
126 bfd_h_put_32 (abfd, in->l_lnno, (bfd_byte *) (ext->l_lnno));
127 if (in->l_lnno == 0)
128 bfd_h_put_32 (abfd, in->l_addr.l_symndx, (bfd_byte *)ext->l_addr.l_symndx);
129 else
130 bfd_h_put_64 (abfd, in->l_addr.l_paddr, (bfd_byte *)ext->l_addr.l_paddr);
132 return bfd_coff_linesz (abfd);
136 static void _bfd_xcoff64_swap_sym_in PARAMS ((bfd *, PTR, PTR));
137 static unsigned int _bfd_xcoff64_swap_sym_out PARAMS ((bfd *, PTR, PTR));
138 static void _bfd_xcoff64_swap_aux_in PARAMS ((bfd *, PTR, int, int, int, int, PTR));
139 static unsigned int _bfd_xcoff64_swap_aux_out PARAMS ((bfd *, PTR, int, int, int, int, PTR));
141 static void
142 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
143 bfd *abfd;
144 PTR ext1;
145 PTR in1;
147 struct external_syment *ext = (struct external_syment *)ext1;
148 struct internal_syment *in = (struct internal_syment *)in1;
150 in->_n._n_n._n_zeroes = 0;
151 in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e_offset);
152 in->n_value = bfd_h_get_64(abfd, (bfd_byte *) ext->e_value);
153 in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
154 in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
155 in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
156 in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
159 static unsigned int
160 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
161 bfd *abfd;
162 PTR inp;
163 PTR extp;
165 struct internal_syment *in = (struct internal_syment *)inp;
166 struct external_syment *ext =(struct external_syment *)extp;
168 bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e_offset);
169 bfd_h_put_64(abfd, in->n_value , (bfd_byte *) ext->e_value);
170 bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum);
171 bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
172 bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
173 bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
174 return bfd_coff_symesz (abfd);
177 static void
178 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
179 bfd *abfd;
180 PTR ext1;
181 int type;
182 int class;
183 int indx;
184 int numaux;
185 PTR in1;
187 union external_auxent *ext = (union external_auxent *)ext1;
188 union internal_auxent *in = (union internal_auxent *)in1;
190 switch (class) {
191 case C_FILE:
192 if (ext->x_file.x_n.x_zeroes == 0) {
193 in->x_file.x_n.x_zeroes = 0;
194 in->x_file.x_n.x_offset =
195 bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
196 } else {
197 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
199 goto end;
201 /* RS/6000 "csect" auxents */
202 case C_EXT:
203 case C_HIDEXT:
204 if (indx + 1 == numaux)
206 bfd_signed_vma h = 0;
207 bfd_vma l = 0;
209 h = bfd_h_get_signed_32(abfd, ext->x_csect.x_scnlen_hi);
210 l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen_lo);
212 in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
214 in->x_csect.x_parmhash = bfd_h_get_32 (abfd,
215 ext->x_csect.x_parmhash);
216 in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash);
217 /* We don't have to hack bitfields in x_smtyp because it's
218 defined by shifts-and-ands, which are equivalent on all
219 byte orders. */
220 in->x_csect.x_smtyp = bfd_h_get_8 (abfd, ext->x_csect.x_smtyp);
221 in->x_csect.x_smclas = bfd_h_get_8 (abfd, ext->x_csect.x_smclas);
222 goto end;
224 break;
226 case C_STAT:
227 case C_LEAFSTAT:
228 case C_HIDDEN:
229 if (type == T_NULL) {
230 /* PE defines some extra fields; we zero them out for
231 safety. */
232 in->x_scn.x_checksum = 0;
233 in->x_scn.x_associated = 0;
234 in->x_scn.x_comdat = 0;
236 goto end;
238 break;
241 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
243 in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_64(abfd, (bfd_byte *)
244 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
245 in->x_sym.x_fcnary.x_fcn.x_endndx.l = bfd_h_get_32(abfd, (bfd_byte *)
246 ext->x_sym.x_fcnary.x_fcn.x_endndx);
248 if (ISFCN(type)) {
249 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_fsize);
251 else {
252 in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_32(abfd, (bfd_byte *)
253 ext->x_sym.x_fcnary.x_lnsz.x_lnno);
254 in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, (bfd_byte *)
255 ext->x_sym.x_fcnary.x_lnsz.x_size);
258 end: ;
259 /* the semicolon is because MSVC doesn't like labels at
260 end of block. */
266 static unsigned int
267 _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
268 bfd *abfd;
269 PTR inp;
270 int type;
271 int class;
272 int indx ATTRIBUTE_UNUSED;
273 int numaux ATTRIBUTE_UNUSED;
274 PTR extp;
276 union internal_auxent *in = (union internal_auxent *)inp;
277 union external_auxent *ext = (union external_auxent *)extp;
279 memset((PTR)ext, 0, bfd_coff_auxesz (abfd));
280 switch (class)
282 case C_FILE:
283 if (ext->x_file.x_n.x_zeroes == 0) {
284 bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
285 bfd_h_put_32 (abfd, in->x_file.x_n.x_offset,
286 (bfd_byte *) ext->x_file.x_n.x_offset);
287 } else {
288 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
290 bfd_h_put_8 (abfd, _AUX_FILE, (bfd_byte *) ext->x_auxtype.x_auxtype);
291 goto end;
293 /* RS/6000 "csect" auxents */
294 case C_EXT:
295 case C_HIDEXT:
296 if (indx + 1 == numaux)
298 bfd_vma temp;
300 temp = in->x_csect.x_scnlen.l & 0xffffffff;
301 bfd_h_put_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
302 temp = in->x_csect.x_scnlen.l >> 32;
303 bfd_h_put_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
304 bfd_h_put_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
305 bfd_h_put_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
306 /* We don't have to hack bitfields in x_smtyp because it's
307 defined by shifts-and-ands, which are equivalent on all
308 byte orders. */
309 bfd_h_put_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
310 bfd_h_put_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
311 bfd_h_put_8 (abfd, _AUX_CSECT, (bfd_byte *) ext->x_auxtype.x_auxtype);
312 goto end;
314 break;
316 case C_STAT:
317 case C_LEAFSTAT:
318 case C_HIDDEN:
319 if (type == T_NULL) {
320 goto end;
322 break;
325 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
327 bfd_h_put_64(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
328 (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
329 bfd_h_put_8 (abfd, _AUX_FCN, (bfd_byte *) ext->x_auxtype.x_auxtype);
330 bfd_h_put_32(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
331 (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx);
333 if (ISFCN (type))
334 bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
335 (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_fsize);
336 else
338 bfd_h_put_32(abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
339 (bfd_byte *)ext->x_sym.x_fcnary.x_lnsz.x_lnno);
340 bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size,
341 (bfd_byte *)ext->x_sym.x_fcnary.x_lnsz.x_size);
344 end:
346 return bfd_coff_auxesz (abfd);
349 static boolean
350 _bfd_xcoff64_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
351 struct internal_syment *sym,
352 const char *name) {
353 boolean hash;
354 bfd_size_type indx;
356 hash = true;
358 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
359 hash = false;
361 indx = _bfd_stringtab_add (strtab, name, hash, false);
363 if (indx == (bfd_size_type) -1)
364 return false;
366 sym->_n._n_n._n_zeroes = 0;
367 sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
369 return true;
372 static boolean
373 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
374 bfd *abfd ATTRIBUTE_UNUSED;
375 struct xcoff_loader_info *ldinfo;
376 struct internal_ldsym *ldsym;
377 const char *name;
380 size_t len;
381 len = strlen (name);
383 if (ldinfo->string_size + len + 3 > ldinfo->string_alc){
384 size_t newalc;
385 bfd_byte *newstrings;
387 newalc = ldinfo->string_alc * 2;
388 if (newalc == 0)
389 newalc = 32;
390 while (ldinfo->string_size + len + 3 > newalc)
391 newalc *= 2;
393 newstrings = ((bfd_byte *)
394 bfd_realloc ((PTR) ldinfo->strings, newalc));
395 if (newstrings == NULL) {
396 ldinfo->failed = true;
397 return false;
399 ldinfo->string_alc = newalc;
400 ldinfo->strings = newstrings;
403 bfd_put_16 (ldinfo->output_bfd, len + 1,
404 ldinfo->strings + ldinfo->string_size);
405 strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
406 ldsym->_l._l_l._l_zeroes = 0;
407 ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
408 ldinfo->string_size += len + 3;
410 return true;
413 extern boolean _bfd_xcoff_mkobject PARAMS ((bfd *));
414 extern boolean _bfd_xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *));
415 extern boolean _bfd_xcoff_is_local_label_name PARAMS ((bfd *, const char *));
416 extern void xcoff64_rtype2howto
417 PARAMS ((arelent *, struct internal_reloc *));
418 extern reloc_howto_type * xcoff64_reloc_type_lookup
419 PARAMS ((bfd *, bfd_reloc_code_real_type));
420 extern boolean _bfd_xcoff_slurp_armap PARAMS ((bfd *));
421 extern PTR _bfd_xcoff_read_ar_hdr PARAMS ((bfd *));
422 extern bfd *_bfd_xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
423 extern int _bfd_xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
424 extern boolean _bfd_xcoff_write_armap
425 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
426 extern boolean _bfd_xcoff_write_archive_contents PARAMS ((bfd *));
427 extern int _bfd_xcoff_sizeof_headers PARAMS ((bfd *, boolean));
428 extern void _bfd_xcoff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
429 extern unsigned int _bfd_xcoff_swap_sym_out PARAMS ((bfd *, PTR, PTR));
430 extern void _bfd_xcoff_swap_aux_in PARAMS ((bfd *, PTR, int, int, int, int, PTR));
431 extern unsigned int _bfd_xcoff_swap_aux_out PARAMS ((bfd *, PTR, int, int, int, int, PTR));
433 /* coffcode.h needs these to be defined */
434 /* Internalcoff.h and coffcode.h modify themselves based on these flags. */
435 #define XCOFF64
436 #define RS6000COFF_C 1
438 #define SELECT_RELOC(internal, howto) \
440 internal.r_type = howto->type; \
441 internal.r_size = \
442 ((howto->complain_on_overflow == complain_overflow_signed \
443 ? 0x80 \
444 : 0) \
445 | (howto->bitsize - 1)); \
448 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
449 #define COFF_LONG_FILENAMES
450 #define NO_COFF_SYMBOLS
451 #define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
452 #define coff_mkobject _bfd_xcoff_mkobject
453 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
454 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
455 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
456 #ifdef AIX_CORE
457 extern const bfd_target * rs6000coff_core_p ();
458 extern boolean rs6000coff_core_file_matches_executable_p ();
459 extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
460 extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
461 #define CORE_FILE_P rs6000coff_core_p
462 #define coff_core_file_failing_command \
463 rs6000coff_core_file_failing_command
464 #define coff_core_file_failing_signal \
465 rs6000coff_core_file_failing_signal
466 #define coff_core_file_matches_executable_p \
467 rs6000coff_core_file_matches_executable_p
468 #else
469 #define CORE_FILE_P _bfd_dummy_target
470 #define coff_core_file_failing_command \
471 _bfd_nocore_core_file_failing_command
472 #define coff_core_file_failing_signal \
473 _bfd_nocore_core_file_failing_signal
474 #define coff_core_file_matches_executable_p \
475 _bfd_nocore_core_file_matches_executable_p
476 #endif
477 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
478 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
479 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
480 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
484 #include "coffcode.h"
486 /* Routines to swap information in the XCOFF .loader section. If we
487 ever need to write an XCOFF loader, this stuff will need to be
488 moved to another file shared by the linker (which XCOFF calls the
489 ``binder'') and the loader. */
491 /* Swap in the ldhdr structure. */
493 static void
494 xcoff64_swap_ldhdr_in (abfd, src, dst)
495 bfd *abfd;
496 const struct external_ldhdr *src;
497 struct internal_ldhdr *dst;
499 dst->l_version = bfd_get_32 (abfd, src->l_version);
500 dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
501 dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
502 dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
503 dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
504 dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
505 dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
506 dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
507 dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
508 dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
511 /* Swap out the ldhdr structure. */
513 static void
514 xcoff64_swap_ldhdr_out (abfd, src, dst)
515 bfd *abfd;
516 const struct internal_ldhdr *src;
517 struct external_ldhdr *dst;
519 bfd_put_32 (abfd, src->l_version, dst->l_version);
520 bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
521 bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
522 bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
523 bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
524 bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
525 bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
526 bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
527 bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
528 bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
531 /* Swap in the ldsym structure. */
533 static void
534 xcoff64_swap_ldsym_in (abfd, src, dst)
535 bfd *abfd;
536 const struct external_ldsym *src;
537 struct internal_ldsym *dst;
540 * XCOFF64 does not use l_zeroes like XCOFF32
541 * Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
542 * as an offset into the loader symbol table
544 dst->_l._l_l._l_zeroes = 0;
545 dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
546 dst->l_value = bfd_get_64 (abfd, src->l_value);
547 dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
548 dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
549 dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
550 dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
551 dst->l_parm = bfd_get_32 (abfd, src->l_parm);
554 /* Swap out the ldsym structure. */
556 static void
557 xcoff64_swap_ldsym_out (abfd, src, dst)
558 bfd *abfd;
559 const struct internal_ldsym *src;
560 struct external_ldsym *dst;
562 bfd_put_64 (abfd, src->l_value, dst->l_value);
563 bfd_put_32 (abfd, src->_l._l_l._l_offset, dst->l_offset);
564 bfd_put_16 (abfd, src->l_scnum, dst->l_scnum);
565 bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
566 bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
567 bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
568 bfd_put_32 (abfd, src->l_parm, dst->l_parm);
571 /* Swap in the ldrel structure. */
573 static void
574 xcoff64_swap_ldrel_in (abfd, src, dst)
575 bfd *abfd;
576 const struct external_ldrel *src;
577 struct internal_ldrel *dst;
579 dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
580 dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
581 dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
582 dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
585 /* Swap out the ldrel structure. */
587 static void
588 xcoff64_swap_ldrel_out (abfd, src, dst)
589 bfd *abfd;
590 const struct internal_ldrel *src;
591 struct external_ldrel *dst;
593 bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
594 bfd_put_16 (abfd, src->l_rtype, dst->l_rtype);
595 bfd_put_16 (abfd, src->l_rsecnm, dst->l_rsecnm);
596 bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
599 static boolean
600 xcoff64_write_object_contents (abfd)
601 bfd * abfd;
603 asection *current;
604 boolean hasrelocs = false;
605 boolean haslinno = false;
606 file_ptr scn_base;
607 file_ptr reloc_base;
608 file_ptr lineno_base;
609 file_ptr sym_base;
610 unsigned long reloc_size = 0;
611 unsigned long lnno_size = 0;
612 boolean long_section_names;
613 asection *text_sec = ((void *)0) ;
614 asection *data_sec = ((void *)0) ;
615 asection *bss_sec = ((void *)0) ;
616 struct internal_filehdr internal_f;
617 struct internal_aouthdr internal_a;
619 bfd_set_error (bfd_error_system_call);
621 if (abfd->output_has_begun == false) {
622 if (! bfd_coff_compute_section_file_positions (abfd))
623 return false;
626 /* Work out the size of the reloc and linno areas */
627 reloc_base = obj_relocbase (abfd);
629 for (current = abfd->sections; current != NULL; current = current->next) {
630 reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
633 lineno_base = reloc_base + reloc_size;
635 /* Make a pass through the symbol table to count line number entries and
636 put them into the correct asections */
637 lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
639 sym_base = lineno_base + lnno_size;
641 /* Indicate in each section->line_filepos its actual file address */
642 for (current = abfd->sections; current != NULL; current = current->next) {
643 if (current->lineno_count) {
644 current->line_filepos = lineno_base;
645 current->moving_line_filepos = lineno_base;
646 lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
647 } else {
648 current->line_filepos = 0;
651 if (current->reloc_count) {
652 current->rel_filepos = reloc_base;
653 reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
654 } else {
655 current->rel_filepos = 0;
659 if ((abfd->flags & EXEC_P) != 0) {
660 scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
661 internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
662 } else {
663 scn_base = bfd_coff_filhsz (abfd);
664 internal_f.f_opthdr = 0;
667 internal_f.f_nscns = 0;
669 if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
670 return false;
672 long_section_names = false;
673 for (current = abfd->sections; current != NULL; current = current->next) {
675 struct internal_scnhdr section;
676 struct external_scnhdr buff;
678 internal_f.f_nscns++;
680 strncpy (section.s_name, current->name, SCNNMLEN);
682 section.s_vaddr = current->vma;
683 section.s_paddr = current->lma;
684 section.s_size = current->_raw_size;
687 If this section has no size or is unloadable then the scnptr
688 will be 0 too
690 if (current->_raw_size == 0 ||
691 (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) {
692 section.s_scnptr = 0;
693 } else {
694 section.s_scnptr = current->filepos;
697 section.s_relptr = current->rel_filepos;
698 section.s_lnnoptr = current->line_filepos;
699 section.s_nreloc = current->reloc_count;
701 section.s_nlnno = current->lineno_count;
702 if (current->reloc_count != 0)
703 hasrelocs = true;
704 if (current->lineno_count != 0)
705 haslinno = true;
707 section.s_flags = sec_to_styp_flags (current->name, current->flags);
709 if (!strcmp (current->name, _TEXT)) {
710 text_sec = current;
711 } else if (!strcmp (current->name, _DATA)) {
712 data_sec = current;
713 } else if (!strcmp (current->name, _BSS)) {
714 bss_sec = current;
717 if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
718 || bfd_write ((PTR) (&buff), 1, bfd_coff_scnhsz (abfd), abfd)
719 != bfd_coff_scnhsz (abfd))
720 return false;
723 internal_f.f_timdat = 0;
725 internal_f.f_flags = 0;
727 if (!hasrelocs)
728 internal_f.f_flags |= F_RELFLG;
729 if (!haslinno)
730 internal_f.f_flags |= F_LNNO;
731 if (abfd->flags & EXEC_P)
732 internal_f.f_flags |= F_EXEC;
734 /* FIXME: this is wrong for PPC_PE! */
735 if (bfd_little_endian (abfd))
736 internal_f.f_flags |= F_AR32WR;
737 else
738 internal_f.f_flags |= F_AR32W;
740 if ((abfd->flags & DYNAMIC) != 0)
741 internal_f.f_flags |= F_SHROBJ;
742 if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
743 internal_f.f_flags |= F_DYNLOAD;
745 memset (&internal_a, 0, sizeof internal_a);
749 * This can only be called from the xcoff64 backend so the magic # must
750 * be for xcoff64
752 internal_f.f_magic = 0757;
754 internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC :
755 (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC :
756 RS6K_AOUTHDR_OMAGIC;
758 /* FIXME: Does anybody ever set this to another value? */
759 internal_a.vstamp = 0;
761 /* Now should write relocs, strings, syms */
762 obj_sym_filepos (abfd) = sym_base;
764 internal_f.f_symptr = 0;
765 internal_f.f_nsyms = 0;
768 * If bfd_get_symcount (abfd) != 0, then we are not using the COFF
769 * backend linker, and obj_raw_syment_count is not valid until after
770 * coff_write_symbols is called.
772 if (bfd_get_symcount (abfd) != 0) {
773 int firstundef;
775 if (!coff_renumber_symbols (abfd, &firstundef))
776 return false;
777 coff_mangle_symbols (abfd);
778 if (! coff_write_symbols (abfd))
779 return false;
780 if (! coff_write_linenumbers (abfd))
781 return false;
782 if (! coff_write_relocs (abfd, firstundef))
783 return false;
785 internal_f.f_symptr = sym_base;
786 internal_f.f_nsyms = bfd_get_symcount (abfd);
787 } else if (obj_raw_syment_count (abfd) != 0) {
788 internal_f.f_symptr = sym_base;
791 * AIX appears to require that F_RELFLG not be set if there are
792 * local symbols but no relocations.
794 internal_f.f_flags &=~ F_RELFLG;
795 } else {
796 internal_f.f_flags |= F_LSYMS;
799 if (text_sec) {
800 internal_a.tsize = bfd_get_section_size_before_reloc (text_sec);
801 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
804 if (data_sec) {
805 internal_a.dsize = bfd_get_section_size_before_reloc (data_sec);
806 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
809 if (bss_sec) {
810 internal_a.bsize = bfd_get_section_size_before_reloc (bss_sec);
811 if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
812 internal_a.data_start = bss_sec->vma;
815 internal_a.entry = bfd_get_start_address (abfd);
816 internal_f.f_nsyms = obj_raw_syment_count (abfd);
818 if (xcoff_data (abfd)->full_aouthdr) {
820 bfd_vma toc;
821 asection *loader_sec;
823 internal_a.vstamp = 1;
825 internal_a.o_snentry = xcoff_data (abfd)->snentry;
826 if (internal_a.o_snentry == 0)
827 internal_a.entry = (bfd_vma) -1;
829 if (text_sec != NULL) {
830 internal_a.o_sntext = text_sec->target_index;
831 internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
832 } else {
833 internal_a.o_sntext = 0;
834 internal_a.o_algntext = 0;
837 if (data_sec != NULL) {
838 internal_a.o_sndata = data_sec->target_index;
839 internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
840 } else {
841 internal_a.o_sndata = 0;
842 internal_a.o_algndata = 0;
845 loader_sec = bfd_get_section_by_name (abfd, ".loader");
846 if (loader_sec != NULL)
847 internal_a.o_snloader = loader_sec->target_index;
848 else
849 internal_a.o_snloader = 0;
850 if (bss_sec != NULL)
851 internal_a.o_snbss = bss_sec->target_index;
852 else
853 internal_a.o_snbss = 0;
855 toc = xcoff_data (abfd)->toc;
856 internal_a.o_toc = toc;
857 internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
859 internal_a.o_modtype = xcoff_data (abfd)->modtype;
860 if (xcoff_data (abfd)->cputype != -1)
861 internal_a.o_cputype = xcoff_data (abfd)->cputype;
862 else
864 switch (bfd_get_arch (abfd))
866 case bfd_arch_rs6000:
867 internal_a.o_cputype = 4;
868 break;
869 case bfd_arch_powerpc:
870 if (bfd_get_mach (abfd) == 0)
871 internal_a.o_cputype = 3;
872 else
873 internal_a.o_cputype = 1;
874 break;
875 default:
876 abort ();
879 internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
880 internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
883 if (bfd_seek (abfd, (file_ptr) 0, 0 ) != 0)
884 return false;
887 char * buff;
888 bfd_size_type amount;
890 buff = bfd_malloc (bfd_coff_filhsz (abfd));
891 if (buff == ((void *)0) )
892 return false;
894 bfd_coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) buff);
895 amount = bfd_write ((PTR) buff, 1, bfd_coff_filhsz (abfd), abfd);
897 free (buff);
899 if (amount != bfd_coff_filhsz (abfd))
900 return false;
903 if (abfd->flags & EXEC_P) {
905 char * buff;
906 bfd_size_type amount;
908 buff = bfd_malloc (bfd_coff_aoutsz (abfd));
909 if (buff == NULL)
910 return false;
912 bfd_coff_swap_aouthdr_out (abfd, (PTR) & internal_a, (PTR) buff);
913 amount = bfd_write ((PTR) buff, 1, bfd_coff_aoutsz (abfd), abfd);
915 free (buff);
917 if (amount != bfd_coff_aoutsz (abfd))
918 return false;
922 return true;
925 /* This is the relocation function for the RS/6000/POWER/PowerPC.
926 This is currently the only processor which uses XCOFF; I hope that
927 will never change. */
929 boolean
930 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
931 input_section, contents, relocs, syms,
932 sections)
933 bfd *output_bfd;
934 struct bfd_link_info *info;
935 bfd *input_bfd;
936 asection *input_section;
937 bfd_byte *contents;
938 struct internal_reloc *relocs;
939 struct internal_syment *syms;
940 asection **sections;
942 struct internal_reloc *rel;
943 struct internal_reloc *relend;
945 rel = relocs;
946 relend = rel + input_section->reloc_count;
947 for (; rel < relend; rel++)
949 long symndx;
950 struct xcoff_link_hash_entry *h;
951 struct internal_syment *sym;
952 bfd_vma addend;
953 bfd_vma val;
954 struct reloc_howto_struct howto;
955 bfd_reloc_status_type rstat;
957 /* Relocation type R_REF is a special relocation type which is
958 merely used to prevent garbage collection from occurring for
959 the csect including the symbol which it references. */
960 if (rel->r_type == R_REF)
961 continue;
963 symndx = rel->r_symndx;
965 if (symndx == -1) {
966 h = NULL;
967 sym = NULL;
968 addend = 0;
969 } else {
970 h = obj_xcoff_sym_hashes (input_bfd)[symndx];
971 sym = syms + symndx;
972 addend = - sym->n_value;
975 /* We build the howto information on the fly. */
977 howto.type = rel->r_type;
978 howto.rightshift = 0;
979 howto.size = 4;
980 howto.bitsize = (rel->r_size & 0x3f) + 1;
981 howto.pc_relative = false;
982 howto.bitpos = 0;
983 if ((rel->r_size & 0x80) != 0)
984 howto.complain_on_overflow = complain_overflow_signed;
985 else
986 howto.complain_on_overflow = complain_overflow_bitfield;
987 howto.special_function = NULL;
988 howto.name = "internal";
989 howto.partial_inplace = true;
991 if (howto.bitsize == 64) {
992 howto.src_mask = howto.dst_mask = MINUS_ONE;
993 } else if (howto.bitsize == 32) {
994 howto.src_mask = howto.dst_mask = 0xffffffff;
995 } else {
996 howto.src_mask = howto.dst_mask = (1 << howto.bitsize) - 1;
997 if (howto.bitsize == 16)
998 howto.size = 1;
1000 howto.pcrel_offset = false;
1002 val = 0;
1004 if (h == NULL) {
1005 asection *sec;
1007 if (symndx == -1) {
1008 sec = bfd_abs_section_ptr;
1009 val = 0;
1010 } else {
1011 sec = sections[symndx];
1012 /* Hack to make sure we use the right TOC anchor value
1013 if this reloc is against the TOC anchor. */
1014 if (sec->name[3] == '0'
1015 && strcmp (sec->name, ".tc0") == 0)
1016 val = xcoff_data (output_bfd)->toc;
1017 else
1018 val = (sec->output_section->vma
1019 + sec->output_offset
1020 + sym->n_value
1021 - sec->vma);
1024 } else {
1026 if (h->root.type == bfd_link_hash_defined
1027 || h->root.type == bfd_link_hash_defweak) {
1028 asection *sec;
1030 sec = h->root.u.def.section;
1031 val = (h->root.u.def.value
1032 + sec->output_section->vma
1033 + sec->output_offset);
1035 } else if (h->root.type == bfd_link_hash_common) {
1036 asection *sec;
1038 sec = h->root.u.c.p->section;
1039 val = (sec->output_section->vma
1040 + sec->output_offset);
1041 } else if ((h->flags & XCOFF_DEF_DYNAMIC) != 0
1042 || (h->flags & XCOFF_IMPORT) != 0) {
1043 /* Every symbol in a shared object is defined somewhere. */
1044 val = 0;
1045 } else if (! info->relocateable) {
1046 if (! ((*info->callbacks->undefined_symbol)
1047 (info, h->root.root.string, input_bfd, input_section,
1048 rel->r_vaddr - input_section->vma, true)))
1049 return false;
1051 /* Don't try to process the reloc. It can't help, and
1052 it may generate another error. */
1053 continue;
1057 /* I took the relocation type definitions from two documents:
1058 the PowerPC AIX Version 4 Application Binary Interface, First
1059 Edition (April 1992), and the PowerOpen ABI, Big-Endian
1060 32-Bit Hardware Implementation (June 30, 1994). Differences
1061 between the documents are noted below. */
1063 switch (rel->r_type) {
1064 case R_RTB:
1065 case R_RRTBI:
1066 case R_RRTBA:
1067 /* These relocs are defined by the PowerPC ABI to be
1068 relative branches which use half of the difference
1069 between the symbol and the program counter. I can't
1070 quite figure out when this is useful. These relocs are
1071 not defined by the PowerOpen ABI. */
1072 default:
1073 (*_bfd_error_handler)
1074 (_("%s: unsupported relocation type 0x%02x"),
1075 bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
1076 bfd_set_error (bfd_error_bad_value);
1077 return false;
1078 case R_POS:
1079 /* Simple positive relocation. */
1080 break;
1081 case R_NEG:
1082 /* Simple negative relocation. */
1083 val = - val;
1084 break;
1085 case R_REL:
1086 /* Simple PC relative relocation. */
1087 howto.pc_relative = true;
1088 break;
1089 case R_TOC:
1090 /* TOC relative relocation. The value in the instruction in
1091 the input file is the offset from the input file TOC to
1092 the desired location. We want the offset from the final
1093 TOC to the desired location. We have:
1094 isym = iTOC + in
1095 iinsn = in + o
1096 osym = oTOC + on
1097 oinsn = on + o
1098 so we must change insn by on - in.
1100 case R_GL:
1101 /* Global linkage relocation. The value of this relocation
1102 is the address of the entry in the TOC section. */
1103 case R_TCL:
1104 /* Local object TOC address. I can't figure out the
1105 difference between this and case R_GL. */
1106 case R_TRL:
1107 /* TOC relative relocation. A TOC relative load instruction
1108 which may be changed to a load address instruction.
1109 FIXME: We don't currently implement this optimization. */
1110 case R_TRLA:
1111 /* TOC relative relocation. This is a TOC relative load
1112 address instruction which may be changed to a load
1113 instruction. FIXME: I don't know if this is the correct
1114 implementation. */
1115 if (h != NULL && h->smclas != XMC_TD)
1117 if (h->toc_section == NULL)
1119 (*_bfd_error_handler)
1120 (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
1121 bfd_get_filename (input_bfd), rel->r_vaddr,
1122 h->root.root.string);
1123 bfd_set_error (bfd_error_bad_value);
1124 return false;
1127 BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
1128 val = (h->toc_section->output_section->vma
1129 + h->toc_section->output_offset);
1134 val = ((val - xcoff_data (output_bfd)->toc)
1135 - (sym->n_value - xcoff_data (input_bfd)->toc));
1137 addend = 0;
1138 break;
1139 case R_BA:
1140 /* Absolute branch. We don't want to mess with the lower
1141 two bits of the instruction. */
1142 case R_CAI:
1143 /* The PowerPC ABI defines this as an absolute call which
1144 may be modified to become a relative call. The PowerOpen
1145 ABI does not define this relocation type. */
1146 case R_RBA:
1147 /* Absolute branch which may be modified to become a
1148 relative branch. */
1149 case R_RBAC:
1150 /* The PowerPC ABI defines this as an absolute branch to a
1151 fixed address which may be modified to an absolute branch
1152 to a symbol. The PowerOpen ABI does not define this
1153 relocation type. */
1154 case R_RBRC:
1155 /* The PowerPC ABI defines this as an absolute branch to a
1156 fixed address which may be modified to a relative branch.
1157 The PowerOpen ABI does not define this relocation type. */
1158 howto.src_mask &= ~3;
1159 howto.dst_mask = howto.src_mask;
1160 break;
1161 case R_BR:
1162 /* Relative branch. We don't want to mess with the lower
1163 two bits of the instruction. */
1164 case R_CREL:
1165 /* The PowerPC ABI defines this as a relative call which may
1166 be modified to become an absolute call. The PowerOpen
1167 ABI does not define this relocation type. */
1168 case R_RBR:
1169 /* A relative branch which may be modified to become an
1170 absolute branch. FIXME: We don't implement this,
1171 although we should for symbols of storage mapping class
1172 XMC_XO. */
1173 howto.pc_relative = true;
1174 howto.src_mask &= ~3;
1175 howto.dst_mask = howto.src_mask;
1176 howto.size = 2;
1177 howto.complain_on_overflow = complain_overflow_bitfield;
1178 break;
1179 case R_RL:
1180 /* The PowerPC AIX ABI describes this as a load which may be
1181 changed to a load address. The PowerOpen ABI says this
1182 is the same as case R_POS. */
1183 break;
1184 case R_RLA:
1185 /* The PowerPC AIX ABI describes this as a load address
1186 which may be changed to a load. The PowerOpen ABI says
1187 this is the same as R_POS. */
1188 break;
1191 /* If we see an R_BR or R_RBR reloc which is jumping to global
1192 linkage code, and it is followed by an appropriate cror nop
1193 instruction, we replace the cror with ld r2,40(r1). This
1194 restores the TOC after the glink code. Contrariwise, if the
1195 call is followed by a ld r2,40(r1), but the call is not
1196 going to global linkage code, we can replace the load with a
1197 cror. */
1198 if ((rel->r_type == R_BR || rel->r_type == R_RBR) &&
1199 h != NULL &&
1200 h->root.type == bfd_link_hash_defined &&
1201 (rel->r_vaddr - input_section->vma + 8
1202 <= input_section->_cooked_size)) {
1204 bfd_byte *pnext;
1205 unsigned long next;
1207 pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
1208 next = bfd_get_32 (input_bfd, pnext);
1211 /* The _ptrgl function is magic. It is used by the AIX
1212 * compiler to call a function through a pointer.
1214 * special case XMC_GL, global linkage
1216 if (h->smclas == XMC_GL
1217 || strcmp (h->root.root.string, "._ptrgl") == 0)
1219 if (next == 0x4def7b82 /* cror 15,15,15 */
1220 || next == 0x4ffffb82 /* cror 31,31,31 */
1221 || next == 0x60000000) /* ori r0,r0,0 */
1222 bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
1224 else
1226 if (next == 0xe8410028) /* ld r2,40(r1) */
1227 bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
1231 /* A PC relative reloc includes the section address. */
1232 if (howto.pc_relative)
1233 addend += input_section->vma;
1235 rstat = _bfd_final_link_relocate (&howto, input_bfd, input_section,
1236 contents,
1237 rel->r_vaddr - input_section->vma,
1238 val, addend);
1240 switch (rstat)
1242 default:
1243 abort ();
1244 case bfd_reloc_ok:
1245 break;
1246 case bfd_reloc_overflow:
1248 const char *name;
1249 char buf[SYMNMLEN + 1];
1250 char howto_name[10];
1252 if (symndx == -1)
1253 name = "*ABS*";
1254 else if (h != NULL)
1255 name = h->root.root.string;
1256 else
1258 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1259 if (name == NULL)
1260 return false;
1262 sprintf (howto_name, "0x%02x", rel->r_type);
1264 if (! ((*info->callbacks->reloc_overflow)
1265 (info, name, howto_name, (bfd_vma) 0, input_bfd,
1266 input_section, rel->r_vaddr - input_section->vma)))
1267 return false;
1272 return true;
1277 /* The XCOFF reloc table. Actually, XCOFF relocations specify the
1278 bitsize and whether they are signed or not, along with a
1279 conventional type. This table is for the types, which are used for
1280 different algorithms for putting in the reloc. Many of these
1281 relocs need special_function entries, which I have not written. */
1284 reloc_howto_type xcoff64_howto_table[] =
1286 /* Standard 64 bit relocation. */
1287 HOWTO (0, /* type */
1288 0, /* rightshift */
1289 4, /* size (0 = byte, 1 = short, 2 = long) */
1290 64, /* bitsize */
1291 false, /* pc_relative */
1292 0, /* bitpos */
1293 complain_overflow_bitfield, /* complain_on_overflow */
1294 0, /* special_function */
1295 "R_POS", /* name */
1296 true, /* partial_inplace */
1297 MINUS_ONE, /* src_mask */
1298 MINUS_ONE, /* dst_mask */
1299 false), /* pcrel_offset */
1301 /* 64 bit relocation, but store negative value. */
1302 HOWTO (1, /* type */
1303 0, /* rightshift */
1304 -4, /* size (0 = byte, 1 = short, 2 = long) */
1305 64, /* bitsize */
1306 false, /* pc_relative */
1307 0, /* bitpos */
1308 complain_overflow_bitfield, /* complain_on_overflow */
1309 0, /* special_function */
1310 "R_NEG", /* name */
1311 true, /* partial_inplace */
1312 MINUS_ONE, /* src_mask */
1313 MINUS_ONE, /* dst_mask */
1314 false), /* pcrel_offset */
1316 /* 32 bit PC relative relocation. */
1317 HOWTO (2, /* type */
1318 0, /* rightshift */
1319 2, /* size (0 = byte, 1 = short, 2 = long) */
1320 32, /* bitsize */
1321 true, /* pc_relative */
1322 0, /* bitpos */
1323 complain_overflow_signed, /* complain_on_overflow */
1324 0, /* special_function */
1325 "R_REL", /* name */
1326 true, /* partial_inplace */
1327 0xffffffff, /* src_mask */
1328 0xffffffff, /* dst_mask */
1329 false), /* pcrel_offset */
1331 /* 16 bit TOC relative relocation. */
1332 HOWTO (3, /* type */
1333 0, /* rightshift */
1334 1, /* size (0 = byte, 1 = short, 2 = long) */
1335 16, /* bitsize */
1336 false, /* pc_relative */
1337 0, /* bitpos */
1338 complain_overflow_bitfield, /* complain_on_overflow */
1339 0, /* special_function */
1340 "R_TOC", /* name */
1341 true, /* partial_inplace */
1342 0xffff, /* src_mask */
1343 0xffff, /* dst_mask */
1344 false), /* pcrel_offset */
1346 /* I don't really know what this is. */
1347 HOWTO (4, /* type */
1348 1, /* rightshift */
1349 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 32, /* bitsize */
1351 false, /* pc_relative */
1352 0, /* bitpos */
1353 complain_overflow_bitfield, /* complain_on_overflow */
1354 0, /* special_function */
1355 "R_RTB", /* name */
1356 true, /* partial_inplace */
1357 0xffffffff, /* src_mask */
1358 0xffffffff, /* dst_mask */
1359 false), /* pcrel_offset */
1361 /* External TOC relative symbol. */
1362 HOWTO (5, /* type */
1363 0, /* rightshift */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1365 16, /* bitsize */
1366 false, /* pc_relative */
1367 0, /* bitpos */
1368 complain_overflow_bitfield, /* complain_on_overflow */
1369 0, /* special_function */
1370 "R_GL", /* name */
1371 true, /* partial_inplace */
1372 0xffff, /* src_mask */
1373 0xffff, /* dst_mask */
1374 false), /* pcrel_offset */
1376 /* Local TOC relative symbol. */
1377 HOWTO (6, /* type */
1378 0, /* rightshift */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1380 16, /* bitsize */
1381 false, /* pc_relative */
1382 0, /* bitpos */
1383 complain_overflow_bitfield, /* complain_on_overflow */
1384 0, /* special_function */
1385 "R_TCL", /* name */
1386 true, /* partial_inplace */
1387 0xffff, /* src_mask */
1388 0xffff, /* dst_mask */
1389 false), /* pcrel_offset */
1391 EMPTY_HOWTO (7),
1393 /* Non modifiable absolute branch. */
1394 HOWTO (8, /* type */
1395 0, /* rightshift */
1396 2, /* size (0 = byte, 1 = short, 2 = long) */
1397 26, /* bitsize */
1398 false, /* pc_relative */
1399 0, /* bitpos */
1400 complain_overflow_bitfield, /* complain_on_overflow */
1401 0, /* special_function */
1402 "R_BA", /* name */
1403 true, /* partial_inplace */
1404 0x3fffffc, /* src_mask */
1405 0x3fffffc, /* dst_mask */
1406 false), /* pcrel_offset */
1408 EMPTY_HOWTO (9),
1410 /* Non modifiable relative branch. */
1411 HOWTO (0xa, /* type */
1412 0, /* rightshift */
1413 2, /* size (0 = byte, 1 = short, 2 = long) */
1414 26, /* bitsize */
1415 true, /* pc_relative */
1416 0, /* bitpos */
1417 complain_overflow_signed, /* complain_on_overflow */
1418 0, /* special_function */
1419 "R_BR", /* name */
1420 true, /* partial_inplace */
1421 0x3fffffc, /* src_mask */
1422 0x3fffffc, /* dst_mask */
1423 false), /* pcrel_offset */
1425 EMPTY_HOWTO (0xb),
1427 /* Indirect load. */
1428 HOWTO (0xc, /* type */
1429 0, /* rightshift */
1430 2, /* size (0 = byte, 1 = short, 2 = long) */
1431 16, /* bitsize */
1432 false, /* pc_relative */
1433 0, /* bitpos */
1434 complain_overflow_bitfield, /* complain_on_overflow */
1435 0, /* special_function */
1436 "R_RL", /* name */
1437 true, /* partial_inplace */
1438 0xffff, /* src_mask */
1439 0xffff, /* dst_mask */
1440 false), /* pcrel_offset */
1442 /* Load address. */
1443 HOWTO (0xd, /* type */
1444 0, /* rightshift */
1445 2, /* size (0 = byte, 1 = short, 2 = long) */
1446 16, /* bitsize */
1447 false, /* pc_relative */
1448 0, /* bitpos */
1449 complain_overflow_bitfield, /* complain_on_overflow */
1450 0, /* special_function */
1451 "R_RLA", /* name */
1452 true, /* partial_inplace */
1453 0xffff, /* src_mask */
1454 0xffff, /* dst_mask */
1455 false), /* pcrel_offset */
1457 EMPTY_HOWTO (0xe),
1459 /* Non-relocating reference. */
1460 HOWTO (0xf, /* type */
1461 0, /* rightshift */
1462 2, /* size (0 = byte, 1 = short, 2 = long) */
1463 32, /* bitsize */
1464 false, /* pc_relative */
1465 0, /* bitpos */
1466 complain_overflow_bitfield, /* complain_on_overflow */
1467 0, /* special_function */
1468 "R_REF", /* name */
1469 false, /* partial_inplace */
1470 0, /* src_mask */
1471 0, /* dst_mask */
1472 false), /* pcrel_offset */
1474 EMPTY_HOWTO (0x10),
1475 EMPTY_HOWTO (0x11),
1477 /* TOC relative indirect load. */
1478 HOWTO (0x12, /* type */
1479 0, /* rightshift */
1480 2, /* size (0 = byte, 1 = short, 2 = long) */
1481 16, /* bitsize */
1482 false, /* pc_relative */
1483 0, /* bitpos */
1484 complain_overflow_bitfield, /* complain_on_overflow */
1485 0, /* special_function */
1486 "R_TRL", /* name */
1487 true, /* partial_inplace */
1488 0xffff, /* src_mask */
1489 0xffff, /* dst_mask */
1490 false), /* pcrel_offset */
1492 /* TOC relative load address. */
1493 HOWTO (0x13, /* type */
1494 0, /* rightshift */
1495 2, /* size (0 = byte, 1 = short, 2 = long) */
1496 16, /* bitsize */
1497 false, /* pc_relative */
1498 0, /* bitpos */
1499 complain_overflow_bitfield, /* complain_on_overflow */
1500 0, /* special_function */
1501 "R_TRLA", /* name */
1502 true, /* partial_inplace */
1503 0xffff, /* src_mask */
1504 0xffff, /* dst_mask */
1505 false), /* pcrel_offset */
1507 /* Modifiable relative branch. */
1508 HOWTO (0x14, /* type */
1509 1, /* rightshift */
1510 2, /* size (0 = byte, 1 = short, 2 = long) */
1511 32, /* bitsize */
1512 false, /* pc_relative */
1513 0, /* bitpos */
1514 complain_overflow_bitfield, /* complain_on_overflow */
1515 0, /* special_function */
1516 "R_RRTBI", /* name */
1517 true, /* partial_inplace */
1518 0xffffffff, /* src_mask */
1519 0xffffffff, /* dst_mask */
1520 false), /* pcrel_offset */
1522 /* Modifiable absolute branch. */
1523 HOWTO (0x15, /* type */
1524 1, /* rightshift */
1525 2, /* size (0 = byte, 1 = short, 2 = long) */
1526 32, /* bitsize */
1527 false, /* pc_relative */
1528 0, /* bitpos */
1529 complain_overflow_bitfield, /* complain_on_overflow */
1530 0, /* special_function */
1531 "R_RRTBA", /* name */
1532 true, /* partial_inplace */
1533 0xffffffff, /* src_mask */
1534 0xffffffff, /* dst_mask */
1535 false), /* pcrel_offset */
1537 /* Modifiable call absolute indirect. */
1538 HOWTO (0x16, /* type */
1539 0, /* rightshift */
1540 2, /* size (0 = byte, 1 = short, 2 = long) */
1541 16, /* bitsize */
1542 false, /* pc_relative */
1543 0, /* bitpos */
1544 complain_overflow_bitfield, /* complain_on_overflow */
1545 0, /* special_function */
1546 "R_CAI", /* name */
1547 true, /* partial_inplace */
1548 0xffff, /* src_mask */
1549 0xffff, /* dst_mask */
1550 false), /* pcrel_offset */
1552 /* Modifiable call relative. */
1553 HOWTO (0x17, /* type */
1554 0, /* rightshift */
1555 2, /* size (0 = byte, 1 = short, 2 = long) */
1556 16, /* bitsize */
1557 false, /* pc_relative */
1558 0, /* bitpos */
1559 complain_overflow_bitfield, /* complain_on_overflow */
1560 0, /* special_function */
1561 "R_CREL", /* name */
1562 true, /* partial_inplace */
1563 0xffff, /* src_mask */
1564 0xffff, /* dst_mask */
1565 false), /* pcrel_offset */
1567 /* Modifiable branch absolute. */
1568 HOWTO (0x18, /* type */
1569 0, /* rightshift */
1570 2, /* size (0 = byte, 1 = short, 2 = long) */
1571 26, /* bitsize */
1572 false, /* pc_relative */
1573 0, /* bitpos */
1574 complain_overflow_bitfield, /* complain_on_overflow */
1575 0, /* special_function */
1576 "R_RBA", /* name */
1577 true, /* partial_inplace */
1578 0xffff, /* src_mask */
1579 0xffff, /* dst_mask */
1580 false), /* pcrel_offset */
1582 /* Modifiable branch absolute. */
1583 HOWTO (0x19, /* type */
1584 0, /* rightshift */
1585 2, /* size (0 = byte, 1 = short, 2 = long) */
1586 32, /* bitsize */
1587 false, /* pc_relative */
1588 0, /* bitpos */
1589 complain_overflow_bitfield, /* complain_on_overflow */
1590 0, /* special_function */
1591 "R_RBAC", /* name */
1592 true, /* partial_inplace */
1593 0xffff, /* src_mask */
1594 0xffff, /* dst_mask */
1595 false), /* pcrel_offset */
1597 /* Modifiable branch relative. */
1598 HOWTO (0x1a, /* type */
1599 0, /* rightshift */
1600 2, /* size (0 = byte, 1 = short, 2 = long) */
1601 26, /* bitsize */
1602 false, /* pc_relative */
1603 0, /* bitpos */
1604 complain_overflow_signed, /* complain_on_overflow */
1605 0, /* special_function */
1606 "R_RBR", /* name */
1607 true, /* partial_inplace */
1608 0xffff, /* src_mask */
1609 0xffff, /* dst_mask */
1610 false), /* pcrel_offset */
1612 /* Modifiable branch absolute. */
1613 HOWTO (0x1b, /* type */
1614 0, /* rightshift */
1615 2, /* size (0 = byte, 1 = short, 2 = long) */
1616 16, /* bitsize */
1617 false, /* pc_relative */
1618 0, /* bitpos */
1619 complain_overflow_bitfield, /* complain_on_overflow */
1620 0, /* special_function */
1621 "R_RBRC", /* name */
1622 true, /* partial_inplace */
1623 0xffff, /* src_mask */
1624 0xffff, /* dst_mask */
1625 false), /* pcrel_offset */
1627 HOWTO (0, /* type */
1628 0, /* rightshift */
1629 4, /* size (0 = byte, 1 = short, 2 = long) */
1630 64, /* bitsize */
1631 false, /* pc_relative */
1632 0, /* bitpos */
1633 complain_overflow_bitfield, /* complain_on_overflow */
1634 0, /* special_function */
1635 "R_POS", /* name */
1636 true, /* partial_inplace */
1637 MINUS_ONE, /* src_mask */
1638 MINUS_ONE, /* dst_mask */
1639 false) /* pcrel_offset */
1643 void
1644 xcoff64_rtype2howto (relent, internal)
1645 arelent *relent;
1646 struct internal_reloc *internal;
1648 relent->howto = xcoff64_howto_table + internal->r_type;
1650 /* Check for relocs we don't know of. */
1651 if (internal->r_type
1652 >= sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]))
1653 abort ();
1654 if (internal->r_type != relent->howto->type)
1655 abort ();
1657 /* The r_size field of an XCOFF reloc encodes the bitsize of the
1658 relocation, as well as indicating whether it is signed or not.
1659 Doublecheck that the relocation information gathered from the
1660 type matches this information. The bitsize is not significant
1661 for R_REF relocs. */
1662 if (relent->howto->dst_mask != 0
1663 && (relent->howto->bitsize
1664 != ((unsigned int) internal->r_size & 0x3f) + 1))
1665 abort ();
1666 #if 0
1667 if ((internal->r_size & 0x80) != 0
1668 ? (relent->howto->complain_on_overflow != complain_overflow_signed)
1669 : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
1670 abort ();
1671 #endif
1674 reloc_howto_type *
1675 xcoff64_reloc_type_lookup (abfd, code)
1676 bfd *abfd ATTRIBUTE_UNUSED;
1677 bfd_reloc_code_real_type code;
1679 switch (code)
1681 case BFD_RELOC_PPC_B26:
1682 return &xcoff64_howto_table[0xa];
1683 case BFD_RELOC_PPC_BA26:
1684 return &xcoff64_howto_table[8];
1685 case BFD_RELOC_PPC_TOC16:
1686 return &xcoff64_howto_table[3];
1687 case BFD_RELOC_32:
1688 case BFD_RELOC_CTOR:
1689 return &xcoff64_howto_table[0];
1690 case BFD_RELOC_64:
1691 return &xcoff64_howto_table[0x1c];
1692 default:
1693 return NULL;
1699 /* Read in the armap of an XCOFF archive. */
1701 boolean
1702 xcoff64_slurp_armap (abfd)
1703 bfd *abfd;
1705 file_ptr off;
1706 size_t namlen;
1707 bfd_size_type sz;
1708 bfd_byte *contents, *cend;
1709 bfd_vma c, i;
1710 carsym *arsym;
1711 bfd_byte *p;
1713 /* This is for the new format. */
1714 struct xcoff_ar_hdr_big hdr;
1716 if (xcoff_ardata (abfd) == NULL) {
1717 bfd_has_map (abfd) = false;
1718 return true;
1721 off = strtol (xcoff_ardata_big (abfd)->symoff64, (char **) NULL, 10);
1722 if (off == 0) {
1723 bfd_has_map (abfd) = false;
1724 return true;
1727 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1728 return false;
1730 /* The symbol table starts with a normal archive header. */
1731 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) != SIZEOF_AR_HDR_BIG)
1732 return false;
1734 /* Skip the name (normally empty). */
1735 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1736 if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0)
1737 return false;
1739 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1740 machines) since the field width is 20 and there numbers with more
1741 than 32 bits can be represented. */
1742 sz = strtol (hdr.size, (char **) NULL, 10);
1744 /* Read in the entire symbol table. */
1745 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1746 if (contents == NULL)
1747 return false;
1748 if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
1749 return false;
1751 /* The symbol table starts with an eight byte count. */
1752 c = bfd_h_get_64 (abfd, contents);
1754 if (c * 8 >= sz) {
1755 bfd_set_error (bfd_error_bad_value);
1756 return false;
1759 bfd_ardata (abfd)->symdefs = ((carsym *)
1760 bfd_alloc (abfd, c * sizeof (carsym)));
1761 if (bfd_ardata (abfd)->symdefs == NULL)
1762 return false;
1764 /* After the count comes a list of eight byte file offsets. */
1765 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1766 i < c;
1767 ++i, ++arsym, p += 8)
1768 arsym->file_offset = bfd_h_get_64 (abfd, p);
1770 /* After the file offsets come null terminated symbol names. */
1771 cend = contents + sz;
1772 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1773 i < c;
1774 ++i, ++arsym, p += strlen ((char *) p) + 1)
1776 if (p >= cend)
1778 bfd_set_error (bfd_error_bad_value);
1779 return false;
1781 arsym->name = (char *) p;
1784 bfd_ardata (abfd)->symdef_count = c;
1785 bfd_has_map (abfd) = true;
1787 return true;
1792 /* See if this is an NEW XCOFF archive. */
1794 const bfd_target *
1795 xcoff64_archive_p (abfd)
1796 bfd *abfd;
1798 char magic[SXCOFFARMAG];
1799 /* This is the new format. */
1800 struct xcoff_ar_file_hdr_big hdr;
1802 if (bfd_read ((PTR) magic, SXCOFFARMAG, 1, abfd) != SXCOFFARMAG) {
1803 if (bfd_get_error () != bfd_error_system_call)
1804 bfd_set_error (bfd_error_wrong_format);
1805 return NULL;
1808 if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0) {
1809 bfd_set_error (bfd_error_wrong_format);
1810 return NULL;
1813 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
1814 involves a cast, we can't do it as the left operand of
1815 assignment. */
1816 abfd->tdata.aout_ar_data =
1817 (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
1819 if (bfd_ardata (abfd) == (struct artdata *) NULL)
1820 return NULL;
1822 bfd_ardata (abfd)->cache = NULL;
1823 bfd_ardata (abfd)->archive_head = NULL;
1824 bfd_ardata (abfd)->symdefs = NULL;
1825 bfd_ardata (abfd)->extended_names = NULL;
1827 /* Copy over the magic string. */
1828 memcpy (hdr.magic, magic, SXCOFFARMAG);
1830 /* Now read the rest of the file header. */
1831 if (bfd_read ((PTR) &hdr.memoff, SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG, 1,
1832 abfd) != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG) {
1833 if (bfd_get_error () != bfd_error_system_call)
1834 bfd_set_error (bfd_error_wrong_format);
1835 return NULL;
1838 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1839 machines) since the field width is 20 and there numbers with more
1840 than 32 bits can be represented. */
1841 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1842 (char **) NULL, 10);
1844 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR_BIG);
1845 if (bfd_ardata (abfd)->tdata == NULL)
1846 return NULL;
1848 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1850 if (! xcoff64_slurp_armap (abfd)) {
1852 bfd_release (abfd, bfd_ardata (abfd));
1853 abfd->tdata.aout_ar_data = (struct artdata *) NULL;
1854 return NULL;
1857 return abfd->xvec;
1861 /* Open the next element in an XCOFF archive. */
1863 bfd *
1864 xcoff64_openr_next_archived_file (archive, last_file)
1865 bfd *archive;
1866 bfd *last_file;
1868 file_ptr filestart;
1870 if ((xcoff_ardata (archive) == NULL) ||
1871 (! xcoff_big_format_p (archive))) {
1872 bfd_set_error (bfd_error_invalid_operation);
1873 return NULL;
1876 if (last_file == NULL) {
1877 filestart = bfd_ardata (archive)->first_file_filepos;
1878 } else {
1879 /* XXX These actually have to be a calls to strtoll (at least
1880 on 32-bit machines) since the fields's width is 20 and
1881 there numbers with more than 32 bits can be represented. */
1882 filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
1883 10);
1885 /* XXX These actually have to be calls to strtoll (at least on 32-bit
1886 machines) since the fields's width is 20 and there numbers with more
1887 than 32 bits can be represented. */
1888 if (filestart == 0
1889 || filestart == strtol (xcoff_ardata_big (archive)->memoff,
1890 (char **) NULL, 10)
1891 || filestart == strtol (xcoff_ardata_big (archive)->symoff,
1892 (char **) NULL, 10)) {
1893 bfd_set_error (bfd_error_no_more_archived_files);
1894 return NULL;
1897 return _bfd_get_elt_at_filepos (archive, filestart);
1900 /* We can't use the usual coff_sizeof_headers routine, because AIX
1901 always uses an a.out header. */
1903 /*ARGSUSED*/
1905 xcoff64_sizeof_headers (abfd, reloc)
1906 bfd *abfd;
1907 boolean reloc ATTRIBUTE_UNUSED;
1909 int size;
1911 size = bfd_coff_filhsz(abfd);
1914 * Don't think the small aout header can be used since some of the the
1915 * old elements have been reordered past the end of the old coff
1916 * small aout size
1919 if (xcoff_data (abfd)->full_aouthdr)
1920 size += bfd_coff_aoutsz(abfd);
1922 size += abfd->section_count * bfd_coff_scnhsz(abfd);
1923 return size;
1928 static asection *
1929 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
1930 bfd *abfd;
1931 union internal_auxent *aux;
1932 const char *symbol_name;
1934 asection *return_value = NULL;
1937 * Changes from 32 :
1938 * .sv == 8, is only for 32 bit programs
1939 * .ti == 12 and .tb == 13 are now reserved
1941 static const char *names[19] = {
1942 ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
1943 NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
1944 ".td", ".sv64", ".sv3264"
1947 if ((19 >= aux->x_csect.x_smclas) &&
1948 (NULL != names[aux->x_csect.x_smclas])) {
1950 return_value = bfd_make_section_anyway
1951 (abfd, names[aux->x_csect.x_smclas]);
1953 } else {
1954 (*_bfd_error_handler)
1955 (_("%s: symbol `%s' has unrecognized smclas %d"),
1956 bfd_get_filename (abfd), symbol_name, aux->x_csect.x_smclas);
1957 bfd_set_error (bfd_error_bad_value);
1960 return return_value;
1963 boolean
1964 xcoff64_is_lineno_count_overflow (abfd, value)
1965 bfd *abfd ATTRIBUTE_UNUSED;
1966 bfd_vma value ATTRIBUTE_UNUSED;
1968 return false;
1971 boolean
1972 xcoff64_is_reloc_count_overflow (abfd, value)
1973 bfd *abfd ATTRIBUTE_UNUSED;
1974 bfd_vma value ATTRIBUTE_UNUSED;
1976 return false;
1979 bfd_vma
1980 xcoff64_loader_symbol_offset (abfd, ldhdr)
1981 bfd *abfd ATTRIBUTE_UNUSED;
1982 struct internal_ldhdr *ldhdr;
1984 return (ldhdr->l_symoff);
1987 bfd_vma
1988 xcoff64_loader_reloc_offset (abfd, ldhdr)
1989 bfd *abfd ATTRIBUTE_UNUSED;
1990 struct internal_ldhdr *ldhdr;
1992 return (ldhdr->l_rldoff);
1995 /* The typical dynamic reloc. */
1997 static reloc_howto_type xcoff64_dynamic_reloc =
1998 HOWTO (0, /* type */
1999 0, /* rightshift */
2000 4, /* size (0 = byte, 1 = short, 2 = long) */
2001 64, /* bitsize */
2002 false, /* pc_relative */
2003 0, /* bitpos */
2004 complain_overflow_bitfield, /* complain_on_overflow */
2005 0, /* special_function */
2006 "R_POS", /* name */
2007 true, /* partial_inplace */
2008 MINUS_ONE, /* src_mask */
2009 MINUS_ONE, /* dst_mask */
2010 false); /* pcrel_offset */
2012 static unsigned long xcoff64_glink_code[10] =
2014 0xe9820000, /* ld r12,0(r2) */
2015 0xf8410028, /* std r2,40(r1) */
2016 0xe80c0000, /* ld r0,0(r12) */
2017 0xe84c0008, /* ld r0,8(r12) */
2018 0x7c0903a6, /* mtctr r0 */
2019 0x4e800420, /* bctr */
2020 0x00000000, /* start of traceback table */
2021 0x000ca000, /* traceback table */
2022 0x00000000, /* traceback table */
2023 0x00000018, /* ??? */
2026 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
2028 { /* COFF backend, defined in libcoff.h */
2029 _bfd_xcoff64_swap_aux_in, /* _bfd_coff_swap_aux_in */
2030 _bfd_xcoff64_swap_sym_in, /* _bfd_coff_swap_sym_in */
2031 _bfd_xcoff64_swap_lineno_in, /* _bfd_coff_swap_lineno_in */
2032 _bfd_xcoff64_swap_aux_out, /* _bfd_swap_aux_out */
2033 _bfd_xcoff64_swap_sym_out, /* _bfd_swap_sym_out */
2034 _bfd_xcoff64_swap_lineno_out, /* _bfd_swap_lineno_out */
2035 coff_swap_reloc_out, /* _bfd_swap_reloc_out */
2036 coff_swap_filehdr_out, /* _bfd_swap_filehdr_out */
2037 coff_swap_aouthdr_out, /* _bfd_swap_aouthdr_out */
2038 coff_swap_scnhdr_out, /* _bfd_swap_scnhdr_out */
2039 FILHSZ, /* _bfd_filhsz */
2040 AOUTSZ, /* _bfd_aoutsz */
2041 SCNHSZ, /* _bfd_scnhsz */
2042 SYMESZ, /* _bfd_symesz */
2043 AUXESZ, /* _bfd_auxesz */
2044 RELSZ, /* _bfd_relsz */
2045 LINESZ, /* _bfd_linesz */
2046 FILNMLEN, /* _bfd_filnmlen */
2047 true, /* _bfd_coff_long_filenames */
2048 false, /* _bfd_coff_long_section_names */
2049 (3), /* _bfd_coff_default_section_alignment_power */
2050 true, /* _bfd_coff_force_symnames_in_strings */
2051 4, /* _bfd_coff_debug_string_prefix_length */
2052 coff_swap_filehdr_in, /* _bfd_coff_swap_filehdr_in */
2053 coff_swap_aouthdr_in, /* _bfd_swap_aouthdr_in */
2054 coff_swap_scnhdr_in, /* _bfd_swap_scnhdr_in */
2055 coff_swap_reloc_in, /* _bfd_reloc_in */
2056 coff_bad_format_hook, /* _bfd_bad_format_hook */
2057 coff_set_arch_mach_hook, /* _bfd_set_arch_mach_hook */
2058 coff_mkobject_hook, /* _bfd_mkobject_hook */
2059 styp_to_sec_flags, /* _bfd_syp_to_sec_flags */
2060 coff_set_alignment_hook, /* _bfd_set_alignment_hook */
2061 coff_slurp_symbol_table, /* _bfd_coff_slurp_symbol_table */
2062 symname_in_debug_hook, /* _coff_symname_in_debug_hook */
2063 coff_pointerize_aux_hook, /* _bfd_coff_pointerize_aux_hook */
2064 coff_print_aux, /* bfd_coff_print_aux */
2065 dummy_reloc16_extra_cases, /* _bfd_coff_reloc16_extra_cases */
2066 dummy_reloc16_estimate, /* _bfd_coff_reloc16_estimate */
2067 NULL, /* bfd_coff_sym_is_global */
2068 /* _bfd_coff_compute_section_file_positions */
2069 coff_compute_section_file_positions,
2070 NULL , /* _bfd_coff_start_final_link */
2071 xcoff64_ppc_relocate_section, /* _bfd_coff_relocate_section */
2072 coff_rtype_to_howto, /* _bfd_coff_rtype_to_howto */
2073 NULL , /* _bfd_coff_addust_symndx */
2074 _bfd_generic_link_add_one_symbol, /* _bfd_coff_add_one_symbol */
2075 coff_link_output_has_begun, /* _bfd_coff_link_output_has_begun */
2076 coff_final_link_postscript /* _bfd_coff_final_link_postscript */
2079 0x01EF, /* magic number */
2080 bfd_arch_powerpc, /* architecture */
2081 bfd_mach_ppc_620, /* machine */
2083 /* function pointers to xcoff specific swap routines */
2084 xcoff64_swap_ldhdr_in, /* _xcoff_swap_ldhdr_in */
2085 xcoff64_swap_ldhdr_out, /* _xcoff_swap_ldhdr_out */
2086 xcoff64_swap_ldsym_in, /* _xcoff_swap_ldsym_in */
2087 xcoff64_swap_ldsym_out, /* _xcoff_swap_ldsym_out */
2088 xcoff64_swap_ldrel_in, /* _xcoff_swap_ldrel_in */
2089 xcoff64_swap_ldrel_out, /* _xcoff_swap_ldrel_out */
2091 /* sizes */
2092 LDHDRSZ, /* _xcoff_ldhdrsz */
2093 LDSYMSZ, /* _xcoff_ldsymsz */
2094 LDRELSZ, /* _xcoff_ldrelsz */
2095 24, /* _xcoff_function_descriptor_size */
2096 0, /* _xcoff_small_aout_header_size */
2097 /* versions */
2098 2, /* _xcoff_ldhdr_version */
2100 /* xcoff vs xcoff64 putting symbol names */
2101 _bfd_xcoff64_put_symbol_name, /* _xcoff_put_symbol_name */
2102 _bfd_xcoff64_put_ldsymbol_name, /* _xcoff_put_ldsymbol_name */
2104 /* dynamic reloc howto */
2105 &xcoff64_dynamic_reloc,
2107 xcoff64_create_csect_from_smclas,
2109 /* lineno and reloc count overflow */
2110 xcoff64_is_lineno_count_overflow,
2111 xcoff64_is_reloc_count_overflow,
2113 xcoff64_loader_symbol_offset,
2114 xcoff64_loader_reloc_offset,
2116 /* glink */
2117 &xcoff64_glink_code[0],
2118 40, /* _xcoff_glink_size */
2122 /* The transfer vector that leads the outside world to all of the above. */
2123 const bfd_target rs6000coff64_vec =
2125 "aixcoff64-rs6000",
2126 bfd_target_xcoff_flavour,
2127 BFD_ENDIAN_BIG, /* data byte order is big */
2128 BFD_ENDIAN_BIG, /* header byte order is big */
2130 (HAS_RELOC | EXEC_P | /* object flags */
2131 HAS_LINENO | HAS_DEBUG | DYNAMIC |
2132 HAS_SYMS | HAS_LOCALS | WP_TEXT),
2134 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2135 0, /* leading char */
2136 '/', /* ar_pad_char */
2137 15, /* ar_max_namelen??? FIXMEmgo */
2139 /* data */
2140 bfd_getb64, /* bfd_getx64 */
2141 bfd_getb_signed_64, /* bfd_getx_signed_64 */
2142 bfd_putb64, /* bfd_putx64 */
2143 bfd_getb32, /* bfd_getx32 */
2144 bfd_getb_signed_32, /* bfd_getx_signed_32 */
2145 bfd_putb32, /* bfd_putx32 */
2146 bfd_getb16, /* bfd_getx16 */
2147 bfd_getb_signed_16, /* bfd_getx_signed_16 */
2148 bfd_putb16, /* bfd_putx16 */
2150 /* hdrs */
2151 bfd_getb64, /* bfd_h_getx64 */
2152 bfd_getb_signed_64, /* bfd_h_getx_signed_64 */
2153 bfd_putb64, /* bfd_h_putx64 */
2154 bfd_getb32, /* bfd_h_getx32 */
2155 bfd_getb_signed_32, /* bfd_h_getx_signed_32 */
2156 bfd_putb32, /* bfd_h_putx32 */
2157 bfd_getb16, /* bfd_h_getx16 */
2158 bfd_getb_signed_16, /* bfd_h_getx_signed_16 */
2159 bfd_putb16, /* bfd_h_putx16 */
2161 { /* bfd_check_format */
2162 _bfd_dummy_target,
2163 coff_object_p,
2164 xcoff64_archive_p,
2165 CORE_FILE_P
2168 { /* bfd_set_format */
2169 bfd_false,
2170 coff_mkobject,
2171 _bfd_generic_mkarchive,
2172 bfd_false
2175 {/* bfd_write_contents */
2176 bfd_false,
2177 xcoff64_write_object_contents,
2178 _bfd_xcoff_write_archive_contents,
2179 bfd_false
2182 /* Generic */
2183 bfd_true, /* _close_and_cleanup */
2184 bfd_true, /* _bfd_free_cached_info */
2185 coff_new_section_hook, /* _new_section_hook */
2186 _bfd_generic_get_section_contents, /* _bfd_get_section_contents */
2187 /* _bfd_get_section_contents_in_window */
2188 _bfd_generic_get_section_contents_in_window,
2190 /* Copy */
2191 _bfd_xcoff_copy_private_bfd_data, /* _bfd_copy_private_bfd */
2192 /* _bfd_merge_private_bfd_data */
2193 ((boolean (*) (bfd *, bfd *)) bfd_true),
2194 /* _bfd_copy_pivate_section_data */
2195 ((boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
2196 /* _bfd_copy_private_symbol_data */
2197 ((boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
2198 ((boolean (*) (bfd *, flagword)) bfd_true), /* _bfd_set_private_flags */
2199 ((boolean (*) (bfd *, void * )) bfd_true), /* _bfd_print_private_bfd_data */
2201 /* Core */
2202 coff_core_file_failing_command, /* _core_file_failing_command */
2203 coff_core_file_failing_signal, /* _core_file_failing_signal */
2204 /* _core_file_matches_executable_p */
2205 coff_core_file_matches_executable_p,
2207 /* Archive */
2208 xcoff64_slurp_armap, /* _slurp_armap */
2209 /* XCOFF archives do not have
2210 anything which corresponds to
2211 an extended name table. */
2212 bfd_false, /* _slurp_extended_name_table */
2213 /* _construct_extended_name_table */
2214 ((boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
2215 bfd_dont_truncate_arname, /* _truncate_arname */
2216 _bfd_xcoff_write_armap, /* _write_armap */
2217 _bfd_xcoff_read_ar_hdr, /* _read_ar_hdr */
2218 xcoff64_openr_next_archived_file, /* _openr_next_archived_file */
2219 _bfd_generic_get_elt_at_index, /* _get_elt_at_index */
2220 _bfd_xcoff_generic_stat_arch_elt, /* _generic_dtat_arch_elt */
2221 /* XCOFF archives do not have
2222 a timestamp. */
2223 bfd_true, /* _update_armap_timestamp */
2225 /* Symbols */
2226 coff_get_symtab_upper_bound, /* _get_symtab_upper_bound */
2227 coff_get_symtab, /* _get_symtab */
2228 coff_make_empty_symbol, /* _make_empty_symbol */
2229 coff_print_symbol, /* _print_symbol */
2230 coff_get_symbol_info, /* _get_symbol_info */
2231 _bfd_xcoff_is_local_label_name, /* _bfd_is_local_label_name */
2232 coff_get_lineno, /* _get_lineno */
2233 coff_find_nearest_line, /* _find_nearest_line */
2234 coff_bfd_make_debug_symbol, /* _bfd_make_debug_symbol */
2235 _bfd_generic_read_minisymbols, /* _read_minisymbols */
2236 _bfd_generic_minisymbol_to_symbol, /* _minsymbol_to_symbol */
2238 /* Reloc */
2239 coff_get_reloc_upper_bound, /* _get_reloc_upper_bound */
2240 coff_canonicalize_reloc, /* _cononicalize_reloc */
2241 xcoff64_reloc_type_lookup, /* _bfd_reloc_type_lookup */
2243 /* Write */
2244 coff_set_arch_mach, /* _set_arch_mach */
2245 coff_set_section_contents, /* _set_section_contents */
2247 /* Link */
2248 xcoff64_sizeof_headers, /* _sizeof_headers */
2249 /* _bfd_get_relocated_section_contents */
2250 bfd_generic_get_relocated_section_contents,
2251 bfd_generic_relax_section, /* _bfd_relax_section */
2252 _bfd_xcoff_bfd_link_hash_table_create, /* _bfd_link_hash_table_create */
2253 _bfd_xcoff_bfd_link_add_symbols, /* _bfd_link_add_symbols */
2254 _bfd_xcoff_bfd_final_link, /* _bfd_filnal_link */
2255 _bfd_generic_link_split_section, /* _bfd_link_split_section */
2256 bfd_generic_gc_sections, /* _bfd_gc_sections */
2257 bfd_generic_merge_sections, /* _bfd_merge_sections */
2259 /* Dynamic */
2260 /* _get_dynamic_symtab_upper_bound */
2261 _bfd_xcoff_get_dynamic_symtab_upper_bound,
2262 _bfd_xcoff_canonicalize_dynamic_symtab, /* _cononicalize_dynamic_symtab */
2263 _bfd_xcoff_get_dynamic_reloc_upper_bound,/* _get_dynamic_reloc_upper_bound */
2264 _bfd_xcoff_canonicalize_dynamic_reloc, /* _cononicalize_dynamic_reloc */
2266 /* Opposite endian version, none exists */
2267 NULL,
2269 /* back end data */
2270 (void *) &bfd_xcoff_backend_data,