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