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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [elf32-mcore.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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