1 |
/* BFD back-end for Intel 860 COFF files. |
/* BFD back-end for Intel i860 COFF files. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002, |
3 |
Free Software Foundation, Inc. |
2003, 2004, 2005 Free Software Foundation, Inc. |
4 |
Created mostly by substituting "860" for "386" in coff-i386.c |
Created mostly by substituting "860" for "386" in coff-i386.c |
5 |
Harry Dolan <dolan@ssd.intel.com>, October 1995 |
Harry Dolan <dolan@ssd.intel.com>, October 1995 |
6 |
|
|
30 |
|
|
31 |
#include "libcoff.h" |
#include "libcoff.h" |
32 |
|
|
|
static bfd_reloc_status_type coff_i860_reloc |
|
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
|
|
static reloc_howto_type *coff_i860_rtype_to_howto |
|
|
PARAMS ((bfd *, asection *, struct internal_reloc *, |
|
|
struct coff_link_hash_entry *, struct internal_syment *, |
|
|
bfd_vma *)); |
|
|
static const bfd_target * i3coff_object_p PARAMS ((bfd *)); |
|
33 |
|
|
34 |
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) |
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) |
35 |
/* The page size is a guess based on ELF. */ |
/* The page size is a guess based on ELF. */ |
40 |
section for a reference to a common symbol is the value itself plus |
section for a reference to a common symbol is the value itself plus |
41 |
any desired offset. Ian Taylor, Cygnus Support. */ |
any desired offset. Ian Taylor, Cygnus Support. */ |
42 |
|
|
43 |
/* If we are producing relocateable output, we need to do some |
/* If we are producing relocatable output, we need to do some |
44 |
adjustments to the object file that are not done by the |
adjustments to the object file that are not done by the |
45 |
bfd_perform_relocation function. This function is called by every |
bfd_perform_relocation function. This function is called by every |
46 |
reloc type to make any required adjustments. */ |
reloc type to make any required adjustments. */ |
47 |
|
|
48 |
static bfd_reloc_status_type |
static bfd_reloc_status_type |
49 |
coff_i860_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, |
coff_i860_reloc (bfd *abfd, |
50 |
error_message) |
arelent *reloc_entry, |
51 |
bfd *abfd; |
asymbol *symbol, |
52 |
arelent *reloc_entry; |
void *data, |
53 |
asymbol *symbol; |
asection *input_section ATTRIBUTE_UNUSED, |
54 |
PTR data; |
bfd *output_bfd, |
55 |
asection *input_section ATTRIBUTE_UNUSED; |
char **error_message ATTRIBUTE_UNUSED) |
|
bfd *output_bfd; |
|
|
char **error_message ATTRIBUTE_UNUSED; |
|
56 |
{ |
{ |
57 |
symvalue diff; |
symvalue diff; |
58 |
|
|
78 |
{ |
{ |
79 |
/* For some reason bfd_perform_relocation always effectively |
/* For some reason bfd_perform_relocation always effectively |
80 |
ignores the addend for a COFF target when producing |
ignores the addend for a COFF target when producing |
81 |
relocateable output. This seems to be always wrong for 860 |
relocatable output. This seems to be always wrong for 860 |
82 |
COFF, so we handle the addend here instead. */ |
COFF, so we handle the addend here instead. */ |
83 |
diff = reloc_entry->addend; |
diff = reloc_entry->addend; |
84 |
} |
} |
126 |
return bfd_reloc_continue; |
return bfd_reloc_continue; |
127 |
} |
} |
128 |
|
|
129 |
|
/* This is just a temporary measure until we teach bfd to generate |
130 |
|
these relocations. */ |
131 |
|
|
132 |
|
static bfd_reloc_status_type |
133 |
|
coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED, |
134 |
|
arelent *reloc_entry, |
135 |
|
asymbol *symbol ATTRIBUTE_UNUSED, |
136 |
|
void *data ATTRIBUTE_UNUSED, |
137 |
|
asection *input_section ATTRIBUTE_UNUSED, |
138 |
|
bfd *output_bfd ATTRIBUTE_UNUSED, |
139 |
|
char **error_message ATTRIBUTE_UNUSED) |
140 |
|
{ |
141 |
|
reloc_howto_type *howto = reloc_entry->howto; |
142 |
|
fprintf (stderr, _("Relocation `%s' not yet implemented\n"), howto->name); |
143 |
|
return bfd_reloc_notsupported; |
144 |
|
} |
145 |
|
|
146 |
#ifndef PCRELOFFSET |
#ifndef PCRELOFFSET |
147 |
#define PCRELOFFSET false |
#define PCRELOFFSET FALSE |
148 |
#endif |
#endif |
149 |
|
|
150 |
static reloc_howto_type howto_table[] = |
static reloc_howto_type howto_table[] = |
159 |
0, /* rightshift */ |
0, /* rightshift */ |
160 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
161 |
32, /* bitsize */ |
32, /* bitsize */ |
162 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
163 |
0, /* bitpos */ |
0, /* bitpos */ |
164 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
165 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
166 |
"dir32", /* name */ |
"dir32", /* name */ |
167 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
168 |
0xffffffff, /* src_mask */ |
0xffffffff, /* src_mask */ |
169 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
170 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
171 |
/* {7}, */ |
/* {7}, */ |
172 |
HOWTO (R_IMAGEBASE, /* type */ |
HOWTO (R_IMAGEBASE, /* type */ |
173 |
0, /* rightshift */ |
0, /* rightshift */ |
174 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
175 |
32, /* bitsize */ |
32, /* bitsize */ |
176 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
177 |
0, /* bitpos */ |
0, /* bitpos */ |
178 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
179 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
180 |
"rva32", /* name */ |
"rva32", /* name */ |
181 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
182 |
0xffffffff, /* src_mask */ |
0xffffffff, /* src_mask */ |
183 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
184 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
185 |
EMPTY_HOWTO (010), |
EMPTY_HOWTO (010), |
186 |
EMPTY_HOWTO (011), |
EMPTY_HOWTO (011), |
187 |
EMPTY_HOWTO (012), |
EMPTY_HOWTO (012), |
193 |
0, /* rightshift */ |
0, /* rightshift */ |
194 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
195 |
8, /* bitsize */ |
8, /* bitsize */ |
196 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
197 |
0, /* bitpos */ |
0, /* bitpos */ |
198 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
199 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
200 |
"8", /* name */ |
"8", /* name */ |
201 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
202 |
0x000000ff, /* src_mask */ |
0x000000ff, /* src_mask */ |
203 |
0x000000ff, /* dst_mask */ |
0x000000ff, /* dst_mask */ |
204 |
PCRELOFFSET), /* pcrel_offset */ |
PCRELOFFSET), /* pcrel_offset */ |
206 |
0, /* rightshift */ |
0, /* rightshift */ |
207 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
208 |
16, /* bitsize */ |
16, /* bitsize */ |
209 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
210 |
0, /* bitpos */ |
0, /* bitpos */ |
211 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
212 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
213 |
"16", /* name */ |
"16", /* name */ |
214 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
215 |
0x0000ffff, /* src_mask */ |
0x0000ffff, /* src_mask */ |
216 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
217 |
PCRELOFFSET), /* pcrel_offset */ |
PCRELOFFSET), /* pcrel_offset */ |
219 |
0, /* rightshift */ |
0, /* rightshift */ |
220 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
221 |
32, /* bitsize */ |
32, /* bitsize */ |
222 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
223 |
0, /* bitpos */ |
0, /* bitpos */ |
224 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
225 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
226 |
"32", /* name */ |
"32", /* name */ |
227 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
228 |
0xffffffff, /* src_mask */ |
0xffffffff, /* src_mask */ |
229 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
230 |
PCRELOFFSET), /* pcrel_offset */ |
PCRELOFFSET), /* pcrel_offset */ |
232 |
0, /* rightshift */ |
0, /* rightshift */ |
233 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
234 |
8, /* bitsize */ |
8, /* bitsize */ |
235 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
236 |
0, /* bitpos */ |
0, /* bitpos */ |
237 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
238 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
239 |
"DISP8", /* name */ |
"DISP8", /* name */ |
240 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
241 |
0x000000ff, /* src_mask */ |
0x000000ff, /* src_mask */ |
242 |
0x000000ff, /* dst_mask */ |
0x000000ff, /* dst_mask */ |
243 |
PCRELOFFSET), /* pcrel_offset */ |
PCRELOFFSET), /* pcrel_offset */ |
245 |
0, /* rightshift */ |
0, /* rightshift */ |
246 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
247 |
16, /* bitsize */ |
16, /* bitsize */ |
248 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
249 |
0, /* bitpos */ |
0, /* bitpos */ |
250 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
251 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
252 |
"DISP16", /* name */ |
"DISP16", /* name */ |
253 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
254 |
0x0000ffff, /* src_mask */ |
0x0000ffff, /* src_mask */ |
255 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
256 |
PCRELOFFSET), /* pcrel_offset */ |
PCRELOFFSET), /* pcrel_offset */ |
258 |
0, /* rightshift */ |
0, /* rightshift */ |
259 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
260 |
32, /* bitsize */ |
32, /* bitsize */ |
261 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
262 |
0, /* bitpos */ |
0, /* bitpos */ |
263 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
264 |
coff_i860_reloc, /* special_function */ |
coff_i860_reloc, /* special_function */ |
265 |
"DISP32", /* name */ |
"DISP32", /* name */ |
266 |
true, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
267 |
0xffffffff, /* src_mask */ |
0xffffffff, /* src_mask */ |
268 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
269 |
PCRELOFFSET) /* pcrel_offset */ |
PCRELOFFSET), /* pcrel_offset */ |
270 |
|
EMPTY_HOWTO (0x15), |
271 |
|
EMPTY_HOWTO (0x16), |
272 |
|
EMPTY_HOWTO (0x17), |
273 |
|
EMPTY_HOWTO (0x18), |
274 |
|
EMPTY_HOWTO (0x19), |
275 |
|
EMPTY_HOWTO (0x1a), |
276 |
|
EMPTY_HOWTO (0x1b), |
277 |
|
HOWTO (COFF860_R_PAIR, /* type */ |
278 |
|
0, /* rightshift */ |
279 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
280 |
|
16, /* bitsize */ |
281 |
|
FALSE, /* pc_relative */ |
282 |
|
0, /* bitpos */ |
283 |
|
complain_overflow_dont, /* complain_on_overflow */ |
284 |
|
coff_i860_reloc_nyi, /* special_function */ |
285 |
|
"PAIR", /* name */ |
286 |
|
FALSE, /* partial_inplace */ |
287 |
|
0xffff, /* src_mask */ |
288 |
|
0xffff, /* dst_mask */ |
289 |
|
FALSE), /* pcrel_offset */ |
290 |
|
EMPTY_HOWTO (0x1d), |
291 |
|
HOWTO (COFF860_R_HIGH, /* type */ |
292 |
|
16, /* rightshift */ |
293 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
294 |
|
16, /* bitsize */ |
295 |
|
FALSE, /* pc_relative */ |
296 |
|
0, /* bitpos */ |
297 |
|
complain_overflow_dont, /* complain_on_overflow */ |
298 |
|
coff_i860_reloc, /* special_function */ |
299 |
|
"HIGH", /* name */ |
300 |
|
FALSE, /* partial_inplace */ |
301 |
|
0xffff, /* src_mask */ |
302 |
|
0xffff, /* dst_mask */ |
303 |
|
FALSE), /* pcrel_offset */ |
304 |
|
HOWTO (COFF860_R_LOW0, /* type */ |
305 |
|
0, /* rightshift */ |
306 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
307 |
|
16, /* bitsize */ |
308 |
|
FALSE, /* pc_relative */ |
309 |
|
0, /* bitpos */ |
310 |
|
complain_overflow_dont, /* complain_on_overflow */ |
311 |
|
coff_i860_reloc, /* special_function */ |
312 |
|
"LOW0", /* name */ |
313 |
|
FALSE, /* partial_inplace */ |
314 |
|
0xffff, /* src_mask */ |
315 |
|
0xffff, /* dst_mask */ |
316 |
|
FALSE), /* pcrel_offset */ |
317 |
|
HOWTO (COFF860_R_LOW1, /* type */ |
318 |
|
0, /* rightshift */ |
319 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
320 |
|
16, /* bitsize */ |
321 |
|
FALSE, /* pc_relative */ |
322 |
|
0, /* bitpos */ |
323 |
|
complain_overflow_dont, /* complain_on_overflow */ |
324 |
|
coff_i860_reloc, /* special_function */ |
325 |
|
"LOW1", /* name */ |
326 |
|
FALSE, /* partial_inplace */ |
327 |
|
0xfffe, /* src_mask */ |
328 |
|
0xfffe, /* dst_mask */ |
329 |
|
FALSE), /* pcrel_offset */ |
330 |
|
HOWTO (COFF860_R_LOW2, /* type */ |
331 |
|
0, /* rightshift */ |
332 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
333 |
|
16, /* bitsize */ |
334 |
|
FALSE, /* pc_relative */ |
335 |
|
0, /* bitpos */ |
336 |
|
complain_overflow_dont, /* complain_on_overflow */ |
337 |
|
coff_i860_reloc, /* special_function */ |
338 |
|
"LOW2", /* name */ |
339 |
|
FALSE, /* partial_inplace */ |
340 |
|
0xfffc, /* src_mask */ |
341 |
|
0xfffc, /* dst_mask */ |
342 |
|
FALSE), /* pcrel_offset */ |
343 |
|
HOWTO (COFF860_R_LOW3, /* type */ |
344 |
|
0, /* rightshift */ |
345 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
346 |
|
16, /* bitsize */ |
347 |
|
FALSE, /* pc_relative */ |
348 |
|
0, /* bitpos */ |
349 |
|
complain_overflow_dont, /* complain_on_overflow */ |
350 |
|
coff_i860_reloc, /* special_function */ |
351 |
|
"LOW3", /* name */ |
352 |
|
FALSE, /* partial_inplace */ |
353 |
|
0xfff8, /* src_mask */ |
354 |
|
0xfff8, /* dst_mask */ |
355 |
|
FALSE), /* pcrel_offset */ |
356 |
|
HOWTO (COFF860_R_LOW4, /* type */ |
357 |
|
0, /* rightshift */ |
358 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
359 |
|
16, /* bitsize */ |
360 |
|
FALSE, /* pc_relative */ |
361 |
|
0, /* bitpos */ |
362 |
|
complain_overflow_dont, /* complain_on_overflow */ |
363 |
|
coff_i860_reloc, /* special_function */ |
364 |
|
"LOW4", /* name */ |
365 |
|
FALSE, /* partial_inplace */ |
366 |
|
0xfff0, /* src_mask */ |
367 |
|
0xfff0, /* dst_mask */ |
368 |
|
FALSE), /* pcrel_offset */ |
369 |
|
HOWTO (COFF860_R_SPLIT0, /* type */ |
370 |
|
0, /* rightshift */ |
371 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
372 |
|
16, /* bitsize */ |
373 |
|
FALSE, /* pc_relative */ |
374 |
|
0, /* bitpos */ |
375 |
|
complain_overflow_dont, /* complain_on_overflow */ |
376 |
|
coff_i860_reloc_nyi, /* special_function */ |
377 |
|
"SPLIT0", /* name */ |
378 |
|
FALSE, /* partial_inplace */ |
379 |
|
0x1f07ff, /* src_mask */ |
380 |
|
0x1f07ff, /* dst_mask */ |
381 |
|
FALSE), /* pcrel_offset */ |
382 |
|
HOWTO (COFF860_R_SPLIT1, /* type */ |
383 |
|
0, /* rightshift */ |
384 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
385 |
|
16, /* bitsize */ |
386 |
|
FALSE, /* pc_relative */ |
387 |
|
0, /* bitpos */ |
388 |
|
complain_overflow_dont, /* complain_on_overflow */ |
389 |
|
coff_i860_reloc_nyi, /* special_function */ |
390 |
|
"SPLIT1", /* name */ |
391 |
|
FALSE, /* partial_inplace */ |
392 |
|
0x1f07fe, /* src_mask */ |
393 |
|
0x1f07fe, /* dst_mask */ |
394 |
|
FALSE), /* pcrel_offset */ |
395 |
|
HOWTO (COFF860_R_SPLIT2, /* type */ |
396 |
|
0, /* rightshift */ |
397 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
398 |
|
16, /* bitsize */ |
399 |
|
FALSE, /* pc_relative */ |
400 |
|
0, /* bitpos */ |
401 |
|
complain_overflow_dont, /* complain_on_overflow */ |
402 |
|
coff_i860_reloc_nyi, /* special_function */ |
403 |
|
"SPLIT2", /* name */ |
404 |
|
FALSE, /* partial_inplace */ |
405 |
|
0x1f07fc, /* src_mask */ |
406 |
|
0x1f07fc, /* dst_mask */ |
407 |
|
FALSE), /* pcrel_offset */ |
408 |
|
HOWTO (COFF860_R_HIGHADJ, /* type */ |
409 |
|
0, /* rightshift */ |
410 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
411 |
|
16, /* bitsize */ |
412 |
|
FALSE, /* pc_relative */ |
413 |
|
0, /* bitpos */ |
414 |
|
complain_overflow_dont, /* complain_on_overflow */ |
415 |
|
coff_i860_reloc_nyi, /* special_function */ |
416 |
|
"HIGHADJ", /* name */ |
417 |
|
FALSE, /* partial_inplace */ |
418 |
|
0xffff, /* src_mask */ |
419 |
|
0xffff, /* dst_mask */ |
420 |
|
FALSE), /* pcrel_offset */ |
421 |
|
HOWTO (COFF860_R_BRADDR, /* type */ |
422 |
|
2, /* rightshift */ |
423 |
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
424 |
|
26, /* bitsize */ |
425 |
|
TRUE, /* pc_relative */ |
426 |
|
0, /* bitpos */ |
427 |
|
complain_overflow_bitfield, /* complain_on_overflow */ |
428 |
|
coff_i860_reloc_nyi, /* special_function */ |
429 |
|
"BRADDR", /* name */ |
430 |
|
FALSE, /* partial_inplace */ |
431 |
|
0x3ffffff, /* src_mask */ |
432 |
|
0x3ffffff, /* dst_mask */ |
433 |
|
TRUE) /* pcrel_offset */ |
434 |
}; |
}; |
435 |
|
|
436 |
/* Turn a howto into a reloc nunmber */ |
/* Turn a howto into a reloc number. */ |
437 |
|
|
438 |
#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } |
#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } |
439 |
#define BADMAG(x) I860BADMAG(x) |
#define BADMAG(x) I860BADMAG(x) |
440 |
#define I860 1 /* Customize coffcode.h */ |
#define I860 1 /* Customize coffcode.h */ |
441 |
|
|
442 |
#define RTYPE2HOWTO(cache_ptr, dst) \ |
#define RTYPE2HOWTO(cache_ptr, dst) \ |
443 |
(cache_ptr)->howto = howto_table + (dst)->r_type; |
((cache_ptr)->howto = \ |
444 |
|
((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \ |
445 |
|
? howto_table + (dst)->r_type \ |
446 |
|
: NULL)) |
447 |
|
|
448 |
/* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared |
/* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared |
449 |
library. On some other COFF targets STYP_BSS is normally |
library. On some other COFF targets STYP_BSS is normally |
463 |
FIXME: This macro refers to symbols and asect; these are from the |
FIXME: This macro refers to symbols and asect; these are from the |
464 |
calling function, not the macro arguments. */ |
calling function, not the macro arguments. */ |
465 |
|
|
466 |
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ |
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) |
|
{ \ |
|
|
coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ |
|
|
if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ |
|
|
coffsym = (obj_symbols (abfd) \ |
|
|
+ (cache_ptr->sym_ptr_ptr - symbols)); \ |
|
|
else if (ptr) \ |
|
|
coffsym = coff_symbol_from (abfd, ptr); \ |
|
|
if (coffsym != (coff_symbol_type *) NULL \ |
|
|
&& coffsym->native->u.syment.n_scnum == 0) \ |
|
|
cache_ptr->addend = - coffsym->native->u.syment.n_value; \ |
|
|
else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ |
|
|
&& ptr->section != (asection *) NULL) \ |
|
|
cache_ptr->addend = - (ptr->section->vma + ptr->value); \ |
|
|
else \ |
|
|
cache_ptr->addend = 0; \ |
|
|
if (ptr && howto_table[reloc.r_type].pc_relative) \ |
|
|
cache_ptr->addend += asect->vma; \ |
|
|
} |
|
467 |
|
|
468 |
/* We use the special COFF backend linker. */ |
/* We use the special COFF backend linker. */ |
469 |
#define coff_relocate_section _bfd_coff_generic_relocate_section |
#define coff_relocate_section _bfd_coff_generic_relocate_section |
470 |
|
|
471 |
static reloc_howto_type * |
static reloc_howto_type * |
472 |
coff_i860_rtype_to_howto (abfd, sec, rel, h, sym, addendp) |
coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, |
473 |
bfd *abfd ATTRIBUTE_UNUSED; |
asection *sec, |
474 |
asection *sec; |
struct internal_reloc *rel, |
475 |
struct internal_reloc *rel; |
struct coff_link_hash_entry *h, |
476 |
struct coff_link_hash_entry *h; |
struct internal_syment *sym, |
477 |
struct internal_syment *sym; |
bfd_vma *addendp) |
|
bfd_vma *addendp; |
|
478 |
{ |
{ |
479 |
|
|
480 |
reloc_howto_type *howto; |
reloc_howto_type *howto; |
481 |
|
|
482 |
|
if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0])) |
483 |
|
{ |
484 |
|
bfd_set_error (bfd_error_bad_value); |
485 |
|
return NULL; |
486 |
|
} |
487 |
|
|
488 |
howto = howto_table + rel->r_type; |
howto = howto_table + rel->r_type; |
489 |
|
|
490 |
if (howto->pc_relative) |
if (howto->pc_relative) |
501 |
BFD_ASSERT (h != NULL); |
BFD_ASSERT (h != NULL); |
502 |
|
|
503 |
/* I think we *do* want to bypass this. If we don't, I have seen some data |
/* I think we *do* want to bypass this. If we don't, I have seen some data |
504 |
parameters get the wrong relcation address. If I link two versions |
parameters get the wrong relocation address. If I link two versions |
505 |
with and without this section bypassed and then do a binary comparison, |
with and without this section bypassed and then do a binary comparison, |
506 |
the addresses which are different can be looked up in the map. The |
the addresses which are different can be looked up in the map. The |
507 |
case in which this section has been bypassed has addresses which correspond |
case in which this section has been bypassed has addresses which correspond |
510 |
} |
} |
511 |
|
|
512 |
/* If the output symbol is common (in which case this must be a |
/* If the output symbol is common (in which case this must be a |
513 |
relocateable link), we need to add in the final size of the |
relocatable link), we need to add in the final size of the |
514 |
common symbol. */ |
common symbol. */ |
515 |
if (h != NULL && h->root.type == bfd_link_hash_common) |
if (h != NULL && h->root.type == bfd_link_hash_common) |
516 |
*addendp += h->root.u.c.size; |
*addendp += h->root.u.c.size; |
518 |
return howto; |
return howto; |
519 |
} |
} |
520 |
|
|
521 |
#define coff_rtype_to_howto coff_i860_rtype_to_howto |
static reloc_howto_type * |
522 |
|
coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
523 |
|
bfd_reloc_code_real_type code) |
524 |
|
{ |
525 |
|
switch (code) |
526 |
|
{ |
527 |
|
case BFD_RELOC_32: |
528 |
|
return howto_table + R_DIR32; |
529 |
|
case BFD_RELOC_860_PC26: |
530 |
|
return howto_table + COFF860_R_BRADDR; |
531 |
|
case BFD_RELOC_860_PC16: |
532 |
|
/* ??? How to handle PC16 for COFF? SPLIT0 is close for now. */ |
533 |
|
return howto_table + COFF860_R_SPLIT0; |
534 |
|
case BFD_RELOC_860_LOW0: |
535 |
|
return howto_table + COFF860_R_LOW0; |
536 |
|
case BFD_RELOC_860_SPLIT0: |
537 |
|
return howto_table + COFF860_R_SPLIT0; |
538 |
|
case BFD_RELOC_860_LOW1: |
539 |
|
return howto_table + COFF860_R_LOW1; |
540 |
|
case BFD_RELOC_860_SPLIT1: |
541 |
|
return howto_table + COFF860_R_SPLIT1; |
542 |
|
case BFD_RELOC_860_LOW2: |
543 |
|
return howto_table + COFF860_R_LOW2; |
544 |
|
case BFD_RELOC_860_SPLIT2: |
545 |
|
return howto_table + COFF860_R_SPLIT2; |
546 |
|
case BFD_RELOC_860_LOW3: |
547 |
|
return howto_table + COFF860_R_LOW3; |
548 |
|
case BFD_RELOC_860_HIGHADJ: |
549 |
|
return howto_table + COFF860_R_HIGHADJ; |
550 |
|
case BFD_RELOC_860_HIGH: |
551 |
|
return howto_table + COFF860_R_HIGH; |
552 |
|
default: |
553 |
|
BFD_FAIL (); |
554 |
|
return 0; |
555 |
|
} |
556 |
|
} |
557 |
|
|
558 |
|
/* This is called from coff_slurp_reloc_table for each relocation |
559 |
|
entry. This special handling is due to the `PAIR' relocation |
560 |
|
which has a different meaning for the `r_symndx' field. */ |
561 |
|
|
562 |
|
static void |
563 |
|
i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst, |
564 |
|
asymbol **symbols, bfd *abfd, asection *asect) |
565 |
|
{ |
566 |
|
if (dst->r_type == COFF860_R_PAIR) |
567 |
|
{ |
568 |
|
/* Handle the PAIR relocation specially. */ |
569 |
|
cache_ptr->howto = howto_table + dst->r_type; |
570 |
|
cache_ptr->address = dst->r_vaddr; |
571 |
|
cache_ptr->addend = dst->r_symndx; |
572 |
|
cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr; |
573 |
|
} |
574 |
|
else |
575 |
|
{ |
576 |
|
/* For every other relocation, do exactly what coff_slurp_reloc_table |
577 |
|
would do (which this code is taken directly from). */ |
578 |
|
asymbol *ptr = NULL; |
579 |
|
cache_ptr->address = dst->r_vaddr; |
580 |
|
|
581 |
|
if (dst->r_symndx != -1) |
582 |
|
{ |
583 |
|
if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd)) |
584 |
|
{ |
585 |
|
(*_bfd_error_handler) |
586 |
|
(_("%B: warning: illegal symbol index %ld in relocs"), |
587 |
|
abfd, dst->r_symndx); |
588 |
|
cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
589 |
|
ptr = NULL; |
590 |
|
} |
591 |
|
else |
592 |
|
{ |
593 |
|
cache_ptr->sym_ptr_ptr = (symbols |
594 |
|
+ obj_convert (abfd)[dst->r_symndx]); |
595 |
|
ptr = *(cache_ptr->sym_ptr_ptr); |
596 |
|
} |
597 |
|
} |
598 |
|
else |
599 |
|
{ |
600 |
|
cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
601 |
|
ptr = NULL; |
602 |
|
} |
603 |
|
|
604 |
|
/* The symbols definitions that we have read in have been |
605 |
|
relocated as if their sections started at 0. But the offsets |
606 |
|
refering to the symbols in the raw data have not been |
607 |
|
modified, so we have to have a negative addend to compensate. |
608 |
|
|
609 |
|
Note that symbols which used to be common must be left alone. */ |
610 |
|
|
611 |
|
/* Calculate any reloc addend by looking at the symbol. */ |
612 |
|
CALC_ADDEND (abfd, ptr, (*dst), cache_ptr); |
613 |
|
|
614 |
|
cache_ptr->address -= asect->vma; |
615 |
|
|
616 |
|
/* Fill in the cache_ptr->howto field from dst->r_type. */ |
617 |
|
RTYPE2HOWTO (cache_ptr, dst); |
618 |
|
} |
619 |
|
} |
620 |
|
|
621 |
|
#define coff_rtype_to_howto coff_i860_rtype_to_howto |
622 |
|
#define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup |
623 |
|
|
624 |
|
#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \ |
625 |
|
i860_reloc_processing (relent, reloc, symbols, abfd, section) |
626 |
|
|
627 |
#include "coffcode.h" |
#include "coffcode.h" |
628 |
|
|
629 |
static const bfd_target * |
static const bfd_target * |
630 |
i3coff_object_p(a) |
i3coff_object_p(bfd *a) |
|
bfd *a; |
|
631 |
{ |
{ |
632 |
return coff_object_p (a); |
return coff_object_p (a); |
633 |
} |
} |