1 /* BFD back-end for Intel i860 COFF files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Created mostly by substituting "860" for "386" in coff-i386.c
5 Harry Dolan <dolan@ssd.intel.com>, October 1995
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. */
27 #include "coff/i860.h"
29 #include "coff/internal.h"
34 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
35 /* The page size is a guess based on ELF. */
37 #define COFF_PAGE_SIZE 0x1000
39 /* For some reason when using i860 COFF the value stored in the .text
40 section for a reference to a common symbol is the value itself plus
41 any desired offset. Ian Taylor, Cygnus Support. */
43 /* If we are producing relocatable output, we need to do some
44 adjustments to the object file that are not done by the
45 bfd_perform_relocation function. This function is called by every
46 reloc type to make any required adjustments. */
48 static bfd_reloc_status_type
49 coff_i860_reloc (bfd
*abfd
,
53 asection
*input_section ATTRIBUTE_UNUSED
,
55 char **error_message ATTRIBUTE_UNUSED
)
59 if (output_bfd
== (bfd
*) NULL
)
60 return bfd_reloc_continue
;
62 if (bfd_is_com_section (symbol
->section
))
64 /* We are relocating a common symbol. The current value in the
65 object file is ORIG + OFFSET, where ORIG is the value of the
66 common symbol as seen by the object file when it was compiled
67 (this may be zero if the symbol was undefined) and OFFSET is
68 the offset into the common symbol (normally zero, but may be
69 non-zero when referring to a field in a common structure).
70 ORIG is the negative of reloc_entry->addend, which is set by
71 the CALC_ADDEND macro below. We want to replace the value in
72 the object file with NEW + OFFSET, where NEW is the value of
73 the common symbol which we are going to put in the final
74 object file. NEW is symbol->value. */
75 diff
= symbol
->value
+ reloc_entry
->addend
;
79 /* For some reason bfd_perform_relocation always effectively
80 ignores the addend for a COFF target when producing
81 relocatable output. This seems to be always wrong for 860
82 COFF, so we handle the addend here instead. */
83 diff
= reloc_entry
->addend
;
87 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
91 reloc_howto_type
*howto
= reloc_entry
->howto
;
92 unsigned char *addr
= (unsigned char *) data
+ reloc_entry
->address
;
98 char x
= bfd_get_8 (abfd
, addr
);
100 bfd_put_8 (abfd
, x
, addr
);
106 short x
= bfd_get_16 (abfd
, addr
);
108 bfd_put_16 (abfd
, (bfd_vma
) x
, addr
);
114 long x
= bfd_get_32 (abfd
, addr
);
116 bfd_put_32 (abfd
, (bfd_vma
) x
, addr
);
125 /* Now let bfd_perform_relocation finish everything up. */
126 return bfd_reloc_continue
;
129 /* This is just a temporary measure until we teach bfd to generate
130 these relocations. */
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
)
141 reloc_howto_type
*howto
= reloc_entry
->howto
;
142 fprintf (stderr
, _("Relocation `%s' not yet implemented\n"), howto
->name
);
146 #define PCRELOFFSET FALSE
149 static reloc_howto_type howto_table
[] =
157 HOWTO (R_DIR32
, /* type */
159 2, /* size (0 = byte, 1 = short, 2 = long) */
161 FALSE
, /* pc_relative */
163 complain_overflow_bitfield
, /* complain_on_overflow */
164 coff_i860_reloc
, /* special_function */
166 TRUE
, /* partial_inplace */
167 0xffffffff, /* src_mask */
168 0xffffffff, /* dst_mask */
169 TRUE
), /* pcrel_offset */
171 HOWTO (R_IMAGEBASE
, /* type */
173 2, /* size (0 = byte, 1 = short, 2 = long) */
175 FALSE
, /* pc_relative */
177 complain_overflow_bitfield
, /* complain_on_overflow */
178 coff_i860_reloc
, /* special_function */
180 TRUE
, /* partial_inplace */
181 0xffffffff, /* src_mask */
182 0xffffffff, /* dst_mask */
183 FALSE
), /* pcrel_offset */
191 HOWTO (R_RELBYTE
, /* type */
193 0, /* size (0 = byte, 1 = short, 2 = long) */
195 FALSE
, /* pc_relative */
197 complain_overflow_bitfield
, /* complain_on_overflow */
198 coff_i860_reloc
, /* special_function */
200 TRUE
, /* partial_inplace */
201 0x000000ff, /* src_mask */
202 0x000000ff, /* dst_mask */
203 PCRELOFFSET
), /* pcrel_offset */
204 HOWTO (R_RELWORD
, /* type */
206 1, /* size (0 = byte, 1 = short, 2 = long) */
208 FALSE
, /* pc_relative */
210 complain_overflow_bitfield
, /* complain_on_overflow */
211 coff_i860_reloc
, /* special_function */
213 TRUE
, /* partial_inplace */
214 0x0000ffff, /* src_mask */
215 0x0000ffff, /* dst_mask */
216 PCRELOFFSET
), /* pcrel_offset */
217 HOWTO (R_RELLONG
, /* type */
219 2, /* size (0 = byte, 1 = short, 2 = long) */
221 FALSE
, /* pc_relative */
223 complain_overflow_bitfield
, /* complain_on_overflow */
224 coff_i860_reloc
, /* special_function */
226 TRUE
, /* partial_inplace */
227 0xffffffff, /* src_mask */
228 0xffffffff, /* dst_mask */
229 PCRELOFFSET
), /* pcrel_offset */
230 HOWTO (R_PCRBYTE
, /* type */
232 0, /* size (0 = byte, 1 = short, 2 = long) */
234 TRUE
, /* pc_relative */
236 complain_overflow_signed
, /* complain_on_overflow */
237 coff_i860_reloc
, /* special_function */
239 TRUE
, /* partial_inplace */
240 0x000000ff, /* src_mask */
241 0x000000ff, /* dst_mask */
242 PCRELOFFSET
), /* pcrel_offset */
243 HOWTO (R_PCRWORD
, /* type */
245 1, /* size (0 = byte, 1 = short, 2 = long) */
247 TRUE
, /* pc_relative */
249 complain_overflow_signed
, /* complain_on_overflow */
250 coff_i860_reloc
, /* special_function */
252 TRUE
, /* partial_inplace */
253 0x0000ffff, /* src_mask */
254 0x0000ffff, /* dst_mask */
255 PCRELOFFSET
), /* pcrel_offset */
256 HOWTO (R_PCRLONG
, /* type */
258 2, /* size (0 = byte, 1 = short, 2 = long) */
260 TRUE
, /* pc_relative */
262 complain_overflow_signed
, /* complain_on_overflow */
263 coff_i860_reloc
, /* special_function */
265 TRUE
, /* partial_inplace */
266 0xffffffff, /* src_mask */
267 0xffffffff, /* dst_mask */
268 PCRELOFFSET
), /* pcrel_offset */
276 HOWTO (COFF860_R_PAIR
, /* type */
278 2, /* size (0 = byte, 1 = short, 2 = long) */
280 FALSE
, /* pc_relative */
282 complain_overflow_dont
, /* complain_on_overflow */
283 coff_i860_reloc_nyi
, /* special_function */
285 FALSE
, /* partial_inplace */
286 0xffff, /* src_mask */
287 0xffff, /* dst_mask */
288 FALSE
), /* pcrel_offset */
290 HOWTO (COFF860_R_HIGH
, /* type */
292 2, /* size (0 = byte, 1 = short, 2 = long) */
294 FALSE
, /* pc_relative */
296 complain_overflow_dont
, /* complain_on_overflow */
297 coff_i860_reloc
, /* special_function */
299 FALSE
, /* partial_inplace */
300 0xffff, /* src_mask */
301 0xffff, /* dst_mask */
302 FALSE
), /* pcrel_offset */
303 HOWTO (COFF860_R_LOW0
, /* type */
305 2, /* size (0 = byte, 1 = short, 2 = long) */
307 FALSE
, /* pc_relative */
309 complain_overflow_dont
, /* complain_on_overflow */
310 coff_i860_reloc
, /* special_function */
312 FALSE
, /* partial_inplace */
313 0xffff, /* src_mask */
314 0xffff, /* dst_mask */
315 FALSE
), /* pcrel_offset */
316 HOWTO (COFF860_R_LOW1
, /* type */
318 2, /* size (0 = byte, 1 = short, 2 = long) */
320 FALSE
, /* pc_relative */
322 complain_overflow_dont
, /* complain_on_overflow */
323 coff_i860_reloc
, /* special_function */
325 FALSE
, /* partial_inplace */
326 0xfffe, /* src_mask */
327 0xfffe, /* dst_mask */
328 FALSE
), /* pcrel_offset */
329 HOWTO (COFF860_R_LOW2
, /* type */
331 2, /* size (0 = byte, 1 = short, 2 = long) */
333 FALSE
, /* pc_relative */
335 complain_overflow_dont
, /* complain_on_overflow */
336 coff_i860_reloc
, /* special_function */
338 FALSE
, /* partial_inplace */
339 0xfffc, /* src_mask */
340 0xfffc, /* dst_mask */
341 FALSE
), /* pcrel_offset */
342 HOWTO (COFF860_R_LOW3
, /* type */
344 2, /* size (0 = byte, 1 = short, 2 = long) */
346 FALSE
, /* pc_relative */
348 complain_overflow_dont
, /* complain_on_overflow */
349 coff_i860_reloc
, /* special_function */
351 FALSE
, /* partial_inplace */
352 0xfff8, /* src_mask */
353 0xfff8, /* dst_mask */
354 FALSE
), /* pcrel_offset */
355 HOWTO (COFF860_R_LOW4
, /* type */
357 2, /* size (0 = byte, 1 = short, 2 = long) */
359 FALSE
, /* pc_relative */
361 complain_overflow_dont
, /* complain_on_overflow */
362 coff_i860_reloc
, /* special_function */
364 FALSE
, /* partial_inplace */
365 0xfff0, /* src_mask */
366 0xfff0, /* dst_mask */
367 FALSE
), /* pcrel_offset */
368 HOWTO (COFF860_R_SPLIT0
, /* type */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
372 FALSE
, /* pc_relative */
374 complain_overflow_dont
, /* complain_on_overflow */
375 coff_i860_reloc_nyi
, /* special_function */
377 FALSE
, /* partial_inplace */
378 0x1f07ff, /* src_mask */
379 0x1f07ff, /* dst_mask */
380 FALSE
), /* pcrel_offset */
381 HOWTO (COFF860_R_SPLIT1
, /* type */
383 2, /* size (0 = byte, 1 = short, 2 = long) */
385 FALSE
, /* pc_relative */
387 complain_overflow_dont
, /* complain_on_overflow */
388 coff_i860_reloc_nyi
, /* special_function */
390 FALSE
, /* partial_inplace */
391 0x1f07fe, /* src_mask */
392 0x1f07fe, /* dst_mask */
393 FALSE
), /* pcrel_offset */
394 HOWTO (COFF860_R_SPLIT2
, /* type */
396 2, /* size (0 = byte, 1 = short, 2 = long) */
398 FALSE
, /* pc_relative */
400 complain_overflow_dont
, /* complain_on_overflow */
401 coff_i860_reloc_nyi
, /* special_function */
403 FALSE
, /* partial_inplace */
404 0x1f07fc, /* src_mask */
405 0x1f07fc, /* dst_mask */
406 FALSE
), /* pcrel_offset */
407 HOWTO (COFF860_R_HIGHADJ
, /* type */
409 2, /* size (0 = byte, 1 = short, 2 = long) */
411 FALSE
, /* pc_relative */
413 complain_overflow_dont
, /* complain_on_overflow */
414 coff_i860_reloc_nyi
, /* special_function */
415 "HIGHADJ", /* name */
416 FALSE
, /* partial_inplace */
417 0xffff, /* src_mask */
418 0xffff, /* dst_mask */
419 FALSE
), /* pcrel_offset */
420 HOWTO (COFF860_R_BRADDR
, /* type */
422 2, /* size (0 = byte, 1 = short, 2 = long) */
424 TRUE
, /* pc_relative */
426 complain_overflow_bitfield
, /* complain_on_overflow */
427 coff_i860_reloc_nyi
, /* special_function */
429 FALSE
, /* partial_inplace */
430 0x3ffffff, /* src_mask */
431 0x3ffffff, /* dst_mask */
432 TRUE
) /* pcrel_offset */
435 /* Turn a howto into a reloc number. */
437 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
438 #define BADMAG(x) I860BADMAG(x)
439 #define I860 1 /* Customize coffcode.h */
441 #define RTYPE2HOWTO(cache_ptr, dst) \
442 ((cache_ptr)->howto = \
443 ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \
444 ? howto_table + (dst)->r_type \
447 /* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
448 library. On some other COFF targets STYP_BSS is normally
450 #define BSS_NOLOAD_IS_SHARED_LIBRARY
452 /* Compute the addend of a reloc. If the reloc is to a common symbol,
453 the object file contains the value of the common symbol. By the
454 time this is called, the linker may be using a different symbol
455 from a different object file with a different value. Therefore, we
456 hack wildly to locate the original symbol from this file so that we
457 can make the correct adjustment. This macro sets coffsym to the
458 symbol from the original file, and uses it to set the addend value
459 correctly. If this is not a common symbol, the usual addend
460 calculation is done, except that an additional tweak is needed for
462 FIXME: This macro refers to symbols and asect; these are from the
463 calling function, not the macro arguments. */
465 /* FIXME: This was copied from the i386 version originally but
466 appears to be wrong for i860. For now we'll do nothing. */
468 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
470 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
471 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
472 coffsym = (obj_symbols (abfd) \
473 + (cache_ptr->sym_ptr_ptr - symbols)); \
475 coffsym = coff_symbol_from (abfd, ptr); \
476 if (coffsym != (coff_symbol_type *) NULL \
477 && coffsym->native->u.syment.n_scnum == 0) \
478 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
479 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
480 && ptr->section != (asection *) NULL) \
481 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
483 cache_ptr->addend = 0; \
484 if (ptr && howto_table[reloc.r_type].pc_relative) \
485 cache_ptr->addend += asect->vma; \
488 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
491 /* We use the special COFF backend linker. */
492 #define coff_relocate_section _bfd_coff_generic_relocate_section
494 static reloc_howto_type
*
495 coff_i860_rtype_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
497 struct internal_reloc
*rel
,
498 struct coff_link_hash_entry
*h
,
499 struct internal_syment
*sym
,
503 reloc_howto_type
*howto
;
505 if (rel
->r_type
> sizeof (howto_table
) / sizeof (howto_table
[0]))
507 bfd_set_error (bfd_error_bad_value
);
511 howto
= howto_table
+ rel
->r_type
;
513 if (howto
->pc_relative
)
514 *addendp
+= sec
->vma
;
516 if (sym
!= NULL
&& sym
->n_scnum
== 0 && sym
->n_value
!= 0)
518 /* This is a common symbol. The section contents include the
519 size (sym->n_value) as an addend. The relocate_section
520 function will be adding in the final value of the symbol. We
521 need to subtract out the current size in order to get the
524 BFD_ASSERT (h
!= NULL
);
526 /* I think we *do* want to bypass this. If we don't, I have seen some data
527 parameters get the wrong relcation address. If I link two versions
528 with and without this section bypassed and then do a binary comparison,
529 the addresses which are different can be looked up in the map. The
530 case in which this section has been bypassed has addresses which correspond
531 to values I can find in the map. */
532 *addendp
-= sym
->n_value
;
535 /* If the output symbol is common (in which case this must be a
536 relocatable link), we need to add in the final size of the
538 if (h
!= NULL
&& h
->root
.type
== bfd_link_hash_common
)
539 *addendp
+= h
->root
.u
.c
.size
;
544 static reloc_howto_type
*
545 coff_i860_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
546 bfd_reloc_code_real_type code
)
551 return howto_table
+ R_DIR32
;
552 case BFD_RELOC_860_PC26
:
553 return howto_table
+ COFF860_R_BRADDR
;
554 case BFD_RELOC_860_PC16
:
555 /* ??? How to handle PC16 for COFF? SPLIT0 is close for now. */
556 return howto_table
+ COFF860_R_SPLIT0
;
557 case BFD_RELOC_860_LOW0
:
558 return howto_table
+ COFF860_R_LOW0
;
559 case BFD_RELOC_860_SPLIT0
:
560 return howto_table
+ COFF860_R_SPLIT0
;
561 case BFD_RELOC_860_LOW1
:
562 return howto_table
+ COFF860_R_LOW1
;
563 case BFD_RELOC_860_SPLIT1
:
564 return howto_table
+ COFF860_R_SPLIT1
;
565 case BFD_RELOC_860_LOW2
:
566 return howto_table
+ COFF860_R_LOW2
;
567 case BFD_RELOC_860_SPLIT2
:
568 return howto_table
+ COFF860_R_SPLIT2
;
569 case BFD_RELOC_860_LOW3
:
570 return howto_table
+ COFF860_R_LOW3
;
571 case BFD_RELOC_860_HIGHADJ
:
572 return howto_table
+ COFF860_R_HIGHADJ
;
573 case BFD_RELOC_860_HIGH
:
574 return howto_table
+ COFF860_R_HIGH
;
581 /* This is called from coff_slurp_reloc_table for each relocation
582 entry. This special handling is due to the `PAIR' relocation
583 which has a different meaning for the `r_symndx' field. */
586 i860_reloc_processing (arelent
*cache_ptr
, struct internal_reloc
*dst
,
587 asymbol
**symbols
, bfd
*abfd
, asection
*asect
)
589 if (dst
->r_type
== COFF860_R_PAIR
)
591 /* Handle the PAIR relocation specially. */
592 cache_ptr
->howto
= howto_table
+ dst
->r_type
;
593 cache_ptr
->address
= dst
->r_vaddr
;
594 cache_ptr
->addend
= dst
->r_symndx
;
595 cache_ptr
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
599 /* For every other relocation, do exactly what coff_slurp_reloc_table
600 would do (which this code is taken directly from). */
602 cache_ptr
->address
= dst
->r_vaddr
;
604 if (dst
->r_symndx
!= -1)
606 if (dst
->r_symndx
< 0 || dst
->r_symndx
>= obj_conv_table_size (abfd
))
608 (*_bfd_error_handler
)
609 (_("%s: warning: illegal symbol index %ld in relocs"),
610 bfd_archive_filename (abfd
), dst
->r_symndx
);
611 cache_ptr
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
616 cache_ptr
->sym_ptr_ptr
= (symbols
617 + obj_convert (abfd
)[dst
->r_symndx
]);
618 ptr
= *(cache_ptr
->sym_ptr_ptr
);
623 cache_ptr
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
627 /* The symbols definitions that we have read in have been
628 relocated as if their sections started at 0. But the offsets
629 refering to the symbols in the raw data have not been
630 modified, so we have to have a negative addend to compensate.
632 Note that symbols which used to be common must be left alone. */
634 /* Calculate any reloc addend by looking at the symbol. */
635 CALC_ADDEND (abfd
, ptr
, (*dst
), cache_ptr
);
637 cache_ptr
->address
-= asect
->vma
;
639 /* Fill in the cache_ptr->howto field from dst->r_type. */
640 RTYPE2HOWTO (cache_ptr
, dst
);
644 #define coff_rtype_to_howto coff_i860_rtype_to_howto
645 #define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup
647 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
648 i860_reloc_processing (relent, reloc, symbols, abfd, section)
650 #include "coffcode.h"
652 static const bfd_target
*
653 i3coff_object_p(bfd
*a
)
655 return coff_object_p (a
);
668 "coff-i860", /* name */
670 bfd_target_coff_flavour
,
671 BFD_ENDIAN_LITTLE
, /* data byte order is little */
672 BFD_ENDIAN_LITTLE
, /* header byte order is little */
674 (HAS_RELOC
| EXEC_P
| /* object flags */
675 HAS_LINENO
| HAS_DEBUG
|
676 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
678 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
679 '_', /* leading underscore */
680 '/', /* ar_pad_char */
681 15, /* ar_max_namelen */
683 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
684 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
685 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* data */
686 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
687 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
688 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* hdrs */
690 /* Note that we allow an object file to be treated as a core file as well. */
691 {_bfd_dummy_target
, i3coff_object_p
, /* bfd_check_format */
692 bfd_generic_archive_p
, i3coff_object_p
},
693 {bfd_false
, coff_mkobject
, _bfd_generic_mkarchive
, /* bfd_set_format */
695 {bfd_false
, coff_write_object_contents
, /* bfd_write_contents */
696 _bfd_write_archive_contents
, bfd_false
},
698 BFD_JUMP_TABLE_GENERIC (coff
),
699 BFD_JUMP_TABLE_COPY (coff
),
700 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
701 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
702 BFD_JUMP_TABLE_SYMBOLS (coff
),
703 BFD_JUMP_TABLE_RELOCS (coff
),
704 BFD_JUMP_TABLE_WRITE (coff
),
705 BFD_JUMP_TABLE_LINK (coff
),
706 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),