1 /* BFD back-end for Motorolla MCore COFF/PE
3 Free Software Foundation, Inc.
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
25 #include "coff/mcore.h"
26 #include "coff/internal.h"
33 #define BADMAG(x) MCOREBADMAG(x)
36 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
39 /* This file is compiled more than once, but we only compile the
40 final_link routine once. */
41 extern boolean mcore_bfd_coff_final_link
42 PARAMS ((bfd *, struct bfd_link_info *));
44 static struct bfd_link_hash_table * coff_mcore_link_hash_table_create
46 static bfd_reloc_status_type mcore_coff_unsupported_reloc
47 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
48 static boolean in_reloc_p
49 PARAMS ((bfd *, reloc_howto_type *));
50 static boolean coff_mcore_relocate_section
51 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
52 struct internal_reloc *, struct internal_syment *, asection **));
53 static reloc_howto_type * mcore_coff_reloc_type_lookup
54 PARAMS ((bfd *, bfd_reloc_code_real_type));
55 static reloc_howto_type * coff_mcore_rtype_to_howto
56 PARAMS ((bfd *, asection *, struct internal_reloc *,
57 struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
58 static const bfd_target * pe_object_p
63 /* The NT loader points the toc register to &toc + 32768, in order to
64 use the complete range of a 16-bit displacement. We have to adjust
65 for this when we fix up loads displaced off the toc reg. */
66 #define TOC_LOAD_ADJUSTMENT (-32768)
67 #define TOC_SECTION_NAME ".private.toc"
69 /* The main body of code is in coffcode.h. */
70 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
72 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
73 from smaller values. Start with zero, widen, *then* decrement. */
74 #define MINUS_ONE (((bfd_vma)0) - 1)
77 static reloc_howto_type mcore_coff_howto_table[] =
80 HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */
82 0, /* size (0 = byte, 1 = short, 2 = long) */
84 false, /* pc_relative */
86 complain_overflow_dont, /* dont complain_on_overflow */
87 0, /* special_function */
88 "ABSOLUTE", /* name */
89 false, /* partial_inplace */
92 false), /* pcrel_offset */
94 HOWTO (IMAGE_REL_MCORE_ADDR32,/* type */
96 2, /* size (0 = byte, 1 = short, 2 = long) */
98 false, /* pc_relative */
100 complain_overflow_bitfield, /* complain_on_overflow */
101 0, /* special_function */
103 true, /* partial_inplace */
104 0xffffffff, /* src_mask */
105 0xffffffff, /* dst_mask */
106 false), /* pcrel_offset */
108 /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
109 Should not appear in object files. */
110 HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4, /* type */
112 1, /* size (0 = byte, 1 = short, 2 = long) */
114 true, /* pc_relative */
116 complain_overflow_bitfield, /* complain_on_overflow */
117 mcore_coff_unsupported_reloc, /* special_function */
118 "IMM8BY4", /* name */
119 false, /* partial_inplace */
122 true), /* pcrel_offset */
124 /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
125 Span 2k instructions == 4k bytes.
126 Only useful pieces at the relocated address are the opcode (5 bits) */
127 HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2,/* type */
129 1, /* size (0 = byte, 1 = short, 2 = long) */
131 true, /* pc_relative */
133 complain_overflow_signed, /* complain_on_overflow */
134 NULL, /* special_function */
135 "IMM11BY2", /* name */
136 false, /* partial_inplace */
138 0x7ff, /* dst_mask */
139 true), /* pcrel_offset */
141 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
142 HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2, /* type */
144 1, /* size (0 = byte, 1 = short, 2 = long) */
146 true, /* pc_relative */
148 complain_overflow_bitfield, /* complain_on_overflow */
149 mcore_coff_unsupported_reloc,/* special_function */
150 "IMM4BY2", /* name */
151 false, /* partial_inplace */
154 true), /* pcrel_offset */
156 /* 32-bit pc-relative. Eventually this will help support PIC code. */
157 HOWTO (IMAGE_REL_MCORE_PCREL_32,/* type */
159 2, /* size (0 = byte, 1 = short, 2 = long) */
161 true, /* pc_relative */
163 complain_overflow_bitfield, /* complain_on_overflow */
164 NULL, /* special_function */
165 "PCREL_32", /* name */
166 false, /* partial_inplace */
168 0xffffffff, /* dst_mask */
169 true), /* pcrel_offset */
171 /* Like PCREL_IMM11BY2, this relocation indicates that there is a
172 'jsri' at the specified address. There is a separate relocation
173 entry for the literal pool entry that it references, but we
174 might be able to change the jsri to a bsr if the target turns out
175 to be close enough [even though we won't reclaim the literal pool
176 entry, we'll get some runtime efficiency back]. Note that this
177 is a relocation that we are allowed to safely ignore. */
178 HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2,/* type */
180 1, /* size (0 = byte, 1 = short, 2 = long) */
182 true, /* pc_relative */
184 complain_overflow_signed, /* complain_on_overflow */
185 NULL, /* special_function */
186 "JSR_IMM11BY2", /* name */
187 false, /* partial_inplace */
189 0x7ff, /* dst_mask */
190 true) /* pcrel_offset */
193 /* Extend the coff_link_hash_table structure with a few M*Core specific fields.
194 This allows us to store global data here without actually creating any
195 global variables, which is a no-no in the BFD world. */
196 typedef struct coff_mcore_link_hash_table
198 /* The original coff_link_hash_table structure. MUST be first field. */
199 struct coff_link_hash_table root;
201 bfd * bfd_of_toc_owner;
202 long int global_toc_size;
203 long int import_table_size;
204 long int first_thunk_address;
209 /* Get the MCore coff linker hash table from a link_info structure. */
210 #define coff_mcore_hash_table(info) \
211 ((mcore_hash_table *) ((info)->hash))
213 /* Create an MCore coff linker hash table. */
214 static struct bfd_link_hash_table *
215 coff_mcore_link_hash_table_create (abfd)
218 mcore_hash_table * ret;
220 ret = ((mcore_hash_table *) bfd_alloc (abfd, sizeof (* ret)));
221 if (ret == (mcore_hash_table *) NULL)
224 if (! _bfd_coff_link_hash_table_init
225 (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
227 bfd_release (abfd, ret);
228 return (struct bfd_link_hash_table *) NULL;
231 ret->bfd_of_toc_owner = NULL;
232 ret->global_toc_size = 0;
233 ret->import_table_size = 0;
234 ret->first_thunk_address = 0;
237 return & ret->root.root;
241 static bfd_reloc_status_type
242 mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
243 output_bfd, error_message)
245 arelent * reloc_entry;
248 asection * input_section;
250 char ** error_message;
252 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
254 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
255 bfd_get_filename (abfd),
256 reloc_entry->howto->name,
257 reloc_entry->howto->type);
259 return bfd_reloc_notsupported;
263 /* A cheesy little macro to make the code a little more readable. */
264 #define HOW2MAP(bfd_rtype, mcore_rtype) \
265 case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
267 static reloc_howto_type *
268 mcore_coff_reloc_type_lookup (abfd, code)
270 bfd_reloc_code_real_type code;
274 HOW2MAP (BFD_RELOC_32, IMAGE_REL_MCORE_ADDR32);
275 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4, IMAGE_REL_MCORE_PCREL_IMM8BY4);
276 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2, IMAGE_REL_MCORE_PCREL_IMM11BY2);
277 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2, IMAGE_REL_MCORE_PCREL_IMM4BY2);
278 HOW2MAP (BFD_RELOC_32_PCREL, IMAGE_REL_MCORE_PCREL_32);
279 HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2);
288 #define RTYPE2HOWTO(cache_ptr, dst) \
289 (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
291 static reloc_howto_type *
292 coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
295 struct internal_reloc * rel;
296 struct coff_link_hash_entry * h;
297 struct internal_syment * sym;
300 reloc_howto_type * howto;
303 if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
306 howto = mcore_coff_howto_table + rel->r_type;
308 if (howto->pc_relative)
310 * addendp = sec->vma - 2; /* XXX guess - is this right ? */
312 /* If the symbol is defined, then the generic code is going to
313 add back the symbol value in order to cancel out an
314 adjustment it made to the addend. However, we set the addend
315 to 0 at the start of this function. We need to adjust here,
316 to avoid the adjustment the generic code will make. FIXME:
317 This is getting a bit hackish. */
318 if (sym != NULL && sym->n_scnum != 0)
319 * addendp -= sym->n_value;
327 /* Return true if this relocation should
328 appear in the output .reloc section. */
329 static boolean in_reloc_p (abfd, howto)
331 reloc_howto_type * howto;
333 return ! howto->pc_relative;
336 /* The reloc processing routine for the optimized COFF linker. */
338 coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section,
339 contents, relocs, syms, sections)
341 struct bfd_link_info * info;
343 asection * input_section;
345 struct internal_reloc * relocs;
346 struct internal_syment * syms;
347 asection ** sections;
349 struct internal_reloc * rel;
350 struct internal_reloc * relend;
354 /* If we are performing a relocateable link, we don't need to do a
355 thing. The caller will take care of adjusting the reloc
356 addresses and symbol indices. */
357 if (info->relocateable)
360 /* Check if we have the same endianess */
361 if ( input_bfd->xvec->byteorder != output_bfd->xvec->byteorder
362 && output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
364 (*_bfd_error_handler)
365 (_("%s: compiled for a %s endian system and target is %s endian.\n"),
366 bfd_get_filename (input_bfd),
367 bfd_big_endian (input_bfd) ? "big" : "little",
368 bfd_big_endian (output_bfd) ? "big" : "little");
370 bfd_set_error (bfd_error_wrong_format);
378 relend = rel + input_section->reloc_count;
380 for (; rel < relend; rel++)
382 asection * toc_section = NULL;
385 struct internal_syment * sym;
388 bfd_reloc_status_type rstat;
390 unsigned short r_type = rel->r_type;
391 reloc_howto_type * howto = NULL;
392 struct coff_link_hash_entry * h;
393 const char * my_name;
395 symndx = rel->r_symndx;
396 loc = contents + rel->r_vaddr - input_section->vma;
405 h = obj_coff_sym_hashes (input_bfd)[symndx];
409 /* Get the howto and initialise the addend. */
410 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
423 asection * sec = sections[symndx];
426 + sec->output_section->vma
427 + sec->output_offset);
430 my_name = "*unknown*";
431 else if ( sym->_n._n_n._n_zeroes == 0
432 && sym->_n._n_n._n_offset != 0)
433 my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
436 static char buf [SYMNMLEN + 1];
438 strncpy (buf, sym->_n._n_name, SYMNMLEN);
439 buf[SYMNMLEN] = '\0';
446 if ( h->root.type == bfd_link_hash_defined
447 || h->root.type == bfd_link_hash_defweak)
449 asection * sec = h->root.u.def.section;
451 val = (h->root.u.def.value
452 + sec->output_section->vma
453 + sec->output_offset);
457 if (! ((*info->callbacks->undefined_symbol)
458 (info, h->root.root.string, input_bfd, input_section,
459 rel->r_vaddr - input_section->vma)))
463 my_name = h->root.root.string;
466 rstat = bfd_reloc_ok;
468 /* Each case must do its own relocation, setting rstat appropriately. */
472 _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
473 bfd_get_filename (input_bfd), r_type);
474 bfd_set_error (bfd_error_bad_value);
477 case IMAGE_REL_MCORE_ABSOLUTE:
479 _("Warning: unsupported reloc %s <file %s, section %s>\n"),
481 bfd_get_filename (input_bfd),
482 input_section->name);
484 fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
485 rel->r_symndx, my_name, (long) rel->r_vaddr,
486 (unsigned long) rel->r_vaddr);
489 case IMAGE_REL_MCORE_PCREL_IMM8BY4:
490 case IMAGE_REL_MCORE_PCREL_IMM11BY2:
491 case IMAGE_REL_MCORE_PCREL_IMM4BY2:
492 case IMAGE_REL_MCORE_PCREL_32:
493 case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2:
494 case IMAGE_REL_MCORE_ADDR32:
495 rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
507 case bfd_reloc_overflow:
508 if (! ((*info->callbacks->reloc_overflow)
509 (info, my_name, howto->name,
510 (bfd_vma) 0, input_bfd,
511 input_section, rel->r_vaddr - input_section->vma)))
520 /* Tailor coffcode.h -- macro heaven. */
522 /* We use the special COFF backend linker, with our own special touch. */
524 #define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
525 #define coff_relocate_section coff_mcore_relocate_section
526 #define coff_rtype_to_howto coff_mcore_rtype_to_howto
528 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
530 #define COFF_PAGE_SIZE 0x1000
532 #include "coffcode.h"
534 static const bfd_target *
538 #ifdef COFF_IMAGE_WITH_PE
539 /* We need to hack badly to handle a PE image correctly. In PE
540 images created by the GNU linker, the offset to the COFF header
541 is always the size. However, this is not the case in images
542 generated by other PE linkers. The PE format stores a four byte
543 offset to the PE signature just before the COFF header at
544 location 0x3c of the file. We pick up that offset, verify that
545 the PE signature is there, and then set ourselves up to read in
548 bfd_byte ext_offset[4];
550 bfd_byte ext_signature[4];
551 unsigned long signature;
553 if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
554 || bfd_read (ext_offset, 1, 4, abfd) != 4)
556 if (bfd_get_error () != bfd_error_system_call)
557 bfd_set_error (bfd_error_wrong_format);
561 offset = bfd_h_get_32 (abfd, ext_offset);
563 if (bfd_seek (abfd, offset, SEEK_SET) != 0
564 || bfd_read (ext_signature, 1, 4, abfd) != 4)
566 if (bfd_get_error () != bfd_error_system_call)
567 bfd_set_error (bfd_error_wrong_format);
572 signature = bfd_h_get_32 (abfd, ext_signature);
574 if (signature != 0x4550)
576 bfd_set_error (bfd_error_wrong_format);
580 /* Here is the hack. coff_object_p wants to read filhsz bytes to
581 pick up the COFF header. We adjust so that that will work. 20
582 is the size of the mips COFF filehdr. */
583 if (bfd_seek (abfd, (bfd_tell (abfd) - bfd_coff_filhsz (abfd) + 20),
586 if (bfd_get_error () != bfd_error_system_call)
587 bfd_set_error (bfd_error_wrong_format);
594 return coff_object_p (abfd);
597 /* The transfer vectors that lead the outside world to all of the above. */
603 bfd_target_coff_flavour,
604 BFD_ENDIAN_BIG, /* data byte order is big */
605 BFD_ENDIAN_BIG, /* header byte order is big */
607 (HAS_RELOC | EXEC_P | /* object flags */
608 HAS_LINENO | HAS_DEBUG |
609 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
611 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
612 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
614 0, /* leading char */
615 '/', /* ar_pad_char */
616 15, /* ar_max_namelen */
618 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
619 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
620 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
622 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
623 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
624 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
627 pe_object_p, /* bfd_check_format */
628 bfd_generic_archive_p, /* _bfd_dummy_target */
633 _bfd_generic_mkarchive, /* bfd_set_format */
637 coff_write_object_contents, /* bfd_write_contents */
638 _bfd_write_archive_contents,
642 BFD_JUMP_TABLE_GENERIC (coff),
643 BFD_JUMP_TABLE_COPY (coff),
644 BFD_JUMP_TABLE_CORE (_bfd_nocore),
645 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
646 BFD_JUMP_TABLE_SYMBOLS (coff),
647 BFD_JUMP_TABLE_RELOCS (coff),
648 BFD_JUMP_TABLE_WRITE (coff),
649 BFD_JUMP_TABLE_LINK (coff),
650 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
659 bfd_target_coff_flavour,
660 BFD_ENDIAN_LITTLE, /* data byte order is little */
661 BFD_ENDIAN_LITTLE, /* header byte order is little */
663 (HAS_RELOC | EXEC_P | /* object flags */
664 HAS_LINENO | HAS_DEBUG |
665 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
667 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
668 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
670 0, /* leading underscore */
671 '/', /* ar_pad_char */
672 15, /* ar_max_namelen */
674 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
675 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
676 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
678 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
679 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
680 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
682 /* Note that we allow an object file to be treated as a core file as well. */
685 pe_object_p, /* bfd_check_format */
686 bfd_generic_archive_p,
692 _bfd_generic_mkarchive, /* bfd_set_format */
697 coff_write_object_contents, /* bfd_write_contents */
698 _bfd_write_archive_contents,
702 BFD_JUMP_TABLE_GENERIC (coff),
703 BFD_JUMP_TABLE_COPY (coff),
704 BFD_JUMP_TABLE_CORE (_bfd_nocore),
705 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
706 BFD_JUMP_TABLE_SYMBOLS (coff),
707 BFD_JUMP_TABLE_RELOCS (coff),
708 BFD_JUMP_TABLE_WRITE (coff),
709 BFD_JUMP_TABLE_LINK (coff),
710 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),