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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [elf32-mep.c] - Blame information for rev 853

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

Line No. Rev Author Line
1 38 julius
/* MeP-specific support for 32-bit ELF.
2
   Copyright (C) 2001, 2002, 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,
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
      fprintf (stderr, "mep: no reloc for code %d\n", code);
158
      return NULL;
159
    }
160
 
161
  if (mep_elf_howto_table[type].type != type)
162
    {
163
      fprintf (stderr, "MeP: howto %d has type %d\n", type, mep_elf_howto_table[type].type);
164
      abort ();
165
    }
166
 
167
  return mep_elf_howto_table + type;
168
}
169
 
170
#undef MAP
171
 
172
static reloc_howto_type *
173
mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
174
{
175
  unsigned int i;
176
 
177
  for (i = 0;
178
       i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
179
       i++)
180
    if (mep_elf_howto_table[i].name != NULL
181
        && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
182
      return &mep_elf_howto_table[i];
183
 
184
  return NULL;
185
}
186
 
187
/* Perform a single relocation.  */
188
 
189
static struct bfd_link_info *mep_info;
190
static int warn_tp = 0, warn_sda = 0;
191
 
192
static bfd_vma
193
mep_lookup_global
194
    (char *    name,
195
     bfd_vma   ofs,
196
     bfd_vma * cache,
197
     int *     warn)
198
{
199
  struct bfd_link_hash_entry *h;
200
 
201
  if (*cache || *warn)
202
    return *cache;
203
 
204
  h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
205
  if (h == 0 || h->type != bfd_link_hash_defined)
206
    {
207
      *warn = ofs + 1;
208
      return 0;
209
    }
210
  *cache = (h->u.def.value
211
          + h->u.def.section->output_section->vma
212
          + h->u.def.section->output_offset);
213
  return *cache;
214
}
215
 
216
static bfd_vma
217
mep_tpoff_base (bfd_vma ofs)
218
{
219
  static bfd_vma cache = 0;
220
  return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
221
}
222
 
223
static bfd_vma
224
mep_sdaoff_base (bfd_vma ofs)
225
{
226
  static bfd_vma cache = 0;
227
  return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
228
}
229
 
230
static bfd_reloc_status_type
231
mep_final_link_relocate
232
    (reloc_howto_type *  howto,
233
     bfd *               input_bfd,
234
     asection *          input_section,
235
     bfd_byte *          contents,
236
     Elf_Internal_Rela * rel,
237
     bfd_vma             relocation)
238
{
239
  unsigned long u;
240
  long s;
241
  unsigned char *byte;
242
  bfd_vma pc;
243
  bfd_reloc_status_type r = bfd_reloc_ok;
244
  int e2, e4;
245
 
246
  if (bfd_big_endian (input_bfd))
247
    {
248
      e2 = 0;
249
      e4 = 0;
250
    }
251
  else
252
    {
253
      e2 = 1;
254
      e4 = 3;
255
    }
256
 
257
  pc = (input_section->output_section->vma
258
        + input_section->output_offset
259
        + rel->r_offset);
260
 
261
  s = relocation + rel->r_addend;
262
 
263
  byte = (unsigned char *)contents + rel->r_offset;
264
 
265
  if (howto->type == R_MEP_PCREL24A2
266
      && s == 0
267
      && pc >= 0x800000)
268
    {
269
      /* This is an unreachable branch to an undefined weak function.
270
         Silently ignore it, since the opcode can't do that but should
271
         never be executed anyway.  */
272
      return bfd_reloc_ok;
273
    }
274
 
275
  if (howto->pc_relative)
276
    s -= pc;
277
 
278
  u = (unsigned long) s;
279
 
280
  switch (howto->type)
281
    {
282
    /* MEPRELOC:APPLY */
283
    /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
284
    case R_MEP_8: /* 76543210 */
285
      if (u > 255) r = bfd_reloc_overflow;
286
      byte[0] = (u & 0xff);
287
      break;
288
    case R_MEP_16: /* fedcba9876543210 */
289
      if (u > 65535) r = bfd_reloc_overflow;
290
      byte[0^e2] = ((u >> 8) & 0xff);
291
      byte[1^e2] = (u & 0xff);
292
      break;
293
    case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
294
      byte[0^e4] = ((u >> 24) & 0xff);
295
      byte[1^e4] = ((u >> 16) & 0xff);
296
      byte[2^e4] = ((u >> 8) & 0xff);
297
      byte[3^e4] = (u & 0xff);
298
      break;
299
    case R_MEP_PCREL8A2: /* --------7654321- */
300
      if (-128 > s || s > 127) r = bfd_reloc_overflow;
301
      byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
302
      break;
303
    case R_MEP_PCREL12A2: /* ----ba987654321- */
304
      if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
305
      byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
306
      byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
307
      break;
308
    case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
309
      if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
310
      byte[2^e2] = ((s >> 9) & 0xff);
311
      byte[3^e2] = ((s >> 1) & 0xff);
312
      break;
313
    case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
314
      if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
315
      byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
316
      byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
317
      byte[2^e2] = ((s >> 16) & 0xff);
318
      byte[3^e2] = ((s >> 8) & 0xff);
319
      break;
320
    case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
321
      if (u > 16777215) r = bfd_reloc_overflow;
322
      byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
323
      byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
324
      byte[2^e2] = ((u >> 16) & 0xff);
325
      byte[3^e2] = ((u >> 8) & 0xff);
326
      break;
327
    case R_MEP_LOW16: /* ----------------fedcba9876543210 */
328
      byte[2^e2] = ((u >> 8) & 0xff);
329
      byte[3^e2] = (u & 0xff);
330
      break;
331
    case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
332
      byte[2^e2] = ((u >> 24) & 0xff);
333
      byte[3^e2] = ((u >> 16) & 0xff);
334
      break;
335
    case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
336
      if (s & 0x8000)
337
        s += 0x10000;
338
      byte[2^e2] = ((s >> 24) & 0xff);
339
      byte[3^e2] = ((s >> 16) & 0xff);
340
      break;
341
    case R_MEP_GPREL: /* ----------------fedcba9876543210 */
342
      s -= mep_sdaoff_base(rel->r_offset);
343
      if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
344
      byte[2^e2] = ((s >> 8) & 0xff);
345
      byte[3^e2] = (s & 0xff);
346
      break;
347
    case R_MEP_TPREL: /* ----------------fedcba9876543210 */
348
      s -= mep_tpoff_base(rel->r_offset);
349
      if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
350
      byte[2^e2] = ((s >> 8) & 0xff);
351
      byte[3^e2] = (s & 0xff);
352
      break;
353
    case R_MEP_TPREL7: /* ---------6543210 */
354
      u -= mep_tpoff_base(rel->r_offset);
355
      if (u > 127) r = bfd_reloc_overflow;
356
      byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
357
      break;
358
    case R_MEP_TPREL7A2: /* ---------654321- */
359
      u -= mep_tpoff_base(rel->r_offset);
360
      if (u > 127) r = bfd_reloc_overflow;
361
      byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
362
      break;
363
    case R_MEP_TPREL7A4: /* ---------65432-- */
364
      u -= mep_tpoff_base(rel->r_offset);
365
      if (u > 127) r = bfd_reloc_overflow;
366
      byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
367
      break;
368
    case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
369
      if (u > 16777215) r = bfd_reloc_overflow;
370
      byte[1^e2] = (u & 0xff);
371
      byte[2^e2] = ((u >> 16) & 0xff);
372
      byte[3^e2] = ((u >> 8) & 0xff);
373
      break;
374
    case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
375
      if (u > 16777215) r = bfd_reloc_overflow;
376
      byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
377
      byte[2^e2] = ((u >> 16) & 0xff);
378
      byte[3^e2] = ((u >> 8) & 0xff);
379
      break;
380
    case R_MEP_GNU_VTINHERIT: /* ---------------- */
381
      break;
382
    case R_MEP_GNU_VTENTRY: /* ---------------- */
383
      break;
384
    /* MEPRELOC:END */
385
    default:
386
      abort ();
387
    }
388
 
389
  return r;
390
}
391
 
392
/* Set the howto pointer for a MEP ELF reloc.  */
393
 
394
static void
395
mep_info_to_howto_rela
396
    (bfd *               abfd ATTRIBUTE_UNUSED,
397
     arelent *           cache_ptr,
398
     Elf_Internal_Rela * dst)
399
{
400
  unsigned int r_type;
401
 
402
  r_type = ELF32_R_TYPE (dst->r_info);
403
  cache_ptr->howto = & mep_elf_howto_table [r_type];
404
}
405
 
406
/* Relocate a MEP ELF section.
407
   There is some attempt to make this function usable for many architectures,
408
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
409
   if only to serve as a learning tool.
410
 
411
   The RELOCATE_SECTION function is called by the new ELF backend linker
412
   to handle the relocations for a section.
413
 
414
   The relocs are always passed as Rela structures; if the section
415
   actually uses Rel structures, the r_addend field will always be
416
   zero.
417
 
418
   This function is responsible for adjusting the section contents as
419
   necessary, and (if using Rela relocs and generating a relocatable
420
   output file) adjusting the reloc addend as necessary.
421
 
422
   This function does not have to worry about setting the reloc
423
   address or the reloc symbol index.
424
 
425
   LOCAL_SYMS is a pointer to the swapped in local symbols.
426
 
427
   LOCAL_SECTIONS is an array giving the section in the input file
428
   corresponding to the st_shndx field of each local symbol.
429
 
430
   The global hash table entry for the global symbols can be found
431
   via elf_sym_hashes (input_bfd).
432
 
433
   When generating relocatable output, this function must handle
434
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
435
   going to be the section symbol corresponding to the output
436
   section, which means that the addend must be adjusted
437
   accordingly.  */
438
 
439
static bfd_boolean
440
mep_elf_relocate_section
441
    (bfd *                   output_bfd ATTRIBUTE_UNUSED,
442
     struct bfd_link_info *  info,
443
     bfd *                   input_bfd,
444
     asection *              input_section,
445
     bfd_byte *              contents,
446
     Elf_Internal_Rela *     relocs,
447
     Elf_Internal_Sym *      local_syms,
448
     asection **             local_sections)
449
{
450
  Elf_Internal_Shdr *           symtab_hdr;
451
  struct elf_link_hash_entry ** sym_hashes;
452
  Elf_Internal_Rela *           rel;
453
  Elf_Internal_Rela *           relend;
454
 
455
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
456
  sym_hashes = elf_sym_hashes (input_bfd);
457
  relend     = relocs + input_section->reloc_count;
458
 
459
  mep_info = info;
460
 
461
  for (rel = relocs; rel < relend; rel ++)
462
    {
463
      reloc_howto_type *           howto;
464
      unsigned long                r_symndx;
465
      Elf_Internal_Sym *           sym;
466
      asection *                   sec;
467
      struct elf_link_hash_entry * h;
468
      bfd_vma                      relocation;
469
      bfd_reloc_status_type        r;
470
      const char *                 name = NULL;
471
      int                          r_type;
472
 
473
      r_type = ELF32_R_TYPE (rel->r_info);
474
      r_symndx = ELF32_R_SYM (rel->r_info);
475
      howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
476
      h      = NULL;
477
      sym    = NULL;
478
      sec    = NULL;
479
 
480
      if (r_symndx < symtab_hdr->sh_info)
481
        {
482
          sym = local_syms + r_symndx;
483
          sec = local_sections [r_symndx];
484
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
485
 
486
          name = bfd_elf_string_from_elf_section
487
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
488
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
489
        }
490
      else
491
        {
492
          bfd_boolean warned, unresolved_reloc;
493
 
494
          RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
495
                                  r_symndx, symtab_hdr, sym_hashes,
496
                                  h, sec, relocation,
497
                                  unresolved_reloc, warned);
498
 
499
          name = h->root.root.string;
500
        }
501
 
502
      if (sec != NULL && elf_discarded_section (sec))
503
        {
504
          /* For relocs against symbols from removed linkonce sections,
505
             or sections discarded by a linker script, we just want the
506
             section contents zeroed.  Avoid any special processing.  */
507
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
508
          rel->r_info = 0;
509
          rel->r_addend = 0;
510
          continue;
511
        }
512
 
513
      if (info->relocatable)
514
        continue;
515
 
516
      if (r_type == R_RELC)
517
        r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
518
                                                contents, rel, relocation);
519
      else
520
        r = mep_final_link_relocate (howto, input_bfd, input_section,
521
                                     contents, rel, relocation);
522
 
523
      if (r != bfd_reloc_ok)
524
        {
525
          const char * msg = (const char *) NULL;
526
 
527
          switch (r)
528
            {
529
            case bfd_reloc_overflow:
530
              r = info->callbacks->reloc_overflow
531
                (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
532
                 input_bfd, input_section, rel->r_offset);
533
              break;
534
 
535
            case bfd_reloc_undefined:
536
              r = info->callbacks->undefined_symbol
537
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
538
              break;
539
 
540
            case bfd_reloc_outofrange:
541
              msg = _("internal error: out of range error");
542
              break;
543
 
544
            case bfd_reloc_notsupported:
545
              msg = _("internal error: unsupported relocation error");
546
              break;
547
 
548
            case bfd_reloc_dangerous:
549
              msg = _("internal error: dangerous relocation");
550
              break;
551
 
552
            default:
553
              msg = _("internal error: unknown error");
554
              break;
555
            }
556
 
557
          if (msg)
558
            r = info->callbacks->warning
559
              (info, msg, name, input_bfd, input_section, rel->r_offset);
560
 
561
          if (! r)
562
            return FALSE;
563
        }
564
    }
565
 
566
  if (warn_tp)
567
    info->callbacks->undefined_symbol
568
      (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
569
  if (warn_sda)
570
    info->callbacks->undefined_symbol
571
      (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
572
  if (warn_sda || warn_tp)
573
    return FALSE;
574
 
575
  return TRUE;
576
}
577
 
578
/* Function to set the ELF flag bits.  */
579
 
580
static bfd_boolean
581
mep_elf_set_private_flags (bfd *    abfd,
582
                           flagword flags)
583
{
584
  elf_elfheader (abfd)->e_flags = flags;
585
  elf_flags_init (abfd) = TRUE;
586
  return TRUE;
587
}
588
 
589
static bfd_boolean
590
mep_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
591
{
592
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
593
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
594
    return TRUE;
595
 
596
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
597
  elf_flags_init (obfd) = TRUE;
598
 
599
  /* Copy object attributes.  */
600
  _bfd_elf_copy_obj_attributes (ibfd, obfd);
601
 
602
  return TRUE;
603
}
604
 
605
/* Merge backend specific data from an object file to the output
606
   object file when linking.  */
607
 
608
static bfd_boolean
609
mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
610
{
611
  static bfd *last_ibfd = 0;
612
  flagword old_flags, new_flags;
613
  flagword old_partial, new_partial;
614
 
615
  /* Check if we have the same endianess.  */
616
  if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
617
    return FALSE;
618
 
619
  new_flags = elf_elfheader (ibfd)->e_flags;
620
  old_flags = elf_elfheader (obfd)->e_flags;
621
 
622
#ifdef DEBUG
623
  _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
624
                      ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
625
#endif
626
 
627
    /* First call, no flags set.  */
628
    if (!elf_flags_init (obfd))
629
    {
630
      elf_flags_init (obfd) = TRUE;
631
      old_flags = new_flags;
632
    }
633
  else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
634
    {
635
      /* Non-library flags trump library flags.  The choice doesn't really
636
         matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
637
      if (old_flags & EF_MEP_LIBRARY)
638
        old_flags = new_flags;
639
    }
640
  else
641
    {
642
      /* Make sure they're for the same mach.  Allow upgrade from the "mep"
643
         mach.  */
644
      new_partial = (new_flags & EF_MEP_CPU_MASK);
645
      old_partial = (old_flags & EF_MEP_CPU_MASK);
646
      if (new_partial == old_partial)
647
        ;
648
      else if (new_partial == EF_MEP_CPU_MEP)
649
        ;
650
      else if (old_partial == EF_MEP_CPU_MEP)
651
        old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
652
      else
653
        {
654
          _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
655
          bfd_set_error (bfd_error_invalid_target);
656
          return FALSE;
657
        }
658
 
659
      /* Make sure they're for the same me_module.  Allow basic config to
660
         mix with any other.  */
661
      new_partial = (new_flags & EF_MEP_INDEX_MASK);
662
      old_partial = (old_flags & EF_MEP_INDEX_MASK);
663
      if (new_partial == old_partial)
664
        ;
665
      else if (new_partial == 0)
666
        ;
667
      else if (old_partial == 0)
668
        old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
669
      else
670
        {
671
          _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
672
          bfd_set_error (bfd_error_invalid_target);
673
          return FALSE;
674
        }
675
    }
676
 
677
  elf_elfheader (obfd)->e_flags = old_flags;
678
  last_ibfd = ibfd;
679
  return TRUE;
680
}
681
 
682
/* This will be edited by the MeP configration tool.  */
683
static const char * config_names[] =
684
{
685
  "basic"
686
  /* start-mepcfgtool */
687
  ,"simple"
688
  ,"fmax"
689
  /* end-mepcfgtool */
690
};
691
 
692
static const char * core_names[] =
693
{
694
  "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
695
};
696
 
697
static bfd_boolean
698
mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
699
{
700
  FILE *   file = (FILE *) ptr;
701
  flagword flags, partial_flags;
702
 
703
  BFD_ASSERT (abfd != NULL && ptr != NULL);
704
 
705
  /* Print normal ELF private data.  */
706
  _bfd_elf_print_private_bfd_data (abfd, ptr);
707
 
708
  flags = elf_elfheader (abfd)->e_flags;
709
  fprintf (file, _("private flags = 0x%lx"), (long)flags);
710
 
711
  partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
712
  if (partial_flags < ARRAY_SIZE (core_names))
713
    fprintf (file, "  core: %s", core_names[(long)partial_flags]);
714
 
715
  partial_flags = flags & EF_MEP_INDEX_MASK;
716
  if (partial_flags < ARRAY_SIZE (config_names))
717
    fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
718
 
719
  fputc ('\n', file);
720
 
721
  return TRUE;
722
}
723
 
724
/* Return the machine subcode from the ELF e_flags header.  */
725
 
726
static int
727
elf32_mep_machine (bfd * abfd)
728
{
729
  switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
730
    {
731
    default: break;
732
    case EF_MEP_CPU_C2: return bfd_mach_mep;
733
    case EF_MEP_CPU_C3: return bfd_mach_mep;
734
    case EF_MEP_CPU_C4: return bfd_mach_mep;
735
    case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
736
    }
737
 
738
  return bfd_mach_mep;
739
}
740
 
741
static bfd_boolean
742
mep_elf_object_p (bfd * abfd)
743
{
744
  bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
745
  return TRUE;
746
}
747
 
748
static bfd_boolean
749
mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
750
{
751
  if (hdr->sh_flags & SHF_MEP_VLIW)
752
    * flags |= SEC_MEP_VLIW;
753
  return TRUE;
754
}
755
 
756
static bfd_boolean
757
mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
758
                       Elf_Internal_Shdr * hdr,
759
                       asection *          sec)
760
{
761
  if (sec->flags & SEC_MEP_VLIW)
762
    hdr->sh_flags |= SHF_MEP_VLIW;
763
  return TRUE;
764
}
765
 
766
 
767
#define ELF_ARCH                bfd_arch_mep
768
#define ELF_MACHINE_CODE        EM_CYGNUS_MEP
769
#define ELF_MAXPAGESIZE         0x1000
770
 
771
#define TARGET_BIG_SYM          bfd_elf32_mep_vec
772
#define TARGET_BIG_NAME         "elf32-mep"
773
 
774
#define TARGET_LITTLE_SYM       bfd_elf32_mep_little_vec
775
#define TARGET_LITTLE_NAME      "elf32-mep-little"
776
 
777
#define elf_info_to_howto_rel                   NULL
778
#define elf_info_to_howto                       mep_info_to_howto_rela
779
#define elf_backend_relocate_section            mep_elf_relocate_section
780
#define elf_backend_object_p                    mep_elf_object_p
781
#define elf_backend_section_flags               mep_elf_section_flags
782
#define elf_backend_fake_sections               mep_elf_fake_sections
783
 
784
#define bfd_elf32_bfd_reloc_type_lookup         mep_reloc_type_lookup
785
#define bfd_elf32_bfd_reloc_name_lookup         mep_reloc_name_lookup
786
#define bfd_elf32_bfd_set_private_flags         mep_elf_set_private_flags
787
#define bfd_elf32_bfd_copy_private_bfd_data     mep_elf_copy_private_bfd_data
788
#define bfd_elf32_bfd_merge_private_bfd_data    mep_elf_merge_private_bfd_data
789
#define bfd_elf32_bfd_print_private_bfd_data    mep_elf_print_private_bfd_data
790
 
791
#define elf_backend_rela_normal                 1
792
 
793
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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