OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-mcore.c] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.