1 /* BFD back-end for Intel 960 COFF files.
2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #define BADMAG(x) I960BADMAG(x)
28 #include "coff/i960.h"
29 #include "coff/internal.h"
30 #include "libcoff.h" /* to allow easier abstraction-breaking */
32 static bfd_reloc_status_type optcall_callback
33 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
35 #define COFF_LONG_FILENAMES
37 #define CALLS 0x66003800 /* Template for 'calls' instruction */
38 #define BAL 0x0b000000 /* Template for 'bal' instruction */
39 #define BAL_MASK 0x00ffffff
41 static bfd_reloc_status_type
42 optcall_callback (abfd, reloc_entry, symbol_in, data,
43 ignore_input_section, ignore_bfd, error_message)
48 asection *ignore_input_section;
52 /* This item has already been relocated correctly, but we may be
53 * able to patch in yet better code - done by digging out the
54 * correct info on this symbol */
55 bfd_reloc_status_type result;
56 coff_symbol_type *cs = coffsymbol(symbol_in);
58 /* So the target symbol has to be of coff type, and the symbol
59 has to have the correct native information within it */
60 if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour)
61 || (cs->native == (combined_entry_type *)NULL))
63 /* This is interesting, consider the case where we're outputting coff
64 from a mix n match input, linking from coff to a symbol defined in a
65 bout file will cause this match to be true. Should I complain? This
66 will only work if the bout symbol is non leaf. */
68 (char *) "uncertain calling convention for non-COFF symbol";
69 result = bfd_reloc_dangerous;
73 switch (cs->native->u.syment.n_sclass)
77 /* This is a call to a leaf procedure, replace instruction with a bal
78 to the correct location. */
80 union internal_auxent *aux = &((cs->native+2)->u.auxent);
81 int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
82 int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
83 BFD_ASSERT(cs->native->u.syment.n_numaux==2);
85 /* We replace the original call instruction with a bal to
86 the bal entry point - the offset of which is described in
87 the 2nd auxent of the original symbol. We keep the native
88 sym and auxents untouched, so the delta between the two
89 is the offset of the bal entry point. */
90 word = ((word + olf) & BAL_MASK) | BAL;
91 bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address);
93 result = bfd_reloc_ok;
96 /* This is a call to a system call, replace with a calls to # */
98 result = bfd_reloc_ok;
101 result = bfd_reloc_ok;
108 static reloc_howto_type howto_rellong =
109 { (unsigned int) R_RELLONG, 0, 2, 32,false, 0,
110 complain_overflow_bitfield, 0,"rellong", true, 0xffffffff,
112 static reloc_howto_type howto_iprmed =
113 { R_IPRMED, 0, 2, 24,true,0, complain_overflow_signed,0,
114 "iprmed ", true, 0x00ffffff, 0x00ffffff};
115 static reloc_howto_type howto_optcall =
116 { R_OPTCALL, 0,2,24,true,0, complain_overflow_signed,
117 optcall_callback, "optcall", true, 0x00ffffff, 0x00ffffff};
119 static const reloc_howto_type *
120 coff_i960_reloc_type_lookup (abfd, code)
122 bfd_reloc_code_real_type code;
128 case BFD_RELOC_I960_CALLJ:
129 return &howto_optcall;
131 return &howto_rellong;
132 case BFD_RELOC_24_PCREL:
133 return &howto_iprmed;
137 /* The real code is in coffcode.h */
139 #define RTYPE2HOWTO(cache_ptr, dst) \
141 reloc_howto_type *howto_ptr; \
142 switch ((dst)->r_type) { \
143 case 17: howto_ptr = &howto_rellong; break; \
144 case 25: howto_ptr = &howto_iprmed; break; \
145 case 27: howto_ptr = &howto_optcall; break; \
146 default: howto_ptr = 0; break; \
148 cache_ptr->howto = howto_ptr; \
151 #include "coffcode.h"
153 #undef coff_bfd_reloc_type_lookup
154 #define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup
156 bfd_target icoff_little_vec =
158 "coff-Intel-little", /* name */
159 bfd_target_coff_flavour,
160 false, /* data byte order is little */
161 false, /* header byte order is little */
163 (HAS_RELOC | EXEC_P | /* object flags */
164 HAS_LINENO | HAS_DEBUG |
165 HAS_SYMS | HAS_LOCALS | WP_TEXT),
167 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
168 0, /* leading underscore */
169 '/', /* ar_pad_char */
170 15, /* ar_max_namelen */
172 3, /* minimum alignment power */
173 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
174 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
175 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
176 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
177 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
178 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
180 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
181 bfd_generic_archive_p, _bfd_dummy_target},
182 {bfd_false, coff_mkobject, /* bfd_set_format */
183 _bfd_generic_mkarchive, bfd_false},
184 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
185 _bfd_write_archive_contents, bfd_false},
187 BFD_JUMP_TABLE_GENERIC (coff),
188 BFD_JUMP_TABLE_COPY (coff),
189 BFD_JUMP_TABLE_CORE (_bfd_nocore),
190 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
191 BFD_JUMP_TABLE_SYMBOLS (coff),
192 BFD_JUMP_TABLE_RELOCS (coff),
193 BFD_JUMP_TABLE_WRITE (coff),
194 BFD_JUMP_TABLE_LINK (coff),
200 bfd_target icoff_big_vec =
202 "coff-Intel-big", /* name */
203 bfd_target_coff_flavour,
204 false, /* data byte order is little */
205 true, /* header byte order is big */
207 (HAS_RELOC | EXEC_P | /* object flags */
208 HAS_LINENO | HAS_DEBUG |
209 HAS_SYMS | HAS_LOCALS | WP_TEXT),
211 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
212 0, /* leading underscore */
213 '/', /* ar_pad_char */
214 15, /* ar_max_namelen */
216 3, /* minimum alignment power */
217 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
218 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
219 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
220 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
221 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
222 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
224 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
225 bfd_generic_archive_p, _bfd_dummy_target},
226 {bfd_false, coff_mkobject, /* bfd_set_format */
227 _bfd_generic_mkarchive, bfd_false},
228 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
229 _bfd_write_archive_contents, bfd_false},
231 BFD_JUMP_TABLE_GENERIC (coff),
232 BFD_JUMP_TABLE_COPY (coff),
233 BFD_JUMP_TABLE_CORE (_bfd_nocore),
234 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
235 BFD_JUMP_TABLE_SYMBOLS (coff),
236 BFD_JUMP_TABLE_RELOCS (coff),
237 BFD_JUMP_TABLE_WRITE (coff),
238 BFD_JUMP_TABLE_LINK (coff),