1 /* BFD back-end for Intel i860 COFF files.
2 Copyright (C) 1990-2018 Free Software Foundation, Inc.
3 Created mostly by substituting "860" for "386" in coff-i386.c
4 Harry Dolan <dolan@ssd.intel.com>, October 1995
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
27 #include "coff/i860.h"
29 #include "coff/internal.h"
31 #ifndef bfd_pe_print_pdata
32 #define bfd_pe_print_pdata NULL
38 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
39 /* The page size is a guess based on ELF. */
41 #define COFF_PAGE_SIZE 0x1000
43 /* For some reason when using i860 COFF the value stored in the .text
44 section for a reference to a common symbol is the value itself plus
45 any desired offset. Ian Taylor, Cygnus Support. */
47 /* If we are producing relocatable output, we need to do some
48 adjustments to the object file that are not done by the
49 bfd_perform_relocation function. This function is called by every
50 reloc type to make any required adjustments. */
52 static bfd_reloc_status_type
53 coff_i860_reloc (bfd
*abfd
,
57 asection
*input_section ATTRIBUTE_UNUSED
,
59 char **error_message ATTRIBUTE_UNUSED
)
63 if (output_bfd
== (bfd
*) NULL
)
64 return bfd_reloc_continue
;
66 if (bfd_is_com_section (symbol
->section
))
68 /* We are relocating a common symbol. The current value in the
69 object file is ORIG + OFFSET, where ORIG is the value of the
70 common symbol as seen by the object file when it was compiled
71 (this may be zero if the symbol was undefined) and OFFSET is
72 the offset into the common symbol (normally zero, but may be
73 non-zero when referring to a field in a common structure).
74 ORIG is the negative of reloc_entry->addend, which is set by
75 the CALC_ADDEND macro below. We want to replace the value in
76 the object file with NEW + OFFSET, where NEW is the value of
77 the common symbol which we are going to put in the final
78 object file. NEW is symbol->value. */
79 diff
= symbol
->value
+ reloc_entry
->addend
;
83 /* For some reason bfd_perform_relocation always effectively
84 ignores the addend for a COFF target when producing
85 relocatable output. This seems to be always wrong for 860
86 COFF, so we handle the addend here instead. */
87 diff
= reloc_entry
->addend
;
91 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
95 reloc_howto_type
*howto
= reloc_entry
->howto
;
96 unsigned char *addr
= (unsigned char *) data
+ reloc_entry
->address
;
98 if (! bfd_reloc_offset_in_range (howto
, abfd
, input_section
,
100 * bfd_octets_per_byte (abfd
)))
101 return bfd_reloc_outofrange
;
107 char x
= bfd_get_8 (abfd
, addr
);
109 bfd_put_8 (abfd
, x
, addr
);
115 short x
= bfd_get_16 (abfd
, addr
);
117 bfd_put_16 (abfd
, (bfd_vma
) x
, addr
);
123 long x
= bfd_get_32 (abfd
, addr
);
125 bfd_put_32 (abfd
, (bfd_vma
) x
, addr
);
134 /* Now let bfd_perform_relocation finish everything up. */
135 return bfd_reloc_continue
;
138 /* This is just a temporary measure until we teach bfd to generate
139 these relocations. */
141 static bfd_reloc_status_type
142 coff_i860_reloc_nyi (bfd
*abfd ATTRIBUTE_UNUSED
,
143 arelent
*reloc_entry
,
144 asymbol
*symbol ATTRIBUTE_UNUSED
,
145 void *data ATTRIBUTE_UNUSED
,
146 asection
*input_section ATTRIBUTE_UNUSED
,
147 bfd
*output_bfd ATTRIBUTE_UNUSED
,
148 char **error_message ATTRIBUTE_UNUSED
)
150 reloc_howto_type
*howto
= reloc_entry
->howto
;
151 _bfd_error_handler (_("relocation `%s' not yet implemented"), howto
->name
);
152 return bfd_reloc_notsupported
;
156 #define PCRELOFFSET FALSE
159 static reloc_howto_type howto_table
[] =
167 HOWTO (R_DIR32
, /* type */
169 2, /* size (0 = byte, 1 = short, 2 = long) */
171 FALSE
, /* pc_relative */
173 complain_overflow_bitfield
, /* complain_on_overflow */
174 coff_i860_reloc
, /* special_function */
176 TRUE
, /* partial_inplace */
177 0xffffffff, /* src_mask */
178 0xffffffff, /* dst_mask */
179 TRUE
), /* pcrel_offset */
181 HOWTO (R_IMAGEBASE
, /* type */
183 2, /* size (0 = byte, 1 = short, 2 = long) */
185 FALSE
, /* pc_relative */
187 complain_overflow_bitfield
, /* complain_on_overflow */
188 coff_i860_reloc
, /* special_function */
190 TRUE
, /* partial_inplace */
191 0xffffffff, /* src_mask */
192 0xffffffff, /* dst_mask */
193 FALSE
), /* pcrel_offset */
201 HOWTO (R_RELBYTE
, /* type */
203 0, /* size (0 = byte, 1 = short, 2 = long) */
205 FALSE
, /* pc_relative */
207 complain_overflow_bitfield
, /* complain_on_overflow */
208 coff_i860_reloc
, /* special_function */
210 TRUE
, /* partial_inplace */
211 0x000000ff, /* src_mask */
212 0x000000ff, /* dst_mask */
213 PCRELOFFSET
), /* pcrel_offset */
214 HOWTO (R_RELWORD
, /* type */
216 1, /* size (0 = byte, 1 = short, 2 = long) */
218 FALSE
, /* pc_relative */
220 complain_overflow_bitfield
, /* complain_on_overflow */
221 coff_i860_reloc
, /* special_function */
223 TRUE
, /* partial_inplace */
224 0x0000ffff, /* src_mask */
225 0x0000ffff, /* dst_mask */
226 PCRELOFFSET
), /* pcrel_offset */
227 HOWTO (R_RELLONG
, /* type */
229 2, /* size (0 = byte, 1 = short, 2 = long) */
231 FALSE
, /* pc_relative */
233 complain_overflow_bitfield
, /* complain_on_overflow */
234 coff_i860_reloc
, /* special_function */
236 TRUE
, /* partial_inplace */
237 0xffffffff, /* src_mask */
238 0xffffffff, /* dst_mask */
239 PCRELOFFSET
), /* pcrel_offset */
240 HOWTO (R_PCRBYTE
, /* type */
242 0, /* size (0 = byte, 1 = short, 2 = long) */
244 TRUE
, /* pc_relative */
246 complain_overflow_signed
, /* complain_on_overflow */
247 coff_i860_reloc
, /* special_function */
249 TRUE
, /* partial_inplace */
250 0x000000ff, /* src_mask */
251 0x000000ff, /* dst_mask */
252 PCRELOFFSET
), /* pcrel_offset */
253 HOWTO (R_PCRWORD
, /* type */
255 1, /* size (0 = byte, 1 = short, 2 = long) */
257 TRUE
, /* pc_relative */
259 complain_overflow_signed
, /* complain_on_overflow */
260 coff_i860_reloc
, /* special_function */
262 TRUE
, /* partial_inplace */
263 0x0000ffff, /* src_mask */
264 0x0000ffff, /* dst_mask */
265 PCRELOFFSET
), /* pcrel_offset */
266 HOWTO (R_PCRLONG
, /* type */
268 2, /* size (0 = byte, 1 = short, 2 = long) */
270 TRUE
, /* pc_relative */
272 complain_overflow_signed
, /* complain_on_overflow */
273 coff_i860_reloc
, /* special_function */
275 TRUE
, /* partial_inplace */
276 0xffffffff, /* src_mask */
277 0xffffffff, /* dst_mask */
278 PCRELOFFSET
), /* pcrel_offset */
286 HOWTO (COFF860_R_PAIR
, /* type */
288 2, /* size (0 = byte, 1 = short, 2 = long) */
290 FALSE
, /* pc_relative */
292 complain_overflow_dont
, /* complain_on_overflow */
293 coff_i860_reloc_nyi
, /* special_function */
295 FALSE
, /* partial_inplace */
296 0xffff, /* src_mask */
297 0xffff, /* dst_mask */
298 FALSE
), /* pcrel_offset */
300 HOWTO (COFF860_R_HIGH
, /* type */
302 2, /* size (0 = byte, 1 = short, 2 = long) */
304 FALSE
, /* pc_relative */
306 complain_overflow_dont
, /* complain_on_overflow */
307 coff_i860_reloc
, /* special_function */
309 FALSE
, /* partial_inplace */
310 0xffff, /* src_mask */
311 0xffff, /* dst_mask */
312 FALSE
), /* pcrel_offset */
313 HOWTO (COFF860_R_LOW0
, /* type */
315 2, /* size (0 = byte, 1 = short, 2 = long) */
317 FALSE
, /* pc_relative */
319 complain_overflow_dont
, /* complain_on_overflow */
320 coff_i860_reloc
, /* special_function */
322 FALSE
, /* partial_inplace */
323 0xffff, /* src_mask */
324 0xffff, /* dst_mask */
325 FALSE
), /* pcrel_offset */
326 HOWTO (COFF860_R_LOW1
, /* type */
328 2, /* size (0 = byte, 1 = short, 2 = long) */
330 FALSE
, /* pc_relative */
332 complain_overflow_dont
, /* complain_on_overflow */
333 coff_i860_reloc
, /* special_function */
335 FALSE
, /* partial_inplace */
336 0xfffe, /* src_mask */
337 0xfffe, /* dst_mask */
338 FALSE
), /* pcrel_offset */
339 HOWTO (COFF860_R_LOW2
, /* type */
341 2, /* size (0 = byte, 1 = short, 2 = long) */
343 FALSE
, /* pc_relative */
345 complain_overflow_dont
, /* complain_on_overflow */
346 coff_i860_reloc
, /* special_function */
348 FALSE
, /* partial_inplace */
349 0xfffc, /* src_mask */
350 0xfffc, /* dst_mask */
351 FALSE
), /* pcrel_offset */
352 HOWTO (COFF860_R_LOW3
, /* type */
354 2, /* size (0 = byte, 1 = short, 2 = long) */
356 FALSE
, /* pc_relative */
358 complain_overflow_dont
, /* complain_on_overflow */
359 coff_i860_reloc
, /* special_function */
361 FALSE
, /* partial_inplace */
362 0xfff8, /* src_mask */
363 0xfff8, /* dst_mask */
364 FALSE
), /* pcrel_offset */
365 HOWTO (COFF860_R_LOW4
, /* type */
367 2, /* size (0 = byte, 1 = short, 2 = long) */
369 FALSE
, /* pc_relative */
371 complain_overflow_dont
, /* complain_on_overflow */
372 coff_i860_reloc
, /* special_function */
374 FALSE
, /* partial_inplace */
375 0xfff0, /* src_mask */
376 0xfff0, /* dst_mask */
377 FALSE
), /* pcrel_offset */
378 HOWTO (COFF860_R_SPLIT0
, /* type */
380 2, /* size (0 = byte, 1 = short, 2 = long) */
382 FALSE
, /* pc_relative */
384 complain_overflow_dont
, /* complain_on_overflow */
385 coff_i860_reloc_nyi
, /* special_function */
387 FALSE
, /* partial_inplace */
388 0x1f07ff, /* src_mask */
389 0x1f07ff, /* dst_mask */
390 FALSE
), /* pcrel_offset */
391 HOWTO (COFF860_R_SPLIT1
, /* type */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
395 FALSE
, /* pc_relative */
397 complain_overflow_dont
, /* complain_on_overflow */
398 coff_i860_reloc_nyi
, /* special_function */
400 FALSE
, /* partial_inplace */
401 0x1f07fe, /* src_mask */
402 0x1f07fe, /* dst_mask */
403 FALSE
), /* pcrel_offset */
404 HOWTO (COFF860_R_SPLIT2
, /* type */
406 2, /* size (0 = byte, 1 = short, 2 = long) */
408 FALSE
, /* pc_relative */
410 complain_overflow_dont
, /* complain_on_overflow */
411 coff_i860_reloc_nyi
, /* special_function */
413 FALSE
, /* partial_inplace */
414 0x1f07fc, /* src_mask */
415 0x1f07fc, /* dst_mask */
416 FALSE
), /* pcrel_offset */
417 HOWTO (COFF860_R_HIGHADJ
, /* type */
419 2, /* size (0 = byte, 1 = short, 2 = long) */
421 FALSE
, /* pc_relative */
423 complain_overflow_dont
, /* complain_on_overflow */
424 coff_i860_reloc_nyi
, /* special_function */
425 "HIGHADJ", /* name */
426 FALSE
, /* partial_inplace */
427 0xffff, /* src_mask */
428 0xffff, /* dst_mask */
429 FALSE
), /* pcrel_offset */
430 HOWTO (COFF860_R_BRADDR
, /* type */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
434 TRUE
, /* pc_relative */
436 complain_overflow_bitfield
, /* complain_on_overflow */
437 coff_i860_reloc_nyi
, /* special_function */
439 FALSE
, /* partial_inplace */
440 0x3ffffff, /* src_mask */
441 0x3ffffff, /* dst_mask */
442 TRUE
) /* pcrel_offset */
445 /* Turn a howto into a reloc number. */
447 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
448 #define BADMAG(x) I860BADMAG(x)
449 #define I860 1 /* Customize coffcode.h */
451 #define RTYPE2HOWTO(cache_ptr, dst) \
452 ((cache_ptr)->howto = \
453 ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \
454 ? howto_table + (dst)->r_type \
457 /* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
458 library. On some other COFF targets STYP_BSS is normally
460 #define BSS_NOLOAD_IS_SHARED_LIBRARY
462 /* Compute the addend of a reloc. If the reloc is to a common symbol,
463 the object file contains the value of the common symbol. By the
464 time this is called, the linker may be using a different symbol
465 from a different object file with a different value. Therefore, we
466 hack wildly to locate the original symbol from this file so that we
467 can make the correct adjustment. This macro sets coffsym to the
468 symbol from the original file, and uses it to set the addend value
469 correctly. If this is not a common symbol, the usual addend
470 calculation is done, except that an additional tweak is needed for
472 FIXME: This macro refers to symbols and asect; these are from the
473 calling function, not the macro arguments. */
475 /* PR 17512: file: 0a38fb7c
476 Set an addend value, even if it is not going to be used. A tool
477 like coffdump might be used to print out the contents of the reloc. */
478 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) (cache_ptr)->addend = 0
480 /* We use the special COFF backend linker. */
481 #define coff_relocate_section _bfd_coff_generic_relocate_section
483 static reloc_howto_type
*
484 coff_i860_rtype_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
486 struct internal_reloc
*rel
,
487 struct coff_link_hash_entry
*h
,
488 struct internal_syment
*sym
,
492 reloc_howto_type
*howto
;
494 if (rel
->r_type
> sizeof (howto_table
) / sizeof (howto_table
[0]))
496 bfd_set_error (bfd_error_bad_value
);
500 howto
= howto_table
+ rel
->r_type
;
502 if (howto
->pc_relative
)
503 *addendp
+= sec
->vma
;
505 if (sym
!= NULL
&& sym
->n_scnum
== 0 && sym
->n_value
!= 0)
507 /* This is a common symbol. The section contents include the
508 size (sym->n_value) as an addend. The relocate_section
509 function will be adding in the final value of the symbol. We
510 need to subtract out the current size in order to get the
513 BFD_ASSERT (h
!= NULL
);
515 /* I think we *do* want to bypass this. If we don't, I have seen some data
516 parameters get the wrong relocation address. If I link two versions
517 with and without this section bypassed and then do a binary comparison,
518 the addresses which are different can be looked up in the map. The
519 case in which this section has been bypassed has addresses which correspond
520 to values I can find in the map. */
521 *addendp
-= sym
->n_value
;
524 /* If the output symbol is common (in which case this must be a
525 relocatable link), we need to add in the final size of the
527 if (h
!= NULL
&& h
->root
.type
== bfd_link_hash_common
)
528 *addendp
+= h
->root
.u
.c
.size
;
533 static reloc_howto_type
*
534 coff_i860_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
535 bfd_reloc_code_real_type code
)
540 return howto_table
+ R_DIR32
;
541 case BFD_RELOC_860_PC26
:
542 return howto_table
+ COFF860_R_BRADDR
;
543 case BFD_RELOC_860_PC16
:
544 /* ??? How to handle PC16 for COFF? SPLIT0 is close for now. */
545 return howto_table
+ COFF860_R_SPLIT0
;
546 case BFD_RELOC_860_LOW0
:
547 return howto_table
+ COFF860_R_LOW0
;
548 case BFD_RELOC_860_SPLIT0
:
549 return howto_table
+ COFF860_R_SPLIT0
;
550 case BFD_RELOC_860_LOW1
:
551 return howto_table
+ COFF860_R_LOW1
;
552 case BFD_RELOC_860_SPLIT1
:
553 return howto_table
+ COFF860_R_SPLIT1
;
554 case BFD_RELOC_860_LOW2
:
555 return howto_table
+ COFF860_R_LOW2
;
556 case BFD_RELOC_860_SPLIT2
:
557 return howto_table
+ COFF860_R_SPLIT2
;
558 case BFD_RELOC_860_LOW3
:
559 return howto_table
+ COFF860_R_LOW3
;
560 case BFD_RELOC_860_HIGHADJ
:
561 return howto_table
+ COFF860_R_HIGHADJ
;
562 case BFD_RELOC_860_HIGH
:
563 return howto_table
+ COFF860_R_HIGH
;
570 static reloc_howto_type
*
571 coff_i860_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
576 for (i
= 0; i
< sizeof (howto_table
) / sizeof (howto_table
[0]); i
++)
577 if (howto_table
[i
].name
!= NULL
578 && strcasecmp (howto_table
[i
].name
, r_name
) == 0)
579 return &howto_table
[i
];
584 /* This is called from coff_slurp_reloc_table for each relocation
585 entry. This special handling is due to the `PAIR' relocation
586 which has a different meaning for the `r_symndx' field. */
589 i860_reloc_processing (arelent
*cache_ptr
, struct internal_reloc
*dst
,
590 asymbol
**symbols
, bfd
*abfd
, asection
*asect
)
592 if (dst
->r_type
== COFF860_R_PAIR
)
594 /* Handle the PAIR relocation specially. */
595 cache_ptr
->howto
= howto_table
+ dst
->r_type
;
596 cache_ptr
->address
= dst
->r_vaddr
;
597 cache_ptr
->addend
= dst
->r_symndx
;
598 cache_ptr
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
602 /* For every other relocation, do exactly what coff_slurp_reloc_table
603 would do (which this code is taken directly from). */
605 cache_ptr
->address
= dst
->r_vaddr
;
607 if (dst
->r_symndx
!= -1)
609 if (dst
->r_symndx
< 0 || dst
->r_symndx
>= obj_conv_table_size (abfd
))
612 /* xgettext: c-format */
613 (_("%B: warning: illegal symbol index %ld in relocs"),
614 abfd
, dst
->r_symndx
);
615 cache_ptr
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
620 cache_ptr
->sym_ptr_ptr
= (symbols
621 + obj_convert (abfd
)[dst
->r_symndx
]);
622 ptr
= *(cache_ptr
->sym_ptr_ptr
);
627 cache_ptr
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
631 /* The symbols definitions that we have read in have been
632 relocated as if their sections started at 0. But the offsets
633 refering to the symbols in the raw data have not been
634 modified, so we have to have a negative addend to compensate.
636 Note that symbols which used to be common must be left alone. */
638 /* Calculate any reloc addend by looking at the symbol. */
639 CALC_ADDEND (abfd
, ptr
, (*dst
), cache_ptr
);
642 cache_ptr
->address
-= asect
->vma
;
644 /* Fill in the cache_ptr->howto field from dst->r_type. */
645 RTYPE2HOWTO (cache_ptr
, dst
);
649 #define coff_rtype_to_howto coff_i860_rtype_to_howto
650 #define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup
651 #define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
653 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
654 i860_reloc_processing (relent, reloc, symbols, abfd, section)
656 #include "coffcode.h"
658 static const bfd_target
*
659 i3coff_object_p(bfd
*a
)
661 return coff_object_p (a
);
674 "coff-i860", /* name */
676 bfd_target_coff_flavour
,
677 BFD_ENDIAN_LITTLE
, /* data byte order is little */
678 BFD_ENDIAN_LITTLE
, /* header byte order is little */
680 (HAS_RELOC
| EXEC_P
| /* object flags */
681 HAS_LINENO
| HAS_DEBUG
|
682 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
684 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
685 '_', /* leading underscore */
686 '/', /* ar_pad_char */
687 15, /* ar_max_namelen */
688 0, /* match priority. */
690 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
691 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
692 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* data */
693 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
694 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
695 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* hdrs */
697 /* Note that we allow an object file to be treated as a core file as well. */
698 {_bfd_dummy_target
, i3coff_object_p
, /* bfd_check_format */
699 bfd_generic_archive_p
, i3coff_object_p
},
700 {bfd_false
, coff_mkobject
, _bfd_generic_mkarchive
, /* bfd_set_format */
702 {bfd_false
, coff_write_object_contents
, /* bfd_write_contents */
703 _bfd_write_archive_contents
, bfd_false
},
705 BFD_JUMP_TABLE_GENERIC (coff
),
706 BFD_JUMP_TABLE_COPY (coff
),
707 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
708 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
709 BFD_JUMP_TABLE_SYMBOLS (coff
),
710 BFD_JUMP_TABLE_RELOCS (coff
),
711 BFD_JUMP_TABLE_WRITE (coff
),
712 BFD_JUMP_TABLE_LINK (coff
),
713 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),