* coff-i960.c (coff_i960_relocate): New function.
[deliverable/binutils-gdb.git] / bfd / coff-i960.c
1 /* BFD back-end for Intel 960 COFF files.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
3 Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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. */
20
21 #define I960 1
22 #define BADMAG(x) I960BADMAG(x)
23
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "libbfd.h"
27 #include "obstack.h"
28 #include "coff/i960.h"
29 #include "coff/internal.h"
30 #include "libcoff.h" /* to allow easier abstraction-breaking */
31
32 static bfd_reloc_status_type optcall_callback
33 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
34 static bfd_reloc_status_type coff_i960_relocate
35 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
36
37 #define COFF_LONG_FILENAMES
38
39 #define CALLS 0x66003800 /* Template for 'calls' instruction */
40 #define BAL 0x0b000000 /* Template for 'bal' instruction */
41 #define BAL_MASK 0x00ffffff
42
43 static bfd_reloc_status_type
44 optcall_callback (abfd, reloc_entry, symbol_in, data,
45 ignore_input_section, ignore_bfd, error_message)
46 bfd *abfd;
47 arelent *reloc_entry;
48 asymbol *symbol_in;
49 PTR data;
50 asection *ignore_input_section;
51 bfd *ignore_bfd;
52 char **error_message;
53 {
54 /* This item has already been relocated correctly, but we may be
55 * able to patch in yet better code - done by digging out the
56 * correct info on this symbol */
57 bfd_reloc_status_type result;
58 coff_symbol_type *cs = coffsymbol(symbol_in);
59
60 /* So the target symbol has to be of coff type, and the symbol
61 has to have the correct native information within it */
62 if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour)
63 || (cs->native == (combined_entry_type *)NULL))
64 {
65 /* This is interesting, consider the case where we're outputting coff
66 from a mix n match input, linking from coff to a symbol defined in a
67 bout file will cause this match to be true. Should I complain? This
68 will only work if the bout symbol is non leaf. */
69 *error_message =
70 (char *) "uncertain calling convention for non-COFF symbol";
71 result = bfd_reloc_dangerous;
72 }
73 else
74 {
75 switch (cs->native->u.syment.n_sclass)
76 {
77 case C_LEAFSTAT:
78 case C_LEAFEXT:
79 /* This is a call to a leaf procedure, replace instruction with a bal
80 to the correct location. */
81 {
82 union internal_auxent *aux = &((cs->native+2)->u.auxent);
83 int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
84 int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
85 BFD_ASSERT(cs->native->u.syment.n_numaux==2);
86
87 /* We replace the original call instruction with a bal to
88 the bal entry point - the offset of which is described in
89 the 2nd auxent of the original symbol. We keep the native
90 sym and auxents untouched, so the delta between the two
91 is the offset of the bal entry point. */
92 word = ((word + olf) & BAL_MASK) | BAL;
93 bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address);
94 }
95 result = bfd_reloc_ok;
96 break;
97 case C_SCALL:
98 /* This is a call to a system call, replace with a calls to # */
99 BFD_ASSERT(0);
100 result = bfd_reloc_ok;
101 break;
102 default:
103 result = bfd_reloc_ok;
104 break;
105 }
106 }
107 return result;
108 }
109
110 /* When generating relocateable output, we don't want to do anything
111 for a reloc against a globally visible symbol. */
112
113 static bfd_reloc_status_type
114 coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section,
115 output_bfd, error_message)
116 bfd *abfd;
117 arelent *reloc_entry;
118 asymbol *symbol;
119 PTR data;
120 asection *input_section;
121 bfd *output_bfd;
122 char **error_message;
123 {
124 if (output_bfd != (bfd *) NULL
125 && (symbol->flags & BSF_SECTION_SYM) == 0
126 && reloc_entry->addend == 0)
127 {
128 reloc_entry->address += input_section->output_offset;
129 return bfd_reloc_ok;
130 }
131
132 return bfd_reloc_continue;
133 }
134
135 static reloc_howto_type howto_rellong =
136 HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,false, 0,
137 complain_overflow_bitfield, coff_i960_relocate,"rellong", true,
138 0xffffffff, 0xffffffff, 0);
139 static reloc_howto_type howto_iprmed =
140 HOWTO (R_IPRMED, 0, 2, 24,true,0, complain_overflow_signed,
141 coff_i960_relocate, "iprmed ", true, 0x00ffffff, 0x00ffffff, 0);
142 static reloc_howto_type howto_optcall =
143 HOWTO (R_OPTCALL, 0,2,24,true,0, complain_overflow_signed,
144 optcall_callback, "optcall", true, 0x00ffffff, 0x00ffffff, 0);
145
146 static const reloc_howto_type *
147 coff_i960_reloc_type_lookup (abfd, code)
148 bfd *abfd;
149 bfd_reloc_code_real_type code;
150 {
151 switch (code)
152 {
153 default:
154 return 0;
155 case BFD_RELOC_I960_CALLJ:
156 return &howto_optcall;
157 case BFD_RELOC_32:
158 case BFD_RELOC_CTOR:
159 return &howto_rellong;
160 case BFD_RELOC_24_PCREL:
161 return &howto_iprmed;
162 }
163 }
164
165 /* The real code is in coffcode.h */
166
167 #define RTYPE2HOWTO(cache_ptr, dst) \
168 { \
169 reloc_howto_type *howto_ptr; \
170 switch ((dst)->r_type) { \
171 case 17: howto_ptr = &howto_rellong; break; \
172 case 25: howto_ptr = &howto_iprmed; break; \
173 case 27: howto_ptr = &howto_optcall; break; \
174 default: howto_ptr = 0; break; \
175 } \
176 cache_ptr->howto = howto_ptr; \
177 }
178
179 #include "coffcode.h"
180
181 #undef coff_bfd_reloc_type_lookup
182 #define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup
183
184 const bfd_target icoff_little_vec =
185 {
186 "coff-Intel-little", /* name */
187 bfd_target_coff_flavour,
188 false, /* data byte order is little */
189 false, /* header byte order is little */
190
191 (HAS_RELOC | EXEC_P | /* object flags */
192 HAS_LINENO | HAS_DEBUG |
193 HAS_SYMS | HAS_LOCALS | WP_TEXT),
194
195 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
196 '_', /* leading underscore */
197 '/', /* ar_pad_char */
198 15, /* ar_max_namelen */
199
200 3, /* minimum alignment power */
201 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
202 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
203 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
204 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
205 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
206 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
207
208 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
209 bfd_generic_archive_p, _bfd_dummy_target},
210 {bfd_false, coff_mkobject, /* bfd_set_format */
211 _bfd_generic_mkarchive, bfd_false},
212 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
213 _bfd_write_archive_contents, bfd_false},
214
215 BFD_JUMP_TABLE_GENERIC (coff),
216 BFD_JUMP_TABLE_COPY (coff),
217 BFD_JUMP_TABLE_CORE (_bfd_nocore),
218 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
219 BFD_JUMP_TABLE_SYMBOLS (coff),
220 BFD_JUMP_TABLE_RELOCS (coff),
221 BFD_JUMP_TABLE_WRITE (coff),
222 BFD_JUMP_TABLE_LINK (coff),
223 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
224
225 COFF_SWAP_TABLE,
226 };
227
228
229 const bfd_target icoff_big_vec =
230 {
231 "coff-Intel-big", /* name */
232 bfd_target_coff_flavour,
233 false, /* data byte order is little */
234 true, /* header byte order is big */
235
236 (HAS_RELOC | EXEC_P | /* object flags */
237 HAS_LINENO | HAS_DEBUG |
238 HAS_SYMS | HAS_LOCALS | WP_TEXT),
239
240 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
241 '_', /* leading underscore */
242 '/', /* ar_pad_char */
243 15, /* ar_max_namelen */
244
245 3, /* minimum alignment power */
246 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
247 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
248 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
249 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
250 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
251 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
252
253 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
254 bfd_generic_archive_p, _bfd_dummy_target},
255 {bfd_false, coff_mkobject, /* bfd_set_format */
256 _bfd_generic_mkarchive, bfd_false},
257 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
258 _bfd_write_archive_contents, bfd_false},
259
260 BFD_JUMP_TABLE_GENERIC (coff),
261 BFD_JUMP_TABLE_COPY (coff),
262 BFD_JUMP_TABLE_CORE (_bfd_nocore),
263 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
264 BFD_JUMP_TABLE_SYMBOLS (coff),
265 BFD_JUMP_TABLE_RELOCS (coff),
266 BFD_JUMP_TABLE_WRITE (coff),
267 BFD_JUMP_TABLE_LINK (coff),
268 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
269
270 COFF_SWAP_TABLE,
271 };
This page took 0.035972 seconds and 5 git commands to generate.