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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [elf32-mcore.c] - Blame information for rev 1776

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

Line No. Rev Author Line
1 578 markom
/* Motorola MCore specific support for 32-bit ELF
2
   Copyright 1994, 1995, 1999, 2000, 2001 Free Software Foundation, Inc.
3
 
4
This file is part of BFD, the Binary File Descriptor library.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
 
20
/* This file is based on a preliminary RCE ELF ABI.  The
21
   information may not match the final RCE ELF ABI.   */
22
 
23
#include "bfd.h"
24
#include "sysdep.h"
25
#include "bfdlink.h"
26
#include "libbfd.h"
27
#include "elf-bfd.h"
28
#include "elf/mcore.h"
29
#include <assert.h>
30
 
31
#define USE_RELA        /* Only USE_REL is actually significant, but this is
32
                           here are a reminder...  */
33
 
34
static void mcore_elf_howto_init
35
  PARAMS ((void));
36
static reloc_howto_type * mcore_elf_reloc_type_lookup
37
  PARAMS ((bfd *, bfd_reloc_code_real_type));
38
static void mcore_elf_info_to_howto
39
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
40
static boolean mcore_elf_set_private_flags
41
  PARAMS ((bfd *, flagword));
42
static boolean mcore_elf_copy_private_bfd_data
43
  PARAMS ((bfd *, bfd *));
44
static boolean mcore_elf_merge_private_bfd_data
45
  PARAMS ((bfd *, bfd *));
46
static bfd_reloc_status_type mcore_elf_unsupported_reloc
47
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
48
static boolean mcore_elf_relocate_section
49
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
50
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
51
 
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
 
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
static reloc_howto_type *
238
mcore_elf_reloc_type_lookup (abfd, code)
239
     bfd * abfd ATTRIBUTE_UNUSED;
240
     bfd_reloc_code_real_type code;
241
{
242
  enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
243
 
244
  switch (code)
245
    {
246
    case BFD_RELOC_NONE:                     mcore_reloc = R_MCORE_NONE; break;
247
    case BFD_RELOC_32:                       mcore_reloc = R_MCORE_ADDR32; break;
248
    case BFD_RELOC_MCORE_PCREL_IMM8BY4:      mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
249
    case BFD_RELOC_MCORE_PCREL_IMM11BY2:     mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
250
    case BFD_RELOC_MCORE_PCREL_IMM4BY2:      mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
251
    case BFD_RELOC_32_PCREL:                 mcore_reloc = R_MCORE_PCREL32; break;
252
    case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
253
    case BFD_RELOC_VTABLE_INHERIT:           mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
254
    case BFD_RELOC_VTABLE_ENTRY:             mcore_reloc = R_MCORE_GNU_VTENTRY; break;
255
    case BFD_RELOC_RVA:                      mcore_reloc = R_MCORE_RELATIVE; break;
256
    default:
257
      return (reloc_howto_type *)NULL;
258
    }
259
 
260
  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
261
    mcore_elf_howto_init ();
262
 
263
  return mcore_elf_howto_table [(int) mcore_reloc];
264
};
265
 
266
/* Set the howto pointer for a RCE ELF reloc.  */
267
static void
268
mcore_elf_info_to_howto (abfd, cache_ptr, dst)
269
     bfd * abfd ATTRIBUTE_UNUSED;
270
     arelent * cache_ptr;
271
     Elf32_Internal_Rela * dst;
272
{
273
  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
274
    mcore_elf_howto_init ();
275
 
276
  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
277
 
278
  cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
279
}
280
 
281
/* Function to set whether a module needs the -mrelocatable bit set.  */
282
static boolean
283
mcore_elf_set_private_flags (abfd, flags)
284
     bfd * abfd;
285
     flagword flags;
286
{
287
  BFD_ASSERT (! elf_flags_init (abfd)
288
              || elf_elfheader (abfd)->e_flags == flags);
289
 
290
  elf_elfheader (abfd)->e_flags = flags;
291
  elf_flags_init (abfd) = true;
292
  return true;
293
}
294
 
295
/* Copy backend specific data from one object module to another.  */
296
static boolean
297
mcore_elf_copy_private_bfd_data (ibfd, obfd)
298
     bfd * ibfd;
299
     bfd * obfd;
300
{
301
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
302
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
303
    return true;
304
 
305
  BFD_ASSERT (! elf_flags_init (obfd)
306
              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
307
 
308
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
309
  elf_flags_init (obfd) = true;
310
  return true;
311
}
312
 
313
/* Merge backend specific data from an object file to the output
314
   object file when linking.  */
315
static boolean
316
mcore_elf_merge_private_bfd_data (ibfd, obfd)
317
     bfd * ibfd;
318
     bfd * obfd;
319
{
320
  flagword old_flags;
321
  flagword new_flags;
322
 
323
  /* Check if we have the same endianess */
324
  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
325
    return false;
326
 
327
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
328
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
329
    return true;
330
 
331
  new_flags = elf_elfheader (ibfd)->e_flags;
332
  old_flags = elf_elfheader (obfd)->e_flags;
333
 
334
  if (! elf_flags_init (obfd))  /* First call, no flags set */
335
    {
336
      elf_flags_init (obfd) = true;
337
      elf_elfheader (obfd)->e_flags = new_flags;
338
    }
339
  else if (new_flags == old_flags)      /* Compatible flags are ok */
340
    ;
341
  else
342
    {
343
      /* FIXME */
344
    }
345
 
346
  return true;
347
}
348
 
349
/* Don't pretend we can deal with unsupported relocs.  */
350
 
351
static bfd_reloc_status_type
352
mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
353
                           output_bfd, error_message)
354
     bfd * abfd;
355
     arelent * reloc_entry;
356
     asymbol * symbol ATTRIBUTE_UNUSED;
357
     PTR data ATTRIBUTE_UNUSED;
358
     asection * input_section ATTRIBUTE_UNUSED;
359
     bfd * output_bfd ATTRIBUTE_UNUSED;
360
     char ** error_message ATTRIBUTE_UNUSED;
361
{
362
  BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
363
 
364
  _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
365
                      bfd_get_filename (abfd),
366
                      reloc_entry->howto->name,
367
                      reloc_entry->howto->type);
368
 
369
  return bfd_reloc_notsupported;
370
}
371
 
372
/* The RELOCATE_SECTION function is called by the ELF backend linker
373
   to handle the relocations for a section.
374
 
375
   The relocs are always passed as Rela structures; if the section
376
   actually uses Rel structures, the r_addend field will always be
377
   zero.
378
 
379
   This function is responsible for adjust the section contents as
380
   necessary, and (if using Rela relocs and generating a
381
   relocateable output file) adjusting the reloc addend as
382
   necessary.
383
 
384
   This function does not have to worry about setting the reloc
385
   address or the reloc symbol index.
386
 
387
   LOCAL_SYMS is a pointer to the swapped in local symbols.
388
 
389
   LOCAL_SECTIONS is an array giving the section in the input file
390
   corresponding to the st_shndx field of each local symbol.
391
 
392
   The global hash table entry for the global symbols can be found
393
   via elf_sym_hashes (input_bfd).
394
 
395
   When generating relocateable output, this function must handle
396
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
397
   going to be the section symbol corresponding to the output
398
   section, which means that the addend must be adjusted
399
   accordingly.  */
400
 
401
static boolean
402
mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
403
                          contents, relocs, local_syms, local_sections)
404
     bfd * output_bfd ATTRIBUTE_UNUSED;
405
     struct bfd_link_info * info;
406
     bfd * input_bfd;
407
     asection * input_section;
408
     bfd_byte * contents;
409
     Elf_Internal_Rela * relocs;
410
     Elf_Internal_Sym * local_syms;
411
     asection ** local_sections;
412
{
413
  Elf_Internal_Shdr *           symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
414
  struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
415
  Elf_Internal_Rela *           rel = relocs;
416
  Elf_Internal_Rela *           relend = relocs + input_section->reloc_count;
417
  boolean ret = true;
418
 
419
#ifdef DEBUG
420
  fprintf (stderr,
421
           "mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n",
422
           bfd_get_filename (input_bfd),
423
           bfd_section_name(input_bfd, input_section),
424
           (long) input_section->reloc_count,
425
           (info->relocateable) ? " (relocatable)" : "");
426
#endif
427
 
428
  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
429
    mcore_elf_howto_init ();
430
 
431
  for (; rel < relend; rel++)
432
    {
433
      enum elf_mcore_reloc_type    r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
434
      bfd_vma                      offset = rel->r_offset;
435
      bfd_vma                      addend = rel->r_addend;
436
      bfd_reloc_status_type        r = bfd_reloc_other;
437
      asection *                   sec = (asection *) 0;
438
      reloc_howto_type *           howto;
439
      bfd_vma                      relocation;
440
      Elf_Internal_Sym *           sym = (Elf_Internal_Sym *) 0;
441
      unsigned long                r_symndx;
442
      struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
443
      unsigned short               oldinst = 0;
444
 
445
      /* Unknown relocation handling */
446
      if ((unsigned) r_type >= (unsigned) R_MCORE_max
447
          || ! mcore_elf_howto_table [(int)r_type])
448
        {
449
          _bfd_error_handler (_("%s: Unknown relocation type %d\n"),
450
                              bfd_get_filename (input_bfd),
451
                              (int) r_type);
452
 
453
          bfd_set_error (bfd_error_bad_value);
454
          ret = false;
455
          continue;
456
        }
457
 
458
      howto = mcore_elf_howto_table [(int) r_type];
459
      r_symndx = ELF32_R_SYM (rel->r_info);
460
 
461
      if (info->relocateable)
462
        {
463
          /* This is a relocateable link.  We don't have to change
464
             anything, unless the reloc is against a section symbol,
465
             in which case we have to adjust according to where the
466
             section symbol winds up in the output section.  */
467
          if (r_symndx < symtab_hdr->sh_info)
468
            {
469
              sym = local_syms + r_symndx;
470
 
471
              if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
472
                {
473
                  sec = local_sections[r_symndx];
474
                  addend = rel->r_addend += sec->output_offset + sym->st_value;
475
                }
476
            }
477
 
478
#ifdef DEBUG
479
          fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
480
                   howto->name, (int) r_type, r_symndx, (long) offset, (long) addend);
481
#endif
482
          continue;
483
        }
484
 
485
      /* This is a final link.  */
486
 
487
      /* Complain about known relocation that are not yet supported.  */
488
      if (howto->special_function == mcore_elf_unsupported_reloc)
489
        {
490
          _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
491
                              bfd_get_filename (input_bfd),
492
                              howto->name,
493
                              (int)r_type);
494
 
495
          bfd_set_error (bfd_error_bad_value);
496
          ret = false;
497
          continue;
498
        }
499
 
500
      if (r_symndx < symtab_hdr->sh_info)
501
        {
502
          sym = local_syms + r_symndx;
503
          sec = local_sections [r_symndx];
504
          relocation = (sec->output_section->vma
505
                        + sec->output_offset
506
                        + sym->st_value);
507
        }
508
      else
509
        {
510
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
511
          if (   h->root.type == bfd_link_hash_defined
512
              || h->root.type == bfd_link_hash_defweak)
513
            {
514
              sec = h->root.u.def.section;
515
              relocation = (h->root.u.def.value
516
                            + sec->output_section->vma
517
                            + sec->output_offset);
518
            }
519
          else if (h->root.type == bfd_link_hash_undefweak)
520
            relocation = 0;
521
          else if (info->shared
522
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
523
            relocation = 0;
524
          else
525
            {
526
              if (! ((*info->callbacks->undefined_symbol)
527
                        (info, h->root.root.string, input_bfd,
528
                         input_section, rel->r_offset, true)))
529
                return false;
530
 
531
              ret = false;
532
              continue;
533
            }
534
        }
535
 
536
      switch (r_type)
537
        {
538
        default:
539
          break;
540
 
541
        case R_MCORE_PCRELJSR_IMM11BY2:
542
          oldinst = bfd_get_16 (input_bfd, contents + offset);
543
#define MCORE_INST_BSR  0xF800
544
          bfd_put_16 (input_bfd, MCORE_INST_BSR, contents + offset);
545
          break;
546
        }
547
 
548
#ifdef DEBUG
549
      fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
550
               howto->name, r_type, r_symndx, (long) offset, (long) addend);
551
#endif
552
 
553
      r = _bfd_final_link_relocate
554
        (howto, input_bfd, input_section, contents, offset, relocation, addend);
555
 
556
      if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
557
        {
558
          /* Wasn't ok, back it out and give up.  */
559
          bfd_put_16 (input_bfd, oldinst, contents + offset);
560
          r = bfd_reloc_ok;
561
        }
562
 
563
      if (r != bfd_reloc_ok)
564
        {
565
          ret = false;
566
 
567
          switch (r)
568
            {
569
            default:
570
              break;
571
 
572
            case bfd_reloc_overflow:
573
              {
574
                const char * name;
575
 
576
                if (h != NULL)
577
                  name = h->root.root.string;
578
                else
579
                  {
580
                    name = bfd_elf_string_from_elf_section
581
                      (input_bfd, symtab_hdr->sh_link, sym->st_name);
582
 
583
                    if (name == NULL)
584
                      break;
585
 
586
                    if (* name == '\0')
587
                      name = bfd_section_name (input_bfd, sec);
588
                  }
589
 
590
                (*info->callbacks->reloc_overflow)
591
                  (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section,
592
                   offset);
593
              }
594
              break;
595
            }
596
        }
597
    }
598
 
599
#ifdef DEBUG
600
  fprintf (stderr, "\n");
601
#endif
602
 
603
  return ret;
604
}
605
 
606
/* Return the section that should be marked against GC for a given
607
   relocation.  */
608
 
609
static asection *
610
mcore_elf_gc_mark_hook (abfd, info, rel, h, sym)
611
     bfd *                        abfd;
612
     struct bfd_link_info *       info ATTRIBUTE_UNUSED;
613
     Elf_Internal_Rela *          rel;
614
     struct elf_link_hash_entry * h;
615
     Elf_Internal_Sym *           sym;
616
{
617
  if (h != NULL)
618
    {
619
      switch (ELF32_R_TYPE (rel->r_info))
620
        {
621
        case R_MCORE_GNU_VTINHERIT:
622
        case R_MCORE_GNU_VTENTRY:
623
          break;
624
 
625
        default:
626
          switch (h->root.type)
627
            {
628
            case bfd_link_hash_defined:
629
            case bfd_link_hash_defweak:
630
              return h->root.u.def.section;
631
 
632
            case bfd_link_hash_common:
633
              return h->root.u.c.p->section;
634
 
635
            default:
636
              break;
637
            }
638
        }
639
    }
640
  else
641
    {
642
      if (!(elf_bad_symtab (abfd)
643
            && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
644
          && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
645
                && sym->st_shndx != SHN_COMMON))
646
        {
647
          return bfd_section_from_elf_index (abfd, sym->st_shndx);
648
        }
649
    }
650
 
651
  return NULL;
652
}
653
 
654
/* Update the got entry reference counts for the section being removed.  */
655
 
656
static boolean
657
mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
658
     bfd *                     abfd ATTRIBUTE_UNUSED;
659
     struct bfd_link_info *    info ATTRIBUTE_UNUSED;
660
     asection *                sec ATTRIBUTE_UNUSED;
661
     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
662
{
663
  return true;
664
}
665
 
666
/* Look through the relocs for a section during the first phase.
667
   Since we don't do .gots or .plts, we just need to consider the
668
   virtual table relocs for gc.  */
669
 
670
static boolean
671
mcore_elf_check_relocs (abfd, info, sec, relocs)
672
     bfd * abfd;
673
     struct bfd_link_info * info;
674
     asection * sec;
675
     const Elf_Internal_Rela * relocs;
676
{
677
  Elf_Internal_Shdr *           symtab_hdr;
678
  struct elf_link_hash_entry ** sym_hashes;
679
  struct elf_link_hash_entry ** sym_hashes_end;
680
  const Elf_Internal_Rela *     rel;
681
  const Elf_Internal_Rela *     rel_end;
682
 
683
  if (info->relocateable)
684
    return true;
685
 
686
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
687
  sym_hashes = elf_sym_hashes (abfd);
688
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
689
  if (!elf_bad_symtab (abfd))
690
    sym_hashes_end -= symtab_hdr->sh_info;
691
 
692
  rel_end = relocs + sec->reloc_count;
693
 
694
  for (rel = relocs; rel < rel_end; rel++)
695
    {
696
      struct elf_link_hash_entry * h;
697
      unsigned long r_symndx;
698
 
699
      r_symndx = ELF32_R_SYM (rel->r_info);
700
 
701
      if (r_symndx < symtab_hdr->sh_info)
702
        h = NULL;
703
      else
704
        h = sym_hashes [r_symndx - symtab_hdr->sh_info];
705
 
706
      switch (ELF32_R_TYPE (rel->r_info))
707
        {
708
        /* This relocation describes the C++ object vtable hierarchy.
709
           Reconstruct it for later use during GC.  */
710
        case R_MCORE_GNU_VTINHERIT:
711
          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
712
            return false;
713
          break;
714
 
715
        /* This relocation describes which C++ vtable entries are actually
716
           used.  Record for later use during GC.  */
717
        case R_MCORE_GNU_VTENTRY:
718
          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
719
            return false;
720
          break;
721
        }
722
    }
723
 
724
  return true;
725
}
726
 
727
#define TARGET_BIG_SYM          bfd_elf32_mcore_big_vec
728
#define TARGET_BIG_NAME         "elf32-mcore-big"
729
#define TARGET_LITTLE_SYM       bfd_elf32_mcore_little_vec
730
#define TARGET_LITTLE_NAME      "elf32-mcore-little"
731
 
732
#define ELF_ARCH                bfd_arch_mcore
733
#define ELF_MACHINE_CODE        EM_MCORE
734
#define ELF_MAXPAGESIZE         0x1000          /* 4k, if we ever have 'em */
735
#define elf_info_to_howto       mcore_elf_info_to_howto
736
#define elf_info_to_howto_rel   NULL
737
 
738
#define bfd_elf32_bfd_copy_private_bfd_data     mcore_elf_copy_private_bfd_data
739
#define bfd_elf32_bfd_merge_private_bfd_data    mcore_elf_merge_private_bfd_data
740
#define bfd_elf32_bfd_set_private_flags         mcore_elf_set_private_flags
741
#define bfd_elf32_bfd_reloc_type_lookup         mcore_elf_reloc_type_lookup
742
#define elf_backend_relocate_section            mcore_elf_relocate_section
743
#define elf_backend_gc_mark_hook                mcore_elf_gc_mark_hook
744
#define elf_backend_gc_sweep_hook               mcore_elf_gc_sweep_hook
745
#define elf_backend_check_relocs                mcore_elf_check_relocs
746
 
747
#define elf_backend_can_gc_sections             1
748
 
749
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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