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 coff_mcore_relocate_section
49 PARAMS ((bfd
*, struct bfd_link_info
*, bfd
*, asection
*, bfd_byte
*,
50 struct internal_reloc
*, struct internal_syment
*, asection
**));
51 static reloc_howto_type
* mcore_coff_reloc_type_lookup
52 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
53 static reloc_howto_type
* coff_mcore_rtype_to_howto
54 PARAMS ((bfd
*, asection
*, struct internal_reloc
*,
55 struct coff_link_hash_entry
*, struct internal_syment
*, bfd_vma
*));
56 static const bfd_target
* pe_object_p
61 /* The NT loader points the toc register to &toc + 32768, in order to
62 use the complete range of a 16-bit displacement. We have to adjust
63 for this when we fix up loads displaced off the toc reg. */
64 #define TOC_LOAD_ADJUSTMENT (-32768)
65 #define TOC_SECTION_NAME ".private.toc"
67 /* The main body of code is in coffcode.h. */
68 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
70 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
71 from smaller values. Start with zero, widen, *then* decrement. */
72 #define MINUS_ONE (((bfd_vma)0) - 1)
75 static reloc_howto_type mcore_coff_howto_table
[] =
78 HOWTO (IMAGE_REL_MCORE_ABSOLUTE
,/* type */
80 0, /* size (0 = byte, 1 = short, 2 = long) */
82 false, /* pc_relative */
84 complain_overflow_dont
, /* dont complain_on_overflow */
85 NULL
, /* special_function */
86 "ABSOLUTE", /* name */
87 false, /* partial_inplace */
90 false), /* pcrel_offset */
92 HOWTO (IMAGE_REL_MCORE_ADDR32
,/* type */
94 2, /* size (0 = byte, 1 = short, 2 = long) */
96 false, /* pc_relative */
98 complain_overflow_bitfield
, /* complain_on_overflow */
99 NULL
, /* special_function */
101 true, /* partial_inplace */
102 0xffffffff, /* src_mask */
103 0xffffffff, /* dst_mask */
104 false), /* pcrel_offset */
106 /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
107 Should not appear in object files. */
108 HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4
, /* type */
110 1, /* size (0 = byte, 1 = short, 2 = long) */
112 true, /* pc_relative */
114 complain_overflow_bitfield
, /* complain_on_overflow */
115 mcore_coff_unsupported_reloc
, /* special_function */
116 "IMM8BY4", /* name */
117 false, /* partial_inplace */
120 true), /* pcrel_offset */
122 /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
123 Span 2k instructions == 4k bytes.
124 Only useful pieces at the relocated address are the opcode (5 bits) */
125 HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2
,/* type */
127 1, /* size (0 = byte, 1 = short, 2 = long) */
129 true, /* pc_relative */
131 complain_overflow_signed
, /* complain_on_overflow */
132 NULL
, /* special_function */
133 "IMM11BY2", /* name */
134 false, /* partial_inplace */
136 0x7ff, /* dst_mask */
137 true), /* pcrel_offset */
139 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
140 HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2
, /* type */
142 1, /* size (0 = byte, 1 = short, 2 = long) */
144 true, /* pc_relative */
146 complain_overflow_bitfield
, /* complain_on_overflow */
147 mcore_coff_unsupported_reloc
, /* special_function */
148 "IMM4BY2", /* name */
149 false, /* partial_inplace */
152 true), /* pcrel_offset */
154 /* 32-bit pc-relative. Eventually this will help support PIC code. */
155 HOWTO (IMAGE_REL_MCORE_PCREL_32
,/* type */
157 2, /* size (0 = byte, 1 = short, 2 = long) */
159 true, /* pc_relative */
161 complain_overflow_bitfield
, /* complain_on_overflow */
162 NULL
, /* special_function */
163 "PCREL_32", /* name */
164 false, /* partial_inplace */
166 0xffffffff, /* dst_mask */
167 true), /* pcrel_offset */
169 /* Like PCREL_IMM11BY2, this relocation indicates that there is a
170 'jsri' at the specified address. There is a separate relocation
171 entry for the literal pool entry that it references, but we
172 might be able to change the jsri to a bsr if the target turns out
173 to be close enough [even though we won't reclaim the literal pool
174 entry, we'll get some runtime efficiency back]. Note that this
175 is a relocation that we are allowed to safely ignore. */
176 HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
,/* type */
178 1, /* size (0 = byte, 1 = short, 2 = long) */
180 true, /* pc_relative */
182 complain_overflow_signed
, /* complain_on_overflow */
183 NULL
, /* special_function */
184 "JSR_IMM11BY2", /* name */
185 false, /* partial_inplace */
187 0x7ff, /* dst_mask */
188 true), /* pcrel_offset */
190 HOWTO (IMAGE_REL_MCORE_RVA
, /* type */
192 2, /* size (0 = byte, 1 = short, 2 = long) */
194 false, /* pc_relative */
196 complain_overflow_signed
, /* complain_on_overflow */
197 NULL
, /* special_function */
198 "MCORE_RVA", /* name */
199 true, /* partial_inplace */
200 0xffffffff, /* src_mask */
201 0xffffffff, /* dst_mask */
202 true) /* pcrel_offset */
205 /* Extend the coff_link_hash_table structure with a few M*Core specific fields.
206 This allows us to store global data here without actually creating any
207 global variables, which is a no-no in the BFD world. */
208 typedef struct coff_mcore_link_hash_table
210 /* The original coff_link_hash_table structure. MUST be first field. */
211 struct coff_link_hash_table root
;
213 bfd
* bfd_of_toc_owner
;
214 long int global_toc_size
;
215 long int import_table_size
;
216 long int first_thunk_address
;
221 /* Get the MCore coff linker hash table from a link_info structure. */
222 #define coff_mcore_hash_table(info) \
223 ((mcore_hash_table *) ((info)->hash))
225 /* Create an MCore coff linker hash table. */
226 static struct bfd_link_hash_table
*
227 coff_mcore_link_hash_table_create (abfd
)
230 mcore_hash_table
* ret
;
232 ret
= ((mcore_hash_table
*) bfd_alloc (abfd
, sizeof (* ret
)));
233 if (ret
== (mcore_hash_table
*) NULL
)
236 if (! _bfd_coff_link_hash_table_init
237 (& ret
->root
, abfd
, _bfd_coff_link_hash_newfunc
))
239 bfd_release (abfd
, ret
);
240 return (struct bfd_link_hash_table
*) NULL
;
243 ret
->bfd_of_toc_owner
= NULL
;
244 ret
->global_toc_size
= 0;
245 ret
->import_table_size
= 0;
246 ret
->first_thunk_address
= 0;
249 return & ret
->root
.root
;
253 static bfd_reloc_status_type
254 mcore_coff_unsupported_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
255 output_bfd
, error_message
)
257 arelent
* reloc_entry
;
260 asection
* input_section
;
262 char ** error_message
;
264 BFD_ASSERT (reloc_entry
->howto
!= (reloc_howto_type
*)0);
266 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
267 bfd_get_filename (abfd
),
268 reloc_entry
->howto
->name
,
269 reloc_entry
->howto
->type
);
271 return bfd_reloc_notsupported
;
275 /* A cheesy little macro to make the code a little more readable. */
276 #define HOW2MAP(bfd_rtype, mcore_rtype) \
277 case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
279 static reloc_howto_type
*
280 mcore_coff_reloc_type_lookup (abfd
, code
)
282 bfd_reloc_code_real_type code
;
286 HOW2MAP (BFD_RELOC_32
, IMAGE_REL_MCORE_ADDR32
);
287 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4
, IMAGE_REL_MCORE_PCREL_IMM8BY4
);
288 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2
, IMAGE_REL_MCORE_PCREL_IMM11BY2
);
289 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2
, IMAGE_REL_MCORE_PCREL_IMM4BY2
);
290 HOW2MAP (BFD_RELOC_32_PCREL
, IMAGE_REL_MCORE_PCREL_32
);
291 HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2
, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
);
292 HOW2MAP (BFD_RELOC_RVA
, IMAGE_REL_MCORE_RVA
);
301 #define RTYPE2HOWTO(cache_ptr, dst) \
302 (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
304 static reloc_howto_type
*
305 coff_mcore_rtype_to_howto (abfd
, sec
, rel
, h
, sym
, addendp
)
308 struct internal_reloc
* rel
;
309 struct coff_link_hash_entry
* h
;
310 struct internal_syment
* sym
;
313 reloc_howto_type
* howto
;
316 if (rel
->r_type
>= NUM_ELEM (mcore_coff_howto_table
))
319 howto
= mcore_coff_howto_table
+ rel
->r_type
;
321 if (rel
->r_type
== IMAGE_REL_MCORE_RVA
)
322 * addendp
-= pe_data (sec
->output_section
->owner
)->pe_opthdr
.ImageBase
;
324 if (howto
->pc_relative
)
326 * addendp
= sec
->vma
- 2; /* XXX guess - is this right ? */
328 /* If the symbol is defined, then the generic code is going to
329 add back the symbol value in order to cancel out an
330 adjustment it made to the addend. However, we set the addend
331 to 0 at the start of this function. We need to adjust here,
332 to avoid the adjustment the generic code will make. FIXME:
333 This is getting a bit hackish. */
334 if (sym
!= NULL
&& sym
->n_scnum
!= 0)
335 * addendp
-= sym
->n_value
;
343 /* The reloc processing routine for the optimized COFF linker. */
345 coff_mcore_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
346 contents
, relocs
, syms
, sections
)
348 struct bfd_link_info
* info
;
350 asection
* input_section
;
352 struct internal_reloc
* relocs
;
353 struct internal_syment
* syms
;
354 asection
** sections
;
356 struct internal_reloc
* rel
;
357 struct internal_reloc
* relend
;
361 /* If we are performing a relocateable link, we don't need to do a
362 thing. The caller will take care of adjusting the reloc
363 addresses and symbol indices. */
364 if (info
->relocateable
)
367 /* Check if we have the same endianess */
368 if ( input_bfd
->xvec
->byteorder
!= output_bfd
->xvec
->byteorder
369 && output_bfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
371 (*_bfd_error_handler
)
372 (_("%s: compiled for a %s endian system and target is %s endian.\n"),
373 bfd_get_filename (input_bfd
),
374 bfd_big_endian (input_bfd
) ? "big" : "little",
375 bfd_big_endian (output_bfd
) ? "big" : "little");
377 bfd_set_error (bfd_error_wrong_format
);
385 relend
= rel
+ input_section
->reloc_count
;
387 for (; rel
< relend
; rel
++)
389 asection
* toc_section
= NULL
;
392 struct internal_syment
* sym
;
395 bfd_reloc_status_type rstat
;
397 unsigned short r_type
= rel
->r_type
;
398 reloc_howto_type
* howto
= NULL
;
399 struct coff_link_hash_entry
* h
;
400 const char * my_name
;
402 symndx
= rel
->r_symndx
;
403 loc
= contents
+ rel
->r_vaddr
- input_section
->vma
;
412 h
= obj_coff_sym_hashes (input_bfd
)[symndx
];
416 /* Get the howto and initialise the addend. */
417 howto
= bfd_coff_rtype_to_howto (input_bfd
, input_section
, rel
, h
,
430 asection
* sec
= sections
[symndx
];
433 + sec
->output_section
->vma
434 + sec
->output_offset
);
437 my_name
= "*unknown*";
438 else if ( sym
->_n
._n_n
._n_zeroes
== 0
439 && sym
->_n
._n_n
._n_offset
!= 0)
440 my_name
= obj_coff_strings (input_bfd
) + sym
->_n
._n_n
._n_offset
;
443 static char buf
[SYMNMLEN
+ 1];
445 strncpy (buf
, sym
->_n
._n_name
, SYMNMLEN
);
446 buf
[SYMNMLEN
] = '\0';
453 if ( h
->root
.type
== bfd_link_hash_defined
454 || h
->root
.type
== bfd_link_hash_defweak
)
456 asection
* sec
= h
->root
.u
.def
.section
;
458 val
= (h
->root
.u
.def
.value
459 + sec
->output_section
->vma
460 + sec
->output_offset
);
464 if (! ((*info
->callbacks
->undefined_symbol
)
465 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
466 rel
->r_vaddr
- input_section
->vma
)))
470 my_name
= h
->root
.root
.string
;
473 rstat
= bfd_reloc_ok
;
475 /* Each case must do its own relocation, setting rstat appropriately. */
479 _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
480 bfd_get_filename (input_bfd
), r_type
);
481 bfd_set_error (bfd_error_bad_value
);
484 case IMAGE_REL_MCORE_ABSOLUTE
:
486 _("Warning: unsupported reloc %s <file %s, section %s>\n"),
488 bfd_get_filename (input_bfd
),
489 input_section
->name
);
491 fprintf (stderr
,"sym %ld (%s), r_vaddr %ld (%lx)\n",
492 rel
->r_symndx
, my_name
, (long) rel
->r_vaddr
,
493 (unsigned long) rel
->r_vaddr
);
496 case IMAGE_REL_MCORE_PCREL_IMM8BY4
:
497 case IMAGE_REL_MCORE_PCREL_IMM11BY2
:
498 case IMAGE_REL_MCORE_PCREL_IMM4BY2
:
499 case IMAGE_REL_MCORE_PCREL_32
:
500 case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
:
501 case IMAGE_REL_MCORE_ADDR32
:
502 case IMAGE_REL_MCORE_RVA
:
503 rstat
= _bfd_relocate_contents (howto
, input_bfd
, val
, loc
);
515 case bfd_reloc_overflow
:
516 if (! ((*info
->callbacks
->reloc_overflow
)
517 (info
, my_name
, howto
->name
,
518 (bfd_vma
) 0, input_bfd
,
519 input_section
, rel
->r_vaddr
- input_section
->vma
)))
528 /* Tailor coffcode.h -- macro heaven. */
530 /* We use the special COFF backend linker, with our own special touch. */
532 #define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
533 #define coff_relocate_section coff_mcore_relocate_section
534 #define coff_rtype_to_howto coff_mcore_rtype_to_howto
536 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
538 #define COFF_PAGE_SIZE 0x1000
540 #include "coffcode.h"
542 static const bfd_target
*
546 #ifdef COFF_IMAGE_WITH_PE
547 /* We need to hack badly to handle a PE image correctly. In PE
548 images created by the GNU linker, the offset to the COFF header
549 is always the size. However, this is not the case in images
550 generated by other PE linkers. The PE format stores a four byte
551 offset to the PE signature just before the COFF header at
552 location 0x3c of the file. We pick up that offset, verify that
553 the PE signature is there, and then set ourselves up to read in
556 bfd_byte ext_offset
[4];
558 bfd_byte ext_signature
[4];
559 unsigned long signature
;
561 if (bfd_seek (abfd
, 0x3c, SEEK_SET
) != 0
562 || bfd_read (ext_offset
, 1, 4, abfd
) != 4)
564 if (bfd_get_error () != bfd_error_system_call
)
565 bfd_set_error (bfd_error_wrong_format
);
569 offset
= bfd_h_get_32 (abfd
, ext_offset
);
571 if (bfd_seek (abfd
, offset
, SEEK_SET
) != 0
572 || bfd_read (ext_signature
, 1, 4, abfd
) != 4)
574 if (bfd_get_error () != bfd_error_system_call
)
575 bfd_set_error (bfd_error_wrong_format
);
580 signature
= bfd_h_get_32 (abfd
, ext_signature
);
582 if (signature
!= 0x4550)
584 bfd_set_error (bfd_error_wrong_format
);
588 /* Here is the hack. coff_object_p wants to read filhsz bytes to
589 pick up the COFF header. We adjust so that that will work. 20
590 is the size of the mips COFF filehdr. */
591 if (bfd_seek (abfd
, (bfd_tell (abfd
) - bfd_coff_filhsz (abfd
) + 20),
594 if (bfd_get_error () != bfd_error_system_call
)
595 bfd_set_error (bfd_error_wrong_format
);
602 return coff_object_p (abfd
);
605 /* The transfer vectors that lead the outside world to all of the above. */
611 bfd_target_coff_flavour
,
612 BFD_ENDIAN_BIG
, /* data byte order is big */
613 BFD_ENDIAN_BIG
, /* header byte order is big */
615 (HAS_RELOC
| EXEC_P
| /* object flags */
616 HAS_LINENO
| HAS_DEBUG
|
617 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
619 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
620 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
622 0, /* leading char */
623 '/', /* ar_pad_char */
624 15, /* ar_max_namelen */
626 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
627 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
628 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
630 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
631 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
632 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
635 pe_object_p
, /* bfd_check_format */
636 bfd_generic_archive_p
, /* _bfd_dummy_target */
641 _bfd_generic_mkarchive
, /* bfd_set_format */
645 coff_write_object_contents
, /* bfd_write_contents */
646 _bfd_write_archive_contents
,
650 BFD_JUMP_TABLE_GENERIC (coff
),
651 BFD_JUMP_TABLE_COPY (coff
),
652 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
653 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
654 BFD_JUMP_TABLE_SYMBOLS (coff
),
655 BFD_JUMP_TABLE_RELOCS (coff
),
656 BFD_JUMP_TABLE_WRITE (coff
),
657 BFD_JUMP_TABLE_LINK (coff
),
658 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
667 bfd_target_coff_flavour
,
668 BFD_ENDIAN_LITTLE
, /* data byte order is little */
669 BFD_ENDIAN_LITTLE
, /* header byte order is little */
671 (HAS_RELOC
| EXEC_P
| /* object flags */
672 HAS_LINENO
| HAS_DEBUG
|
673 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
675 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
676 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
678 0, /* leading underscore */
679 '/', /* ar_pad_char */
680 15, /* ar_max_namelen */
682 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
683 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
684 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. */
693 pe_object_p
, /* bfd_check_format */
694 bfd_generic_archive_p
,
700 _bfd_generic_mkarchive
, /* bfd_set_format */
705 coff_write_object_contents
, /* bfd_write_contents */
706 _bfd_write_archive_contents
,
710 BFD_JUMP_TABLE_GENERIC (coff
),
711 BFD_JUMP_TABLE_COPY (coff
),
712 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
713 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
714 BFD_JUMP_TABLE_SYMBOLS (coff
),
715 BFD_JUMP_TABLE_RELOCS (coff
),
716 BFD_JUMP_TABLE_WRITE (coff
),
717 BFD_JUMP_TABLE_LINK (coff
),
718 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),