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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [bfd/] [elf32-d10v.c] - Blame information for rev 1782

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

Line No. Rev Author Line
1 578 markom
/* D10V-specific support for 32-bit ELF
2
   Copyright 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
3
   Contributed by Martin Hunt (hunt@cygnus.com).
4
 
5
This file is part of BFD, the Binary File Descriptor library.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "bfd.h"
22
#include "sysdep.h"
23
#include "libbfd.h"
24
#include "elf-bfd.h"
25
#include "elf/d10v.h"
26
 
27
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
28
  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
29
static void d10v_info_to_howto_rel
30
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
31
 
32
/* Use REL instead of RELA to save space */
33
#define USE_REL
34
 
35
static reloc_howto_type elf_d10v_howto_table[] =
36
{
37
  /* This reloc does nothing.  */
38
  HOWTO (R_D10V_NONE,           /* type */
39
         0,                      /* rightshift */
40
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
41
         32,                    /* bitsize */
42
         false,                 /* pc_relative */
43
         0,                      /* bitpos */
44
         complain_overflow_bitfield, /* complain_on_overflow */
45
         bfd_elf_generic_reloc, /* special_function */
46
         "R_D10V_NONE",         /* name */
47
         false,                 /* partial_inplace */
48
         0,                      /* src_mask */
49
         0,                      /* dst_mask */
50
         false),                /* pcrel_offset */
51
 
52
  /* An PC Relative 10-bit relocation, shifted by 2  */
53
  /* right container */
54
  HOWTO (R_D10V_10_PCREL_R,     /* type */
55
         2,                     /* rightshift */
56
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
57
         10,                    /* bitsize */
58
         true,                  /* pc_relative */
59
         0,                      /* bitpos */
60
         complain_overflow_bitfield, /* complain_on_overflow */
61
         bfd_elf_generic_reloc, /* special_function */
62
         "R_D10V_10_PCREL_R",   /* name */
63
         false,                 /* partial_inplace */
64
         0xff,                  /* src_mask */
65
         0xff,                  /* dst_mask */
66
         true),                 /* pcrel_offset */
67
 
68
  /* An PC Relative 10-bit relocation, shifted by 2  */
69
  /* left container */
70
  HOWTO (R_D10V_10_PCREL_L,     /* type */
71
         2,                     /* rightshift */
72
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
73
         10,                    /* bitsize */
74
         true,                  /* pc_relative */
75
         15,                    /* bitpos */
76
         complain_overflow_bitfield, /* complain_on_overflow */
77
         bfd_elf_generic_reloc, /* special_function */
78
         "R_D10V_10_PCREL_L",   /* name */
79
         false,                 /* partial_inplace */
80
         0x07f8000,                     /* src_mask */
81
         0x07f8000,             /* dst_mask */
82
         true),                 /* pcrel_offset */
83
 
84
  /* A 16 bit absolute relocation */
85
  HOWTO (R_D10V_16,             /* type */
86
         0,                      /* rightshift */
87
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
88
         16,                    /* bitsize */
89
         false,                 /* pc_relative */
90
         0,                      /* bitpos */
91
         complain_overflow_dont, /* complain_on_overflow */
92
         bfd_elf_generic_reloc, /* special_function */
93
         "R_D10V_16",           /* name */
94
         false,                 /* partial_inplace */
95
         0xffff,                /* src_mask */
96
         0xffff,                /* dst_mask */
97
         false),                /* pcrel_offset */
98
 
99
  /* An 18 bit absolute relocation, right shifted 2 */
100
  HOWTO (R_D10V_18,             /* type */
101
         2,                     /* rightshift */
102
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
103
         18,                    /* bitsize */
104
         false,                 /* pc_relative */
105
         0,                      /* bitpos */
106
         complain_overflow_dont, /* complain_on_overflow */
107
         bfd_elf_generic_reloc, /* special_function */
108
         "R_D10V_18",           /* name */
109
         false,                 /* partial_inplace */
110
         0xffff,                /* src_mask */
111
         0xffff,                /* dst_mask */
112
         false),                /* pcrel_offset */
113
 
114
  /* A relative 18 bit relocation, right shifted by 2  */
115
  HOWTO (R_D10V_18_PCREL,       /* type */
116
         2,                     /* rightshift */
117
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
118
         18,                    /* bitsize */
119
         true,                  /* pc_relative */
120
         0,                      /* bitpos */
121
         complain_overflow_signed, /* complain_on_overflow */
122
         bfd_elf_generic_reloc, /* special_function */
123
         "R_D10V_18_PCREL",     /* name */
124
         false,                 /* partial_inplace */
125
         0xffff,                /* src_mask */
126
         0xffff,                /* dst_mask */
127
         true),                 /* pcrel_offset */
128
 
129
  /* A 32 bit absolute relocation */
130
  HOWTO (R_D10V_32,             /* type */
131
         0,                      /* rightshift */
132
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
133
         32,                    /* bitsize */
134
         false,                 /* pc_relative */
135
         0,                      /* bitpos */
136
         complain_overflow_bitfield, /* complain_on_overflow */
137
         bfd_elf_generic_reloc, /* special_function */
138
         "R_D10V_32",           /* name */
139
         false,                 /* partial_inplace */
140
         0xffffffff,            /* src_mask */
141
         0xffffffff,            /* dst_mask */
142
         false),                /* pcrel_offset */
143
 
144
  /* GNU extension to record C++ vtable hierarchy */
145
  HOWTO (R_D10V_GNU_VTINHERIT, /* type */
146
         0,                     /* rightshift */
147
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
148
         0,                     /* bitsize */
149
         false,                 /* pc_relative */
150
         0,                     /* bitpos */
151
         complain_overflow_dont, /* complain_on_overflow */
152
         NULL,                  /* special_function */
153
         "R_D10V_GNU_VTINHERIT", /* name */
154
         false,                 /* partial_inplace */
155
         0,                     /* src_mask */
156
         0,                     /* dst_mask */
157
         false),                /* pcrel_offset */
158
 
159
  /* GNU extension to record C++ vtable member usage */
160
  HOWTO (R_D10V_GNU_VTENTRY,     /* type */
161
         0,                     /* rightshift */
162
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
163
         0,                     /* bitsize */
164
         false,                 /* pc_relative */
165
         0,                     /* bitpos */
166
         complain_overflow_dont, /* complain_on_overflow */
167
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
168
         "R_D10V_GNU_VTENTRY",   /* name */
169
         false,                 /* partial_inplace */
170
         0,                     /* src_mask */
171
         0,                     /* dst_mask */
172
         false),                /* pcrel_offset */
173
 
174
};
175
 
176
/* Map BFD reloc types to D10V ELF reloc types.  */
177
 
178
struct d10v_reloc_map
179
{
180
  bfd_reloc_code_real_type bfd_reloc_val;
181
  unsigned char elf_reloc_val;
182
};
183
 
184
 static const struct d10v_reloc_map d10v_reloc_map[] =
185
{
186
  { BFD_RELOC_NONE, R_D10V_NONE, },
187
  { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
188
  { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
189
  { BFD_RELOC_16, R_D10V_16 },
190
  { BFD_RELOC_D10V_18, R_D10V_18 },
191
  { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
192
  { BFD_RELOC_32, R_D10V_32 },
193
  { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
194
  { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
195
};
196
 
197
static reloc_howto_type *
198
bfd_elf32_bfd_reloc_type_lookup (abfd, code)
199
     bfd *abfd ATTRIBUTE_UNUSED;
200
     bfd_reloc_code_real_type code;
201
{
202
  unsigned int i;
203
 
204
  for (i = 0;
205
       i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map);
206
       i++)
207
    {
208
      if (d10v_reloc_map[i].bfd_reloc_val == code)
209
        return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val];
210
    }
211
 
212
  return NULL;
213
}
214
 
215
/* Set the howto pointer for an D10V ELF reloc.  */
216
 
217
static void
218
d10v_info_to_howto_rel (abfd, cache_ptr, dst)
219
     bfd *abfd ATTRIBUTE_UNUSED;
220
     arelent *cache_ptr;
221
     Elf32_Internal_Rel *dst;
222
{
223
  unsigned int r_type;
224
 
225
  r_type = ELF32_R_TYPE (dst->r_info);
226
  BFD_ASSERT (r_type < (unsigned int) R_D10V_max);
227
  cache_ptr->howto = &elf_d10v_howto_table[r_type];
228
}
229
 
230
static asection *
231
elf32_d10v_gc_mark_hook (abfd, info, rel, h, sym)
232
       bfd *abfd;
233
       struct bfd_link_info *info ATTRIBUTE_UNUSED;
234
       Elf_Internal_Rela *rel;
235
       struct elf_link_hash_entry *h;
236
       Elf_Internal_Sym *sym;
237
{
238
  if (h != NULL)
239
    {
240
      switch (ELF32_R_TYPE (rel->r_info))
241
      {
242
      case R_D10V_GNU_VTINHERIT:
243
      case R_D10V_GNU_VTENTRY:
244
        break;
245
 
246
      default:
247
        switch (h->root.type)
248
          {
249
          case bfd_link_hash_defined:
250
          case bfd_link_hash_defweak:
251
            return h->root.u.def.section;
252
 
253
          case bfd_link_hash_common:
254
            return h->root.u.c.p->section;
255
 
256
          default:
257
            break;
258
          }
259
       }
260
     }
261
   else
262
     {
263
       if (!(elf_bad_symtab (abfd)
264
           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
265
         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
266
                && sym->st_shndx != SHN_COMMON))
267
          {
268
            return bfd_section_from_elf_index (abfd, sym->st_shndx);
269
          }
270
      }
271
  return NULL;
272
}
273
 
274
static boolean
275
elf32_d10v_gc_sweep_hook (abfd, info, sec, relocs)
276
     bfd *abfd ATTRIBUTE_UNUSED;
277
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
278
     asection *sec ATTRIBUTE_UNUSED;
279
     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
280
{
281
  /* we don't use got and plt entries for d10v */
282
  return true;
283
}
284
 
285
/* Look through the relocs for a section during the first phase.
286
   Since we don't do .gots or .plts, we just need to consider the
287
   virtual table relocs for gc.  */
288
 
289
static boolean
290
elf32_d10v_check_relocs (abfd, info, sec, relocs)
291
     bfd *abfd;
292
     struct bfd_link_info *info;
293
     asection *sec;
294
     const Elf_Internal_Rela *relocs;
295
{
296
  Elf_Internal_Shdr *symtab_hdr;
297
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
298
  const Elf_Internal_Rela *rel;
299
  const Elf_Internal_Rela *rel_end;
300
 
301
  if (info->relocateable)
302
    return true;
303
 
304
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
305
  sym_hashes = elf_sym_hashes (abfd);
306
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
307
  if (!elf_bad_symtab (abfd))
308
    sym_hashes_end -= symtab_hdr->sh_info;
309
 
310
  rel_end = relocs + sec->reloc_count;
311
  for (rel = relocs; rel < rel_end; rel++)
312
    {
313
      struct elf_link_hash_entry *h;
314
      unsigned long r_symndx;
315
 
316
      r_symndx = ELF32_R_SYM (rel->r_info);
317
      if (r_symndx < symtab_hdr->sh_info)
318
        h = NULL;
319
      else
320
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
321
 
322
      switch (ELF32_R_TYPE (rel->r_info))
323
        {
324
        /* This relocation describes the C++ object vtable hierarchy.
325
           Reconstruct it for later use during GC.  */
326
        case R_D10V_GNU_VTINHERIT:
327
          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
328
            return false;
329
          break;
330
 
331
        /* This relocation describes which C++ vtable entries are actually
332
           used.  Record for later use during GC.  */
333
        case R_D10V_GNU_VTENTRY:
334
          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
335
            return false;
336
          break;
337
        }
338
    }
339
 
340
  return true;
341
}
342
 
343
/* Relocate a D10V ELF section.  */
344
static boolean
345
elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
346
                            contents, relocs, local_syms, local_sections)
347
     bfd *output_bfd ATTRIBUTE_UNUSED;
348
     struct bfd_link_info *info;
349
     bfd *input_bfd;
350
     asection *input_section;
351
     bfd_byte *contents;
352
     Elf_Internal_Rela *relocs;
353
     Elf_Internal_Sym *local_syms;
354
     asection **local_sections;
355
{
356
  Elf_Internal_Shdr *symtab_hdr;
357
  struct elf_link_hash_entry **sym_hashes;
358
  Elf_Internal_Rela *rel, *relend;
359
  const char *name;
360
 
361
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
362
  sym_hashes = elf_sym_hashes (input_bfd);
363
 
364
  rel = relocs;
365
  relend = relocs + input_section->reloc_count;
366
  for (; rel < relend; rel++)
367
    {
368
      int r_type;
369
      reloc_howto_type *howto;
370
      unsigned long r_symndx;
371
      Elf_Internal_Sym *sym;
372
      asection *sec;
373
      struct elf_link_hash_entry *h;
374
      bfd_vma relocation;
375
      bfd_reloc_status_type r;
376
 
377
      r_symndx = ELF32_R_SYM (rel->r_info);
378
      r_type = ELF32_R_TYPE (rel->r_info);
379
 
380
      if (r_type == R_D10V_GNU_VTENTRY
381
          || r_type == R_D10V_GNU_VTINHERIT )
382
        continue;
383
 
384
      howto = elf_d10v_howto_table + r_type;
385
 
386
      if (info->relocateable)
387
        {
388
          /* This is a relocateable link.  We don't have to change
389
             anything, unless the reloc is against a section symbol,
390
             in which case we have to adjust according to where the
391
             section symbol winds up in the output section.  */
392
          if (r_symndx < symtab_hdr->sh_info)
393
            {
394
              sym = local_syms + r_symndx;
395
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
396
                {
397
                  sec = local_sections[r_symndx];
398
                  rel->r_addend += sec->output_offset + sym->st_value;
399
                }
400
            }
401
 
402
          continue;
403
        }
404
 
405
      /* This is a final link.  */
406
      h = NULL;
407
      sym = NULL;
408
      sec = NULL;
409
      if (r_symndx < symtab_hdr->sh_info)
410
        {
411
          sym = local_syms + r_symndx;
412
          sec = local_sections[r_symndx];
413
          relocation = (sec->output_section->vma
414
                        + sec->output_offset
415
                        + sym->st_value);
416
        }
417
      else
418
        {
419
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
420
          while (h->root.type == bfd_link_hash_indirect
421
                 || h->root.type == bfd_link_hash_warning)
422
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
423
          if (h->root.type == bfd_link_hash_defined
424
              || h->root.type == bfd_link_hash_defweak)
425
            {
426
              sec = h->root.u.def.section;
427
              relocation = (h->root.u.def.value
428
                            + sec->output_section->vma
429
                            + sec->output_offset);
430
            }
431
          else if (h->root.type == bfd_link_hash_undefweak)
432
            relocation = 0;
433
          else
434
            {
435
              if (!((*info->callbacks->undefined_symbol)
436
                    (info, h->root.root.string, input_bfd,
437
                     input_section, rel->r_offset, true)))
438
                return false;
439
              relocation = 0;
440
            }
441
        }
442
 
443
      if (h != NULL)
444
        name = h->root.root.string;
445
      else
446
        {
447
          name = (bfd_elf_string_from_elf_section
448
                  (input_bfd, symtab_hdr->sh_link, sym->st_name));
449
          if (name == NULL || *name == '\0')
450
            name = bfd_section_name (input_bfd, sec);
451
        }
452
 
453
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
454
                                    contents, rel->r_offset,
455
                                    relocation, rel->r_addend);
456
 
457
      if (r != bfd_reloc_ok)
458
        {
459
          const char * msg = (const char *) 0;
460
 
461
          switch (r)
462
            {
463
            case bfd_reloc_overflow:
464
              if (!((*info->callbacks->reloc_overflow)
465
                    (info, name, howto->name, (bfd_vma) 0,
466
                     input_bfd, input_section, rel->r_offset)))
467
                return false;
468
              break;
469
 
470
            case bfd_reloc_undefined:
471
              if (!((*info->callbacks->undefined_symbol)
472
                    (info, name, input_bfd, input_section,
473
                     rel->r_offset, true)))
474
                return false;
475
              break;
476
 
477
            case bfd_reloc_outofrange:
478
              msg = _ ("internal error: out of range error");
479
              goto common_error;
480
 
481
            case bfd_reloc_notsupported:
482
              msg = _ ("internal error: unsupported relocation error");
483
              goto common_error;
484
 
485
            case bfd_reloc_dangerous:
486
              msg = _ ("internal error: dangerous error");
487
              goto common_error;
488
 
489
            default:
490
              msg = _ ("internal error: unknown error");
491
              /* fall through */
492
 
493
            common_error:
494
              if (!((*info->callbacks->warning)
495
                    (info, msg, name, input_bfd, input_section,
496
                     rel->r_offset)))
497
                return false;
498
              break;
499
            }
500
        }
501
    }
502
 
503
  return true;
504
}
505
#define ELF_ARCH                bfd_arch_d10v
506
#define ELF_MACHINE_CODE        EM_CYGNUS_D10V
507
#define ELF_MAXPAGESIZE         0x1000
508
 
509
#define TARGET_BIG_SYM          bfd_elf32_d10v_vec
510
#define TARGET_BIG_NAME         "elf32-d10v"
511
 
512
#define elf_info_to_howto                    0
513
#define elf_info_to_howto_rel                d10v_info_to_howto_rel
514
#define elf_backend_object_p                 0
515
#define elf_backend_final_write_processing   0
516
#define elf_backend_gc_mark_hook             elf32_d10v_gc_mark_hook
517
#define elf_backend_gc_sweep_hook            elf32_d10v_gc_sweep_hook
518
#define elf_backend_check_relocs             elf32_d10v_check_relocs
519
#define elf_backend_relocate_section         elf32_d10v_relocate_section
520
#define elf_backend_can_gc_sections          1
521
 
522
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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