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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 14 khays
/*  MSP430-specific support for 32-bit ELF
2
    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010
3
    Free Software Foundation, Inc.
4
    Contributed by Dmitry Diky <diwil@mail.ru>
5
 
6
    This file is part of BFD, the Binary File Descriptor library.
7
 
8
    This program is free software; you can redistribute it and/or modify
9
    it under the terms of the GNU General Public License as published by
10
    the Free Software Foundation; either version 3 of the License, or
11
    (at your option) any later version.
12
 
13
    This program is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
    GNU General Public License for more details.
17
 
18
    You should have received a copy of the GNU General Public License
19
    along with this program; if not, write to the Free Software
20
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
    MA 02110-1301, USA.  */
22
 
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libiberty.h"
26
#include "libbfd.h"
27
#include "elf-bfd.h"
28
#include "elf/msp430.h"
29
 
30
/* Use RELA instead of REL.  */
31
#undef USE_REL
32
 
33
static reloc_howto_type elf_msp430_howto_table[] =
34
{
35
  HOWTO (R_MSP430_NONE,         /* type */
36
         0,                      /* rightshift */
37
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
38
         32,                    /* bitsize */
39
         FALSE,                 /* pc_relative */
40
         0,                      /* bitpos */
41
         complain_overflow_bitfield,/* complain_on_overflow */
42
         bfd_elf_generic_reloc, /* special_function */
43
         "R_MSP430_NONE",       /* name */
44
         FALSE,                 /* partial_inplace */
45
         0,                      /* src_mask */
46
         0,                      /* dst_mask */
47
         FALSE),                /* pcrel_offset */
48
 
49
  HOWTO (R_MSP430_32,           /* type */
50
         0,                      /* rightshift */
51
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
52
         32,                    /* bitsize */
53
         FALSE,                 /* pc_relative */
54
         0,                      /* bitpos */
55
         complain_overflow_bitfield,/* complain_on_overflow */
56
         bfd_elf_generic_reloc, /* special_function */
57
         "R_MSP430_32",         /* name */
58
         FALSE,                 /* partial_inplace */
59
         0xffffffff,            /* src_mask */
60
         0xffffffff,            /* dst_mask */
61
         FALSE),                /* pcrel_offset */
62
 
63
  /* A 13 bit PC relative relocation.  */
64
  HOWTO (R_MSP430_10_PCREL,     /* type */
65
         1,                     /* rightshift */
66
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
67
         10,                    /* bitsize */
68
         TRUE,                  /* pc_relative */
69
         0,                      /* bitpos */
70
         complain_overflow_bitfield,/* complain_on_overflow */
71
         bfd_elf_generic_reloc, /* special_function */
72
         "R_MSP430_13_PCREL",   /* name */
73
         FALSE,                 /* partial_inplace */
74
         0xfff,                 /* src_mask */
75
         0xfff,                 /* dst_mask */
76
         TRUE),                 /* pcrel_offset */
77
 
78
  /* A 16 bit absolute relocation.  */
79
  HOWTO (R_MSP430_16,           /* type */
80
         0,                      /* rightshift */
81
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
82
         16,                    /* bitsize */
83
         FALSE,                 /* pc_relative */
84
         0,                      /* bitpos */
85
         complain_overflow_dont,/* complain_on_overflow */
86
         bfd_elf_generic_reloc, /* special_function */
87
         "R_MSP430_16",         /* name */
88
         FALSE,                 /* partial_inplace */
89
         0,                      /* src_mask */
90
         0xffff,                /* dst_mask */
91
         FALSE),                /* pcrel_offset */
92
 
93
  /* A 16 bit absolute relocation for command address.  */
94
  HOWTO (R_MSP430_16_PCREL,     /* type */
95
         1,                     /* rightshift */
96
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
97
         16,                    /* bitsize */
98
         TRUE,                  /* pc_relative */
99
         0,                      /* bitpos */
100
         complain_overflow_dont,/* complain_on_overflow */
101
         bfd_elf_generic_reloc, /* special_function */
102
         "R_MSP430_16_PCREL",   /* name */
103
         FALSE,                 /* partial_inplace */
104
         0,                      /* src_mask */
105
         0xffff,                /* dst_mask */
106
         TRUE),                 /* pcrel_offset */
107
 
108
  /* A 16 bit absolute relocation, byte operations.  */
109
  HOWTO (R_MSP430_16_BYTE,      /* type */
110
         0,                      /* rightshift */
111
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
112
         16,                    /* bitsize */
113
         FALSE,                 /* pc_relative */
114
         0,                      /* bitpos */
115
         complain_overflow_dont,/* complain_on_overflow */
116
         bfd_elf_generic_reloc, /* special_function */
117
         "R_MSP430_16_BYTE",    /* name */
118
         FALSE,                 /* partial_inplace */
119
         0xffff,                /* src_mask */
120
         0xffff,                /* dst_mask */
121
         FALSE),                /* pcrel_offset */
122
 
123
  /* A 16 bit absolute relocation for command address.  */
124
  HOWTO (R_MSP430_16_PCREL_BYTE,/* type */
125
         1,                     /* rightshift */
126
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
127
         16,                    /* bitsize */
128
         TRUE,                  /* pc_relative */
129
         0,                      /* bitpos */
130
         complain_overflow_dont,/* complain_on_overflow */
131
         bfd_elf_generic_reloc, /* special_function */
132
         "R_MSP430_16_PCREL_BYTE",/* name */
133
         FALSE,                 /* partial_inplace */
134
         0xffff,                /* src_mask */
135
         0xffff,                /* dst_mask */
136
         TRUE),                 /* pcrel_offset */
137
 
138
  /* A 13 bit PC relative relocation for complicated polymorphs.  */
139
  HOWTO (R_MSP430_2X_PCREL,     /* type */
140
         1,                     /* rightshift */
141
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
142
         10,                    /* bitsize */
143
         TRUE,                  /* pc_relative */
144
         0,                      /* bitpos */
145
         complain_overflow_bitfield,/* complain_on_overflow */
146
         bfd_elf_generic_reloc, /* special_function */
147
         "R_MSP430_2X_PCREL",   /* name */
148
         FALSE,                 /* partial_inplace */
149
         0xfff,                 /* src_mask */
150
         0xfff,                 /* dst_mask */
151
         TRUE),                 /* pcrel_offset */
152
 
153
  /* A 16 bit relaxable relocation for command address.  */
154
  HOWTO (R_MSP430_RL_PCREL,     /* type */
155
         1,                     /* rightshift */
156
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
157
         16,                    /* bitsize */
158
         TRUE,                  /* pc_relative */
159
         0,                      /* bitpos */
160
         complain_overflow_dont,/* complain_on_overflow */
161
         bfd_elf_generic_reloc, /* special_function */
162
         "R_MSP430_RL_PCREL",   /* name */
163
         FALSE,                 /* partial_inplace */
164
         0,                      /* src_mask */
165
         0xffff,                /* dst_mask */
166
         TRUE)                  /* pcrel_offset */
167
};
168
 
169
/* Map BFD reloc types to MSP430 ELF reloc types.  */
170
 
171
struct msp430_reloc_map
172
{
173
  bfd_reloc_code_real_type bfd_reloc_val;
174
  unsigned int elf_reloc_val;
175
};
176
 
177
static const struct msp430_reloc_map msp430_reloc_map[] =
178
  {
179
    {BFD_RELOC_NONE,                 R_MSP430_NONE},
180
    {BFD_RELOC_32,                   R_MSP430_32},
181
    {BFD_RELOC_MSP430_10_PCREL,      R_MSP430_10_PCREL},
182
    {BFD_RELOC_16,                   R_MSP430_16_BYTE},
183
    {BFD_RELOC_MSP430_16_PCREL,      R_MSP430_16_PCREL},
184
    {BFD_RELOC_MSP430_16,            R_MSP430_16},
185
    {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
186
    {BFD_RELOC_MSP430_16_BYTE,       R_MSP430_16_BYTE},
187
    {BFD_RELOC_MSP430_2X_PCREL,      R_MSP430_2X_PCREL},
188
    {BFD_RELOC_MSP430_RL_PCREL,      R_MSP430_RL_PCREL}
189
  };
190
 
191
static reloc_howto_type *
192
bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
193
                                 bfd_reloc_code_real_type code)
194
{
195
  unsigned int i;
196
 
197
  for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
198
    if (msp430_reloc_map[i].bfd_reloc_val == code)
199
      return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
200
 
201
  return NULL;
202
}
203
 
204
static reloc_howto_type *
205
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
206
                                 const char *r_name)
207
{
208
  unsigned int i;
209
 
210
  for (i = 0;
211
       i < (sizeof (elf_msp430_howto_table)
212
            / sizeof (elf_msp430_howto_table[0]));
213
       i++)
214
    if (elf_msp430_howto_table[i].name != NULL
215
        && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
216
      return &elf_msp430_howto_table[i];
217
 
218
  return NULL;
219
}
220
 
221
/* Set the howto pointer for an MSP430 ELF reloc.  */
222
 
223
static void
224
msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
225
                           arelent * cache_ptr,
226
                           Elf_Internal_Rela * dst)
227
{
228
  unsigned int r_type;
229
 
230
  r_type = ELF32_R_TYPE (dst->r_info);
231
  BFD_ASSERT (r_type < (unsigned int) R_MSP430_max);
232
  cache_ptr->howto = &elf_msp430_howto_table[r_type];
233
}
234
 
235
/* Look through the relocs for a section during the first phase.
236
   Since we don't do .gots or .plts, we just need to consider the
237
   virtual table relocs for gc.  */
238
 
239
static bfd_boolean
240
elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info,
241
                           asection * sec, const Elf_Internal_Rela * relocs)
242
{
243
  Elf_Internal_Shdr *symtab_hdr;
244
  struct elf_link_hash_entry **sym_hashes;
245
  const Elf_Internal_Rela *rel;
246
  const Elf_Internal_Rela *rel_end;
247
 
248
  if (info->relocatable)
249
    return TRUE;
250
 
251
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
252
  sym_hashes = elf_sym_hashes (abfd);
253
 
254
  rel_end = relocs + sec->reloc_count;
255
  for (rel = relocs; rel < rel_end; rel++)
256
    {
257
      struct elf_link_hash_entry *h;
258
      unsigned long r_symndx;
259
 
260
      r_symndx = ELF32_R_SYM (rel->r_info);
261
      if (r_symndx < symtab_hdr->sh_info)
262
        h = NULL;
263
      else
264
        {
265
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
266
          while (h->root.type == bfd_link_hash_indirect
267
                 || h->root.type == bfd_link_hash_warning)
268
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
269
        }
270
    }
271
 
272
  return TRUE;
273
}
274
 
275
/* Perform a single relocation.  By default we use the standard BFD
276
   routines, but a few relocs, we have to do them ourselves.  */
277
 
278
static bfd_reloc_status_type
279
msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
280
                            asection * input_section, bfd_byte * contents,
281
                            Elf_Internal_Rela * rel, bfd_vma relocation)
282
{
283
  bfd_reloc_status_type r = bfd_reloc_ok;
284
  bfd_vma x;
285
  bfd_signed_vma srel;
286
 
287
  switch (howto->type)
288
    {
289
    case R_MSP430_10_PCREL:
290
      contents += rel->r_offset;
291
      srel = (bfd_signed_vma) relocation;
292
      srel += rel->r_addend;
293
      srel -= rel->r_offset;
294
      srel -= 2;                /* Branch instructions add 2 to the PC...  */
295
      srel -= (input_section->output_section->vma +
296
               input_section->output_offset);
297
 
298
      if (srel & 1)
299
        return bfd_reloc_outofrange;
300
 
301
      /* MSP430 addresses commands as words.  */
302
      srel >>= 1;
303
 
304
      /* Check for an overflow.  */
305
      if (srel < -512 || srel > 511)
306
        return bfd_reloc_overflow;
307
 
308
      x = bfd_get_16 (input_bfd, contents);
309
      x = (x & 0xfc00) | (srel & 0x3ff);
310
      bfd_put_16 (input_bfd, x, contents);
311
      break;
312
 
313
    case R_MSP430_2X_PCREL:
314
      contents += rel->r_offset;
315
      srel = (bfd_signed_vma) relocation;
316
      srel += rel->r_addend;
317
      srel -= rel->r_offset;
318
      srel -= 2;                /* Branch instructions add 2 to the PC...  */
319
      srel -= (input_section->output_section->vma +
320
               input_section->output_offset);
321
 
322
      if (srel & 1)
323
        return bfd_reloc_outofrange;
324
 
325
      /* MSP430 addresses commands as words.  */
326
      srel >>= 1;
327
 
328
      /* Check for an overflow.  */
329
      if (srel < -512 || srel > 511)
330
        return bfd_reloc_overflow;
331
 
332
      x = bfd_get_16 (input_bfd, contents);
333
      x = (x & 0xfc00) | (srel & 0x3ff);
334
      bfd_put_16 (input_bfd, x, contents);
335
      /* Handle second jump instruction.  */
336
      x = bfd_get_16 (input_bfd, contents - 2);
337
      srel += 1;
338
      x = (x & 0xfc00) | (srel & 0x3ff);
339
      bfd_put_16 (input_bfd, x, contents - 2);
340
      break;
341
 
342
    case R_MSP430_16_PCREL:
343
    case R_MSP430_RL_PCREL:
344
      contents += rel->r_offset;
345
      srel = (bfd_signed_vma) relocation;
346
      srel += rel->r_addend;
347
      srel -= rel->r_offset;
348
      /* Only branch instructions add 2 to the PC...  */
349
      srel -= (input_section->output_section->vma +
350
               input_section->output_offset);
351
 
352
      if (srel & 1)
353
        return bfd_reloc_outofrange;
354
 
355
      bfd_put_16 (input_bfd, srel & 0xffff, contents);
356
      break;
357
 
358
    case R_MSP430_16_PCREL_BYTE:
359
      contents += rel->r_offset;
360
      srel = (bfd_signed_vma) relocation;
361
      srel += rel->r_addend;
362
      srel -= rel->r_offset;
363
      /* Only branch instructions add 2 to the PC...  */
364
      srel -= (input_section->output_section->vma +
365
               input_section->output_offset);
366
 
367
      bfd_put_16 (input_bfd, srel & 0xffff, contents);
368
      break;
369
 
370
    case R_MSP430_16_BYTE:
371
      contents += rel->r_offset;
372
      srel = (bfd_signed_vma) relocation;
373
      srel += rel->r_addend;
374
      bfd_put_16 (input_bfd, srel & 0xffff, contents);
375
      break;
376
 
377
    case R_MSP430_16:
378
      contents += rel->r_offset;
379
      srel = (bfd_signed_vma) relocation;
380
      srel += rel->r_addend;
381
 
382
      if (srel & 1)
383
        return bfd_reloc_notsupported;
384
 
385
      bfd_put_16 (input_bfd, srel & 0xffff, contents);
386
      break;
387
 
388
    default:
389
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
390
                                    contents, rel->r_offset,
391
                                    relocation, rel->r_addend);
392
    }
393
 
394
  return r;
395
}
396
 
397
/* Relocate an MSP430 ELF section.  */
398
 
399
static bfd_boolean
400
elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
401
                               struct bfd_link_info * info,
402
                               bfd * input_bfd,
403
                               asection * input_section,
404
                               bfd_byte * contents,
405
                               Elf_Internal_Rela * relocs,
406
                               Elf_Internal_Sym * local_syms,
407
                               asection ** local_sections)
408
{
409
  Elf_Internal_Shdr *symtab_hdr;
410
  struct elf_link_hash_entry **sym_hashes;
411
  Elf_Internal_Rela *rel;
412
  Elf_Internal_Rela *relend;
413
 
414
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
415
  sym_hashes = elf_sym_hashes (input_bfd);
416
  relend = relocs + input_section->reloc_count;
417
 
418
  for (rel = relocs; rel < relend; rel++)
419
    {
420
      reloc_howto_type *howto;
421
      unsigned long r_symndx;
422
      Elf_Internal_Sym *sym;
423
      asection *sec;
424
      struct elf_link_hash_entry *h;
425
      bfd_vma relocation;
426
      bfd_reloc_status_type r;
427
      const char *name = NULL;
428
      int r_type;
429
 
430
      r_type = ELF32_R_TYPE (rel->r_info);
431
      r_symndx = ELF32_R_SYM (rel->r_info);
432
      howto = elf_msp430_howto_table + r_type;
433
      h = NULL;
434
      sym = NULL;
435
      sec = NULL;
436
 
437
      if (r_symndx < symtab_hdr->sh_info)
438
        {
439
          sym = local_syms + r_symndx;
440
          sec = local_sections[r_symndx];
441
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
442
 
443
          name = bfd_elf_string_from_elf_section
444
              (input_bfd, symtab_hdr->sh_link, sym->st_name);
445
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
446
        }
447
      else
448
        {
449
          bfd_boolean unresolved_reloc, warned;
450
 
451
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
452
                                   r_symndx, symtab_hdr, sym_hashes,
453
                                   h, sec, relocation,
454
                                   unresolved_reloc, warned);
455
        }
456
 
457
      if (sec != NULL && elf_discarded_section (sec))
458
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
459
                                         rel, relend, howto, contents);
460
 
461
      if (info->relocatable)
462
        continue;
463
 
464
      r = msp430_final_link_relocate (howto, input_bfd, input_section,
465
                                      contents, rel, relocation);
466
 
467
      if (r != bfd_reloc_ok)
468
        {
469
          const char *msg = (const char *) NULL;
470
 
471
          switch (r)
472
            {
473
            case bfd_reloc_overflow:
474
              r = info->callbacks->reloc_overflow
475
                  (info, (h ? &h->root : NULL), name, howto->name,
476
                   (bfd_vma) 0, input_bfd, input_section,
477
                   rel->r_offset);
478
              break;
479
 
480
            case bfd_reloc_undefined:
481
              r = info->callbacks->undefined_symbol
482
                  (info, name, input_bfd, input_section, rel->r_offset, TRUE);
483
              break;
484
 
485
            case bfd_reloc_outofrange:
486
              msg = _("internal error: out of range error");
487
              break;
488
 
489
            case bfd_reloc_notsupported:
490
              msg = _("internal error: unsupported relocation error");
491
              break;
492
 
493
            case bfd_reloc_dangerous:
494
              msg = _("internal error: dangerous relocation");
495
              break;
496
 
497
            default:
498
              msg = _("internal error: unknown error");
499
              break;
500
            }
501
 
502
          if (msg)
503
            r = info->callbacks->warning
504
                (info, msg, name, input_bfd, input_section, rel->r_offset);
505
 
506
          if (!r)
507
            return FALSE;
508
        }
509
 
510
    }
511
 
512
  return TRUE;
513
}
514
 
515
/* The final processing done just before writing out a MSP430 ELF object
516
   file.  This gets the MSP430 architecture right based on the machine
517
   number.  */
518
 
519
static void
520
bfd_elf_msp430_final_write_processing (bfd * abfd,
521
                                       bfd_boolean linker ATTRIBUTE_UNUSED)
522
{
523
  unsigned long val;
524
 
525
  switch (bfd_get_mach (abfd))
526
    {
527
    default:
528
    case bfd_mach_msp110:
529
      val = E_MSP430_MACH_MSP430x11x1;
530
      break;
531
 
532
    case bfd_mach_msp11:
533
      val = E_MSP430_MACH_MSP430x11;
534
      break;
535
 
536
    case bfd_mach_msp12:
537
      val = E_MSP430_MACH_MSP430x12;
538
      break;
539
 
540
    case bfd_mach_msp13:
541
      val = E_MSP430_MACH_MSP430x13;
542
      break;
543
 
544
    case bfd_mach_msp14:
545
      val = E_MSP430_MACH_MSP430x14;
546
      break;
547
 
548
    case bfd_mach_msp15:
549
      val = E_MSP430_MACH_MSP430x15;
550
      break;
551
 
552
    case bfd_mach_msp16:
553
      val = E_MSP430_MACH_MSP430x16;
554
      break;
555
 
556
    case bfd_mach_msp31:
557
      val = E_MSP430_MACH_MSP430x31;
558
      break;
559
 
560
    case bfd_mach_msp32:
561
      val = E_MSP430_MACH_MSP430x32;
562
      break;
563
 
564
    case bfd_mach_msp33:
565
      val = E_MSP430_MACH_MSP430x33;
566
      break;
567
 
568
    case bfd_mach_msp41:
569
      val = E_MSP430_MACH_MSP430x41;
570
      break;
571
 
572
    case bfd_mach_msp42:
573
      val = E_MSP430_MACH_MSP430x42;
574
      break;
575
 
576
    case bfd_mach_msp43:
577
      val = E_MSP430_MACH_MSP430x43;
578
      break;
579
 
580
    case bfd_mach_msp44:
581
      val = E_MSP430_MACH_MSP430x44;
582
      break;
583
    }
584
 
585
  elf_elfheader (abfd)->e_machine = EM_MSP430;
586
  elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
587
  elf_elfheader (abfd)->e_flags |= val;
588
}
589
 
590
/* Set the right machine number.  */
591
 
592
static bfd_boolean
593
elf32_msp430_object_p (bfd * abfd)
594
{
595
  int e_set = bfd_mach_msp14;
596
 
597
  if (elf_elfheader (abfd)->e_machine == EM_MSP430
598
      || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
599
    {
600
      int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
601
 
602
      switch (e_mach)
603
        {
604
        default:
605
        case E_MSP430_MACH_MSP430x11:
606
          e_set = bfd_mach_msp11;
607
          break;
608
 
609
        case E_MSP430_MACH_MSP430x11x1:
610
          e_set = bfd_mach_msp110;
611
          break;
612
 
613
        case E_MSP430_MACH_MSP430x12:
614
          e_set = bfd_mach_msp12;
615
          break;
616
 
617
        case E_MSP430_MACH_MSP430x13:
618
          e_set = bfd_mach_msp13;
619
          break;
620
 
621
        case E_MSP430_MACH_MSP430x14:
622
          e_set = bfd_mach_msp14;
623
          break;
624
 
625
        case E_MSP430_MACH_MSP430x15:
626
          e_set = bfd_mach_msp15;
627
          break;
628
 
629
        case E_MSP430_MACH_MSP430x16:
630
          e_set = bfd_mach_msp16;
631
          break;
632
 
633
        case E_MSP430_MACH_MSP430x31:
634
          e_set = bfd_mach_msp31;
635
          break;
636
 
637
        case E_MSP430_MACH_MSP430x32:
638
          e_set = bfd_mach_msp32;
639
          break;
640
 
641
        case E_MSP430_MACH_MSP430x33:
642
          e_set = bfd_mach_msp33;
643
          break;
644
 
645
        case E_MSP430_MACH_MSP430x41:
646
          e_set = bfd_mach_msp41;
647
          break;
648
 
649
        case E_MSP430_MACH_MSP430x42:
650
          e_set = bfd_mach_msp42;
651
          break;
652
 
653
        case E_MSP430_MACH_MSP430x43:
654
          e_set = bfd_mach_msp43;
655
          break;
656
 
657
        case E_MSP430_MACH_MSP430x44:
658
          e_set = bfd_mach_msp44;
659
          break;
660
        }
661
    }
662
 
663
  return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
664
}
665
 
666
/* These functions handle relaxing for the msp430.
667
   Relaxation required only in two cases:
668
    - Bad hand coding like jumps from one section to another or
669
      from file to file.
670
    - Sibling calls. This will affect onlu 'jump label' polymorph. Without
671
      relaxing this enlarges code by 2 bytes. Sibcalls implemented but
672
      do not work in gcc's port by the reason I do not know.
673
   Anyway, if a relaxation required, user should pass -relax option to the
674
   linker.
675
 
676
   There are quite a few relaxing opportunities available on the msp430:
677
 
678
   ================================================================
679
 
680
   1. 3 words -> 1 word
681
 
682
   eq      ==      jeq label                    jne +4; br lab
683
   ne      !=      jne label                    jeq +4; br lab
684
   lt      <       jl  label                    jge +4; br lab
685
   ltu     <       jlo label                    lhs +4; br lab
686
   ge      >=      jge label                    jl  +4; br lab
687
   geu     >=      jhs label                    jlo +4; br lab
688
 
689
   2. 4 words -> 1 word
690
 
691
   ltn     <       jn                      jn  +2; jmp +4; br lab
692
 
693
   3. 4 words -> 2 words
694
 
695
   gt      >       jeq +2; jge label       jeq +6; jl  +4; br label
696
   gtu     >       jeq +2; jhs label       jeq +6; jlo +4; br label
697
 
698
   4. 4 words -> 2 words and 2 labels
699
 
700
   leu     <=      jeq label; jlo label    jeq +2; jhs +4; br label
701
   le      <=      jeq label; jl  label    jeq +2; jge +4; br label
702
   =================================================================
703
 
704
   codemap for first cases is (labels masked ):
705
              eq:       0x2002,0x4010,0x0000 -> 0x2400
706
              ne:       0x2402,0x4010,0x0000 -> 0x2000
707
              lt:       0x3402,0x4010,0x0000 -> 0x3800
708
              ltu:      0x2c02,0x4010,0x0000 -> 0x2800
709
              ge:       0x3802,0x4010,0x0000 -> 0x3400
710
              geu:      0x2802,0x4010,0x0000 -> 0x2c00
711
 
712
  second case:
713
              ltn:      0x3001,0x3c02,0x4010,0x0000 -> 0x3000
714
 
715
  third case:
716
              gt:       0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400
717
              gtu:      0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00
718
 
719
  fourth case:
720
              leu:      0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800
721
              le:       0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800
722
 
723
  Unspecified case :)
724
              jump:     0x4010,0x0000 -> 0x3c00.  */
725
 
726
#define NUMB_RELAX_CODES        12
727
static struct rcodes_s
728
{
729
  int f0, f1;                   /* From code.  */
730
  int t0, t1;                   /* To code.  */
731
  int labels;                   /* Position of labels: 1 - one label at first
732
                                   word, 2 - one at second word, 3 - two
733
                                   labels at both.  */
734
  int cdx;                      /* Words to match.  */
735
  int bs;                       /* Shrink bytes.  */
736
  int off;                      /* Offset from old label for new code.  */
737
  int ncl;                      /* New code length.  */
738
} rcode[] =
739
{/*                               lab,cdx,bs,off,ncl */
740
  { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2,   2},    /* jump */
741
  { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4,  2},    /* eq */
742
  { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4,  2},    /* ne */
743
  { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4,  2},    /* lt */
744
  { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4,  2},    /* ltu */
745
  { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4,  2},    /* ge */
746
  { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4,  2},    /* geu */
747
  { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6,  2},    /* ltn */
748
  { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6,  4},    /* gt */
749
  { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6,  4},    /* gtu */
750
  { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6,  4},    /* leu , 2 labels */
751
  { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6,  4},    /* le  , 2 labels */
752
  { 0,       0,       0,       0,       0, 0, 0, 0,  0}
753
};
754
 
755
/* Return TRUE if a symbol exists at the given address.  */
756
 
757
static bfd_boolean
758
msp430_elf_symbol_address_p (bfd * abfd,
759
                             asection * sec,
760
                             Elf_Internal_Sym * isym,
761
                             bfd_vma addr)
762
{
763
  Elf_Internal_Shdr *symtab_hdr;
764
  unsigned int sec_shndx;
765
  Elf_Internal_Sym *isymend;
766
  struct elf_link_hash_entry **sym_hashes;
767
  struct elf_link_hash_entry **end_hashes;
768
  unsigned int symcount;
769
 
770
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
771
 
772
  /* Examine all the local symbols.  */
773
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
774
  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
775
    if (isym->st_shndx == sec_shndx && isym->st_value == addr)
776
      return TRUE;
777
 
778
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
779
              - symtab_hdr->sh_info);
780
  sym_hashes = elf_sym_hashes (abfd);
781
  end_hashes = sym_hashes + symcount;
782
  for (; sym_hashes < end_hashes; sym_hashes++)
783
    {
784
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
785
 
786
      if ((sym_hash->root.type == bfd_link_hash_defined
787
           || sym_hash->root.type == bfd_link_hash_defweak)
788
          && sym_hash->root.u.def.section == sec
789
          && sym_hash->root.u.def.value == addr)
790
        return TRUE;
791
    }
792
 
793
  return FALSE;
794
}
795
 
796
/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has sec_shndx)
797
    referenced from current and other sections */
798
static bfd_boolean
799
msp430_elf_relax_adjust_locals(bfd * abfd, asection * sec, bfd_vma addr,
800
    int count, unsigned int sec_shndx, bfd_vma toaddr)
801
{
802
  Elf_Internal_Shdr *symtab_hdr;
803
  Elf_Internal_Rela *irel;
804
  Elf_Internal_Rela *irelend;
805
  Elf_Internal_Sym *isym;
806
 
807
  irel = elf_section_data (sec)->relocs;
808
  irelend = irel + sec->reloc_count;
809
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
810
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
811
 
812
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
813
    {
814
      int sidx = ELF32_R_SYM(irel->r_info);
815
      Elf_Internal_Sym *lsym = isym + sidx;
816
 
817
      /* Adjust symbols referenced by .sec+0xXX */
818
      if (irel->r_addend > addr && irel->r_addend < toaddr
819
          && lsym->st_shndx == sec_shndx)
820
        irel->r_addend -= count;
821
    }
822
 
823
  return TRUE;
824
}
825
 
826
/* Delete some bytes from a section while relaxing.  */
827
 
828
static bfd_boolean
829
msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
830
                               int count)
831
{
832
  Elf_Internal_Shdr *symtab_hdr;
833
  unsigned int sec_shndx;
834
  bfd_byte *contents;
835
  Elf_Internal_Rela *irel;
836
  Elf_Internal_Rela *irelend;
837
  bfd_vma toaddr;
838
  Elf_Internal_Sym *isym;
839
  Elf_Internal_Sym *isymend;
840
  struct elf_link_hash_entry **sym_hashes;
841
  struct elf_link_hash_entry **end_hashes;
842
  unsigned int symcount;
843
  asection *p;
844
 
845
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
846
 
847
  contents = elf_section_data (sec)->this_hdr.contents;
848
 
849
  toaddr = sec->size;
850
 
851
  irel = elf_section_data (sec)->relocs;
852
  irelend = irel + sec->reloc_count;
853
 
854
  /* Actually delete the bytes.  */
855
  memmove (contents + addr, contents + addr + count,
856
           (size_t) (toaddr - addr - count));
857
  sec->size -= count;
858
 
859
  /* Adjust all the relocs.  */
860
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
861
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
862
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
863
    {
864
      /* Get the new reloc address.  */
865
      if ((irel->r_offset > addr && irel->r_offset < toaddr))
866
        irel->r_offset -= count;
867
    }
868
 
869
  for (p = abfd->sections; p != NULL; p = p->next)
870
    msp430_elf_relax_adjust_locals(abfd,p,addr,count,sec_shndx,toaddr);
871
 
872
  /* Adjust the local symbols defined in this section.  */
873
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
874
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
875
  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
876
    if (isym->st_shndx == sec_shndx
877
        && isym->st_value > addr && isym->st_value < toaddr)
878
      isym->st_value -= count;
879
 
880
  /* Now adjust the global symbols defined in this section.  */
881
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
882
              - symtab_hdr->sh_info);
883
  sym_hashes = elf_sym_hashes (abfd);
884
  end_hashes = sym_hashes + symcount;
885
  for (; sym_hashes < end_hashes; sym_hashes++)
886
    {
887
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
888
 
889
      if ((sym_hash->root.type == bfd_link_hash_defined
890
           || sym_hash->root.type == bfd_link_hash_defweak)
891
          && sym_hash->root.u.def.section == sec
892
          && sym_hash->root.u.def.value > addr
893
          && sym_hash->root.u.def.value < toaddr)
894
        sym_hash->root.u.def.value -= count;
895
    }
896
 
897
  return TRUE;
898
}
899
 
900
 
901
static bfd_boolean
902
msp430_elf_relax_section (bfd * abfd, asection * sec,
903
                          struct bfd_link_info * link_info,
904
                          bfd_boolean * again)
905
{
906
  Elf_Internal_Shdr * symtab_hdr;
907
  Elf_Internal_Rela * internal_relocs;
908
  Elf_Internal_Rela * irel;
909
  Elf_Internal_Rela * irelend;
910
  bfd_byte *          contents = NULL;
911
  Elf_Internal_Sym *  isymbuf = NULL;
912
 
913
  /* Assume nothing changes.  */
914
  *again = FALSE;
915
 
916
  /* We don't have to do anything for a relocatable link, if
917
     this section does not have relocs, or if this is not a
918
     code section.  */
919
  if (link_info->relocatable
920
      || (sec->flags & SEC_RELOC) == 0
921
      || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
922
    return TRUE;
923
 
924
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
925
 
926
  /* Get a copy of the native relocations.  */
927
  internal_relocs =
928
    _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
929
  if (internal_relocs == NULL)
930
    goto error_return;
931
 
932
  /* Walk through them looking for relaxing opportunities.  */
933
  irelend = internal_relocs + sec->reloc_count;
934
  for (irel = internal_relocs; irel < irelend; irel++)
935
    {
936
      bfd_vma symval;
937
 
938
      /* If this isn't something that can be relaxed, then ignore
939
         this reloc.  */
940
      if (ELF32_R_TYPE (irel->r_info) != (int) R_MSP430_RL_PCREL)
941
        continue;
942
 
943
      /* Get the section contents if we haven't done so already.  */
944
      if (contents == NULL)
945
        {
946
          /* Get cached copy if it exists.  */
947
          if (elf_section_data (sec)->this_hdr.contents != NULL)
948
            contents = elf_section_data (sec)->this_hdr.contents;
949
          else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
950
            goto error_return;
951
        }
952
 
953
      /* Read this BFD's local symbols if we haven't done so already.  */
954
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
955
        {
956
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
957
          if (isymbuf == NULL)
958
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
959
                                            symtab_hdr->sh_info, 0,
960
                                            NULL, NULL, NULL);
961
          if (isymbuf == NULL)
962
            goto error_return;
963
        }
964
 
965
      /* Get the value of the symbol referred to by the reloc.  */
966
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
967
        {
968
          /* A local symbol.  */
969
          Elf_Internal_Sym *isym;
970
          asection *sym_sec;
971
 
972
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
973
          if (isym->st_shndx == SHN_UNDEF)
974
            sym_sec = bfd_und_section_ptr;
975
          else if (isym->st_shndx == SHN_ABS)
976
            sym_sec = bfd_abs_section_ptr;
977
          else if (isym->st_shndx == SHN_COMMON)
978
            sym_sec = bfd_com_section_ptr;
979
          else
980
            sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
981
          symval = (isym->st_value
982
                    + sym_sec->output_section->vma + sym_sec->output_offset);
983
        }
984
      else
985
        {
986
          unsigned long indx;
987
          struct elf_link_hash_entry *h;
988
 
989
          /* An external symbol.  */
990
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
991
          h = elf_sym_hashes (abfd)[indx];
992
          BFD_ASSERT (h != NULL);
993
 
994
          if (h->root.type != bfd_link_hash_defined
995
              && h->root.type != bfd_link_hash_defweak)
996
            /* This appears to be a reference to an undefined
997
               symbol.  Just ignore it--it will be caught by the
998
               regular reloc processing.  */
999
            continue;
1000
 
1001
          symval = (h->root.u.def.value
1002
                    + h->root.u.def.section->output_section->vma
1003
                    + h->root.u.def.section->output_offset);
1004
        }
1005
 
1006
      /* For simplicity of coding, we are going to modify the section
1007
         contents, the section relocs, and the BFD symbol table.  We
1008
         must tell the rest of the code not to free up this
1009
         information.  It would be possible to instead create a table
1010
         of changes which have to be made, as is done in coff-mips.c;
1011
         that would be more work, but would require less memory when
1012
         the linker is run.  */
1013
 
1014
      /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
1015
         branch.  */
1016
      /* Paranoia? paranoia...  */
1017
      if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
1018
        {
1019
          bfd_vma value = symval;
1020
 
1021
          /* Deal with pc-relative gunk.  */
1022
          value -= (sec->output_section->vma + sec->output_offset);
1023
          value -= irel->r_offset;
1024
          value += irel->r_addend;
1025
 
1026
          /* See if the value will fit in 10 bits, note the high value is
1027
             1016 as the target will be two bytes closer if we are
1028
             able to relax. */
1029
          if ((long) value < 1016 && (long) value > -1016)
1030
            {
1031
              int code0 = 0, code1 = 0, code2 = 0;
1032
              int i;
1033
              struct rcodes_s *rx;
1034
 
1035
              /* Get the opcode.  */
1036
              if (irel->r_offset >= 6)
1037
                code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
1038
 
1039
              if (irel->r_offset >= 4)
1040
                code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
1041
 
1042
              code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
1043
 
1044
              if (code2 != 0x4010)
1045
                continue;
1046
 
1047
              /* Check r4 and r3.  */
1048
              for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
1049
                {
1050
                  rx = &rcode[i];
1051
                  if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
1052
                    break;
1053
                  else if (rx->cdx == 1 && rx->f1 == code1)
1054
                    break;
1055
                  else if (rx->cdx == 0) /* This is an unconditional jump.  */
1056
                    break;
1057
                }
1058
 
1059
              /* Check labels:
1060
                   .Label0:       ; we do not care about this label
1061
                      jeq    +6
1062
                   .Label1:       ; make sure there is no label here
1063
                      jl     +4
1064
                   .Label2:       ; make sure there is no label here
1065
                      br .Label_dst
1066
 
1067
                 So, if there is .Label1 or .Label2 we cannot relax this code.
1068
                 This actually should not happen, cause for relaxable
1069
                 instructions we use RL_PCREL reloc instead of 16_PCREL.
1070
                 Will change this in the future. */
1071
 
1072
              if (rx->cdx > 0
1073
                  && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
1074
                                                  irel->r_offset - 2))
1075
                continue;
1076
              if (rx->cdx > 1
1077
                  && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
1078
                                                  irel->r_offset - 4))
1079
                continue;
1080
 
1081
              /* Note that we've changed the relocs, section contents, etc.  */
1082
              elf_section_data (sec)->relocs = internal_relocs;
1083
              elf_section_data (sec)->this_hdr.contents = contents;
1084
              symtab_hdr->contents = (unsigned char *) isymbuf;
1085
 
1086
              /* Fix the relocation's type.  */
1087
              if (rx->labels == 3)      /* Handle special cases.  */
1088
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1089
                                           R_MSP430_2X_PCREL);
1090
              else
1091
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1092
                                           R_MSP430_10_PCREL);
1093
 
1094
              /* Fix the opcode right way.  */
1095
              bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
1096
              if (rx->t1)
1097
                bfd_put_16 (abfd, rx->t1,
1098
                            contents + irel->r_offset - rx->off + 2);
1099
 
1100
              /* Delete bytes. */
1101
              if (!msp430_elf_relax_delete_bytes (abfd, sec,
1102
                                                  irel->r_offset - rx->off +
1103
                                                  rx->ncl, rx->bs))
1104
                goto error_return;
1105
 
1106
              /* Handle unconditional jumps.  */
1107
              if (rx->cdx == 0)
1108
                irel->r_offset -= 2;
1109
 
1110
              /* That will change things, so, we should relax again.
1111
                 Note that this is not required, and it may be slow.  */
1112
              *again = TRUE;
1113
            }
1114
        }
1115
    }
1116
 
1117
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
1118
    {
1119
      if (!link_info->keep_memory)
1120
        free (isymbuf);
1121
      else
1122
        {
1123
          /* Cache the symbols for elf_link_input_bfd.  */
1124
          symtab_hdr->contents = (unsigned char *) isymbuf;
1125
        }
1126
    }
1127
 
1128
  if (contents != NULL
1129
      && elf_section_data (sec)->this_hdr.contents != contents)
1130
    {
1131
      if (!link_info->keep_memory)
1132
        free (contents);
1133
      else
1134
        {
1135
          /* Cache the section contents for elf_link_input_bfd.  */
1136
          elf_section_data (sec)->this_hdr.contents = contents;
1137
        }
1138
    }
1139
 
1140
  if (internal_relocs != NULL
1141
      && elf_section_data (sec)->relocs != internal_relocs)
1142
    free (internal_relocs);
1143
 
1144
  return TRUE;
1145
 
1146
error_return:
1147
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
1148
    free (isymbuf);
1149
  if (contents != NULL
1150
      && elf_section_data (sec)->this_hdr.contents != contents)
1151
    free (contents);
1152
  if (internal_relocs != NULL
1153
      && elf_section_data (sec)->relocs != internal_relocs)
1154
    free (internal_relocs);
1155
 
1156
  return FALSE;
1157
}
1158
 
1159
 
1160
#define ELF_ARCH                bfd_arch_msp430
1161
#define ELF_MACHINE_CODE        EM_MSP430
1162
#define ELF_MACHINE_ALT1        EM_MSP430_OLD
1163
#define ELF_MAXPAGESIZE         1
1164
#define ELF_OSABI               ELFOSABI_STANDALONE
1165
 
1166
#define TARGET_LITTLE_SYM       bfd_elf32_msp430_vec
1167
#define TARGET_LITTLE_NAME      "elf32-msp430"
1168
 
1169
#define elf_info_to_howto                    msp430_info_to_howto_rela
1170
#define elf_info_to_howto_rel                NULL
1171
#define elf_backend_relocate_section         elf32_msp430_relocate_section
1172
#define elf_backend_check_relocs             elf32_msp430_check_relocs
1173
#define elf_backend_can_gc_sections          1
1174
#define elf_backend_final_write_processing   bfd_elf_msp430_final_write_processing
1175
#define elf_backend_object_p                 elf32_msp430_object_p
1176
#define elf_backend_post_process_headers     _bfd_elf_set_osabi
1177
#define bfd_elf32_bfd_relax_section          msp430_elf_relax_section
1178
 
1179
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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