Add new field to bfd_target structure.
[deliverable/binutils-gdb.git] / bfd / coff-mcore.c
1 /* BFD back-end for Motorolla MCore COFF/PE
2 Copyright 1999 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
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.
10
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.
15
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. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "coff/mcore.h"
25 #include "coff/internal.h"
26 #include "coff/pe.h"
27 #include "libcoff.h"
28
29 #ifdef BADMAG
30 #undef BADMAG
31 #endif
32 #define BADMAG(x) MCOREBADMAG(x)
33
34 #ifndef NUM_ELEM
35 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
36 #endif
37
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 *));
42
43 static struct bfd_link_hash_table * coff_mcore_link_hash_table_create
44 PARAMS ((bfd *));
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
56 PARAMS ((bfd *));
57
58
59 \f
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"
65
66 /* The main body of code is in coffcode.h. */
67 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
68
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)
72
73 \f
74 static reloc_howto_type mcore_coff_howto_table[] =
75 {
76 /* Unused: */
77 HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */
78 0, /* rightshift */
79 0, /* size (0 = byte, 1 = short, 2 = long) */
80 0, /* bitsize */
81 false, /* pc_relative */
82 0, /* bitpos */
83 complain_overflow_dont, /* dont complain_on_overflow */
84 NULL, /* special_function */
85 "ABSOLUTE", /* name */
86 false, /* partial_inplace */
87 0x00, /* src_mask */
88 0x00, /* dst_mask */
89 false), /* pcrel_offset */
90
91 HOWTO (IMAGE_REL_MCORE_ADDR32,/* type */
92 0, /* rightshift */
93 2, /* size (0 = byte, 1 = short, 2 = long) */
94 32, /* bitsize */
95 false, /* pc_relative */
96 0, /* bitpos */
97 complain_overflow_bitfield, /* complain_on_overflow */
98 NULL, /* special_function */
99 "ADDR32", /* name */
100 true, /* partial_inplace */
101 0xffffffff, /* src_mask */
102 0xffffffff, /* dst_mask */
103 false), /* pcrel_offset */
104
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 */
108 2, /* rightshift */
109 1, /* size (0 = byte, 1 = short, 2 = long) */
110 8, /* bitsize */
111 true, /* pc_relative */
112 0, /* bitpos */
113 complain_overflow_bitfield, /* complain_on_overflow */
114 mcore_coff_unsupported_reloc, /* special_function */
115 "IMM8BY4", /* name */
116 false, /* partial_inplace */
117 0, /* src_mask */
118 0, /* dst_mask */
119 true), /* pcrel_offset */
120
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 */
125 1, /* rightshift */
126 1, /* size (0 = byte, 1 = short, 2 = long) */
127 11, /* bitsize */
128 true, /* pc_relative */
129 0, /* bitpos */
130 complain_overflow_signed, /* complain_on_overflow */
131 NULL, /* special_function */
132 "IMM11BY2", /* name */
133 false, /* partial_inplace */
134 0x0, /* src_mask */
135 0x7ff, /* dst_mask */
136 true), /* pcrel_offset */
137
138 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
139 HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2, /* type */
140 1, /* rightshift */
141 1, /* size (0 = byte, 1 = short, 2 = long) */
142 4, /* bitsize */
143 true, /* pc_relative */
144 0, /* bitpos */
145 complain_overflow_bitfield, /* complain_on_overflow */
146 mcore_coff_unsupported_reloc, /* special_function */
147 "IMM4BY2", /* name */
148 false, /* partial_inplace */
149 0, /* src_mask */
150 0, /* dst_mask */
151 true), /* pcrel_offset */
152
153 /* 32-bit pc-relative. Eventually this will help support PIC code. */
154 HOWTO (IMAGE_REL_MCORE_PCREL_32,/* type */
155 0, /* rightshift */
156 2, /* size (0 = byte, 1 = short, 2 = long) */
157 32, /* bitsize */
158 true, /* pc_relative */
159 0, /* bitpos */
160 complain_overflow_bitfield, /* complain_on_overflow */
161 NULL, /* special_function */
162 "PCREL_32", /* name */
163 false, /* partial_inplace */
164 0x0, /* src_mask */
165 0xffffffff, /* dst_mask */
166 true), /* pcrel_offset */
167
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 */
176 1, /* rightshift */
177 1, /* size (0 = byte, 1 = short, 2 = long) */
178 11, /* bitsize */
179 true, /* pc_relative */
180 0, /* bitpos */
181 complain_overflow_signed, /* complain_on_overflow */
182 NULL, /* special_function */
183 "JSR_IMM11BY2", /* name */
184 false, /* partial_inplace */
185 0x0, /* src_mask */
186 0x7ff, /* dst_mask */
187 true), /* pcrel_offset */
188
189 HOWTO (IMAGE_REL_MCORE_RVA, /* type */
190 0, /* rightshift */
191 2, /* size (0 = byte, 1 = short, 2 = long) */
192 32, /* bitsize */
193 false, /* pc_relative */
194 0, /* bitpos */
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 */
202 };
203 \f
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
208 {
209 /* The original coff_link_hash_table structure. MUST be first field. */
210 struct coff_link_hash_table root;
211
212 bfd * bfd_of_toc_owner;
213 long int global_toc_size;
214 long int import_table_size;
215 long int first_thunk_address;
216 long int thunk_size;
217 }
218 mcore_hash_table;
219
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))
223
224 /* Create an MCore coff linker hash table. */
225 static struct bfd_link_hash_table *
226 coff_mcore_link_hash_table_create (abfd)
227 bfd * abfd;
228 {
229 mcore_hash_table * ret;
230
231 ret = ((mcore_hash_table *) bfd_alloc (abfd, sizeof (* ret)));
232 if (ret == (mcore_hash_table *) NULL)
233 return NULL;
234
235 if (! _bfd_coff_link_hash_table_init
236 (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
237 {
238 bfd_release (abfd, ret);
239 return (struct bfd_link_hash_table *) NULL;
240 }
241
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;
246 ret->thunk_size = 0;
247
248 return & ret->root.root;
249 }
250 \f
251 /*ARGSUSED*/
252 static bfd_reloc_status_type
253 mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
254 output_bfd, error_message)
255 bfd * abfd;
256 arelent * reloc_entry;
257 asymbol * symbol ATTRIBUTE_UNUSED;
258 PTR data ATTRIBUTE_UNUSED;
259 asection * input_section ATTRIBUTE_UNUSED;
260 bfd * output_bfd ATTRIBUTE_UNUSED;
261 char ** error_message ATTRIBUTE_UNUSED;
262 {
263 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
264
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);
269
270 return bfd_reloc_notsupported;
271 }
272
273 \f
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]
277
278 static reloc_howto_type *
279 mcore_coff_reloc_type_lookup (abfd, code)
280 bfd * abfd ATTRIBUTE_UNUSED;
281 bfd_reloc_code_real_type code;
282 {
283 switch (code)
284 {
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);
292 default:
293 return NULL;
294 }
295 /*NOTREACHED*/
296 }
297
298 #undef HOW2MAP
299
300 #define RTYPE2HOWTO(cache_ptr, dst) \
301 (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
302
303 static reloc_howto_type *
304 coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
305 bfd * abfd ATTRIBUTE_UNUSED;
306 asection * sec;
307 struct internal_reloc * rel;
308 struct coff_link_hash_entry * h ATTRIBUTE_UNUSED;
309 struct internal_syment * sym;
310 bfd_vma * addendp;
311 {
312 reloc_howto_type * howto;
313
314
315 if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
316 return NULL;
317
318 howto = mcore_coff_howto_table + rel->r_type;
319
320 if (rel->r_type == IMAGE_REL_MCORE_RVA)
321 * addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
322
323 if (howto->pc_relative)
324 {
325 * addendp = sec->vma - 2; /* XXX guess - is this right ? */
326
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;
335 }
336 else
337 * addendp = 0;
338
339 return howto;
340 }
341
342 /* Return true if this relocation should appear in the output .reloc section.
343 This function is referenced in pe_mkobject in peicode.h. */
344 static boolean
345 in_reloc_p (abfd, howto)
346 bfd * abfd ATTRIBUTE_UNUSED;
347 reloc_howto_type * howto;
348 {
349 return ! howto->pc_relative && howto->type != IMAGE_REL_MCORE_RVA;
350 }
351
352 \f
353 /* The reloc processing routine for the optimized COFF linker. */
354 static boolean
355 coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section,
356 contents, relocs, syms, sections)
357 bfd * output_bfd;
358 struct bfd_link_info * info;
359 bfd * input_bfd;
360 asection * input_section;
361 bfd_byte * contents;
362 struct internal_reloc * relocs;
363 struct internal_syment * syms;
364 asection ** sections;
365 {
366 struct internal_reloc * rel;
367 struct internal_reloc * relend;
368 boolean hihalf;
369 bfd_vma hihalf_val;
370
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)
375 return true;
376
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)
380 {
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");
386
387 bfd_set_error (bfd_error_wrong_format);
388 return false;
389 }
390
391 hihalf = false;
392 hihalf_val = 0;
393
394 rel = relocs;
395 relend = rel + input_section->reloc_count;
396
397 for (; rel < relend; rel++)
398 {
399 long symndx;
400 struct internal_syment * sym;
401 bfd_vma val;
402 bfd_vma addend;
403 bfd_reloc_status_type rstat;
404 bfd_byte * loc;
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;
409
410 symndx = rel->r_symndx;
411 loc = contents + rel->r_vaddr - input_section->vma;
412
413 if (symndx == -1)
414 {
415 h = NULL;
416 sym = NULL;
417 }
418 else
419 {
420 h = obj_coff_sym_hashes (input_bfd)[symndx];
421 sym = syms + symndx;
422 }
423
424 /* Get the howto and initialise the addend. */
425 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
426 sym, & addend);
427 if (howto == NULL)
428 return false;
429
430 val = 0;
431
432 if (h == NULL)
433 {
434 if (symndx == -1)
435 my_name = "*ABS*";
436 else
437 {
438 asection * sec = sections[symndx];
439
440 val = (sym->n_value
441 + sec->output_section->vma
442 + sec->output_offset);
443
444 if (sym == NULL)
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;
449 else
450 {
451 static char buf [SYMNMLEN + 1];
452
453 strncpy (buf, sym->_n._n_name, SYMNMLEN);
454 buf[SYMNMLEN] = '\0';
455 my_name = buf;
456 }
457 }
458 }
459 else
460 {
461 if ( h->root.type == bfd_link_hash_defined
462 || h->root.type == bfd_link_hash_defweak)
463 {
464 asection * sec = h->root.u.def.section;
465
466 val = (h->root.u.def.value
467 + sec->output_section->vma
468 + sec->output_offset);
469 }
470 else
471 {
472 if (! ((*info->callbacks->undefined_symbol)
473 (info, h->root.root.string, input_bfd, input_section,
474 rel->r_vaddr - input_section->vma)))
475 return false;
476 }
477
478 my_name = h->root.root.string;
479 }
480
481 rstat = bfd_reloc_ok;
482
483 /* Each case must do its own relocation, setting rstat appropriately. */
484 switch (r_type)
485 {
486 default:
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);
490 return false;
491
492 case IMAGE_REL_MCORE_ABSOLUTE:
493 fprintf (stderr,
494 _("Warning: unsupported reloc %s <file %s, section %s>\n"),
495 howto->name,
496 bfd_get_filename (input_bfd),
497 input_section->name);
498
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);
502 break;
503
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);
512 break;
513 }
514
515 switch (rstat)
516 {
517 default:
518 abort ();
519
520 case bfd_reloc_ok:
521 break;
522
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)))
528 return false;
529 }
530 }
531
532 return true;
533 }
534
535 \f
536 /* Tailor coffcode.h -- macro heaven. */
537
538 /* We use the special COFF backend linker, with our own special touch. */
539
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
543
544 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
545
546 #define COFF_PAGE_SIZE 0x1000
547
548 #include "coffcode.h"
549 \f
550 static const bfd_target *
551 pe_object_p (abfd)
552 bfd * abfd;
553 {
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
562 the COFF header. */
563 {
564 bfd_byte ext_offset[4];
565 file_ptr offset;
566 bfd_byte ext_signature[4];
567 unsigned long signature;
568
569 if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
570 || bfd_read (ext_offset, 1, 4, abfd) != 4)
571 {
572 if (bfd_get_error () != bfd_error_system_call)
573 bfd_set_error (bfd_error_wrong_format);
574 return NULL;
575 }
576
577 offset = bfd_h_get_32 (abfd, ext_offset);
578
579 if (bfd_seek (abfd, offset, SEEK_SET) != 0
580 || bfd_read (ext_signature, 1, 4, abfd) != 4)
581 {
582 if (bfd_get_error () != bfd_error_system_call)
583 bfd_set_error (bfd_error_wrong_format);
584
585 return NULL;
586 }
587
588 signature = bfd_h_get_32 (abfd, ext_signature);
589
590 if (signature != 0x4550)
591 {
592 bfd_set_error (bfd_error_wrong_format);
593 return NULL;
594 }
595
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),
600 SEEK_SET) != 0)
601 {
602 if (bfd_get_error () != bfd_error_system_call)
603 bfd_set_error (bfd_error_wrong_format);
604
605 return NULL;
606 }
607 }
608 #endif
609
610 return coff_object_p (abfd);
611 }
612 \f
613 /* Forward declaration to initialise alterbative_target field. */
614 extern const bfd_target TARGET_LITTLE_SYM;
615
616 /* The transfer vectors that lead the outside world to all of the above. */
617 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, (SEC_LINK_ONCE | SEC_LINK_DUPLICATES), 0, & TARGET_LITTLE_SYM)
618 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, (SEC_LINK_ONCE | SEC_LINK_DUPLICATES), 0, & TARGET_BIG_SYM)
This page took 0.04378 seconds and 5 git commands to generate.