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 /* Return true if this relocation should appear in the output .reloc section.
344 This function is referenced in pe_mkobject in peicode.h. */
346 in_reloc_p (abfd
, howto
)
348 reloc_howto_type
* howto
;
350 return ! howto
->pc_relative
&& howto
->type
!= IMAGE_REL_MCORE_RVA
;
354 /* The reloc processing routine for the optimized COFF linker. */
356 coff_mcore_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
357 contents
, relocs
, syms
, sections
)
359 struct bfd_link_info
* info
;
361 asection
* input_section
;
363 struct internal_reloc
* relocs
;
364 struct internal_syment
* syms
;
365 asection
** sections
;
367 struct internal_reloc
* rel
;
368 struct internal_reloc
* relend
;
372 /* If we are performing a relocateable link, we don't need to do a
373 thing. The caller will take care of adjusting the reloc
374 addresses and symbol indices. */
375 if (info
->relocateable
)
378 /* Check if we have the same endianess */
379 if ( input_bfd
->xvec
->byteorder
!= output_bfd
->xvec
->byteorder
380 && output_bfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
382 (*_bfd_error_handler
)
383 (_("%s: compiled for a %s endian system and target is %s endian.\n"),
384 bfd_get_filename (input_bfd
),
385 bfd_big_endian (input_bfd
) ? "big" : "little",
386 bfd_big_endian (output_bfd
) ? "big" : "little");
388 bfd_set_error (bfd_error_wrong_format
);
396 relend
= rel
+ input_section
->reloc_count
;
398 for (; rel
< relend
; rel
++)
400 asection
* toc_section
= NULL
;
403 struct internal_syment
* sym
;
406 bfd_reloc_status_type rstat
;
408 unsigned short r_type
= rel
->r_type
;
409 reloc_howto_type
* howto
= NULL
;
410 struct coff_link_hash_entry
* h
;
411 const char * my_name
;
413 symndx
= rel
->r_symndx
;
414 loc
= contents
+ rel
->r_vaddr
- input_section
->vma
;
423 h
= obj_coff_sym_hashes (input_bfd
)[symndx
];
427 /* Get the howto and initialise the addend. */
428 howto
= bfd_coff_rtype_to_howto (input_bfd
, input_section
, rel
, h
,
441 asection
* sec
= sections
[symndx
];
444 + sec
->output_section
->vma
445 + sec
->output_offset
);
448 my_name
= "*unknown*";
449 else if ( sym
->_n
._n_n
._n_zeroes
== 0
450 && sym
->_n
._n_n
._n_offset
!= 0)
451 my_name
= obj_coff_strings (input_bfd
) + sym
->_n
._n_n
._n_offset
;
454 static char buf
[SYMNMLEN
+ 1];
456 strncpy (buf
, sym
->_n
._n_name
, SYMNMLEN
);
457 buf
[SYMNMLEN
] = '\0';
464 if ( h
->root
.type
== bfd_link_hash_defined
465 || h
->root
.type
== bfd_link_hash_defweak
)
467 asection
* sec
= h
->root
.u
.def
.section
;
469 val
= (h
->root
.u
.def
.value
470 + sec
->output_section
->vma
471 + sec
->output_offset
);
475 if (! ((*info
->callbacks
->undefined_symbol
)
476 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
477 rel
->r_vaddr
- input_section
->vma
)))
481 my_name
= h
->root
.root
.string
;
484 rstat
= bfd_reloc_ok
;
486 /* Each case must do its own relocation, setting rstat appropriately. */
490 _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
491 bfd_get_filename (input_bfd
), r_type
);
492 bfd_set_error (bfd_error_bad_value
);
495 case IMAGE_REL_MCORE_ABSOLUTE
:
497 _("Warning: unsupported reloc %s <file %s, section %s>\n"),
499 bfd_get_filename (input_bfd
),
500 input_section
->name
);
502 fprintf (stderr
,"sym %ld (%s), r_vaddr %ld (%lx)\n",
503 rel
->r_symndx
, my_name
, (long) rel
->r_vaddr
,
504 (unsigned long) rel
->r_vaddr
);
507 case IMAGE_REL_MCORE_PCREL_IMM8BY4
:
508 case IMAGE_REL_MCORE_PCREL_IMM11BY2
:
509 case IMAGE_REL_MCORE_PCREL_IMM4BY2
:
510 case IMAGE_REL_MCORE_PCREL_32
:
511 case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2
:
512 case IMAGE_REL_MCORE_ADDR32
:
513 case IMAGE_REL_MCORE_RVA
:
514 rstat
= _bfd_relocate_contents (howto
, input_bfd
, val
, loc
);
526 case bfd_reloc_overflow
:
527 if (! ((*info
->callbacks
->reloc_overflow
)
528 (info
, my_name
, howto
->name
,
529 (bfd_vma
) 0, input_bfd
,
530 input_section
, rel
->r_vaddr
- input_section
->vma
)))
539 /* Tailor coffcode.h -- macro heaven. */
541 /* We use the special COFF backend linker, with our own special touch. */
543 #define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
544 #define coff_relocate_section coff_mcore_relocate_section
545 #define coff_rtype_to_howto coff_mcore_rtype_to_howto
547 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
549 #define COFF_PAGE_SIZE 0x1000
551 #include "coffcode.h"
553 static const bfd_target
*
557 #ifdef COFF_IMAGE_WITH_PE
558 /* We need to hack badly to handle a PE image correctly. In PE
559 images created by the GNU linker, the offset to the COFF header
560 is always the size. However, this is not the case in images
561 generated by other PE linkers. The PE format stores a four byte
562 offset to the PE signature just before the COFF header at
563 location 0x3c of the file. We pick up that offset, verify that
564 the PE signature is there, and then set ourselves up to read in
567 bfd_byte ext_offset
[4];
569 bfd_byte ext_signature
[4];
570 unsigned long signature
;
572 if (bfd_seek (abfd
, 0x3c, SEEK_SET
) != 0
573 || bfd_read (ext_offset
, 1, 4, abfd
) != 4)
575 if (bfd_get_error () != bfd_error_system_call
)
576 bfd_set_error (bfd_error_wrong_format
);
580 offset
= bfd_h_get_32 (abfd
, ext_offset
);
582 if (bfd_seek (abfd
, offset
, SEEK_SET
) != 0
583 || bfd_read (ext_signature
, 1, 4, abfd
) != 4)
585 if (bfd_get_error () != bfd_error_system_call
)
586 bfd_set_error (bfd_error_wrong_format
);
591 signature
= bfd_h_get_32 (abfd
, ext_signature
);
593 if (signature
!= 0x4550)
595 bfd_set_error (bfd_error_wrong_format
);
599 /* Here is the hack. coff_object_p wants to read filhsz bytes to
600 pick up the COFF header. We adjust so that that will work. 20
601 is the size of the mips COFF filehdr. */
602 if (bfd_seek (abfd
, (bfd_tell (abfd
) - bfd_coff_filhsz (abfd
) + 20),
605 if (bfd_get_error () != bfd_error_system_call
)
606 bfd_set_error (bfd_error_wrong_format
);
613 return coff_object_p (abfd
);
616 /* The transfer vectors that lead the outside world to all of the above. */
622 bfd_target_coff_flavour
,
623 BFD_ENDIAN_BIG
, /* data byte order is big */
624 BFD_ENDIAN_BIG
, /* header byte order is big */
626 (HAS_RELOC
| EXEC_P
| /* object flags */
627 HAS_LINENO
| HAS_DEBUG
|
628 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
630 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
631 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
633 0, /* leading char */
634 '/', /* ar_pad_char */
635 15, /* ar_max_namelen */
637 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
638 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
639 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
641 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
642 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
643 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
646 pe_object_p
, /* bfd_check_format */
647 bfd_generic_archive_p
, /* _bfd_dummy_target */
652 _bfd_generic_mkarchive
, /* bfd_set_format */
656 coff_write_object_contents
, /* bfd_write_contents */
657 _bfd_write_archive_contents
,
661 BFD_JUMP_TABLE_GENERIC (coff
),
662 BFD_JUMP_TABLE_COPY (coff
),
663 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
664 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
665 BFD_JUMP_TABLE_SYMBOLS (coff
),
666 BFD_JUMP_TABLE_RELOCS (coff
),
667 BFD_JUMP_TABLE_WRITE (coff
),
668 BFD_JUMP_TABLE_LINK (coff
),
669 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
678 bfd_target_coff_flavour
,
679 BFD_ENDIAN_LITTLE
, /* data byte order is little */
680 BFD_ENDIAN_LITTLE
, /* header byte order is little */
682 (HAS_RELOC
| EXEC_P
| /* object flags */
683 HAS_LINENO
| HAS_DEBUG
|
684 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
686 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
687 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
689 0, /* leading underscore */
690 '/', /* ar_pad_char */
691 15, /* ar_max_namelen */
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
, /* data */
697 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
698 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
699 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* hdrs */
701 /* Note that we allow an object file to be treated as a core file as well. */
704 pe_object_p
, /* bfd_check_format */
705 bfd_generic_archive_p
,
711 _bfd_generic_mkarchive
, /* bfd_set_format */
716 coff_write_object_contents
, /* bfd_write_contents */
717 _bfd_write_archive_contents
,
721 BFD_JUMP_TABLE_GENERIC (coff
),
722 BFD_JUMP_TABLE_COPY (coff
),
723 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
724 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
725 BFD_JUMP_TABLE_SYMBOLS (coff
),
726 BFD_JUMP_TABLE_RELOCS (coff
),
727 BFD_JUMP_TABLE_WRITE (coff
),
728 BFD_JUMP_TABLE_LINK (coff
),
729 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),