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 BFD_ASSERT (input_bfd->xvec->byteorder
361 == output_bfd->xvec->byteorder);
367 relend = rel + input_section->reloc_count;
369 for (; rel < relend; rel++)
371 asection * toc_section = NULL;
374 struct internal_syment * sym;
377 bfd_reloc_status_type rstat;
379 unsigned short r_type = rel->r_type;
380 reloc_howto_type * howto = NULL;
381 struct coff_link_hash_entry * h;
382 const char * my_name;
384 symndx = rel->r_symndx;
385 loc = contents + rel->r_vaddr - input_section->vma;
394 h = obj_coff_sym_hashes (input_bfd)[symndx];
398 /* Get the howto and initialise the addend. */
399 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
412 asection * sec = sections[symndx];
415 + sec->output_section->vma
416 + sec->output_offset);
419 my_name = "*unknown*";
420 else if ( sym->_n._n_n._n_zeroes == 0
421 && sym->_n._n_n._n_offset != 0)
422 my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
425 static char buf [SYMNMLEN + 1];
427 strncpy (buf, sym->_n._n_name, SYMNMLEN);
428 buf[SYMNMLEN] = '\0';
435 if ( h->root.type == bfd_link_hash_defined
436 || h->root.type == bfd_link_hash_defweak)
438 asection * sec = h->root.u.def.section;
440 val = (h->root.u.def.value
441 + sec->output_section->vma
442 + sec->output_offset);
446 if (! ((*info->callbacks->undefined_symbol)
447 (info, h->root.root.string, input_bfd, input_section,
448 rel->r_vaddr - input_section->vma)))
452 my_name = h->root.root.string;
455 rstat = bfd_reloc_ok;
457 /* Each case must do its own relocation, setting rstat appropriately. */
461 _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
462 bfd_get_filename (input_bfd), r_type);
463 bfd_set_error (bfd_error_bad_value);
466 case IMAGE_REL_MCORE_ABSOLUTE:
468 _("Warning: unsupported reloc %s <file %s, section %s>\n"),
470 bfd_get_filename (input_bfd),
471 input_section->name);
473 fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
474 rel->r_symndx, my_name, (long) rel->r_vaddr,
475 (unsigned long) rel->r_vaddr);
478 case IMAGE_REL_MCORE_PCREL_IMM8BY4:
479 case IMAGE_REL_MCORE_PCREL_IMM11BY2:
480 case IMAGE_REL_MCORE_PCREL_IMM4BY2:
481 case IMAGE_REL_MCORE_PCREL_32:
482 case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2:
483 case IMAGE_REL_MCORE_ADDR32:
484 rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
496 case bfd_reloc_overflow:
497 if (! ((*info->callbacks->reloc_overflow)
498 (info, my_name, howto->name,
499 (bfd_vma) 0, input_bfd,
500 input_section, rel->r_vaddr - input_section->vma)))
509 /* Tailor coffcode.h -- macro heaven. */
511 /* We use the special COFF backend linker, with our own special touch. */
513 #define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
514 #define coff_relocate_section coff_mcore_relocate_section
515 #define coff_rtype_to_howto coff_mcore_rtype_to_howto
517 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
519 #define COFF_PAGE_SIZE 0x1000
521 #include "coffcode.h"
523 static const bfd_target *
527 #ifdef COFF_IMAGE_WITH_PE
528 /* We need to hack badly to handle a PE image correctly. In PE
529 images created by the GNU linker, the offset to the COFF header
530 is always the size. However, this is not the case in images
531 generated by other PE linkers. The PE format stores a four byte
532 offset to the PE signature just before the COFF header at
533 location 0x3c of the file. We pick up that offset, verify that
534 the PE signature is there, and then set ourselves up to read in
537 bfd_byte ext_offset[4];
539 bfd_byte ext_signature[4];
540 unsigned long signature;
542 if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
543 || bfd_read (ext_offset, 1, 4, abfd) != 4)
545 if (bfd_get_error () != bfd_error_system_call)
546 bfd_set_error (bfd_error_wrong_format);
550 offset = bfd_h_get_32 (abfd, ext_offset);
552 if (bfd_seek (abfd, offset, SEEK_SET) != 0
553 || bfd_read (ext_signature, 1, 4, abfd) != 4)
555 if (bfd_get_error () != bfd_error_system_call)
556 bfd_set_error (bfd_error_wrong_format);
561 signature = bfd_h_get_32 (abfd, ext_signature);
563 if (signature != 0x4550)
565 bfd_set_error (bfd_error_wrong_format);
569 /* Here is the hack. coff_object_p wants to read filhsz bytes to
570 pick up the COFF header. We adjust so that that will work. 20
571 is the size of the mips COFF filehdr. */
572 if (bfd_seek (abfd, (bfd_tell (abfd) - bfd_coff_filhsz (abfd) + 20),
575 if (bfd_get_error () != bfd_error_system_call)
576 bfd_set_error (bfd_error_wrong_format);
583 return coff_object_p (abfd);
586 /* The transfer vectors that lead the outside world to all of the above. */
592 bfd_target_coff_flavour,
593 BFD_ENDIAN_BIG, /* data byte order is big */
594 BFD_ENDIAN_BIG, /* header byte order is big */
596 (HAS_RELOC | EXEC_P | /* object flags */
597 HAS_LINENO | HAS_DEBUG |
598 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
600 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
601 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
603 0, /* leading char */
604 '/', /* ar_pad_char */
605 15, /* ar_max_namelen */
607 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
608 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
609 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
611 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
612 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
613 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
616 pe_object_p, /* bfd_check_format */
617 bfd_generic_archive_p, /* _bfd_dummy_target */
622 _bfd_generic_mkarchive, /* bfd_set_format */
626 coff_write_object_contents, /* bfd_write_contents */
627 _bfd_write_archive_contents,
631 BFD_JUMP_TABLE_GENERIC (coff),
632 BFD_JUMP_TABLE_COPY (coff),
633 BFD_JUMP_TABLE_CORE (_bfd_nocore),
634 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
635 BFD_JUMP_TABLE_SYMBOLS (coff),
636 BFD_JUMP_TABLE_RELOCS (coff),
637 BFD_JUMP_TABLE_WRITE (coff),
638 BFD_JUMP_TABLE_LINK (coff),
639 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
648 bfd_target_coff_flavour,
649 BFD_ENDIAN_LITTLE, /* data byte order is little */
650 BFD_ENDIAN_LITTLE, /* header byte order is little */
652 (HAS_RELOC | EXEC_P | /* object flags */
653 HAS_LINENO | HAS_DEBUG |
654 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
656 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
657 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
659 0, /* leading underscore */
660 '/', /* ar_pad_char */
661 15, /* ar_max_namelen */
663 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
664 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
665 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
667 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
668 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
669 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
671 /* Note that we allow an object file to be treated as a core file as well. */
674 pe_object_p, /* bfd_check_format */
675 bfd_generic_archive_p,
681 _bfd_generic_mkarchive, /* bfd_set_format */
686 coff_write_object_contents, /* bfd_write_contents */
687 _bfd_write_archive_contents,
691 BFD_JUMP_TABLE_GENERIC (coff),
692 BFD_JUMP_TABLE_COPY (coff),
693 BFD_JUMP_TABLE_CORE (_bfd_nocore),
694 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
695 BFD_JUMP_TABLE_SYMBOLS (coff),
696 BFD_JUMP_TABLE_RELOCS (coff),
697 BFD_JUMP_TABLE_WRITE (coff),
698 BFD_JUMP_TABLE_LINK (coff),
699 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),