OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [elf32-iq2000.c] - Blame information for rev 173

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

Line No. Rev Author Line
1 24 jeremybenn
/* IQ2000-specific support for 32-bit ELF.
2
   Copyright (C) 2003, 2004, 2005, 2006, 2007
3
   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, MA 02110-1301, USA.  */
20
 
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "libbfd.h"
24
#include "elf-bfd.h"
25
#include "elf/iq2000.h"
26
 
27
/* Forward declarations.  */
28
 
29
static bfd_reloc_status_type iq2000_elf_howto_hi16_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
30
 
31
 
32
static reloc_howto_type iq2000_elf_howto_table [] =
33
{
34
  /* This reloc does nothing.  */
35
 
36
  HOWTO (R_IQ2000_NONE,              /* type */
37
         0,                           /* rightshift */
38
         2,                          /* size (0 = byte, 1 = short, 2 = long) */
39
         32,                         /* bitsize */
40
         FALSE,                      /* pc_relative */
41
         0,                           /* bitpos */
42
         complain_overflow_bitfield, /* complain_on_overflow */
43
         bfd_elf_generic_reloc,      /* special_function */
44
         "R_IQ2000_NONE",            /* name */
45
         FALSE,                      /* partial_inplace */
46
         0,                           /* src_mask */
47
         0,                           /* dst_mask */
48
         FALSE),                     /* pcrel_offset */
49
 
50
  /* A 16 bit absolute relocation.  */
51
  HOWTO (R_IQ2000_16,                /* type */
52
         0,                           /* rightshift */
53
         1,                          /* size (0 = byte, 1 = short, 2 = long) */
54
         16,                         /* bitsize */
55
         FALSE,                      /* pc_relative */
56
         0,                           /* bitpos */
57
         complain_overflow_bitfield, /* complain_on_overflow */
58
         bfd_elf_generic_reloc,      /* special_function */
59
         "R_IQ2000_16",              /* name */
60
         FALSE,                      /* partial_inplace */
61
         0x0000,                     /* src_mask */
62
         0xffff,                     /* dst_mask */
63
         FALSE),                     /* pcrel_offset */
64
 
65
  /* A 32 bit absolute relocation.  */
66
  HOWTO (R_IQ2000_32,                /* type */
67
         0,                           /* rightshift */
68
         2,                          /* size (0 = byte, 1 = short, 2 = long) */
69
         31,                         /* bitsize */
70
         FALSE,                      /* pc_relative */
71
         0,                           /* bitpos */
72
         complain_overflow_bitfield, /* complain_on_overflow */
73
         bfd_elf_generic_reloc,      /* special_function */
74
         "R_IQ2000_32",              /* name */
75
         FALSE,                      /* partial_inplace */
76
         0x00000000,                 /* src_mask */
77
         0x7fffffff,                 /* dst_mask */
78
         FALSE),                     /* pcrel_offset */
79
 
80
  /* 26 bit branch address.  */
81
  HOWTO (R_IQ2000_26,           /* type */
82
         2,                     /* rightshift */
83
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
84
         26,                    /* bitsize */
85
         FALSE,                 /* pc_relative */
86
         0,                      /* bitpos */
87
         complain_overflow_dont, /* complain_on_overflow */
88
                                /* This needs complex overflow
89
                                   detection, because the upper four
90
                                   bits must match the PC.  */
91
         bfd_elf_generic_reloc, /* special_function */
92
         "R_IQ2000_26",         /* name */
93
         FALSE,                 /* partial_inplace */
94
         0x00000000,            /* src_mask */
95
         0x03ffffff,            /* dst_mask */
96
         FALSE),                /* pcrel_offset */
97
 
98
  /* 16 bit PC relative reference.  */
99
  HOWTO (R_IQ2000_PC16,         /* type */
100
         2,                     /* rightshift */
101
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
102
         16,                    /* bitsize */
103
         TRUE,                  /* pc_relative */
104
         0,                      /* bitpos */
105
         complain_overflow_signed, /* complain_on_overflow */
106
         bfd_elf_generic_reloc, /* special_function */
107
         "R_IQ2000_PC16",       /* name */
108
         FALSE,                 /* partial_inplace */
109
         0x0000,                /* src_mask */
110
         0xffff,                /* dst_mask */
111
         TRUE),                 /* pcrel_offset */
112
 
113
  /* high 16 bits of symbol value.  */
114
  HOWTO (R_IQ2000_HI16,         /* type */
115
         16,                    /* rightshift */
116
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
117
         15,                    /* bitsize */
118
         FALSE,                 /* pc_relative */
119
         0,                      /* bitpos */
120
         complain_overflow_dont, /* complain_on_overflow */
121
         iq2000_elf_howto_hi16_reloc,   /* special_function */
122
         "R_IQ2000_HI16",       /* name */
123
         FALSE,                 /* partial_inplace */
124
         0x0000,                /* src_mask */
125
         0x7fff,                /* dst_mask */
126
         FALSE),                /* pcrel_offset */
127
 
128
  /* Low 16 bits of symbol value.  */
129
  HOWTO (R_IQ2000_LO16,         /* type */
130
         0,                      /* rightshift */
131
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
132
         16,                    /* bitsize */
133
         FALSE,                 /* pc_relative */
134
         0,                      /* bitpos */
135
         complain_overflow_dont, /* complain_on_overflow */
136
         bfd_elf_generic_reloc, /* special_function */
137
         "R_IQ2000_LO16",       /* name */
138
         FALSE,                 /* partial_inplace */
139
         0x0000,                /* src_mask */
140
         0xffff,                /* dst_mask */
141
         FALSE),                /* pcrel_offset */
142
 
143
  /* 16-bit jump offset.  */
144
  HOWTO (R_IQ2000_OFFSET_16,    /* type */
145
         2,                     /* rightshift */
146
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
147
         16,                    /* bitsize */
148
         FALSE,                 /* pc_relative */
149
         0,                      /* bitpos */
150
         complain_overflow_dont, /* complain_on_overflow */
151
         bfd_elf_generic_reloc, /* special_function */
152
         "R_IQ2000_OFFSET_16",  /* name */
153
         FALSE,                 /* partial_inplace */
154
         0x0000,                /* src_mask */
155
         0xffff,                /* dst_mask */
156
         FALSE),                /* pcrel_offset */
157
 
158
  /* 21-bit jump offset.  */
159
  HOWTO (R_IQ2000_OFFSET_21,    /* type */
160
         2,                     /* rightshift */
161
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
162
         21,                    /* bitsize */
163
         FALSE,                 /* pc_relative */
164
         0,                      /* bitpos */
165
         complain_overflow_dont, /* complain_on_overflow */
166
         bfd_elf_generic_reloc, /* special_function */
167
         "R_IQ2000_OFFSET_21",  /* name */
168
         FALSE,                 /* partial_inplace */
169
         0x000000,              /* src_mask */
170
         0x1fffff,              /* dst_mask */
171
         FALSE),                /* pcrel_offset */
172
 
173
  /* unsigned high 16 bits of value.  */
174
  HOWTO (R_IQ2000_OFFSET_21,    /* type */
175
         16,                    /* rightshift */
176
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
177
         16,                    /* bitsize */
178
         FALSE,                 /* pc_relative */
179
         0,                      /* bitpos */
180
         complain_overflow_dont, /* complain_on_overflow */
181
         bfd_elf_generic_reloc, /* special_function */
182
         "R_IQ2000_UHI16",      /* name */
183
         FALSE,                 /* partial_inplace */
184
         0x0000,                /* src_mask */
185
         0x7fff,                /* dst_mask */
186
         FALSE),                /* pcrel_offset */
187
 
188
  /* A 32 bit absolute debug relocation.  */
189
  HOWTO (R_IQ2000_32_DEBUG,          /* type */
190
         0,                           /* rightshift */
191
         2,                          /* size (0 = byte, 1 = short, 2 = long) */
192
         32,                         /* bitsize */
193
         FALSE,                      /* pc_relative */
194
         0,                           /* bitpos */
195
         complain_overflow_bitfield, /* complain_on_overflow */
196
         bfd_elf_generic_reloc,      /* special_function */
197
         "R_IQ2000_32",              /* name */
198
         FALSE,                      /* partial_inplace */
199
         0x00000000,                 /* src_mask */
200
         0xffffffff,                 /* dst_mask */
201
         FALSE),                     /* pcrel_offset */
202
 
203
};
204
 
205
/* GNU extension to record C++ vtable hierarchy.  */
206
static reloc_howto_type iq2000_elf_vtinherit_howto =
207
  HOWTO (R_IQ2000_GNU_VTINHERIT,    /* type */
208
         0,                         /* rightshift */
209
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
210
         0,                         /* bitsize */
211
         FALSE,                    /* pc_relative */
212
         0,                         /* bitpos */
213
         complain_overflow_dont,   /* complain_on_overflow */
214
         NULL,                     /* special_function */
215
         "R_IQ2000_GNU_VTINHERIT",  /* name */
216
         FALSE,                    /* partial_inplace */
217
         0,                         /* src_mask */
218
         0,                         /* dst_mask */
219
         FALSE);                   /* pcrel_offset */
220
 
221
/* GNU extension to record C++ vtable member usage.  */
222
static reloc_howto_type iq2000_elf_vtentry_howto =
223
  HOWTO (R_IQ2000_GNU_VTENTRY,     /* type */
224
         0,                         /* rightshift */
225
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
226
         0,                         /* bitsize */
227
         FALSE,                    /* pc_relative */
228
         0,                         /* bitpos */
229
         complain_overflow_dont,   /* complain_on_overflow */
230
         NULL,                     /* special_function */
231
         "R_IQ2000_GNU_VTENTRY",    /* name */
232
         FALSE,                    /* partial_inplace */
233
         0,                         /* src_mask */
234
         0,                         /* dst_mask */
235
         FALSE);                   /* pcrel_offset */
236
 
237
 
238
static bfd_reloc_status_type
239
iq2000_elf_howto_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
240
                             arelent *reloc_entry,
241
                             asymbol *symbol,
242
                             void * data,
243
                             asection *input_section,
244
                             bfd *output_bfd,
245
                             char **error_message ATTRIBUTE_UNUSED)
246
{
247
  bfd_reloc_status_type ret;
248
  bfd_vma relocation;
249
 
250
  /* If we're relocating and this an external symbol,
251
     we don't want to change anything.  */
252
  if (output_bfd != (bfd *) NULL
253
      && (symbol->flags & BSF_SECTION_SYM) == 0
254
      && reloc_entry->addend == 0)
255
    {
256
      reloc_entry->address += input_section->output_offset;
257
      return bfd_reloc_ok;
258
    }
259
 
260
  if (bfd_is_com_section (symbol->section))
261
    relocation = 0;
262
  else
263
    relocation = symbol->value;
264
 
265
  relocation += symbol->section->output_section->vma;
266
  relocation += symbol->section->output_offset;
267
  relocation += reloc_entry->addend;
268
 
269
  /* If %lo will have sign-extension, compensate by add 0x10000 to hi portion.  */
270
  if (relocation & 0x8000)
271
    reloc_entry->addend += 0x10000;
272
 
273
  /* Now do the reloc in the usual way.  */
274
  ret = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
275
                                input_section, output_bfd, error_message);
276
 
277
  /* Put it back the way it was.  */
278
  if (relocation & 0x8000)
279
    reloc_entry->addend -= 0x10000;
280
 
281
  return ret;
282
}
283
 
284
static bfd_reloc_status_type
285
iq2000_elf_relocate_hi16 (bfd *input_bfd,
286
                          Elf_Internal_Rela *relhi,
287
                          bfd_byte *contents,
288
                          bfd_vma value)
289
{
290
  bfd_vma insn;
291
 
292
  insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
293
 
294
  value += relhi->r_addend;
295
  value &= 0x7fffffff; /* Mask off top-bit which is Harvard mask bit.  */
296
 
297
  /* If top-bit of %lo value is on, this means that %lo will
298
     sign-propagate and so we compensate by adding 1 to %hi value.  */
299
  if (value & 0x8000)
300
    value += 0x10000;
301
 
302
  value >>= 16;
303
  insn = ((insn & ~0xFFFF) | value);
304
 
305
  bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
306
  return bfd_reloc_ok;
307
}
308
 
309
static bfd_reloc_status_type
310
iq2000_elf_relocate_offset16 (bfd *input_bfd,
311
                              Elf_Internal_Rela *rel,
312
                              bfd_byte *contents,
313
                              bfd_vma value,
314
                              bfd_vma location)
315
{
316
  bfd_vma insn;
317
  bfd_vma jtarget;
318
 
319
  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
320
 
321
  value += rel->r_addend;
322
 
323
  if (value & 3)
324
    return bfd_reloc_dangerous;
325
 
326
  jtarget = (value & 0x3fffc) | (location & 0xf0000000L);
327
 
328
  if (jtarget != value)
329
    return bfd_reloc_overflow;
330
 
331
  insn = (insn & ~0xFFFF) | ((value >> 2) & 0xFFFF);
332
 
333
  bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
334
  return bfd_reloc_ok;
335
}
336
 
337
/* Map BFD reloc types to IQ2000 ELF reloc types.  */
338
 
339
static reloc_howto_type *
340
iq2000_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
341
                          bfd_reloc_code_real_type code)
342
{
343
  /* Note that the iq2000_elf_howto_table is indxed by the R_
344
     constants.  Thus, the order that the howto records appear in the
345
     table *must* match the order of the relocation types defined in
346
     include/elf/iq2000.h.  */
347
 
348
  switch (code)
349
    {
350
    case BFD_RELOC_NONE:
351
      return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
352
    case BFD_RELOC_16:
353
      return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
354
    case BFD_RELOC_32:
355
      return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
356
    case BFD_RELOC_MIPS_JMP:
357
      return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
358
    case BFD_RELOC_IQ2000_OFFSET_16:
359
      return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
360
    case BFD_RELOC_IQ2000_OFFSET_21:
361
      return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
362
    case BFD_RELOC_16_PCREL_S2:
363
      return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
364
    case BFD_RELOC_HI16:
365
      return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
366
    case BFD_RELOC_IQ2000_UHI16:
367
      return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
368
    case BFD_RELOC_LO16:
369
      return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
370
    case BFD_RELOC_VTABLE_INHERIT:
371
      return &iq2000_elf_vtinherit_howto;
372
    case BFD_RELOC_VTABLE_ENTRY:
373
      return &iq2000_elf_vtentry_howto;
374
    default:
375
      /* Pacify gcc -Wall.  */
376
      return NULL;
377
    }
378
  return NULL;
379
}
380
 
381
static reloc_howto_type *
382
iq2000_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
383
{
384
  unsigned int i;
385
 
386
  for (i = 0;
387
       i < (sizeof (iq2000_elf_howto_table)
388
            / sizeof (iq2000_elf_howto_table[0]));
389
       i++)
390
    if (iq2000_elf_howto_table[i].name != NULL
391
        && strcasecmp (iq2000_elf_howto_table[i].name, r_name) == 0)
392
      return &iq2000_elf_howto_table[i];
393
 
394
  if (strcasecmp (iq2000_elf_vtinherit_howto.name, r_name) == 0)
395
    return &iq2000_elf_vtinherit_howto;
396
  if (strcasecmp (iq2000_elf_vtentry_howto.name, r_name) == 0)
397
    return &iq2000_elf_vtentry_howto;
398
 
399
  return NULL;
400
}
401
 
402
/* Perform a single relocation.  By default we use the standard BFD
403
   routines.  */
404
 
405
static bfd_reloc_status_type
406
iq2000_final_link_relocate (reloc_howto_type *  howto,
407
                            bfd *               input_bfd,
408
                            asection *          input_section,
409
                            bfd_byte *          contents,
410
                            Elf_Internal_Rela * rel,
411
                            bfd_vma             relocation)
412
{
413
  return _bfd_final_link_relocate (howto, input_bfd, input_section,
414
                                   contents, rel->r_offset,
415
                                   relocation, rel->r_addend);
416
}
417
 
418
/* Set the howto pointer for a IQ2000 ELF reloc.  */
419
 
420
static void
421
iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
422
                           arelent * cache_ptr,
423
                           Elf_Internal_Rela * dst)
424
{
425
  unsigned int r_type;
426
 
427
  r_type = ELF32_R_TYPE (dst->r_info);
428
  switch (r_type)
429
    {
430
    case R_IQ2000_GNU_VTINHERIT:
431
      cache_ptr->howto = & iq2000_elf_vtinherit_howto;
432
      break;
433
 
434
    case R_IQ2000_GNU_VTENTRY:
435
      cache_ptr->howto = & iq2000_elf_vtentry_howto;
436
      break;
437
 
438
    default:
439
      cache_ptr->howto = & iq2000_elf_howto_table [r_type];
440
      break;
441
    }
442
}
443
 
444
/* Look through the relocs for a section during the first phase.
445
   Since we don't do .gots or .plts, we just need to consider the
446
   virtual table relocs for gc.  */
447
 
448
static bfd_boolean
449
iq2000_elf_check_relocs (bfd *abfd,
450
                         struct bfd_link_info *info,
451
                         asection *sec,
452
                         const Elf_Internal_Rela *relocs)
453
{
454
  Elf_Internal_Shdr *symtab_hdr;
455
  struct elf_link_hash_entry **sym_hashes;
456
  const Elf_Internal_Rela *rel;
457
  const Elf_Internal_Rela *rel_end;
458
  bfd_boolean changed = FALSE;
459
 
460
  if (info->relocatable)
461
    return TRUE;
462
 
463
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
464
  sym_hashes = elf_sym_hashes (abfd);
465
 
466
  rel_end = relocs + sec->reloc_count;
467
  for (rel = relocs; rel < rel_end; rel++)
468
    {
469
      struct elf_link_hash_entry *h;
470
      unsigned long r_symndx;
471
 
472
      r_symndx = ELF32_R_SYM (rel->r_info);
473
      if (r_symndx < symtab_hdr->sh_info)
474
        h = NULL;
475
      else
476
        {
477
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
478
          while (h->root.type == bfd_link_hash_indirect
479
                 || h->root.type == bfd_link_hash_warning)
480
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
481
        }
482
 
483
      switch (ELF32_R_TYPE (rel->r_info))
484
        {
485
          /* This relocation describes the C++ object vtable
486
             hierarchy.  Reconstruct it for later use during GC.  */
487
        case R_IQ2000_GNU_VTINHERIT:
488
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
489
            return FALSE;
490
          break;
491
 
492
          /* This relocation describes which C++ vtable entries
493
             are actually used.  Record for later use during GC.  */
494
        case R_IQ2000_GNU_VTENTRY:
495
          BFD_ASSERT (h != NULL);
496
          if (h != NULL
497
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
498
            return FALSE;
499
          break;
500
 
501
        case R_IQ2000_32:
502
          /* For debug section, change to special harvard-aware relocations.  */
503
          if (CONST_STRNEQ (sec->name, ".debug")
504
              || CONST_STRNEQ (sec->name, ".stab")
505
              || CONST_STRNEQ (sec->name, ".eh_frame"))
506
            {
507
              ((Elf_Internal_Rela *) rel)->r_info
508
                = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
509
              changed = TRUE;
510
            }
511
          break;
512
        }
513
    }
514
 
515
  if (changed)
516
    /* Note that we've changed relocs, otherwise if !info->keep_memory
517
       we'll free the relocs and lose our changes.  */
518
    elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
519
 
520
  return TRUE;
521
}
522
 
523
 
524
/* Relocate a IQ2000 ELF section.
525
   There is some attempt to make this function usable for many architectures,
526
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
527
   if only to serve as a learning tool.
528
 
529
   The RELOCATE_SECTION function is called by the new ELF backend linker
530
   to handle the relocations for a section.
531
 
532
   The relocs are always passed as Rela structures; if the section
533
   actually uses Rel structures, the r_addend field will always be
534
   zero.
535
 
536
   This function is responsible for adjusting the section contents as
537
   necessary, and (if using Rela relocs and generating a relocatable
538
   output file) adjusting the reloc addend as necessary.
539
 
540
   This function does not have to worry about setting the reloc
541
   address or the reloc symbol index.
542
 
543
   LOCAL_SYMS is a pointer to the swapped in local symbols.
544
 
545
   LOCAL_SECTIONS is an array giving the section in the input file
546
   corresponding to the st_shndx field of each local symbol.
547
 
548
   The global hash table entry for the global symbols can be found
549
   via elf_sym_hashes (input_bfd).
550
 
551
   When generating relocatable output, this function must handle
552
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
553
   going to be the section symbol corresponding to the output
554
   section, which means that the addend must be adjusted
555
   accordingly.  */
556
 
557
static bfd_boolean
558
iq2000_elf_relocate_section (bfd *                   output_bfd ATTRIBUTE_UNUSED,
559
                             struct bfd_link_info *  info,
560
                             bfd *                   input_bfd,
561
                             asection *              input_section,
562
                             bfd_byte *              contents,
563
                             Elf_Internal_Rela *     relocs,
564
                             Elf_Internal_Sym *      local_syms,
565
                             asection **             local_sections)
566
{
567
  Elf_Internal_Shdr *           symtab_hdr;
568
  struct elf_link_hash_entry ** sym_hashes;
569
  Elf_Internal_Rela *           rel;
570
  Elf_Internal_Rela *           relend;
571
 
572
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
573
  sym_hashes = elf_sym_hashes (input_bfd);
574
  relend     = relocs + input_section->reloc_count;
575
 
576
  for (rel = relocs; rel < relend; rel ++)
577
    {
578
      reloc_howto_type *           howto;
579
      unsigned long                r_symndx;
580
      Elf_Internal_Sym *           sym;
581
      asection *                   sec;
582
      struct elf_link_hash_entry * h;
583
      bfd_vma                      relocation;
584
      bfd_reloc_status_type        r;
585
      const char *                 name = NULL;
586
      int                          r_type;
587
 
588
      r_type = ELF32_R_TYPE (rel->r_info);
589
 
590
      if (   r_type == R_IQ2000_GNU_VTINHERIT
591
          || r_type == R_IQ2000_GNU_VTENTRY)
592
        continue;
593
 
594
      r_symndx = ELF32_R_SYM (rel->r_info);
595
 
596
      howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
597
      h      = NULL;
598
      sym    = NULL;
599
      sec    = NULL;
600
 
601
      if (r_symndx < symtab_hdr->sh_info)
602
        {
603
          asection *osec;
604
 
605
          sym = local_syms + r_symndx;
606
          osec = sec = local_sections [r_symndx];
607
          if ((sec->flags & SEC_MERGE)
608
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
609
            /* This relocation is relative to a section symbol that is
610
               going to be merged.  Change it so that it is relative
611
               to the merged section symbol.  */
612
            rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym, &sec,
613
                                                    rel->r_addend);
614
 
615
          relocation = (sec->output_section->vma
616
                        + sec->output_offset
617
                        + sym->st_value);
618
 
619
          name = bfd_elf_string_from_elf_section
620
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
621
          name = (name == NULL) ? bfd_section_name (input_bfd, osec) : name;
622
        }
623
      else
624
        {
625
          bfd_boolean unresolved_reloc;
626
          bfd_boolean warned;
627
 
628
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
629
                                   r_symndx, symtab_hdr, sym_hashes,
630
                                   h, sec, relocation,
631
                                   unresolved_reloc, warned);
632
 
633
          name = h->root.root.string;
634
        }
635
 
636
      if (sec != NULL && elf_discarded_section (sec))
637
        {
638
          /* For relocs against symbols from removed linkonce sections,
639
             or sections discarded by a linker script, we just want the
640
             section contents zeroed.  Avoid any special processing.  */
641
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
642
          rel->r_info = 0;
643
          rel->r_addend = 0;
644
          continue;
645
        }
646
 
647
      if (info->relocatable)
648
        continue;
649
 
650
      switch (r_type)
651
        {
652
        case R_IQ2000_HI16:
653
          r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
654
          break;
655
 
656
        case R_IQ2000_OFFSET_16:
657
          r = iq2000_elf_relocate_offset16 (input_bfd, rel, contents, relocation,
658
                                            input_section->output_section->vma
659
                                            + input_section->output_offset
660
                                            + rel->r_offset);
661
          break;
662
 
663
        case R_IQ2000_PC16:
664
          rel->r_addend -= 4;
665
          /* Fall through.  */
666
 
667
        default:
668
          r = iq2000_final_link_relocate (howto, input_bfd, input_section,
669
                                         contents, rel, relocation);
670
          break;
671
        }
672
 
673
      if (r != bfd_reloc_ok)
674
        {
675
          const char * msg = (const char *) NULL;
676
 
677
          switch (r)
678
            {
679
            case bfd_reloc_overflow:
680
              r = info->callbacks->reloc_overflow
681
                (info, (h ? &h->root : NULL), name, howto->name,
682
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
683
              break;
684
 
685
            case bfd_reloc_undefined:
686
              r = info->callbacks->undefined_symbol
687
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
688
              break;
689
 
690
            case bfd_reloc_outofrange:
691
              msg = _("internal error: out of range error");
692
              break;
693
 
694
            case bfd_reloc_notsupported:
695
              msg = _("internal error: unsupported relocation error");
696
              break;
697
 
698
            case bfd_reloc_dangerous:
699
              msg = _("internal error: dangerous relocation");
700
              break;
701
 
702
            default:
703
              msg = _("internal error: unknown error");
704
              break;
705
            }
706
 
707
          if (msg)
708
            r = info->callbacks->warning
709
              (info, msg, name, input_bfd, input_section, rel->r_offset);
710
 
711
          if (! r)
712
            return FALSE;
713
        }
714
    }
715
 
716
  return TRUE;
717
}
718
 
719
 
720
/* Return the section that should be marked against GC for a given
721
   relocation.  */
722
 
723
static asection *
724
iq2000_elf_gc_mark_hook (asection *sec,
725
                         struct bfd_link_info *info,
726
                         Elf_Internal_Rela *rel,
727
                         struct elf_link_hash_entry *h,
728
                         Elf_Internal_Sym *sym)
729
{
730
  if (h != NULL)
731
    switch (ELF32_R_TYPE (rel->r_info))
732
      {
733
      case R_IQ2000_GNU_VTINHERIT:
734
      case R_IQ2000_GNU_VTENTRY:
735
        return NULL;
736
      }
737
 
738
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
739
}
740
 
741
 
742
/* Return the MACH for an e_flags value.  */
743
 
744
static int
745
elf32_iq2000_machine (bfd *abfd)
746
{
747
  switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
748
    {
749
    case EF_IQ2000_CPU_IQ10:
750
      return bfd_mach_iq10;
751
 
752
    case EF_IQ2000_CPU_IQ2000:
753
    default:
754
      return bfd_mach_iq2000;
755
    }
756
}
757
 
758
 
759
/* Function to set the ELF flag bits.  */
760
 
761
static bfd_boolean
762
iq2000_elf_set_private_flags (bfd *abfd, flagword flags)
763
{
764
  elf_elfheader (abfd)->e_flags = flags;
765
  elf_flags_init (abfd) = TRUE;
766
  return TRUE;
767
}
768
 
769
/* Copy backend specific data from one object module to another.  */
770
 
771
static bfd_boolean
772
iq2000_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
773
{
774
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
775
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
776
    return TRUE;
777
 
778
  BFD_ASSERT (!elf_flags_init (obfd)
779
              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
780
 
781
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
782
  elf_flags_init (obfd) = TRUE;
783
 
784
  /* Copy object attributes.  */
785
  _bfd_elf_copy_obj_attributes (ibfd, obfd);
786
 
787
  return TRUE;
788
}
789
 
790
/* Merge backend specific data from an object
791
   file to the output object file when linking.  */
792
 
793
static bfd_boolean
794
iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
795
{
796
  flagword old_flags, old_partial;
797
  flagword new_flags, new_partial;
798
  bfd_boolean error = FALSE;
799
  char new_opt[80];
800
  char old_opt[80];
801
 
802
  new_opt[0] = old_opt[0] = '\0';
803
  new_flags = elf_elfheader (ibfd)->e_flags;
804
  old_flags = elf_elfheader (obfd)->e_flags;
805
 
806
  if (!elf_flags_init (obfd))
807
    {
808
      /* First call, no flags set.  */
809
      elf_flags_init (obfd) = TRUE;
810
      elf_elfheader (obfd)->e_flags = new_flags;
811
    }
812
 
813
  else if (new_flags != old_flags)
814
    {
815
      /* Warn if different cpu is used, but allow a
816
         specific cpu to override the generic cpu.  */
817
      new_partial = (new_flags & EF_IQ2000_CPU_MASK);
818
      old_partial = (old_flags & EF_IQ2000_CPU_MASK);
819
 
820
      if (new_partial != old_partial)
821
        {
822
          switch (new_partial)
823
            {
824
            case EF_IQ2000_CPU_IQ10:
825
              strcat (new_opt, " -m10");
826
              break;
827
 
828
            default:
829
            case EF_IQ2000_CPU_IQ2000:
830
              strcat (new_opt, " -m2000");
831
              break;
832
            }
833
 
834
          switch (old_partial)
835
            {
836
            case EF_IQ2000_CPU_IQ10:
837
              strcat (old_opt, " -m10");
838
              break;
839
 
840
            default:
841
            case EF_IQ2000_CPU_IQ2000:
842
              strcat (old_opt, " -m2000");
843
              break;
844
            }
845
        }
846
 
847
      /* Print out any mismatches from above.  */
848
      if (new_opt[0])
849
        {
850
          error = TRUE;
851
          _bfd_error_handler
852
            (_("%s: compiled with %s and linked with modules compiled with %s"),
853
             bfd_get_filename (ibfd), new_opt, old_opt);
854
        }
855
 
856
      new_flags &= ~ EF_IQ2000_ALL_FLAGS;
857
      old_flags &= ~ EF_IQ2000_ALL_FLAGS;
858
 
859
      /* Warn about any other mismatches.  */
860
      if (new_flags != old_flags)
861
        {
862
          error = TRUE;
863
 
864
          _bfd_error_handler
865
            (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
866
             bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
867
        }
868
    }
869
 
870
  if (error)
871
    bfd_set_error (bfd_error_bad_value);
872
 
873
  return !error;
874
}
875
 
876
 
877
static bfd_boolean
878
iq2000_elf_print_private_bfd_data (bfd *abfd, void * ptr)
879
{
880
  FILE *file = (FILE *) ptr;
881
  flagword flags;
882
 
883
  BFD_ASSERT (abfd != NULL && ptr != NULL);
884
 
885
  /* Print normal ELF private data.  */
886
  _bfd_elf_print_private_bfd_data (abfd, ptr);
887
 
888
  flags = elf_elfheader (abfd)->e_flags;
889
  fprintf (file, _("private flags = 0x%lx:"), (long)flags);
890
 
891
  switch (flags & EF_IQ2000_CPU_MASK)
892
    {
893
    case EF_IQ2000_CPU_IQ10:
894
      fprintf (file, " -m10");
895
      break;
896
    case EF_IQ2000_CPU_IQ2000:
897
      fprintf (file, " -m2000");
898
      break;
899
    default:
900
      break;
901
    }
902
 
903
  fputc ('\n', file);
904
  return TRUE;
905
}
906
 
907
static
908
bfd_boolean
909
iq2000_elf_object_p (bfd *abfd)
910
{
911
  bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
912
                             elf32_iq2000_machine (abfd));
913
  return TRUE;
914
}
915
 
916
 
917
#define ELF_ARCH                bfd_arch_iq2000
918
#define ELF_MACHINE_CODE        EM_IQ2000
919
#define ELF_MAXPAGESIZE         0x1000
920
 
921
#define TARGET_BIG_SYM          bfd_elf32_iq2000_vec
922
#define TARGET_BIG_NAME         "elf32-iq2000"
923
 
924
#define elf_info_to_howto_rel                   NULL
925
#define elf_info_to_howto                       iq2000_info_to_howto_rela
926
#define elf_backend_relocate_section            iq2000_elf_relocate_section
927
#define elf_backend_gc_mark_hook                iq2000_elf_gc_mark_hook
928
#define elf_backend_check_relocs                iq2000_elf_check_relocs
929
#define elf_backend_object_p                    iq2000_elf_object_p
930
#define elf_backend_rela_normal                 1
931
 
932
#define elf_backend_can_gc_sections             1
933
 
934
#define bfd_elf32_bfd_reloc_type_lookup         iq2000_reloc_type_lookup
935
#define bfd_elf32_bfd_reloc_name_lookup iq2000_reloc_name_lookup
936
#define bfd_elf32_bfd_set_private_flags         iq2000_elf_set_private_flags
937
#define bfd_elf32_bfd_copy_private_bfd_data     iq2000_elf_copy_private_bfd_data
938
#define bfd_elf32_bfd_merge_private_bfd_data    iq2000_elf_merge_private_bfd_data
939
#define bfd_elf32_bfd_print_private_bfd_data    iq2000_elf_print_private_bfd_data
940
 
941
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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