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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [bfd/] [elf32-mcore.c] - Blame information for rev 298

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* Motorola MCore specific support for 32-bit ELF
2
   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3
   2007 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 endianess.  */
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
        {
471
          /* For relocs against symbols from removed linkonce sections,
472
             or sections discarded by a linker script, we just want the
473
             section contents zeroed.  Avoid any special processing.  */
474
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
475
          rel->r_info = 0;
476
          rel->r_addend = 0;
477
          continue;
478
        }
479
 
480
      if (info->relocatable)
481
        continue;
482
 
483
      switch (r_type)
484
        {
485
        default:
486
          break;
487
 
488
        case R_MCORE_PCRELJSR_IMM11BY2:
489
          oldinst = bfd_get_16 (input_bfd, contents + offset);
490
#define MCORE_INST_BSR  0xF800
491
          bfd_put_16 (input_bfd, (bfd_vma) MCORE_INST_BSR, contents + offset);
492
          break;
493
        }
494
 
495
#ifdef DEBUG
496
      fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
497
               howto->name, r_type, r_symndx, (long) offset, (long) addend);
498
#endif
499
 
500
      r = _bfd_final_link_relocate
501
        (howto, input_bfd, input_section, contents, offset, relocation, addend);
502
 
503
      if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
504
        {
505
          /* Wasn't ok, back it out and give up.  */
506
          bfd_put_16 (input_bfd, (bfd_vma) oldinst, contents + offset);
507
          r = bfd_reloc_ok;
508
        }
509
 
510
      if (r != bfd_reloc_ok)
511
        {
512
          ret = FALSE;
513
 
514
          switch (r)
515
            {
516
            default:
517
              break;
518
 
519
            case bfd_reloc_overflow:
520
              {
521
                const char * name;
522
 
523
                if (h != NULL)
524
                  name = NULL;
525
                else
526
                  {
527
                    name = bfd_elf_string_from_elf_section
528
                      (input_bfd, symtab_hdr->sh_link, sym->st_name);
529
 
530
                    if (name == NULL)
531
                      break;
532
 
533
                    if (* name == '\0')
534
                      name = bfd_section_name (input_bfd, sec);
535
                  }
536
 
537
                (*info->callbacks->reloc_overflow)
538
                  (info, (h ? &h->root : NULL), name, howto->name,
539
                   (bfd_vma) 0, input_bfd, input_section, offset);
540
              }
541
              break;
542
            }
543
        }
544
    }
545
 
546
#ifdef DEBUG
547
  fprintf (stderr, "\n");
548
#endif
549
 
550
  return ret;
551
}
552
 
553
/* Return the section that should be marked against GC for a given
554
   relocation.  */
555
 
556
static asection *
557
mcore_elf_gc_mark_hook (asection *sec,
558
                        struct bfd_link_info *info,
559
                        Elf_Internal_Rela *rel,
560
                        struct elf_link_hash_entry *h,
561
                        Elf_Internal_Sym *sym)
562
{
563
  if (h != NULL)
564
    switch (ELF32_R_TYPE (rel->r_info))
565
      {
566
      case R_MCORE_GNU_VTINHERIT:
567
      case R_MCORE_GNU_VTENTRY:
568
        return NULL;
569
      }
570
 
571
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
572
}
573
 
574
/* Update the got entry reference counts for the section being removed.  */
575
 
576
static bfd_boolean
577
mcore_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
578
                         struct bfd_link_info * info ATTRIBUTE_UNUSED,
579
                         asection * sec ATTRIBUTE_UNUSED,
580
                         const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
581
{
582
  return TRUE;
583
}
584
 
585
/* Look through the relocs for a section during the first phase.
586
   Since we don't do .gots or .plts, we just need to consider the
587
   virtual table relocs for gc.  */
588
 
589
static bfd_boolean
590
mcore_elf_check_relocs (bfd * abfd,
591
                        struct bfd_link_info * info,
592
                        asection * sec,
593
                        const Elf_Internal_Rela * relocs)
594
{
595
  Elf_Internal_Shdr * symtab_hdr;
596
  struct elf_link_hash_entry ** sym_hashes;
597
  const Elf_Internal_Rela * rel;
598
  const Elf_Internal_Rela * rel_end;
599
 
600
  if (info->relocatable)
601
    return TRUE;
602
 
603
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
604
  sym_hashes = elf_sym_hashes (abfd);
605
 
606
  rel_end = relocs + sec->reloc_count;
607
 
608
  for (rel = relocs; rel < rel_end; rel++)
609
    {
610
      struct elf_link_hash_entry * h;
611
      unsigned long r_symndx;
612
 
613
      r_symndx = ELF32_R_SYM (rel->r_info);
614
 
615
      if (r_symndx < symtab_hdr->sh_info)
616
        h = NULL;
617
      else
618
        {
619
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
620
          while (h->root.type == bfd_link_hash_indirect
621
                 || h->root.type == bfd_link_hash_warning)
622
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
623
        }
624
 
625
      switch (ELF32_R_TYPE (rel->r_info))
626
        {
627
        /* This relocation describes the C++ object vtable hierarchy.
628
           Reconstruct it for later use during GC.  */
629
        case R_MCORE_GNU_VTINHERIT:
630
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
631
            return FALSE;
632
          break;
633
 
634
        /* This relocation describes which C++ vtable entries are actually
635
           used.  Record for later use during GC.  */
636
        case R_MCORE_GNU_VTENTRY:
637
          BFD_ASSERT (h != NULL);
638
          if (h != NULL
639
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
640
            return FALSE;
641
          break;
642
        }
643
    }
644
 
645
  return TRUE;
646
}
647
 
648
static const struct bfd_elf_special_section mcore_elf_special_sections[]=
649
{
650
  { STRING_COMMA_LEN (".ctors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
651
  { STRING_COMMA_LEN (".dtors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
652
  { NULL,                     0,  0, 0,            0 }
653
};
654
 
655
#define TARGET_BIG_SYM          bfd_elf32_mcore_big_vec
656
#define TARGET_BIG_NAME         "elf32-mcore-big"
657
#define TARGET_LITTLE_SYM       bfd_elf32_mcore_little_vec
658
#define TARGET_LITTLE_NAME      "elf32-mcore-little"
659
 
660
#define ELF_ARCH                bfd_arch_mcore
661
#define ELF_MACHINE_CODE        EM_MCORE
662
#define ELF_MAXPAGESIZE         0x1000          /* 4k, if we ever have 'em */
663
#define elf_info_to_howto       mcore_elf_info_to_howto
664
#define elf_info_to_howto_rel   NULL
665
 
666
#define bfd_elf32_bfd_merge_private_bfd_data    mcore_elf_merge_private_bfd_data
667
#define bfd_elf32_bfd_set_private_flags         mcore_elf_set_private_flags
668
#define bfd_elf32_bfd_reloc_type_lookup         mcore_elf_reloc_type_lookup
669
#define bfd_elf32_bfd_reloc_name_lookup mcore_elf_reloc_name_lookup
670
#define elf_backend_relocate_section            mcore_elf_relocate_section
671
#define elf_backend_gc_mark_hook                mcore_elf_gc_mark_hook
672
#define elf_backend_gc_sweep_hook               mcore_elf_gc_sweep_hook
673
#define elf_backend_check_relocs                mcore_elf_check_relocs
674
#define elf_backend_special_sections            mcore_elf_special_sections
675
 
676
#define elf_backend_can_gc_sections             1
677
#define elf_backend_rela_normal                 1
678
 
679
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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