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