1 /* BFD back-end for Motorolla MCore COFF/PE
2 Copyright 1999 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
24 #include "coff/mcore.h"
25 #include "coff/internal.h"
32 #define BADMAG(x) MCOREBADMAG(x)
35 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
38 /* This file is compiled more than once, but we only compile the
39 final_link routine once. */
40 extern boolean mcore_bfd_coff_final_link
41 PARAMS ((bfd
*, struct bfd_link_info
*));
43 static struct bfd_link_hash_table
* coff_mcore_link_hash_table_create
45 static bfd_reloc_status_type mcore_coff_unsupported_reloc
46 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
47 static boolean coff_mcore_relocate_section
48 PARAMS ((bfd
*, struct bfd_link_info
*, bfd
*, asection
*, bfd_byte
*,
49 struct internal_reloc
*, struct internal_syment
*, asection
**));
50 static reloc_howto_type
* mcore_coff_reloc_type_lookup
51 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
52 static reloc_howto_type
* coff_mcore_rtype_to_howto
53 PARAMS ((bfd
*, asection
*, struct internal_reloc
*,
54 struct coff_link_hash_entry
*, struct internal_syment
*, bfd_vma
*));
55 static const bfd_target
* pe_object_p
60 /* The NT loader points the toc register to &toc + 32768, in order to
61 use the complete range of a 16-bit displacement. We have to adjust
62 for this when we fix up loads displaced off the toc reg. */
63 #define TOC_LOAD_ADJUSTMENT (-32768)
64 #define TOC_SECTION_NAME ".private.toc"
66 /* The main body of code is in coffcode.h. */
67 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
69 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
70 from smaller values. Start with zero, widen, *then* decrement. */
71 #define MINUS_ONE (((bfd_vma)0) - 1)
74 static reloc_howto_type mcore_coff_howto_table
[] =
77 HOWTO (IMAGE_REL_MCORE_ABSOLUTE
,/* type */
79 0, /* size (0 = byte, 1 = short, 2 = long) */
81 false, /* pc_relative */
83 complain_overflow_dont
, /* dont complain_on_overflow */
84 NULL
, /* special_function */
85 "ABSOLUTE", /* name */
86 false, /* partial_inplace */
89 false), /* pcrel_offset */
91 HOWTO (IMAGE_REL_MCORE_ADDR32
,/* type */
93 2, /* size (0 = byte, 1 = short, 2 = long) */
95 false, /* pc_relative */
97 complain_overflow_bitfield
, /* complain_on_overflow */
98 NULL
, /* special_function */
100 true, /* partial_inplace */
101 0xffffffff, /* src_mask */
102 0xffffffff, /* dst_mask */
103 false), /* pcrel_offset */
105 /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
106 Should not appear in object files. */
107 HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4
, /* type */
109 1, /* size (0 = byte, 1 = short, 2 = long) */
111 true, /* pc_relative */
113 complain_overflow_bitfield
, /* complain_on_overflow */
114 mcore_coff_unsupported_reloc
, /* special_function */
115 "IMM8BY4", /* name */
116 false, /* partial_inplace */
119 true), /* pcrel_offset */
121 /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
122 Span 2k instructions == 4k bytes.
123 Only useful pieces at the relocated address are the opcode (5 bits) */
124 HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2
,/* type */
126 1, /* size (0 = byte, 1 = short, 2 = long) */
128 true, /* pc_relative */
130 complain_overflow_signed
, /* complain_on_overflow */
131 NULL
, /* special_function */
132 "IMM11BY2", /* name */
133 false, /* partial_inplace */
135 0x7ff, /* dst_mask */
136 true), /* pcrel_offset */
138 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
139 HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2
, /* type */
141 1, /* size (0 = byte, 1 = short, 2 = long) */
143 true, /* pc_relative */
145 complain_overflow_bitfield
, /* complain_on_overflow */
146 mcore_coff_unsupported_reloc
, /* special_function */
147 "IMM4BY2", /* name */
148 false, /* partial_inplace */
151 true), /* pcrel_offset */
153 /* 32-bit pc-relative. Eventually this will help support PIC code. */
154 HOWTO (IMAGE_REL_MCORE_PCREL_32
,/* type */
156 2, /* size (0 = byte, 1 = short, 2 = long) */
158 true, /* pc_relative */
160 complain_overflow_bitfield
, /* complain_on_overflow */
161 NULL
, /* special_function */
162 "PCREL_32", /* name */
163 false, /* partial_inplace */
165 0xffffffff, /* dst_mask */
166 true), /* pcrel_offset */
168 /* Like PCREL_IMM11BY2, this relocation indicates that there is a
169 'jsri' at the specified address. There is a separate relocation
170 entry for the literal pool entry that it references, but we
171 might be able to change the jsri to a bsr if the target turns out
172 to be close enough [even though we won't reclaim the literal pool
173 entry, we'll get some runtime efficiency back]. Note that this
174 is a relocation that we are allowed to safely ignore. */
175 HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
,/* type */
177 1, /* size (0 = byte, 1 = short, 2 = long) */
179 true, /* pc_relative */
181 complain_overflow_signed
, /* complain_on_overflow */
182 NULL
, /* special_function */
183 "JSR_IMM11BY2", /* name */
184 false, /* partial_inplace */
186 0x7ff, /* dst_mask */
187 true), /* pcrel_offset */
189 HOWTO (IMAGE_REL_MCORE_RVA
, /* type */
191 2, /* size (0 = byte, 1 = short, 2 = long) */
193 false, /* pc_relative */
195 complain_overflow_signed
, /* complain_on_overflow */
196 NULL
, /* special_function */
197 "MCORE_RVA", /* name */
198 true, /* partial_inplace */
199 0xffffffff, /* src_mask */
200 0xffffffff, /* dst_mask */
201 true) /* pcrel_offset */
204 /* Extend the coff_link_hash_table structure with a few M*Core specific fields.
205 This allows us to store global data here without actually creating any
206 global variables, which is a no-no in the BFD world. */
207 typedef struct coff_mcore_link_hash_table
209 /* The original coff_link_hash_table structure. MUST be first field. */
210 struct coff_link_hash_table root
;
212 bfd
* bfd_of_toc_owner
;
213 long int global_toc_size
;
214 long int import_table_size
;
215 long int first_thunk_address
;
220 /* Get the MCore coff linker hash table from a link_info structure. */
221 #define coff_mcore_hash_table(info) \
222 ((mcore_hash_table *) ((info)->hash))
224 /* Create an MCore coff linker hash table. */
225 static struct bfd_link_hash_table
*
226 coff_mcore_link_hash_table_create (abfd
)
229 mcore_hash_table
* ret
;
231 ret
= ((mcore_hash_table
*) bfd_alloc (abfd
, sizeof (* ret
)));
232 if (ret
== (mcore_hash_table
*) NULL
)
235 if (! _bfd_coff_link_hash_table_init
236 (& ret
->root
, abfd
, _bfd_coff_link_hash_newfunc
))
238 bfd_release (abfd
, ret
);
239 return (struct bfd_link_hash_table
*) NULL
;
242 ret
->bfd_of_toc_owner
= NULL
;
243 ret
->global_toc_size
= 0;
244 ret
->import_table_size
= 0;
245 ret
->first_thunk_address
= 0;
248 return & ret
->root
.root
;
252 static bfd_reloc_status_type
253 mcore_coff_unsupported_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
254 output_bfd
, error_message
)
256 arelent
* reloc_entry
;
259 asection
* input_section
;
261 char ** error_message
;
263 BFD_ASSERT (reloc_entry
->howto
!= (reloc_howto_type
*)0);
265 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
266 bfd_get_filename (abfd
),
267 reloc_entry
->howto
->name
,
268 reloc_entry
->howto
->type
);
270 return bfd_reloc_notsupported
;
274 /* A cheesy little macro to make the code a little more readable. */
275 #define HOW2MAP(bfd_rtype, mcore_rtype) \
276 case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
278 static reloc_howto_type
*
279 mcore_coff_reloc_type_lookup (abfd
, code
)
281 bfd_reloc_code_real_type code
;
285 HOW2MAP (BFD_RELOC_32
, IMAGE_REL_MCORE_ADDR32
);
286 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4
, IMAGE_REL_MCORE_PCREL_IMM8BY4
);
287 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2
, IMAGE_REL_MCORE_PCREL_IMM11BY2
);
288 HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2
, IMAGE_REL_MCORE_PCREL_IMM4BY2
);
289 HOW2MAP (BFD_RELOC_32_PCREL
, IMAGE_REL_MCORE_PCREL_32
);
290 HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2
, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
);
291 HOW2MAP (BFD_RELOC_RVA
, IMAGE_REL_MCORE_RVA
);
300 #define RTYPE2HOWTO(cache_ptr, dst) \
301 (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
303 static reloc_howto_type
*
304 coff_mcore_rtype_to_howto (abfd
, sec
, rel
, h
, sym
, addendp
)
307 struct internal_reloc
* rel
;
308 struct coff_link_hash_entry
* h
;
309 struct internal_syment
* sym
;
312 reloc_howto_type
* howto
;
315 if (rel
->r_type
>= NUM_ELEM (mcore_coff_howto_table
))
318 howto
= mcore_coff_howto_table
+ rel
->r_type
;
320 if (rel
->r_type
== IMAGE_REL_MCORE_RVA
)
321 * addendp
-= pe_data (sec
->output_section
->owner
)->pe_opthdr
.ImageBase
;
323 if (howto
->pc_relative
)
325 * addendp
= sec
->vma
- 2; /* XXX guess - is this right ? */
327 /* If the symbol is defined, then the generic code is going to
328 add back the symbol value in order to cancel out an
329 adjustment it made to the addend. However, we set the addend
330 to 0 at the start of this function. We need to adjust here,
331 to avoid the adjustment the generic code will make. FIXME:
332 This is getting a bit hackish. */
333 if (sym
!= NULL
&& sym
->n_scnum
!= 0)
334 * addendp
-= sym
->n_value
;
342 /* Return true if this relocation should appear in the output .reloc section.
343 This function is referenced in pe_mkobject in peicode.h. */
345 in_reloc_p (abfd
, howto
)
347 reloc_howto_type
* howto
;
349 return ! howto
->pc_relative
&& howto
->type
!= IMAGE_REL_MCORE_RVA
;
353 /* The reloc processing routine for the optimized COFF linker. */
355 coff_mcore_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
356 contents
, relocs
, syms
, sections
)
358 struct bfd_link_info
* info
;
360 asection
* input_section
;
362 struct internal_reloc
* relocs
;
363 struct internal_syment
* syms
;
364 asection
** sections
;
366 struct internal_reloc
* rel
;
367 struct internal_reloc
* relend
;
371 /* If we are performing a relocateable link, we don't need to do a
372 thing. The caller will take care of adjusting the reloc
373 addresses and symbol indices. */
374 if (info
->relocateable
)
377 /* Check if we have the same endianess */
378 if ( input_bfd
->xvec
->byteorder
!= output_bfd
->xvec
->byteorder
379 && output_bfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
381 (*_bfd_error_handler
)
382 (_("%s: compiled for a %s endian system and target is %s endian.\n"),
383 bfd_get_filename (input_bfd
),
384 bfd_big_endian (input_bfd
) ? "big" : "little",
385 bfd_big_endian (output_bfd
) ? "big" : "little");
387 bfd_set_error (bfd_error_wrong_format
);
395 relend
= rel
+ input_section
->reloc_count
;
397 for (; rel
< relend
; rel
++)
400 struct internal_syment
* sym
;
403 bfd_reloc_status_type rstat
;
405 unsigned short r_type
= rel
->r_type
;
406 reloc_howto_type
* howto
= NULL
;
407 struct coff_link_hash_entry
* h
;
408 const char * my_name
;
410 symndx
= rel
->r_symndx
;
411 loc
= contents
+ rel
->r_vaddr
- input_section
->vma
;
420 h
= obj_coff_sym_hashes (input_bfd
)[symndx
];
424 /* Get the howto and initialise the addend. */
425 howto
= bfd_coff_rtype_to_howto (input_bfd
, input_section
, rel
, h
,
438 asection
* sec
= sections
[symndx
];
441 + sec
->output_section
->vma
442 + sec
->output_offset
);
445 my_name
= "*unknown*";
446 else if ( sym
->_n
._n_n
._n_zeroes
== 0
447 && sym
->_n
._n_n
._n_offset
!= 0)
448 my_name
= obj_coff_strings (input_bfd
) + sym
->_n
._n_n
._n_offset
;
451 static char buf
[SYMNMLEN
+ 1];
453 strncpy (buf
, sym
->_n
._n_name
, SYMNMLEN
);
454 buf
[SYMNMLEN
] = '\0';
461 if ( h
->root
.type
== bfd_link_hash_defined
462 || h
->root
.type
== bfd_link_hash_defweak
)
464 asection
* sec
= h
->root
.u
.def
.section
;
466 val
= (h
->root
.u
.def
.value
467 + sec
->output_section
->vma
468 + sec
->output_offset
);
472 if (! ((*info
->callbacks
->undefined_symbol
)
473 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
474 rel
->r_vaddr
- input_section
->vma
)))
478 my_name
= h
->root
.root
.string
;
481 rstat
= bfd_reloc_ok
;
483 /* Each case must do its own relocation, setting rstat appropriately. */
487 _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
488 bfd_get_filename (input_bfd
), r_type
);
489 bfd_set_error (bfd_error_bad_value
);
492 case IMAGE_REL_MCORE_ABSOLUTE
:
494 _("Warning: unsupported reloc %s <file %s, section %s>\n"),
496 bfd_get_filename (input_bfd
),
497 input_section
->name
);
499 fprintf (stderr
,"sym %ld (%s), r_vaddr %ld (%lx)\n",
500 rel
->r_symndx
, my_name
, (long) rel
->r_vaddr
,
501 (unsigned long) rel
->r_vaddr
);
504 case IMAGE_REL_MCORE_PCREL_IMM8BY4
:
505 case IMAGE_REL_MCORE_PCREL_IMM11BY2
:
506 case IMAGE_REL_MCORE_PCREL_IMM4BY2
:
507 case IMAGE_REL_MCORE_PCREL_32
:
508 case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
:
509 case IMAGE_REL_MCORE_ADDR32
:
510 case IMAGE_REL_MCORE_RVA
:
511 rstat
= _bfd_relocate_contents (howto
, input_bfd
, val
, loc
);
523 case bfd_reloc_overflow
:
524 if (! ((*info
->callbacks
->reloc_overflow
)
525 (info
, my_name
, howto
->name
,
526 (bfd_vma
) 0, input_bfd
,
527 input_section
, rel
->r_vaddr
- input_section
->vma
)))
536 /* Tailor coffcode.h -- macro heaven. */
538 /* We use the special COFF backend linker, with our own special touch. */
540 #define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
541 #define coff_relocate_section coff_mcore_relocate_section
542 #define coff_rtype_to_howto coff_mcore_rtype_to_howto
544 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
546 #define COFF_PAGE_SIZE 0x1000
548 #include "coffcode.h"
550 static const bfd_target
*
554 #ifdef COFF_IMAGE_WITH_PE
555 /* We need to hack badly to handle a PE image correctly. In PE
556 images created by the GNU linker, the offset to the COFF header
557 is always the size. However, this is not the case in images
558 generated by other PE linkers. The PE format stores a four byte
559 offset to the PE signature just before the COFF header at
560 location 0x3c of the file. We pick up that offset, verify that
561 the PE signature is there, and then set ourselves up to read in
564 bfd_byte ext_offset
[4];
566 bfd_byte ext_signature
[4];
567 unsigned long signature
;
569 if (bfd_seek (abfd
, 0x3c, SEEK_SET
) != 0
570 || bfd_read (ext_offset
, 1, 4, abfd
) != 4)
572 if (bfd_get_error () != bfd_error_system_call
)
573 bfd_set_error (bfd_error_wrong_format
);
577 offset
= bfd_h_get_32 (abfd
, ext_offset
);
579 if (bfd_seek (abfd
, offset
, SEEK_SET
) != 0
580 || bfd_read (ext_signature
, 1, 4, abfd
) != 4)
582 if (bfd_get_error () != bfd_error_system_call
)
583 bfd_set_error (bfd_error_wrong_format
);
588 signature
= bfd_h_get_32 (abfd
, ext_signature
);
590 if (signature
!= 0x4550)
592 bfd_set_error (bfd_error_wrong_format
);
596 /* Here is the hack. coff_object_p wants to read filhsz bytes to
597 pick up the COFF header. We adjust so that that will work. 20
598 is the size of the mips COFF filehdr. */
599 if (bfd_seek (abfd
, (bfd_tell (abfd
) - bfd_coff_filhsz (abfd
) + 20),
602 if (bfd_get_error () != bfd_error_system_call
)
603 bfd_set_error (bfd_error_wrong_format
);
610 return coff_object_p (abfd
);
613 /* The transfer vectors that lead the outside world to all of the above. */
619 bfd_target_coff_flavour
,
620 BFD_ENDIAN_BIG
, /* data byte order is big */
621 BFD_ENDIAN_BIG
, /* header byte order is big */
623 (HAS_RELOC
| EXEC_P
| /* object flags */
624 HAS_LINENO
| HAS_DEBUG
|
625 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
627 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
628 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
630 0, /* leading char */
631 '/', /* ar_pad_char */
632 15, /* ar_max_namelen */
634 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
635 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
636 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
638 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
639 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
640 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
643 pe_object_p
, /* bfd_check_format */
644 bfd_generic_archive_p
, /* _bfd_dummy_target */
649 _bfd_generic_mkarchive
, /* bfd_set_format */
653 coff_write_object_contents
, /* bfd_write_contents */
654 _bfd_write_archive_contents
,
658 BFD_JUMP_TABLE_GENERIC (coff
),
659 BFD_JUMP_TABLE_COPY (coff
),
660 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
661 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
662 BFD_JUMP_TABLE_SYMBOLS (coff
),
663 BFD_JUMP_TABLE_RELOCS (coff
),
664 BFD_JUMP_TABLE_WRITE (coff
),
665 BFD_JUMP_TABLE_LINK (coff
),
666 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
675 bfd_target_coff_flavour
,
676 BFD_ENDIAN_LITTLE
, /* data byte order is little */
677 BFD_ENDIAN_LITTLE
, /* header byte order is little */
679 (HAS_RELOC
| EXEC_P
| /* object flags */
680 HAS_LINENO
| HAS_DEBUG
|
681 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
683 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
684 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
686 0, /* leading underscore */
687 '/', /* ar_pad_char */
688 15, /* ar_max_namelen */
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 */
694 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
695 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
696 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* hdrs */
698 /* Note that we allow an object file to be treated as a core file as well. */
701 pe_object_p
, /* bfd_check_format */
702 bfd_generic_archive_p
,
708 _bfd_generic_mkarchive
, /* bfd_set_format */
713 coff_write_object_contents
, /* bfd_write_contents */
714 _bfd_write_archive_contents
,
718 BFD_JUMP_TABLE_GENERIC (coff
),
719 BFD_JUMP_TABLE_COPY (coff
),
720 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
721 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
722 BFD_JUMP_TABLE_SYMBOLS (coff
),
723 BFD_JUMP_TABLE_RELOCS (coff
),
724 BFD_JUMP_TABLE_WRITE (coff
),
725 BFD_JUMP_TABLE_LINK (coff
),
726 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),