OSDN Git Service

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