OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains3x.git] / bfd / elf32-mcore.c
1 /* Motorolla MCore specific support for 32-bit ELF
2    Copyright 1994, 1995, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 /* This file is based on a preliminary RCE ELF ABI.  The
21    information may not match the final RCE ELF ABI.   */
22
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>
30
31 #define USE_RELA        /* Only USE_REL is actually significant, but this is
32                            here are a reminder... */
33
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 **));
51
52 static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
53
54 static reloc_howto_type mcore_elf_howto_raw[] =
55 {
56   /* This reloc does nothing.  */
57   HOWTO (R_MCORE_NONE,          /* type */
58          0,                     /* rightshift */
59          2,                     /* size (0 = byte, 1 = short, 2 = long) */
60          1,                     /* bitsize */
61          true,                  /* pc_relative */
62          0,                     /* bitpos */
63          complain_overflow_bitfield,  /* complain_on_overflow */
64          mcore_elf_unsupported_reloc, /* special_function */
65          "R_MCORE_NONE",        /* name */
66          false,                 /* partial_inplace */
67          0,                     /* src_mask */
68          0,                     /* dst_mask */
69          true),                 /* pcrel_offset */
70
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 */
85
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 */
101
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 */
118
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 */
133
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 */
148
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 */
169   
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 */
184
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 */
199 };
200
201 #ifndef NUM_ELEM
202 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
203 #endif
204 \f
205 /* Initialize the mcore_elf_howto_table, so that linear accesses can be done.  */
206 static void
207 mcore_elf_howto_init ()
208 {
209   unsigned int i;
210
211   for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
212     {
213       unsigned int type;
214       
215       type = mcore_elf_howto_raw[i].type;
216       
217       BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
218       
219       mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
220     }
221 }
222
223 \f
224 static reloc_howto_type *
225 mcore_elf_reloc_type_lookup (abfd, code)
226      bfd * abfd;
227      bfd_reloc_code_real_type code;
228 {
229   enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
230
231   switch (code)
232     {
233     case BFD_RELOC_NONE:                     mcore_reloc = R_MCORE_NONE; break;
234     case BFD_RELOC_32:                       mcore_reloc = R_MCORE_ADDR32; break;
235     case BFD_RELOC_MCORE_PCREL_IMM8BY4:      mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
236     case BFD_RELOC_MCORE_PCREL_IMM11BY2:     mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
237     case BFD_RELOC_MCORE_PCREL_IMM4BY2:      mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
238     case BFD_RELOC_32_PCREL:                 mcore_reloc = R_MCORE_PCREL32; break;
239     case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
240     case BFD_RELOC_VTABLE_INHERIT:           mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
241     case BFD_RELOC_VTABLE_ENTRY:             mcore_reloc = R_MCORE_GNU_VTENTRY; break;
242     default:
243       return (reloc_howto_type *)NULL;
244     }
245
246   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
247     mcore_elf_howto_init ();
248
249   return mcore_elf_howto_table [(int) mcore_reloc];
250 };
251
252 /* Set the howto pointer for a RCE ELF reloc.  */
253 static void
254 mcore_elf_info_to_howto (abfd, cache_ptr, dst)
255      bfd * abfd;
256      arelent * cache_ptr;
257      Elf32_Internal_Rela * dst;
258 {
259   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
260     mcore_elf_howto_init ();
261
262   BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
263   
264   cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
265 }
266
267 /* Function to set whether a module needs the -mrelocatable bit set. */
268 static boolean
269 mcore_elf_set_private_flags (abfd, flags)
270      bfd * abfd;
271      flagword flags;
272 {
273   BFD_ASSERT (! elf_flags_init (abfd)
274               || elf_elfheader (abfd)->e_flags == flags);
275
276   elf_elfheader (abfd)->e_flags = flags;
277   elf_flags_init (abfd) = true;
278   return true;
279 }
280
281 /* Copy backend specific data from one object module to another.  */
282 static boolean
283 mcore_elf_copy_private_bfd_data (ibfd, obfd)
284      bfd * ibfd;
285      bfd * obfd;
286 {
287   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
288       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
289     return true;
290
291   BFD_ASSERT (! elf_flags_init (obfd)
292               || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
293
294   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
295   elf_flags_init (obfd) = true;
296   return true;
297 }
298
299 /* Merge backend specific data from an object file to the output
300    object file when linking.  */
301 static boolean
302 mcore_elf_merge_private_bfd_data (ibfd, obfd)
303      bfd * ibfd;
304      bfd * obfd;
305 {
306   flagword old_flags;
307   flagword new_flags;
308   boolean error;
309
310   /* Check if we have the same endianess */
311   if (   ibfd->xvec->byteorder != obfd->xvec->byteorder
312       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
313     {
314       (*_bfd_error_handler)
315         (_("%s: compiled for a %s endian system and target is %s endian.\n"),
316          bfd_get_filename (ibfd),
317          bfd_big_endian (ibfd) ? "big" : "little",
318          bfd_big_endian (obfd) ? "big" : "little");
319
320       bfd_set_error (bfd_error_wrong_format);
321       return false;
322     }
323
324   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
325       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
326     return true;
327
328   new_flags = elf_elfheader (ibfd)->e_flags;
329   old_flags = elf_elfheader (obfd)->e_flags;
330   
331   if (! elf_flags_init (obfd))  /* First call, no flags set */
332     {
333       elf_flags_init (obfd) = true;
334       elf_elfheader (obfd)->e_flags = new_flags;
335     }
336   else if (new_flags == old_flags)      /* Compatible flags are ok */
337     ;
338   
339   return true;
340 }
341
342 \f
343 /* Don't pretend we can deal with unsupported relocs.  */
344
345 /*ARGSUSED*/
346 static bfd_reloc_status_type
347 mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
348                            output_bfd, error_message)
349      bfd * abfd;
350      arelent * reloc_entry;
351      asymbol * symbol;
352      PTR data;
353      asection * input_section;
354      bfd * output_bfd;
355      char ** error_message;
356 {
357   BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
358   
359   _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
360                       bfd_get_filename (abfd),
361                       reloc_entry->howto->name,
362                       reloc_entry->howto->type);
363
364   return bfd_reloc_notsupported;
365 }
366
367 \f
368 /* The RELOCATE_SECTION function is called by the ELF backend linker
369    to handle the relocations for a section.
370
371    The relocs are always passed as Rela structures; if the section
372    actually uses Rel structures, the r_addend field will always be
373    zero.
374
375    This function is responsible for adjust the section contents as
376    necessary, and (if using Rela relocs and generating a
377    relocateable output file) adjusting the reloc addend as
378    necessary.
379
380    This function does not have to worry about setting the reloc
381    address or the reloc symbol index.
382
383    LOCAL_SYMS is a pointer to the swapped in local symbols.
384
385    LOCAL_SECTIONS is an array giving the section in the input file
386    corresponding to the st_shndx field of each local symbol.
387
388    The global hash table entry for the global symbols can be found
389    via elf_sym_hashes (input_bfd).
390
391    When generating relocateable output, this function must handle
392    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
393    going to be the section symbol corresponding to the output
394    section, which means that the addend must be adjusted
395    accordingly.  */
396
397 static boolean
398 mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
399                           contents, relocs, local_syms, local_sections)
400      bfd * output_bfd;
401      struct bfd_link_info * info;
402      bfd * input_bfd;
403      asection * input_section;
404      bfd_byte * contents;
405      Elf_Internal_Rela * relocs;
406      Elf_Internal_Sym * local_syms;
407      asection ** local_sections;
408 {
409   Elf_Internal_Shdr *           symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
410   struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
411   Elf_Internal_Rela *           rel = relocs;
412   Elf_Internal_Rela *           relend = relocs + input_section->reloc_count;
413   boolean ret = true;
414   long insn;
415
416 #ifdef DEBUG
417   fprintf (stderr,
418            "mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n",
419            bfd_get_filename (input_bfd),
420            bfd_section_name(input_bfd, input_section),
421            (long) input_section->reloc_count,
422            (info->relocateable) ? " (relocatable)" : "");
423 #endif
424
425   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
426     mcore_elf_howto_init ();
427
428   for (; rel < relend; rel++)
429     {
430       enum elf_mcore_reloc_type    r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
431       bfd_vma                      offset = rel->r_offset;
432       bfd_vma                      addend = rel->r_addend;
433       bfd_reloc_status_type        r = bfd_reloc_other;
434       asection *                   sec = (asection *) 0;
435       reloc_howto_type *           howto;
436       bfd_vma                      relocation;
437       Elf_Internal_Sym *           sym = (Elf_Internal_Sym *) 0;
438       unsigned long                r_symndx;
439       struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
440       unsigned short               oldinst;
441       
442       /* Unknown relocation handling */
443       if ((unsigned) r_type >= (unsigned) R_MCORE_max
444           || ! mcore_elf_howto_table [(int)r_type])
445         {
446           _bfd_error_handler (_("%s: Unknown relocation type %d\n"),
447                               bfd_get_filename (input_bfd),
448                               (int) r_type);
449
450           bfd_set_error (bfd_error_bad_value);
451           ret = false;
452           continue;
453         }
454       
455       howto = mcore_elf_howto_table [(int) r_type];
456       r_symndx = ELF32_R_SYM (rel->r_info);
457       
458       if (info->relocateable)
459         {
460           /* This is a relocateable link.  We don't have to change
461              anything, unless the reloc is against a section symbol,
462              in which case we have to adjust according to where the
463              section symbol winds up in the output section.  */
464           if (r_symndx < symtab_hdr->sh_info)
465             {
466               sym = local_syms + r_symndx;
467               
468               if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
469                 {
470                   sec = local_sections[r_symndx];
471                   addend = rel->r_addend += sec->output_offset + sym->st_value;
472                 }
473             }
474
475 #ifdef DEBUG
476           fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
477                    howto->name, (int) r_type, r_symndx, (long) offset, (long) addend);
478 #endif
479           continue;
480         }
481
482       /* This is a final link.  */
483
484       /* Complain about known relocation that are not yet supported */
485       if (howto->special_function == mcore_elf_unsupported_reloc)
486         {
487           _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
488                               bfd_get_filename (input_bfd),
489                               howto->name,
490                               (int)r_type);
491
492           bfd_set_error (bfd_error_bad_value);
493           ret = false;
494           continue;
495         }
496
497       if (r_symndx < symtab_hdr->sh_info)
498         {
499           sym = local_syms + r_symndx;
500           sec = local_sections [r_symndx];
501           relocation = (sec->output_section->vma
502                         + sec->output_offset
503                         + sym->st_value);
504         }
505       else
506         {
507           h = sym_hashes [r_symndx - symtab_hdr->sh_info];
508           if (   h->root.type == bfd_link_hash_defined
509               || h->root.type == bfd_link_hash_defweak)
510             {
511               sec = h->root.u.def.section;
512               relocation = (h->root.u.def.value
513                             + sec->output_section->vma
514                             + sec->output_offset);
515             }
516           else if (h->root.type == bfd_link_hash_undefweak)
517             relocation = 0;
518           else if (info->shared)
519             relocation = 0;
520           else
521             {
522               if (! ((*info->callbacks->undefined_symbol)
523                         (info, h->root.root.string, input_bfd,
524                          input_section, rel->r_offset)))
525                 return false;
526
527               ret = false;
528               continue;
529             }
530         }
531
532       switch (r_type)
533         {
534         default:
535         case R_MCORE_PCRELIMM8BY4:      
536         case R_MCORE_PCRELIMM11BY2:
537         case R_MCORE_PCRELIMM4BY2:
538           break;
539
540         case R_MCORE_PCRELJSR_IMM11BY2:
541           oldinst = bfd_get_16 (input_bfd, contents + offset);
542 #define MCORE_INST_BSR  0xF800
543           bfd_put_16 (input_bfd, MCORE_INST_BSR, contents + offset);
544           break;
545         }
546
547
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
552
553       r = _bfd_final_link_relocate
554         (howto, input_bfd, input_section, contents, offset, relocation, addend);
555
556       if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
557         {
558           /* Wasn't ok, back it out and give up.  */
559           bfd_put_16 (input_bfd, oldinst, contents + offset);
560           r = bfd_reloc_ok;
561         }
562       
563       if (r != bfd_reloc_ok)
564         {
565           ret = false;
566           
567           switch (r)
568             {
569             default:
570               break;
571
572             case bfd_reloc_overflow:
573               {
574                 const char * name;
575
576                 if (h != NULL)
577                   name = h->root.root.string;
578                 else
579                   {
580                     name = bfd_elf_string_from_elf_section
581                       (input_bfd, symtab_hdr->sh_link, sym->st_name);
582                     
583                     if (name == NULL)
584                       break;
585
586                     if (* name == '\0')
587                       name = bfd_section_name (input_bfd, sec);
588                   }
589
590                 (*info->callbacks->reloc_overflow)
591                   (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section,
592                    offset);
593               }
594               break;
595             }
596         }
597     }
598
599 #ifdef DEBUG
600   fprintf (stderr, "\n");
601 #endif
602
603   return ret;
604 }
605 \f
606 /* Return the section that should be marked against GC for a given
607    relocation.  */
608
609 static asection *
610 mcore_elf_gc_mark_hook (abfd, info, rel, h, sym)
611      bfd *                        abfd;
612      struct bfd_link_info *       info;
613      Elf_Internal_Rela *          rel;
614      struct elf_link_hash_entry * h;
615      Elf_Internal_Sym *           sym;
616 {
617   if (h != NULL)
618     {
619       switch (ELF32_R_TYPE (rel->r_info))
620         {
621         case R_MCORE_GNU_VTINHERIT:
622         case R_MCORE_GNU_VTENTRY:
623           break;
624
625         default:
626           switch (h->root.type)
627             {
628             case bfd_link_hash_defined:
629             case bfd_link_hash_defweak:
630               return h->root.u.def.section;
631               
632             case bfd_link_hash_common:
633               return h->root.u.c.p->section;
634             }
635         }
636     }
637   else
638     {
639       if (!(elf_bad_symtab (abfd)
640             && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
641           && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
642                 && sym->st_shndx != SHN_COMMON))
643         {
644           return bfd_section_from_elf_index (abfd, sym->st_shndx);
645         }
646     }
647
648   return NULL;
649 }
650
651 /* Update the got entry reference counts for the section being removed.  */
652
653 static boolean
654 mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
655      bfd *                     abfd;
656      struct bfd_link_info *    info;
657      asection *                sec;
658      const Elf_Internal_Rela * relocs;
659 {
660   return true;
661 }
662
663 /* Look through the relocs for a section during the first phase.
664    Since we don't do .gots or .plts, we just need to consider the
665    virtual table relocs for gc.  */
666  
667 static boolean
668 mcore_elf_check_relocs (abfd, info, sec, relocs)
669      bfd * abfd;
670      struct bfd_link_info * info;
671      asection * sec;
672      const Elf_Internal_Rela * relocs;
673 {
674   Elf_Internal_Shdr *           symtab_hdr;
675   struct elf_link_hash_entry ** sym_hashes;
676   struct elf_link_hash_entry ** sym_hashes_end;
677   const Elf_Internal_Rela *     rel;
678   const Elf_Internal_Rela *     rel_end;
679  
680   if (info->relocateable)
681     return true;
682  
683   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
684   sym_hashes = elf_sym_hashes (abfd);
685   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
686   if (!elf_bad_symtab (abfd))
687     sym_hashes_end -= symtab_hdr->sh_info;
688  
689   rel_end = relocs + sec->reloc_count;
690   
691   for (rel = relocs; rel < rel_end; rel++)
692     {
693       struct elf_link_hash_entry * h;
694       unsigned long r_symndx;
695  
696       r_symndx = ELF32_R_SYM (rel->r_info);
697       
698       if (r_symndx < symtab_hdr->sh_info)
699         h = NULL;
700       else
701         h = sym_hashes [r_symndx - symtab_hdr->sh_info];
702  
703       switch (ELF32_R_TYPE (rel->r_info))
704         {
705         /* This relocation describes the C++ object vtable hierarchy.
706            Reconstruct it for later use during GC.  */
707         case R_MCORE_GNU_VTINHERIT:
708           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
709             return false;
710           break;
711           
712         /* This relocation describes which C++ vtable entries are actually
713            used.  Record for later use during GC.  */
714         case R_MCORE_GNU_VTENTRY:
715           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
716             return false;
717           break;
718         }
719     }
720  
721   return true;
722 }
723
724 #define TARGET_BIG_SYM          bfd_elf32_mcore_big_vec
725 #define TARGET_BIG_NAME         "elf32-mcore-big"
726 #define TARGET_LITTLE_SYM       bfd_elf32_mcore_little_vec
727 #define TARGET_LITTLE_NAME      "elf32-mcore-little"
728
729 #define ELF_ARCH                bfd_arch_mcore
730 #define ELF_MACHINE_CODE        EM_MCORE
731 #define ELF_MAXPAGESIZE         0x1000          /* 4k, if we ever have 'em */
732 #define elf_info_to_howto       mcore_elf_info_to_howto
733 #define elf_info_to_howto_rel   NULL
734
735
736 #define bfd_elf32_bfd_copy_private_bfd_data     mcore_elf_copy_private_bfd_data
737 #define bfd_elf32_bfd_merge_private_bfd_data    mcore_elf_merge_private_bfd_data
738 #define bfd_elf32_bfd_set_private_flags         mcore_elf_set_private_flags
739 #define bfd_elf32_bfd_reloc_type_lookup         mcore_elf_reloc_type_lookup
740 #define elf_backend_relocate_section            mcore_elf_relocate_section
741 #define elf_backend_gc_mark_hook                mcore_elf_gc_mark_hook
742 #define elf_backend_gc_sweep_hook               mcore_elf_gc_sweep_hook
743 #define elf_backend_check_relocs                mcore_elf_check_relocs
744
745 #define elf_backend_can_gc_sections             1
746
747 #include "elf32-target.h"