2001-02-17 Philip Blundell <philb@gnu.org>
[binutils.git] / bfd / elf32-mcore.c
blob051bd0d2074cfc0161eafb9d6b362375460b728e
1 /* Motorola MCore specific support for 32-bit ELF
2 Copyright 1994, 1995, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 /* This file is based on a preliminary RCE ELF ABI. The
21 information may not match the final RCE ELF ABI. */
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "elf-bfd.h"
28 #include "elf/mcore.h"
29 #include <assert.h>
31 #define USE_RELA /* Only USE_REL is actually significant, but this is
32 here are a reminder... */
34 static void mcore_elf_howto_init
35 PARAMS ((void));
36 static reloc_howto_type * mcore_elf_reloc_type_lookup
37 PARAMS ((bfd *, bfd_reloc_code_real_type));
38 static void mcore_elf_info_to_howto
39 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
40 static boolean mcore_elf_set_private_flags
41 PARAMS ((bfd *, flagword));
42 static boolean mcore_elf_copy_private_bfd_data
43 PARAMS ((bfd *, bfd *));
44 static boolean mcore_elf_merge_private_bfd_data
45 PARAMS ((bfd *, bfd *));
46 static bfd_reloc_status_type mcore_elf_unsupported_reloc
47 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
48 static boolean mcore_elf_relocate_section
49 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
50 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
52 static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
54 static reloc_howto_type mcore_elf_howto_raw[] =
56 /* This reloc does nothing. */
57 HOWTO (R_MCORE_NONE, /* type */
58 0, /* rightshift */
59 2, /* size (0 = byte, 1 = short, 2 = long) */
60 32, /* bitsize */
61 false, /* pc_relative */
62 0, /* bitpos */
63 complain_overflow_bitfield, /* complain_on_overflow */
64 NULL, /* special_function */
65 "R_MCORE_NONE", /* name */
66 false, /* partial_inplace */
67 0, /* src_mask */
68 0, /* dst_mask */
69 false), /* pcrel_offset */
71 /* A standard 32 bit relocation. */
72 HOWTO (R_MCORE_ADDR32, /* type */
73 0, /* rightshift */
74 2, /* size (0 = byte, 1 = short, 2 = long) */
75 32, /* bitsize */
76 false, /* pc_relative */
77 0, /* bitpos */
78 complain_overflow_bitfield, /* complain_on_overflow */
79 bfd_elf_generic_reloc, /* special_function */
80 "ADDR32", /* name *//* For compatability with coff/pe port. */
81 false, /* partial_inplace */
82 0x0, /* src_mask */
83 0xffffffff, /* dst_mask */
84 false), /* pcrel_offset */
86 /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
87 Should not appear in object files. */
88 HOWTO (R_MCORE_PCRELIMM8BY4, /* type */
89 2, /* rightshift */
90 1, /* size (0 = byte, 1 = short, 2 = long) */
91 8, /* bitsize */
92 true, /* pc_relative */
93 0, /* bitpos */
94 complain_overflow_bitfield, /* complain_on_overflow */
95 mcore_elf_unsupported_reloc, /* special_function */
96 "R_MCORE_PCRELIMM8BY4",/* name */
97 false, /* partial_inplace */
98 0, /* src_mask */
99 0, /* dst_mask */
100 true), /* pcrel_offset */
102 /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
103 Span 2k instructions == 4k bytes.
104 Only useful pieces at the relocated address are the opcode (5 bits) */
105 HOWTO (R_MCORE_PCRELIMM11BY2,/* type */
106 1, /* rightshift */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
108 11, /* bitsize */
109 true, /* pc_relative */
110 0, /* bitpos */
111 complain_overflow_signed, /* complain_on_overflow */
112 bfd_elf_generic_reloc, /* special_function */
113 "R_MCORE_PCRELIMM11BY2",/* name */
114 false, /* partial_inplace */
115 0x0, /* src_mask */
116 0x7ff, /* dst_mask */
117 true), /* pcrel_offset */
119 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
120 HOWTO (R_MCORE_PCRELIMM4BY2, /* type */
121 1, /* rightshift */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
123 4, /* bitsize */
124 true, /* pc_relative */
125 0, /* bitpos */
126 complain_overflow_bitfield, /* complain_on_overflow */
127 mcore_elf_unsupported_reloc,/* special_function */
128 "R_MCORE_PCRELIMM4BY2",/* name */
129 false, /* partial_inplace */
130 0, /* src_mask */
131 0, /* dst_mask */
132 true), /* pcrel_offset */
134 /* 32-bit pc-relative. Eventually this will help support PIC code. */
135 HOWTO (R_MCORE_PCREL32, /* type */
136 0, /* rightshift */
137 2, /* size (0 = byte, 1 = short, 2 = long) */
138 32, /* bitsize */
139 true, /* pc_relative */
140 0, /* bitpos */
141 complain_overflow_bitfield, /* complain_on_overflow */
142 bfd_elf_generic_reloc, /* special_function */
143 "R_MCORE_PCREL32", /* name */
144 false, /* partial_inplace */
145 0x0, /* src_mask */
146 0xffffffff, /* dst_mask */
147 true), /* pcrel_offset */
149 /* Like PCRELIMM11BY2, this relocation indicates that there is a
150 'jsri' at the specified address. There is a separate relocation
151 entry for the literal pool entry that it references, but we
152 might be able to change the jsri to a bsr if the target turns out
153 to be close enough [even though we won't reclaim the literal pool
154 entry, we'll get some runtime efficiency back]. Note that this
155 is a relocation that we are allowed to safely ignore. */
156 HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */
157 1, /* rightshift */
158 1, /* size (0 = byte, 1 = short, 2 = long) */
159 11, /* bitsize */
160 true, /* pc_relative */
161 0, /* bitpos */
162 complain_overflow_signed, /* complain_on_overflow */
163 bfd_elf_generic_reloc, /* special_function */
164 "R_MCORE_PCRELJSR_IMM11BY2", /* name */
165 false, /* partial_inplace */
166 0x0, /* src_mask */
167 0x7ff, /* dst_mask */
168 true), /* pcrel_offset */
170 /* GNU extension to record C++ vtable hierarchy */
171 HOWTO (R_MCORE_GNU_VTINHERIT, /* type */
172 0, /* rightshift */
173 2, /* size (0 = byte, 1 = short, 2 = long) */
174 0, /* bitsize */
175 false, /* pc_relative */
176 0, /* bitpos */
177 complain_overflow_dont, /* complain_on_overflow */
178 NULL, /* special_function */
179 "R_MCORE_GNU_VTINHERIT", /* name */
180 false, /* partial_inplace */
181 0, /* src_mask */
182 0, /* dst_mask */
183 false), /* pcrel_offset */
185 /* GNU extension to record C++ vtable member usage */
186 HOWTO (R_MCORE_GNU_VTENTRY, /* type */
187 0, /* rightshift */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
189 0, /* bitsize */
190 false, /* pc_relative */
191 0, /* bitpos */
192 complain_overflow_dont,/* complain_on_overflow */
193 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
194 "R_MCORE_GNU_VTENTRY", /* name */
195 false, /* partial_inplace */
196 0, /* src_mask */
197 0, /* dst_mask */
198 false), /* pcrel_offset */
200 HOWTO (R_MCORE_RELATIVE, /* type */
201 0, /* rightshift */
202 2, /* size (0 = byte, 1 = short, 2 = long) */
203 32, /* bitsize */
204 false, /* pc_relative */
205 0, /* bitpos */
206 complain_overflow_signed, /* complain_on_overflow */
207 NULL, /* special_function */
208 "R_MCORE_RELATIVE", /* name */
209 true, /* partial_inplace */
210 0xffffffff, /* src_mask */
211 0xffffffff, /* dst_mask */
212 false) /* pcrel_offset */
215 #ifndef NUM_ELEM
216 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
217 #endif
219 /* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */
220 static void
221 mcore_elf_howto_init ()
223 unsigned int i;
225 for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
227 unsigned int type;
229 type = mcore_elf_howto_raw[i].type;
231 BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
233 mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
237 static reloc_howto_type *
238 mcore_elf_reloc_type_lookup (abfd, code)
239 bfd * abfd ATTRIBUTE_UNUSED;
240 bfd_reloc_code_real_type code;
242 enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
244 switch (code)
246 case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break;
247 case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break;
248 case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
249 case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
250 case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
251 case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break;
252 case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
253 case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
254 case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break;
255 case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break;
256 default:
257 return (reloc_howto_type *)NULL;
260 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
261 mcore_elf_howto_init ();
263 return mcore_elf_howto_table [(int) mcore_reloc];
266 /* Set the howto pointer for a RCE ELF reloc. */
267 static void
268 mcore_elf_info_to_howto (abfd, cache_ptr, dst)
269 bfd * abfd ATTRIBUTE_UNUSED;
270 arelent * cache_ptr;
271 Elf32_Internal_Rela * dst;
273 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
274 mcore_elf_howto_init ();
276 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
278 cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
281 /* Function to set whether a module needs the -mrelocatable bit set. */
282 static boolean
283 mcore_elf_set_private_flags (abfd, flags)
284 bfd * abfd;
285 flagword flags;
287 BFD_ASSERT (! elf_flags_init (abfd)
288 || elf_elfheader (abfd)->e_flags == flags);
290 elf_elfheader (abfd)->e_flags = flags;
291 elf_flags_init (abfd) = true;
292 return true;
295 /* Copy backend specific data from one object module to another. */
296 static boolean
297 mcore_elf_copy_private_bfd_data (ibfd, obfd)
298 bfd * ibfd;
299 bfd * obfd;
301 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
302 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
303 return true;
305 BFD_ASSERT (! elf_flags_init (obfd)
306 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
308 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
309 elf_flags_init (obfd) = true;
310 return true;
313 /* Merge backend specific data from an object file to the output
314 object file when linking. */
315 static boolean
316 mcore_elf_merge_private_bfd_data (ibfd, obfd)
317 bfd * ibfd;
318 bfd * obfd;
320 flagword old_flags;
321 flagword new_flags;
323 /* Check if we have the same endianess */
324 if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
325 return false;
327 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
328 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
329 return true;
331 new_flags = elf_elfheader (ibfd)->e_flags;
332 old_flags = elf_elfheader (obfd)->e_flags;
334 if (! elf_flags_init (obfd)) /* First call, no flags set */
336 elf_flags_init (obfd) = true;
337 elf_elfheader (obfd)->e_flags = new_flags;
339 else if (new_flags == old_flags) /* Compatible flags are ok */
341 else
343 /* FIXME */
346 return true;
349 /* Don't pretend we can deal with unsupported relocs. */
351 static bfd_reloc_status_type
352 mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
353 output_bfd, error_message)
354 bfd * abfd;
355 arelent * reloc_entry;
356 asymbol * symbol ATTRIBUTE_UNUSED;
357 PTR data ATTRIBUTE_UNUSED;
358 asection * input_section ATTRIBUTE_UNUSED;
359 bfd * output_bfd ATTRIBUTE_UNUSED;
360 char ** error_message ATTRIBUTE_UNUSED;
362 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
364 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
365 bfd_get_filename (abfd),
366 reloc_entry->howto->name,
367 reloc_entry->howto->type);
369 return bfd_reloc_notsupported;
372 /* The RELOCATE_SECTION function is called by the ELF backend linker
373 to handle the relocations for a section.
375 The relocs are always passed as Rela structures; if the section
376 actually uses Rel structures, the r_addend field will always be
377 zero.
379 This function is responsible for adjust the section contents as
380 necessary, and (if using Rela relocs and generating a
381 relocateable output file) adjusting the reloc addend as
382 necessary.
384 This function does not have to worry about setting the reloc
385 address or the reloc symbol index.
387 LOCAL_SYMS is a pointer to the swapped in local symbols.
389 LOCAL_SECTIONS is an array giving the section in the input file
390 corresponding to the st_shndx field of each local symbol.
392 The global hash table entry for the global symbols can be found
393 via elf_sym_hashes (input_bfd).
395 When generating relocateable output, this function must handle
396 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
397 going to be the section symbol corresponding to the output
398 section, which means that the addend must be adjusted
399 accordingly. */
401 static boolean
402 mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
403 contents, relocs, local_syms, local_sections)
404 bfd * output_bfd ATTRIBUTE_UNUSED;
405 struct bfd_link_info * info;
406 bfd * input_bfd;
407 asection * input_section;
408 bfd_byte * contents;
409 Elf_Internal_Rela * relocs;
410 Elf_Internal_Sym * local_syms;
411 asection ** local_sections;
413 Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
414 struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
415 Elf_Internal_Rela * rel = relocs;
416 Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
417 boolean ret = true;
419 #ifdef DEBUG
420 fprintf (stderr,
421 "mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n",
422 bfd_get_filename (input_bfd),
423 bfd_section_name(input_bfd, input_section),
424 (long) input_section->reloc_count,
425 (info->relocateable) ? " (relocatable)" : "");
426 #endif
428 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
429 mcore_elf_howto_init ();
431 for (; rel < relend; rel++)
433 enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
434 bfd_vma offset = rel->r_offset;
435 bfd_vma addend = rel->r_addend;
436 bfd_reloc_status_type r = bfd_reloc_other;
437 asection * sec = (asection *) 0;
438 reloc_howto_type * howto;
439 bfd_vma relocation;
440 Elf_Internal_Sym * sym = (Elf_Internal_Sym *) 0;
441 unsigned long r_symndx;
442 struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
443 unsigned short oldinst = 0;
445 /* Unknown relocation handling */
446 if ((unsigned) r_type >= (unsigned) R_MCORE_max
447 || ! mcore_elf_howto_table [(int)r_type])
449 _bfd_error_handler (_("%s: Unknown relocation type %d\n"),
450 bfd_get_filename (input_bfd),
451 (int) r_type);
453 bfd_set_error (bfd_error_bad_value);
454 ret = false;
455 continue;
458 howto = mcore_elf_howto_table [(int) r_type];
459 r_symndx = ELF32_R_SYM (rel->r_info);
461 if (info->relocateable)
463 /* This is a relocateable link. We don't have to change
464 anything, unless the reloc is against a section symbol,
465 in which case we have to adjust according to where the
466 section symbol winds up in the output section. */
467 if (r_symndx < symtab_hdr->sh_info)
469 sym = local_syms + r_symndx;
471 if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
473 sec = local_sections[r_symndx];
474 addend = rel->r_addend += sec->output_offset + sym->st_value;
478 #ifdef DEBUG
479 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
480 howto->name, (int) r_type, r_symndx, (long) offset, (long) addend);
481 #endif
482 continue;
485 /* This is a final link. */
487 /* Complain about known relocation that are not yet supported. */
488 if (howto->special_function == mcore_elf_unsupported_reloc)
490 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
491 bfd_get_filename (input_bfd),
492 howto->name,
493 (int)r_type);
495 bfd_set_error (bfd_error_bad_value);
496 ret = false;
497 continue;
500 if (r_symndx < symtab_hdr->sh_info)
502 sym = local_syms + r_symndx;
503 sec = local_sections [r_symndx];
504 relocation = (sec->output_section->vma
505 + sec->output_offset
506 + sym->st_value);
508 else
510 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
511 if ( h->root.type == bfd_link_hash_defined
512 || h->root.type == bfd_link_hash_defweak)
514 sec = h->root.u.def.section;
515 relocation = (h->root.u.def.value
516 + sec->output_section->vma
517 + sec->output_offset);
519 else if (h->root.type == bfd_link_hash_undefweak)
520 relocation = 0;
521 else if (info->shared
522 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
523 relocation = 0;
524 else
526 if (! ((*info->callbacks->undefined_symbol)
527 (info, h->root.root.string, input_bfd,
528 input_section, rel->r_offset, true)))
529 return false;
531 ret = false;
532 continue;
536 switch (r_type)
538 default:
539 break;
541 case R_MCORE_PCRELJSR_IMM11BY2:
542 oldinst = bfd_get_16 (input_bfd, contents + offset);
543 #define MCORE_INST_BSR 0xF800
544 bfd_put_16 (input_bfd, MCORE_INST_BSR, contents + offset);
545 break;
548 #ifdef DEBUG
549 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
550 howto->name, r_type, r_symndx, (long) offset, (long) addend);
551 #endif
553 r = _bfd_final_link_relocate
554 (howto, input_bfd, input_section, contents, offset, relocation, addend);
556 if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
558 /* Wasn't ok, back it out and give up. */
559 bfd_put_16 (input_bfd, oldinst, contents + offset);
560 r = bfd_reloc_ok;
563 if (r != bfd_reloc_ok)
565 ret = false;
567 switch (r)
569 default:
570 break;
572 case bfd_reloc_overflow:
574 const char * name;
576 if (h != NULL)
577 name = h->root.root.string;
578 else
580 name = bfd_elf_string_from_elf_section
581 (input_bfd, symtab_hdr->sh_link, sym->st_name);
583 if (name == NULL)
584 break;
586 if (* name == '\0')
587 name = bfd_section_name (input_bfd, sec);
590 (*info->callbacks->reloc_overflow)
591 (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section,
592 offset);
594 break;
599 #ifdef DEBUG
600 fprintf (stderr, "\n");
601 #endif
603 return ret;
606 /* Return the section that should be marked against GC for a given
607 relocation. */
609 static asection *
610 mcore_elf_gc_mark_hook (abfd, info, rel, h, sym)
611 bfd * abfd;
612 struct bfd_link_info * info ATTRIBUTE_UNUSED;
613 Elf_Internal_Rela * rel;
614 struct elf_link_hash_entry * h;
615 Elf_Internal_Sym * sym;
617 if (h != NULL)
619 switch (ELF32_R_TYPE (rel->r_info))
621 case R_MCORE_GNU_VTINHERIT:
622 case R_MCORE_GNU_VTENTRY:
623 break;
625 default:
626 switch (h->root.type)
628 case bfd_link_hash_defined:
629 case bfd_link_hash_defweak:
630 return h->root.u.def.section;
632 case bfd_link_hash_common:
633 return h->root.u.c.p->section;
635 default:
636 break;
640 else
642 if (!(elf_bad_symtab (abfd)
643 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
644 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
645 && sym->st_shndx != SHN_COMMON))
647 return bfd_section_from_elf_index (abfd, sym->st_shndx);
651 return NULL;
654 /* Update the got entry reference counts for the section being removed. */
656 static boolean
657 mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
658 bfd * abfd ATTRIBUTE_UNUSED;
659 struct bfd_link_info * info ATTRIBUTE_UNUSED;
660 asection * sec ATTRIBUTE_UNUSED;
661 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
663 return true;
666 /* Look through the relocs for a section during the first phase.
667 Since we don't do .gots or .plts, we just need to consider the
668 virtual table relocs for gc. */
670 static boolean
671 mcore_elf_check_relocs (abfd, info, sec, relocs)
672 bfd * abfd;
673 struct bfd_link_info * info;
674 asection * sec;
675 const Elf_Internal_Rela * relocs;
677 Elf_Internal_Shdr * symtab_hdr;
678 struct elf_link_hash_entry ** sym_hashes;
679 struct elf_link_hash_entry ** sym_hashes_end;
680 const Elf_Internal_Rela * rel;
681 const Elf_Internal_Rela * rel_end;
683 if (info->relocateable)
684 return true;
686 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
687 sym_hashes = elf_sym_hashes (abfd);
688 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
689 if (!elf_bad_symtab (abfd))
690 sym_hashes_end -= symtab_hdr->sh_info;
692 rel_end = relocs + sec->reloc_count;
694 for (rel = relocs; rel < rel_end; rel++)
696 struct elf_link_hash_entry * h;
697 unsigned long r_symndx;
699 r_symndx = ELF32_R_SYM (rel->r_info);
701 if (r_symndx < symtab_hdr->sh_info)
702 h = NULL;
703 else
704 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
706 switch (ELF32_R_TYPE (rel->r_info))
708 /* This relocation describes the C++ object vtable hierarchy.
709 Reconstruct it for later use during GC. */
710 case R_MCORE_GNU_VTINHERIT:
711 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
712 return false;
713 break;
715 /* This relocation describes which C++ vtable entries are actually
716 used. Record for later use during GC. */
717 case R_MCORE_GNU_VTENTRY:
718 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
719 return false;
720 break;
724 return true;
727 #define TARGET_BIG_SYM bfd_elf32_mcore_big_vec
728 #define TARGET_BIG_NAME "elf32-mcore-big"
729 #define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec
730 #define TARGET_LITTLE_NAME "elf32-mcore-little"
732 #define ELF_ARCH bfd_arch_mcore
733 #define ELF_MACHINE_CODE EM_MCORE
734 #define ELF_MAXPAGESIZE 0x1000 /* 4k, if we ever have 'em */
735 #define elf_info_to_howto mcore_elf_info_to_howto
736 #define elf_info_to_howto_rel NULL
738 #define bfd_elf32_bfd_copy_private_bfd_data mcore_elf_copy_private_bfd_data
739 #define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data
740 #define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags
741 #define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup
742 #define elf_backend_relocate_section mcore_elf_relocate_section
743 #define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook
744 #define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook
745 #define elf_backend_check_relocs mcore_elf_check_relocs
747 #define elf_backend_can_gc_sections 1
749 #include "elf32-target.h"