OSDN Git Service

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