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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-mep.c] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* MeP-specific support for 32-bit ELF.
2
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3
   2010, 2011  Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/mep.h"
27
#include "libiberty.h"
28
 
29
/* Forward declarations.  */
30
 
31
/* Private relocation functions.  */
32
 
33
#define MEPREL(type, size, bits, right, left, pcrel, overflow, mask) \
34
  {(unsigned)type, right, size, bits, pcrel, left, overflow, mep_reloc, #type, FALSE, 0, mask, 0 }
35
 
36
#define N complain_overflow_dont
37
#define S complain_overflow_signed
38
#define U complain_overflow_unsigned
39
 
40
static bfd_reloc_status_type mep_reloc (bfd *, arelent *, struct bfd_symbol *,
41
                                        void *, asection *, bfd *, char **);
42
 
43
static reloc_howto_type mep_elf_howto_table [] =
44
{
45
  /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask.  */
46
  MEPREL (R_MEP_NONE,     0,  0, 0, 0, 0, N, 0),
47
  MEPREL (R_RELC,         0,  0, 0, 0, 0, N, 0),
48
  /* MEPRELOC:HOWTO */
49
    /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
50
  MEPREL (R_MEP_8,        0,  8, 0, 0, 0, U, 0xff),
51
  MEPREL (R_MEP_16,       1, 16, 0, 0, 0, U, 0xffff),
52
  MEPREL (R_MEP_32,       2, 32, 0, 0, 0, U, 0xffffffff),
53
  MEPREL (R_MEP_PCREL8A2, 1,  8, 1, 1, 1, S, 0x00fe),
54
  MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe),
55
  MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff),
56
  MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff),
57
  MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff),
58
  MEPREL (R_MEP_LOW16,    2, 16, 0, 0, 0, N, 0x0000ffff),
59
  MEPREL (R_MEP_HI16U,    2, 32, 0,16, 0, N, 0x0000ffff),
60
  MEPREL (R_MEP_HI16S,    2, 32, 0,16, 0, N, 0x0000ffff),
61
  MEPREL (R_MEP_GPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
62
  MEPREL (R_MEP_TPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
63
  MEPREL (R_MEP_TPREL7,   1,  7, 0, 0, 0, U, 0x007f),
64
  MEPREL (R_MEP_TPREL7A2, 1,  7, 1, 1, 0, U, 0x007e),
65
  MEPREL (R_MEP_TPREL7A4, 1,  7, 2, 2, 0, U, 0x007c),
66
  MEPREL (R_MEP_UIMM24,   2, 24, 0, 0, 0, U, 0x00ffffff),
67
  MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff),
68
  MEPREL (R_MEP_GNU_VTINHERIT,1,  0,16,32, 0, N, 0x0000),
69
  MEPREL (R_MEP_GNU_VTENTRY,1,  0,16,32, 0, N, 0x0000),
70
  /* MEPRELOC:END */
71
};
72
 
73
#define VALID_MEP_RELOC(N) ((N) >= 0 \
74
  && (N) < ARRAY_SIZE (mep_elf_howto_table)
75
 
76
#undef N
77
#undef S
78
#undef U
79
 
80
static bfd_reloc_status_type
81
mep_reloc
82
    (bfd *               abfd ATTRIBUTE_UNUSED,
83
     arelent *           reloc_entry ATTRIBUTE_UNUSED,
84
     struct bfd_symbol * symbol ATTRIBUTE_UNUSED,
85
     void *              data ATTRIBUTE_UNUSED,
86
     asection *          input_section ATTRIBUTE_UNUSED,
87
     bfd *               output_bfd ATTRIBUTE_UNUSED,
88
     char **             error_message ATTRIBUTE_UNUSED)
89
{
90
  return bfd_reloc_ok;
91
}
92
 
93
 
94
 
95
#define BFD_RELOC_MEP_NONE BFD_RELOC_NONE
96
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
97
#define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break
98
#else
99
#define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
100
#endif
101
 
102
static reloc_howto_type *
103
mep_reloc_type_lookup
104
    (bfd * abfd ATTRIBUTE_UNUSED,
105
     bfd_reloc_code_real_type code)
106
{
107
  unsigned int type = 0;
108
 
109
  switch (code)
110
    {
111
    MAP(NONE);
112
    case BFD_RELOC_8:
113
      type = R_MEP_8;
114
      break;
115
    case BFD_RELOC_16:
116
      type = R_MEP_16;
117
      break;
118
    case BFD_RELOC_32:
119
      type = R_MEP_32;
120
      break;
121
    case BFD_RELOC_VTABLE_ENTRY:
122
      type = R_MEP_GNU_VTENTRY;
123
      break;
124
    case BFD_RELOC_VTABLE_INHERIT:
125
      type = R_MEP_GNU_VTINHERIT;
126
      break;
127
    case BFD_RELOC_RELC:
128
      type = R_RELC;
129
      break;
130
 
131
    /* MEPRELOC:MAP */
132
    /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
133
    MAP(8);
134
    MAP(16);
135
    MAP(32);
136
    MAP(PCREL8A2);
137
    MAP(PCREL12A2);
138
    MAP(PCREL17A2);
139
    MAP(PCREL24A2);
140
    MAP(PCABS24A2);
141
    MAP(LOW16);
142
    MAP(HI16U);
143
    MAP(HI16S);
144
    MAP(GPREL);
145
    MAP(TPREL);
146
    MAP(TPREL7);
147
    MAP(TPREL7A2);
148
    MAP(TPREL7A4);
149
    MAP(UIMM24);
150
    MAP(ADDR24A4);
151
    MAP(GNU_VTINHERIT);
152
    MAP(GNU_VTENTRY);
153
    /* MEPRELOC:END */
154
 
155
    default:
156
      /* Pacify gcc -Wall.  */
157
      (*_bfd_error_handler) (_("mep: no reloc for code %d"), code);
158
      return NULL;
159
    }
160
 
161
  if (mep_elf_howto_table[type].type != type)
162
    {
163
      (*_bfd_error_handler) (_("MeP: howto %d has type %d"),
164
                             type, mep_elf_howto_table[type].type);
165
      abort ();
166
    }
167
 
168
  return mep_elf_howto_table + type;
169
}
170
 
171
#undef MAP
172
 
173
static reloc_howto_type *
174
mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
175
{
176
  unsigned int i;
177
 
178
  for (i = 0;
179
       i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
180
       i++)
181
    if (mep_elf_howto_table[i].name != NULL
182
        && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
183
      return &mep_elf_howto_table[i];
184
 
185
  return NULL;
186
}
187
 
188
/* Perform a single relocation.  */
189
 
190
static struct bfd_link_info *mep_info;
191
static int warn_tp = 0, warn_sda = 0;
192
 
193
static bfd_vma
194
mep_lookup_global
195
    (char *    name,
196
     bfd_vma   ofs,
197
     bfd_vma * cache,
198
     int *     warn)
199
{
200
  struct bfd_link_hash_entry *h;
201
 
202
  if (*cache || *warn)
203
    return *cache;
204
 
205
  h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
206
  if (h == 0 || h->type != bfd_link_hash_defined)
207
    {
208
      *warn = ofs + 1;
209
      return 0;
210
    }
211
  *cache = (h->u.def.value
212
          + h->u.def.section->output_section->vma
213
          + h->u.def.section->output_offset);
214
  return *cache;
215
}
216
 
217
static bfd_vma
218
mep_tpoff_base (bfd_vma ofs)
219
{
220
  static bfd_vma cache = 0;
221
  return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
222
}
223
 
224
static bfd_vma
225
mep_sdaoff_base (bfd_vma ofs)
226
{
227
  static bfd_vma cache = 0;
228
  return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
229
}
230
 
231
static bfd_reloc_status_type
232
mep_final_link_relocate
233
    (reloc_howto_type *  howto,
234
     bfd *               input_bfd,
235
     asection *          input_section,
236
     bfd_byte *          contents,
237
     Elf_Internal_Rela * rel,
238
     bfd_vma             relocation)
239
{
240
  unsigned long u;
241
  long s;
242
  unsigned char *byte;
243
  bfd_vma pc;
244
  bfd_reloc_status_type r = bfd_reloc_ok;
245
  int e2, e4;
246
 
247
  if (bfd_big_endian (input_bfd))
248
    {
249
      e2 = 0;
250
      e4 = 0;
251
    }
252
  else
253
    {
254
      e2 = 1;
255
      e4 = 3;
256
    }
257
 
258
  pc = (input_section->output_section->vma
259
        + input_section->output_offset
260
        + rel->r_offset);
261
 
262
  s = relocation + rel->r_addend;
263
 
264
  byte = (unsigned char *)contents + rel->r_offset;
265
 
266
  if (howto->type == R_MEP_PCREL24A2
267
      && s == 0
268
      && pc >= 0x800000)
269
    {
270
      /* This is an unreachable branch to an undefined weak function.
271
         Silently ignore it, since the opcode can't do that but should
272
         never be executed anyway.  */
273
      return bfd_reloc_ok;
274
    }
275
 
276
  if (howto->pc_relative)
277
    s -= pc;
278
 
279
  u = (unsigned long) s;
280
 
281
  switch (howto->type)
282
    {
283
    /* MEPRELOC:APPLY */
284
    /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
285
    case R_MEP_8: /* 76543210 */
286
      if (u > 255) r = bfd_reloc_overflow;
287
      byte[0] = (u & 0xff);
288
      break;
289
    case R_MEP_16: /* fedcba9876543210 */
290
      if (u > 65535) r = bfd_reloc_overflow;
291
      byte[0^e2] = ((u >> 8) & 0xff);
292
      byte[1^e2] = (u & 0xff);
293
      break;
294
    case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
295
      byte[0^e4] = ((u >> 24) & 0xff);
296
      byte[1^e4] = ((u >> 16) & 0xff);
297
      byte[2^e4] = ((u >> 8) & 0xff);
298
      byte[3^e4] = (u & 0xff);
299
      break;
300
    case R_MEP_PCREL8A2: /* --------7654321- */
301
      if (-128 > s || s > 127) r = bfd_reloc_overflow;
302
      byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
303
      break;
304
    case R_MEP_PCREL12A2: /* ----ba987654321- */
305
      if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
306
      byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
307
      byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
308
      break;
309
    case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
310
      if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
311
      byte[2^e2] = ((s >> 9) & 0xff);
312
      byte[3^e2] = ((s >> 1) & 0xff);
313
      break;
314
    case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
315
      if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
316
      byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
317
      byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
318
      byte[2^e2] = ((s >> 16) & 0xff);
319
      byte[3^e2] = ((s >> 8) & 0xff);
320
      break;
321
    case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
322
      if (u > 16777215) r = bfd_reloc_overflow;
323
      byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
324
      byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
325
      byte[2^e2] = ((u >> 16) & 0xff);
326
      byte[3^e2] = ((u >> 8) & 0xff);
327
      break;
328
    case R_MEP_LOW16: /* ----------------fedcba9876543210 */
329
      byte[2^e2] = ((u >> 8) & 0xff);
330
      byte[3^e2] = (u & 0xff);
331
      break;
332
    case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
333
      byte[2^e2] = ((u >> 24) & 0xff);
334
      byte[3^e2] = ((u >> 16) & 0xff);
335
      break;
336
    case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
337
      if (s & 0x8000)
338
        s += 0x10000;
339
      byte[2^e2] = ((s >> 24) & 0xff);
340
      byte[3^e2] = ((s >> 16) & 0xff);
341
      break;
342
    case R_MEP_GPREL: /* ----------------fedcba9876543210 */
343
      s -= mep_sdaoff_base(rel->r_offset);
344
      if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
345
      byte[2^e2] = ((s >> 8) & 0xff);
346
      byte[3^e2] = (s & 0xff);
347
      break;
348
    case R_MEP_TPREL: /* ----------------fedcba9876543210 */
349
      s -= mep_tpoff_base(rel->r_offset);
350
      if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
351
      byte[2^e2] = ((s >> 8) & 0xff);
352
      byte[3^e2] = (s & 0xff);
353
      break;
354
    case R_MEP_TPREL7: /* ---------6543210 */
355
      u -= mep_tpoff_base(rel->r_offset);
356
      if (u > 127) r = bfd_reloc_overflow;
357
      byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
358
      break;
359
    case R_MEP_TPREL7A2: /* ---------654321- */
360
      u -= mep_tpoff_base(rel->r_offset);
361
      if (u > 127) r = bfd_reloc_overflow;
362
      byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
363
      break;
364
    case R_MEP_TPREL7A4: /* ---------65432-- */
365
      u -= mep_tpoff_base(rel->r_offset);
366
      if (u > 127) r = bfd_reloc_overflow;
367
      byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
368
      break;
369
    case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
370
      if (u > 16777215) r = bfd_reloc_overflow;
371
      byte[1^e2] = (u & 0xff);
372
      byte[2^e2] = ((u >> 16) & 0xff);
373
      byte[3^e2] = ((u >> 8) & 0xff);
374
      break;
375
    case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
376
      if (u > 16777215) r = bfd_reloc_overflow;
377
      byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
378
      byte[2^e2] = ((u >> 16) & 0xff);
379
      byte[3^e2] = ((u >> 8) & 0xff);
380
      break;
381
    case R_MEP_GNU_VTINHERIT: /* ---------------- */
382
      break;
383
    case R_MEP_GNU_VTENTRY: /* ---------------- */
384
      break;
385
    /* MEPRELOC:END */
386
    default:
387
      abort ();
388
    }
389
 
390
  return r;
391
}
392
 
393
/* Set the howto pointer for a MEP ELF reloc.  */
394
 
395
static void
396
mep_info_to_howto_rela
397
    (bfd *               abfd ATTRIBUTE_UNUSED,
398
     arelent *           cache_ptr,
399
     Elf_Internal_Rela * dst)
400
{
401
  unsigned int r_type;
402
 
403
  r_type = ELF32_R_TYPE (dst->r_info);
404
  cache_ptr->howto = & mep_elf_howto_table [r_type];
405
}
406
 
407
/* Relocate a MEP ELF section.
408
   There is some attempt to make this function usable for many architectures,
409
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
410
   if only to serve as a learning tool.
411
 
412
   The RELOCATE_SECTION function is called by the new ELF backend linker
413
   to handle the relocations for a section.
414
 
415
   The relocs are always passed as Rela structures; if the section
416
   actually uses Rel structures, the r_addend field will always be
417
   zero.
418
 
419
   This function is responsible for adjusting the section contents as
420
   necessary, and (if using Rela relocs and generating a relocatable
421
   output file) adjusting the reloc addend as necessary.
422
 
423
   This function does not have to worry about setting the reloc
424
   address or the reloc symbol index.
425
 
426
   LOCAL_SYMS is a pointer to the swapped in local symbols.
427
 
428
   LOCAL_SECTIONS is an array giving the section in the input file
429
   corresponding to the st_shndx field of each local symbol.
430
 
431
   The global hash table entry for the global symbols can be found
432
   via elf_sym_hashes (input_bfd).
433
 
434
   When generating relocatable output, this function must handle
435
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
436
   going to be the section symbol corresponding to the output
437
   section, which means that the addend must be adjusted
438
   accordingly.  */
439
 
440
static bfd_boolean
441
mep_elf_relocate_section
442
    (bfd *                   output_bfd ATTRIBUTE_UNUSED,
443
     struct bfd_link_info *  info,
444
     bfd *                   input_bfd,
445
     asection *              input_section,
446
     bfd_byte *              contents,
447
     Elf_Internal_Rela *     relocs,
448
     Elf_Internal_Sym *      local_syms,
449
     asection **             local_sections)
450
{
451
  Elf_Internal_Shdr *           symtab_hdr;
452
  struct elf_link_hash_entry ** sym_hashes;
453
  Elf_Internal_Rela *           rel;
454
  Elf_Internal_Rela *           relend;
455
 
456
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
457
  sym_hashes = elf_sym_hashes (input_bfd);
458
  relend     = relocs + input_section->reloc_count;
459
 
460
  mep_info = info;
461
 
462
  for (rel = relocs; rel < relend; rel ++)
463
    {
464
      reloc_howto_type *           howto;
465
      unsigned long                r_symndx;
466
      Elf_Internal_Sym *           sym;
467
      asection *                   sec;
468
      struct elf_link_hash_entry * h;
469
      bfd_vma                      relocation;
470
      bfd_reloc_status_type        r;
471
      const char *                 name = NULL;
472
      int                          r_type;
473
 
474
      r_type = ELF32_R_TYPE (rel->r_info);
475
      r_symndx = ELF32_R_SYM (rel->r_info);
476
      howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
477
      h      = NULL;
478
      sym    = NULL;
479
      sec    = NULL;
480
 
481
      if (r_symndx < symtab_hdr->sh_info)
482
        {
483
          sym = local_syms + r_symndx;
484
          sec = local_sections [r_symndx];
485
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
486
 
487
          name = bfd_elf_string_from_elf_section
488
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
489
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
490
        }
491
      else
492
        {
493
          bfd_boolean warned, unresolved_reloc;
494
 
495
          RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
496
                                  r_symndx, symtab_hdr, sym_hashes,
497
                                  h, sec, relocation,
498
                                  unresolved_reloc, warned);
499
 
500
          name = h->root.root.string;
501
        }
502
 
503
      if (sec != NULL && elf_discarded_section (sec))
504
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
505
                                         rel, relend, howto, contents);
506
 
507
      if (info->relocatable)
508
        continue;
509
 
510
      if (r_type == R_RELC)
511
        r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
512
                                                contents, rel, relocation);
513
      else
514
        r = mep_final_link_relocate (howto, input_bfd, input_section,
515
                                     contents, rel, relocation);
516
 
517
      if (r != bfd_reloc_ok)
518
        {
519
          const char * msg = (const char *) NULL;
520
 
521
          switch (r)
522
            {
523
            case bfd_reloc_overflow:
524
              r = info->callbacks->reloc_overflow
525
                (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
526
                 input_bfd, input_section, rel->r_offset);
527
              break;
528
 
529
            case bfd_reloc_undefined:
530
              r = info->callbacks->undefined_symbol
531
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
532
              break;
533
 
534
            case bfd_reloc_outofrange:
535
              msg = _("internal error: out of range error");
536
              break;
537
 
538
            case bfd_reloc_notsupported:
539
              msg = _("internal error: unsupported relocation error");
540
              break;
541
 
542
            case bfd_reloc_dangerous:
543
              msg = _("internal error: dangerous relocation");
544
              break;
545
 
546
            default:
547
              msg = _("internal error: unknown error");
548
              break;
549
            }
550
 
551
          if (msg)
552
            r = info->callbacks->warning
553
              (info, msg, name, input_bfd, input_section, rel->r_offset);
554
 
555
          if (! r)
556
            return FALSE;
557
        }
558
    }
559
 
560
  if (warn_tp)
561
    info->callbacks->undefined_symbol
562
      (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
563
  if (warn_sda)
564
    info->callbacks->undefined_symbol
565
      (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
566
  if (warn_sda || warn_tp)
567
    return FALSE;
568
 
569
  return TRUE;
570
}
571
 
572
/* Function to set the ELF flag bits.  */
573
 
574
static bfd_boolean
575
mep_elf_set_private_flags (bfd *    abfd,
576
                           flagword flags)
577
{
578
  elf_elfheader (abfd)->e_flags = flags;
579
  elf_flags_init (abfd) = TRUE;
580
  return TRUE;
581
}
582
 
583
static bfd_boolean
584
mep_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
585
{
586
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
587
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
588
    return TRUE;
589
 
590
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
591
  elf_flags_init (obfd) = TRUE;
592
 
593
  /* Copy object attributes.  */
594
  _bfd_elf_copy_obj_attributes (ibfd, obfd);
595
 
596
  return TRUE;
597
}
598
 
599
/* Merge backend specific data from an object file to the output
600
   object file when linking.  */
601
 
602
static bfd_boolean
603
mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
604
{
605
  static bfd *last_ibfd = 0;
606
  flagword old_flags, new_flags;
607
  flagword old_partial, new_partial;
608
 
609
  /* Check if we have the same endianness.  */
610
  if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
611
    return FALSE;
612
 
613
  new_flags = elf_elfheader (ibfd)->e_flags;
614
  old_flags = elf_elfheader (obfd)->e_flags;
615
 
616
#ifdef DEBUG
617
  _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
618
                      ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
619
#endif
620
 
621
    /* First call, no flags set.  */
622
    if (!elf_flags_init (obfd))
623
    {
624
      elf_flags_init (obfd) = TRUE;
625
      old_flags = new_flags;
626
    }
627
  else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
628
    {
629
      /* Non-library flags trump library flags.  The choice doesn't really
630
         matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
631
      if (old_flags & EF_MEP_LIBRARY)
632
        old_flags = new_flags;
633
    }
634
  else
635
    {
636
      /* Make sure they're for the same mach.  Allow upgrade from the "mep"
637
         mach.  */
638
      new_partial = (new_flags & EF_MEP_CPU_MASK);
639
      old_partial = (old_flags & EF_MEP_CPU_MASK);
640
      if (new_partial == old_partial)
641
        ;
642
      else if (new_partial == EF_MEP_CPU_MEP)
643
        ;
644
      else if (old_partial == EF_MEP_CPU_MEP)
645
        old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
646
      else
647
        {
648
          _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
649
          bfd_set_error (bfd_error_invalid_target);
650
          return FALSE;
651
        }
652
 
653
      /* Make sure they're for the same me_module.  Allow basic config to
654
         mix with any other.  */
655
      new_partial = (new_flags & EF_MEP_INDEX_MASK);
656
      old_partial = (old_flags & EF_MEP_INDEX_MASK);
657
      if (new_partial == old_partial)
658
        ;
659
      else if (new_partial == 0)
660
        ;
661
      else if (old_partial == 0)
662
        old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
663
      else
664
        {
665
          _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
666
          bfd_set_error (bfd_error_invalid_target);
667
          return FALSE;
668
        }
669
    }
670
 
671
  elf_elfheader (obfd)->e_flags = old_flags;
672
  last_ibfd = ibfd;
673
  return TRUE;
674
}
675
 
676
/* This will be edited by the MeP configration tool.  */
677
static const char * config_names[] =
678
{
679
  "basic"
680
  /* start-mepcfgtool */
681
  ,"default"
682
  /* end-mepcfgtool */
683
};
684
 
685
static const char * core_names[] =
686
{
687
  "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
688
};
689
 
690
static bfd_boolean
691
mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
692
{
693
  FILE *   file = (FILE *) ptr;
694
  flagword flags, partial_flags;
695
 
696
  BFD_ASSERT (abfd != NULL && ptr != NULL);
697
 
698
  /* Print normal ELF private data.  */
699
  _bfd_elf_print_private_bfd_data (abfd, ptr);
700
 
701
  flags = elf_elfheader (abfd)->e_flags;
702
  fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
703
 
704
  partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
705
  if (partial_flags < ARRAY_SIZE (core_names))
706
    fprintf (file, "  core: %s", core_names[(long)partial_flags]);
707
 
708
  partial_flags = flags & EF_MEP_INDEX_MASK;
709
  if (partial_flags < ARRAY_SIZE (config_names))
710
    fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
711
 
712
  fputc ('\n', file);
713
 
714
  return TRUE;
715
}
716
 
717
/* Return the machine subcode from the ELF e_flags header.  */
718
 
719
static int
720
elf32_mep_machine (bfd * abfd)
721
{
722
  switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
723
    {
724
    default: break;
725
    case EF_MEP_CPU_C2: return bfd_mach_mep;
726
    case EF_MEP_CPU_C3: return bfd_mach_mep;
727
    case EF_MEP_CPU_C4: return bfd_mach_mep;
728
    case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
729
    case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
730
    }
731
 
732
  return bfd_mach_mep;
733
}
734
 
735
static bfd_boolean
736
mep_elf_object_p (bfd * abfd)
737
{
738
  bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
739
  return TRUE;
740
}
741
 
742
static bfd_boolean
743
mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
744
{
745
  if (hdr->sh_flags & SHF_MEP_VLIW)
746
    * flags |= SEC_MEP_VLIW;
747
  return TRUE;
748
}
749
 
750
static bfd_boolean
751
mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
752
                       Elf_Internal_Shdr * hdr,
753
                       asection *          sec)
754
{
755
  if (sec->flags & SEC_MEP_VLIW)
756
    hdr->sh_flags |= SHF_MEP_VLIW;
757
  return TRUE;
758
}
759
 
760
 
761
#define ELF_ARCH                bfd_arch_mep
762
#define ELF_MACHINE_CODE        EM_CYGNUS_MEP
763
#define ELF_MAXPAGESIZE         0x1000
764
 
765
#define TARGET_BIG_SYM          bfd_elf32_mep_vec
766
#define TARGET_BIG_NAME         "elf32-mep"
767
 
768
#define TARGET_LITTLE_SYM       bfd_elf32_mep_little_vec
769
#define TARGET_LITTLE_NAME      "elf32-mep-little"
770
 
771
#define elf_info_to_howto_rel                   NULL
772
#define elf_info_to_howto                       mep_info_to_howto_rela
773
#define elf_backend_relocate_section            mep_elf_relocate_section
774
#define elf_backend_object_p                    mep_elf_object_p
775
#define elf_backend_section_flags               mep_elf_section_flags
776
#define elf_backend_fake_sections               mep_elf_fake_sections
777
 
778
#define bfd_elf32_bfd_reloc_type_lookup         mep_reloc_type_lookup
779
#define bfd_elf32_bfd_reloc_name_lookup         mep_reloc_name_lookup
780
#define bfd_elf32_bfd_set_private_flags         mep_elf_set_private_flags
781
#define bfd_elf32_bfd_copy_private_bfd_data     mep_elf_copy_private_bfd_data
782
#define bfd_elf32_bfd_merge_private_bfd_data    mep_elf_merge_private_bfd_data
783
#define bfd_elf32_bfd_print_private_bfd_data    mep_elf_print_private_bfd_data
784
 
785
#define elf_backend_rela_normal                 1
786
 
787
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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