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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [elf-m10200.c] - Blame information for rev 854

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

Line No. Rev Author Line
1 205 julius
/* Matsushita 10200 specific support for 32-bit ELF
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 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
 
27
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
28
  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
29
static void mn10200_info_to_howto
30
  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
31
static bfd_boolean mn10200_elf_relax_delete_bytes
32
  PARAMS ((bfd *, asection *, bfd_vma, int));
33
static bfd_boolean mn10200_elf_symbol_address_p
34
  PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
35
static bfd_reloc_status_type mn10200_elf_final_link_relocate
36
  PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
37
           bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
38
           struct bfd_link_info *, asection *, int));
39
static bfd_boolean mn10200_elf_relocate_section
40
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
41
           bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
42
           asection **));
43
static bfd_boolean mn10200_elf_relax_section
44
  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
45
static bfd_byte * mn10200_elf_get_relocated_section_contents
46
  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
47
           bfd_byte *, bfd_boolean, asymbol **));
48
 
49
enum reloc_type {
50
  R_MN10200_NONE = 0,
51
  R_MN10200_32,
52
  R_MN10200_16,
53
  R_MN10200_8,
54
  R_MN10200_24,
55
  R_MN10200_PCREL8,
56
  R_MN10200_PCREL16,
57
  R_MN10200_PCREL24,
58
  R_MN10200_MAX
59
};
60
 
61
static reloc_howto_type elf_mn10200_howto_table[] = {
62
  /* Dummy relocation.  Does nothing.  */
63
  HOWTO (R_MN10200_NONE,
64
         0,
65
         2,
66
         16,
67
         FALSE,
68
         0,
69
         complain_overflow_bitfield,
70
         bfd_elf_generic_reloc,
71
         "R_MN10200_NONE",
72
         FALSE,
73
         0,
74
         0,
75
         FALSE),
76
  /* Standard 32 bit reloc.  */
77
  HOWTO (R_MN10200_32,
78
         0,
79
         2,
80
         32,
81
         FALSE,
82
         0,
83
         complain_overflow_bitfield,
84
         bfd_elf_generic_reloc,
85
         "R_MN10200_32",
86
         FALSE,
87
         0xffffffff,
88
         0xffffffff,
89
         FALSE),
90
  /* Standard 16 bit reloc.  */
91
  HOWTO (R_MN10200_16,
92
         0,
93
         1,
94
         16,
95
         FALSE,
96
         0,
97
         complain_overflow_bitfield,
98
         bfd_elf_generic_reloc,
99
         "R_MN10200_16",
100
         FALSE,
101
         0xffff,
102
         0xffff,
103
         FALSE),
104
  /* Standard 8 bit reloc.  */
105
  HOWTO (R_MN10200_8,
106
         0,
107
         0,
108
         8,
109
         FALSE,
110
         0,
111
         complain_overflow_bitfield,
112
         bfd_elf_generic_reloc,
113
         "R_MN10200_8",
114
         FALSE,
115
         0xff,
116
         0xff,
117
         FALSE),
118
  /* Standard 24 bit reloc.  */
119
  HOWTO (R_MN10200_24,
120
         0,
121
         2,
122
         24,
123
         FALSE,
124
         0,
125
         complain_overflow_bitfield,
126
         bfd_elf_generic_reloc,
127
         "R_MN10200_24",
128
         FALSE,
129
         0xffffff,
130
         0xffffff,
131
         FALSE),
132
  /* Simple 8 pc-relative reloc.  */
133
  HOWTO (R_MN10200_PCREL8,
134
         0,
135
         0,
136
         8,
137
         TRUE,
138
         0,
139
         complain_overflow_bitfield,
140
         bfd_elf_generic_reloc,
141
         "R_MN10200_PCREL8",
142
         FALSE,
143
         0xff,
144
         0xff,
145
         TRUE),
146
  /* Simple 16 pc-relative reloc.  */
147
  HOWTO (R_MN10200_PCREL16,
148
         0,
149
         1,
150
         16,
151
         TRUE,
152
         0,
153
         complain_overflow_bitfield,
154
         bfd_elf_generic_reloc,
155
         "R_MN10200_PCREL16",
156
         FALSE,
157
         0xffff,
158
         0xffff,
159
         TRUE),
160
  /* Simple 32bit pc-relative reloc with a 1 byte adjustment
161
     to get the pc-relative offset correct.  */
162
  HOWTO (R_MN10200_PCREL24,
163
         0,
164
         2,
165
         24,
166
         TRUE,
167
         0,
168
         complain_overflow_bitfield,
169
         bfd_elf_generic_reloc,
170
         "R_MN10200_PCREL24",
171
         FALSE,
172
         0xffffff,
173
         0xffffff,
174
         TRUE),
175
};
176
 
177
struct mn10200_reloc_map {
178
  bfd_reloc_code_real_type bfd_reloc_val;
179
  unsigned char elf_reloc_val;
180
};
181
 
182
static const struct mn10200_reloc_map mn10200_reloc_map[] = {
183
  { BFD_RELOC_NONE    , R_MN10200_NONE   , },
184
  { BFD_RELOC_32      , R_MN10200_32     , },
185
  { BFD_RELOC_16      , R_MN10200_16     , },
186
  { BFD_RELOC_8       , R_MN10200_8      , },
187
  { BFD_RELOC_24      , R_MN10200_24     , },
188
  { BFD_RELOC_8_PCREL , R_MN10200_PCREL8 , },
189
  { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
190
  { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
191
};
192
 
193
static reloc_howto_type *
194
bfd_elf32_bfd_reloc_type_lookup (abfd, code)
195
     bfd *abfd ATTRIBUTE_UNUSED;
196
     bfd_reloc_code_real_type code;
197
{
198
  unsigned int i;
199
 
200
  for (i = 0;
201
       i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
202
       i++)
203
    {
204
      if (mn10200_reloc_map[i].bfd_reloc_val == code)
205
        return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
206
    }
207
 
208
  return NULL;
209
}
210
 
211
static reloc_howto_type *
212
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
213
                                 const char *r_name)
214
{
215
  unsigned int i;
216
 
217
  for (i = 0;
218
       i < (sizeof (elf_mn10200_howto_table)
219
            / sizeof (elf_mn10200_howto_table[0]));
220
       i++)
221
    if (elf_mn10200_howto_table[i].name != NULL
222
        && strcasecmp (elf_mn10200_howto_table[i].name, r_name) == 0)
223
      return &elf_mn10200_howto_table[i];
224
 
225
  return NULL;
226
}
227
 
228
/* Set the howto pointer for an MN10200 ELF reloc.  */
229
 
230
static void
231
mn10200_info_to_howto (abfd, cache_ptr, dst)
232
     bfd *abfd ATTRIBUTE_UNUSED;
233
     arelent *cache_ptr;
234
     Elf_Internal_Rela *dst;
235
{
236
  unsigned int r_type;
237
 
238
  r_type = ELF32_R_TYPE (dst->r_info);
239
  BFD_ASSERT (r_type < (unsigned int) R_MN10200_MAX);
240
  cache_ptr->howto = &elf_mn10200_howto_table[r_type];
241
}
242
 
243
/* Perform a relocation as part of a final link.  */
244
 
245
static bfd_reloc_status_type
246
mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
247
                                 input_section, contents, offset, value,
248
                                 addend, info, sym_sec, is_local)
249
     reloc_howto_type *howto;
250
     bfd *input_bfd;
251
     bfd *output_bfd ATTRIBUTE_UNUSED;
252
     asection *input_section;
253
     bfd_byte *contents;
254
     bfd_vma offset;
255
     bfd_vma value;
256
     bfd_vma addend;
257
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
258
     asection *sym_sec ATTRIBUTE_UNUSED;
259
     int is_local ATTRIBUTE_UNUSED;
260
{
261
  unsigned long r_type = howto->type;
262
  bfd_byte *hit_data = contents + offset;
263
 
264
  switch (r_type)
265
    {
266
 
267
    case R_MN10200_NONE:
268
      return bfd_reloc_ok;
269
 
270
    case R_MN10200_32:
271
      value += addend;
272
      bfd_put_32 (input_bfd, value, hit_data);
273
      return bfd_reloc_ok;
274
 
275
    case R_MN10200_16:
276
      value += addend;
277
 
278
      if ((long) value > 0x7fff || (long) value < -0x8000)
279
        return bfd_reloc_overflow;
280
 
281
      bfd_put_16 (input_bfd, value, hit_data);
282
      return bfd_reloc_ok;
283
 
284
    case R_MN10200_8:
285
      value += addend;
286
 
287
      if ((long) value > 0x7f || (long) value < -0x80)
288
        return bfd_reloc_overflow;
289
 
290
      bfd_put_8 (input_bfd, value, hit_data);
291
      return bfd_reloc_ok;
292
 
293
    case R_MN10200_24:
294
      value += addend;
295
 
296
      if ((long) value > 0x7fffff || (long) value < -0x800000)
297
        return bfd_reloc_overflow;
298
 
299
      value &= 0xffffff;
300
      value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
301
      bfd_put_32 (input_bfd, value, hit_data);
302
      return bfd_reloc_ok;
303
 
304
    case R_MN10200_PCREL8:
305
      value -= (input_section->output_section->vma
306
                + input_section->output_offset);
307
      value -= (offset + 1);
308
      value += addend;
309
 
310
      if ((long) value > 0xff || (long) value < -0x100)
311
        return bfd_reloc_overflow;
312
 
313
      bfd_put_8 (input_bfd, value, hit_data);
314
      return bfd_reloc_ok;
315
 
316
    case R_MN10200_PCREL16:
317
      value -= (input_section->output_section->vma
318
                + input_section->output_offset);
319
      value -= (offset + 2);
320
      value += addend;
321
 
322
      if ((long) value > 0xffff || (long) value < -0x10000)
323
        return bfd_reloc_overflow;
324
 
325
      bfd_put_16 (input_bfd, value, hit_data);
326
      return bfd_reloc_ok;
327
 
328
    case R_MN10200_PCREL24:
329
      value -= (input_section->output_section->vma
330
                + input_section->output_offset);
331
      value -= (offset + 3);
332
      value += addend;
333
 
334
      if ((long) value > 0xffffff || (long) value < -0x1000000)
335
        return bfd_reloc_overflow;
336
 
337
      value &= 0xffffff;
338
      value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
339
      bfd_put_32 (input_bfd, value, hit_data);
340
      return bfd_reloc_ok;
341
 
342
    default:
343
      return bfd_reloc_notsupported;
344
    }
345
}
346
 
347
/* Relocate an MN10200 ELF section.  */
348
static bfd_boolean
349
mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
350
                              contents, relocs, local_syms, local_sections)
351
     bfd *output_bfd;
352
     struct bfd_link_info *info;
353
     bfd *input_bfd;
354
     asection *input_section;
355
     bfd_byte *contents;
356
     Elf_Internal_Rela *relocs;
357
     Elf_Internal_Sym *local_syms;
358
     asection **local_sections;
359
{
360
  Elf_Internal_Shdr *symtab_hdr;
361
  struct elf_link_hash_entry **sym_hashes;
362
  Elf_Internal_Rela *rel, *relend;
363
 
364
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
365
  sym_hashes = elf_sym_hashes (input_bfd);
366
 
367
  rel = relocs;
368
  relend = relocs + input_section->reloc_count;
369
  for (; rel < relend; rel++)
370
    {
371
      int r_type;
372
      reloc_howto_type *howto;
373
      unsigned long r_symndx;
374
      Elf_Internal_Sym *sym;
375
      asection *sec;
376
      struct elf_link_hash_entry *h;
377
      bfd_vma relocation;
378
      bfd_reloc_status_type r;
379
 
380
      r_symndx = ELF32_R_SYM (rel->r_info);
381
      r_type = ELF32_R_TYPE (rel->r_info);
382
      howto = elf_mn10200_howto_table + r_type;
383
 
384
      h = NULL;
385
      sym = NULL;
386
      sec = NULL;
387
      if (r_symndx < symtab_hdr->sh_info)
388
        {
389
          sym = local_syms + r_symndx;
390
          sec = local_sections[r_symndx];
391
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
392
        }
393
      else
394
        {
395
          bfd_boolean unresolved_reloc, warned;
396
 
397
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
398
                                   r_symndx, symtab_hdr, sym_hashes,
399
                                   h, sec, relocation,
400
                                   unresolved_reloc, warned);
401
        }
402
 
403
      if (sec != NULL && elf_discarded_section (sec))
404
        {
405
          /* For relocs against symbols from removed linkonce sections,
406
             or sections discarded by a linker script, we just want the
407
             section contents zeroed.  Avoid any special processing.  */
408
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
409
          rel->r_info = 0;
410
          rel->r_addend = 0;
411
          continue;
412
        }
413
 
414
      if (info->relocatable)
415
        continue;
416
 
417
      r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
418
                                           input_section,
419
                                           contents, rel->r_offset,
420
                                           relocation, rel->r_addend,
421
                                           info, sec, h == NULL);
422
 
423
      if (r != bfd_reloc_ok)
424
        {
425
          const char *name;
426
          const char *msg = (const char *) 0;
427
 
428
          if (h != NULL)
429
            name = h->root.root.string;
430
          else
431
            {
432
              name = (bfd_elf_string_from_elf_section
433
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
434
              if (name == NULL || *name == '\0')
435
                name = bfd_section_name (input_bfd, sec);
436
            }
437
 
438
          switch (r)
439
            {
440
            case bfd_reloc_overflow:
441
              if (! ((*info->callbacks->reloc_overflow)
442
                     (info, (h ? &h->root : NULL), name, howto->name,
443
                      (bfd_vma) 0, input_bfd, input_section,
444
                      rel->r_offset)))
445
                return FALSE;
446
              break;
447
 
448
            case bfd_reloc_undefined:
449
              if (! ((*info->callbacks->undefined_symbol)
450
                     (info, name, input_bfd, input_section,
451
                      rel->r_offset, TRUE)))
452
                return FALSE;
453
              break;
454
 
455
            case bfd_reloc_outofrange:
456
              msg = _("internal error: out of range error");
457
              goto common_error;
458
 
459
            case bfd_reloc_notsupported:
460
              msg = _("internal error: unsupported relocation error");
461
              goto common_error;
462
 
463
            case bfd_reloc_dangerous:
464
              msg = _("internal error: dangerous error");
465
              goto common_error;
466
 
467
            default:
468
              msg = _("internal error: unknown error");
469
              /* fall through */
470
 
471
            common_error:
472
              if (!((*info->callbacks->warning)
473
                    (info, msg, name, input_bfd, input_section,
474
                     rel->r_offset)))
475
                return FALSE;
476
              break;
477
            }
478
        }
479
    }
480
 
481
  return TRUE;
482
}
483
 
484
/* This function handles relaxing for the mn10200.
485
 
486
   There are quite a few relaxing opportunities available on the mn10200:
487
 
488
        * jsr:24 -> jsr:16                                         2 bytes
489
 
490
        * jmp:24 -> jmp:16                                         2 bytes
491
        * jmp:16 -> bra:8                                          1 byte
492
 
493
                * If the previous instruction is a conditional branch
494
                around the jump/bra, we may be able to reverse its condition
495
                and change its target to the jump's target.  The jump/bra
496
                can then be deleted.                               2 bytes
497
 
498
        * mov abs24 -> mov abs16        2 byte savings
499
 
500
        * Most instructions which accept imm24 can relax to imm16  2 bytes
501
        - Most instructions which accept imm16 can relax to imm8   1 byte
502
 
503
        * Most instructions which accept d24 can relax to d16      2 bytes
504
        - Most instructions which accept d16 can relax to d8       1 byte
505
 
506
        abs24, imm24, d24 all look the same at the reloc level.  It
507
        might make the code simpler if we had different relocs for
508
        the various relaxable operand types.
509
 
510
        We don't handle imm16->imm8 or d16->d8 as they're very rare
511
        and somewhat more difficult to support.  */
512
 
513
static bfd_boolean
514
mn10200_elf_relax_section (abfd, sec, link_info, again)
515
     bfd *abfd;
516
     asection *sec;
517
     struct bfd_link_info *link_info;
518
     bfd_boolean *again;
519
{
520
  Elf_Internal_Shdr *symtab_hdr;
521
  Elf_Internal_Rela *internal_relocs;
522
  Elf_Internal_Rela *irel, *irelend;
523
  bfd_byte *contents = NULL;
524
  Elf_Internal_Sym *isymbuf = NULL;
525
 
526
  /* Assume nothing changes.  */
527
  *again = FALSE;
528
 
529
  /* We don't have to do anything for a relocatable link, if
530
     this section does not have relocs, or if this is not a
531
     code section.  */
532
  if (link_info->relocatable
533
      || (sec->flags & SEC_RELOC) == 0
534
      || sec->reloc_count == 0
535
      || (sec->flags & SEC_CODE) == 0)
536
    return TRUE;
537
 
538
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
539
 
540
  /* Get a copy of the native relocations.  */
541
  internal_relocs = (_bfd_elf_link_read_relocs
542
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
543
                      link_info->keep_memory));
544
  if (internal_relocs == NULL)
545
    goto error_return;
546
 
547
  /* Walk through them looking for relaxing opportunities.  */
548
  irelend = internal_relocs + sec->reloc_count;
549
  for (irel = internal_relocs; irel < irelend; irel++)
550
    {
551
      bfd_vma symval;
552
 
553
      /* If this isn't something that can be relaxed, then ignore
554
         this reloc.  */
555
      if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
556
          || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
557
          || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
558
        continue;
559
 
560
      /* Get the section contents if we haven't done so already.  */
561
      if (contents == NULL)
562
        {
563
          /* Get cached copy if it exists.  */
564
          if (elf_section_data (sec)->this_hdr.contents != NULL)
565
            contents = elf_section_data (sec)->this_hdr.contents;
566
          else
567
            {
568
              /* Go get them off disk.  */
569
              if (!bfd_malloc_and_get_section (abfd, sec, &contents))
570
                goto error_return;
571
            }
572
        }
573
 
574
      /* Read this BFD's local symbols if we haven't done so already.  */
575
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
576
        {
577
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
578
          if (isymbuf == NULL)
579
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
580
                                            symtab_hdr->sh_info, 0,
581
                                            NULL, NULL, NULL);
582
          if (isymbuf == NULL)
583
            goto error_return;
584
        }
585
 
586
      /* Get the value of the symbol referred to by the reloc.  */
587
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
588
        {
589
          /* A local symbol.  */
590
          Elf_Internal_Sym *isym;
591
          asection *sym_sec;
592
 
593
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
594
          if (isym->st_shndx == SHN_UNDEF)
595
            sym_sec = bfd_und_section_ptr;
596
          else if (isym->st_shndx == SHN_ABS)
597
            sym_sec = bfd_abs_section_ptr;
598
          else if (isym->st_shndx == SHN_COMMON)
599
            sym_sec = bfd_com_section_ptr;
600
          else
601
            sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
602
          symval = (isym->st_value
603
                    + sym_sec->output_section->vma
604
                    + sym_sec->output_offset);
605
        }
606
      else
607
        {
608
          unsigned long indx;
609
          struct elf_link_hash_entry *h;
610
 
611
          /* An external symbol.  */
612
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
613
          h = elf_sym_hashes (abfd)[indx];
614
          BFD_ASSERT (h != NULL);
615
          if (h->root.type != bfd_link_hash_defined
616
              && h->root.type != bfd_link_hash_defweak)
617
            {
618
              /* This appears to be a reference to an undefined
619
                 symbol.  Just ignore it--it will be caught by the
620
                 regular reloc processing.  */
621
              continue;
622
            }
623
 
624
          symval = (h->root.u.def.value
625
                    + h->root.u.def.section->output_section->vma
626
                    + h->root.u.def.section->output_offset);
627
        }
628
 
629
      /* For simplicity of coding, we are going to modify the section
630
         contents, the section relocs, and the BFD symbol table.  We
631
         must tell the rest of the code not to free up this
632
         information.  It would be possible to instead create a table
633
         of changes which have to be made, as is done in coff-mips.c;
634
         that would be more work, but would require less memory when
635
         the linker is run.  */
636
 
637
      /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
638
         branch/call.  */
639
      if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
640
        {
641
          bfd_vma value = symval;
642
 
643
          /* Deal with pc-relative gunk.  */
644
          value -= (sec->output_section->vma + sec->output_offset);
645
          value -= (irel->r_offset + 3);
646
          value += irel->r_addend;
647
 
648
          /* See if the value will fit in 16 bits, note the high value is
649
             0x7fff + 2 as the target will be two bytes closer if we are
650
             able to relax.  */
651
          if ((long) value < 0x8001 && (long) value > -0x8000)
652
            {
653
              unsigned char code;
654
 
655
              /* Get the opcode.  */
656
              code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
657
 
658
              if (code != 0xe0 && code != 0xe1)
659
                continue;
660
 
661
              /* Note that we've changed the relocs, section contents, etc.  */
662
              elf_section_data (sec)->relocs = internal_relocs;
663
              elf_section_data (sec)->this_hdr.contents = contents;
664
              symtab_hdr->contents = (unsigned char *) isymbuf;
665
 
666
              /* Fix the opcode.  */
667
              if (code == 0xe0)
668
                bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
669
              else if (code == 0xe1)
670
                bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
671
 
672
              /* Fix the relocation's type.  */
673
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
674
                                           R_MN10200_PCREL16);
675
 
676
              /* The opcode got shorter too, so we have to fix the offset.  */
677
              irel->r_offset -= 1;
678
 
679
              /* Delete two bytes of data.  */
680
              if (!mn10200_elf_relax_delete_bytes (abfd, sec,
681
                                                   irel->r_offset + 1, 2))
682
                goto error_return;
683
 
684
              /* That will change things, so, we should relax again.
685
                 Note that this is not required, and it may be slow.  */
686
              *again = TRUE;
687
            }
688
        }
689
 
690
      /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
691
         branch.  */
692
      if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
693
        {
694
          bfd_vma value = symval;
695
 
696
          /* Deal with pc-relative gunk.  */
697
          value -= (sec->output_section->vma + sec->output_offset);
698
          value -= (irel->r_offset + 2);
699
          value += irel->r_addend;
700
 
701
          /* See if the value will fit in 8 bits, note the high value is
702
             0x7f + 1 as the target will be one bytes closer if we are
703
             able to relax.  */
704
          if ((long) value < 0x80 && (long) value > -0x80)
705
            {
706
              unsigned char code;
707
 
708
              /* Get the opcode.  */
709
              code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
710
 
711
              if (code != 0xfc)
712
                continue;
713
 
714
              /* Note that we've changed the relocs, section contents, etc.  */
715
              elf_section_data (sec)->relocs = internal_relocs;
716
              elf_section_data (sec)->this_hdr.contents = contents;
717
              symtab_hdr->contents = (unsigned char *) isymbuf;
718
 
719
              /* Fix the opcode.  */
720
              bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
721
 
722
              /* Fix the relocation's type.  */
723
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
724
                                           R_MN10200_PCREL8);
725
 
726
              /* Delete one byte of data.  */
727
              if (!mn10200_elf_relax_delete_bytes (abfd, sec,
728
                                                   irel->r_offset + 1, 1))
729
                goto error_return;
730
 
731
              /* That will change things, so, we should relax again.
732
                 Note that this is not required, and it may be slow.  */
733
              *again = TRUE;
734
            }
735
        }
736
 
737
      /* Try to eliminate an unconditional 8 bit pc-relative branch
738
         which immediately follows a conditional 8 bit pc-relative
739
         branch around the unconditional branch.
740
 
741
            original:           new:
742
            bCC lab1            bCC' lab2
743
            bra lab2
744
           lab1:               lab1:
745
 
746
         This happens when the bCC can't reach lab2 at assembly time,
747
         but due to other relaxations it can reach at link time.  */
748
      if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
749
        {
750
          Elf_Internal_Rela *nrel;
751
          bfd_vma value = symval;
752
          unsigned char code;
753
 
754
          /* Deal with pc-relative gunk.  */
755
          value -= (sec->output_section->vma + sec->output_offset);
756
          value -= (irel->r_offset + 1);
757
          value += irel->r_addend;
758
 
759
          /* Do nothing if this reloc is the last byte in the section.  */
760
          if (irel->r_offset == sec->size)
761
            continue;
762
 
763
          /* See if the next instruction is an unconditional pc-relative
764
             branch, more often than not this test will fail, so we
765
             test it first to speed things up.  */
766
          code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
767
          if (code != 0xea)
768
            continue;
769
 
770
          /* Also make sure the next relocation applies to the next
771
             instruction and that it's a pc-relative 8 bit branch.  */
772
          nrel = irel + 1;
773
          if (nrel == irelend
774
              || irel->r_offset + 2 != nrel->r_offset
775
              || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
776
            continue;
777
 
778
          /* Make sure our destination immediately follows the
779
             unconditional branch.  */
780
          if (symval != (sec->output_section->vma + sec->output_offset
781
                         + irel->r_offset + 3))
782
            continue;
783
 
784
          /* Now make sure we are a conditional branch.  This may not
785
             be necessary, but why take the chance.
786
 
787
             Note these checks assume that R_MN10200_PCREL8 relocs
788
             only occur on bCC and bCCx insns.  If they occured
789
             elsewhere, we'd need to know the start of this insn
790
             for this check to be accurate.  */
791
          code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
792
          if (code != 0xe0 && code != 0xe1 && code != 0xe2
793
              && code != 0xe3 && code != 0xe4 && code != 0xe5
794
              && code != 0xe6 && code != 0xe7 && code != 0xe8
795
              && code != 0xe9 && code != 0xec && code != 0xed
796
              && code != 0xee && code != 0xef && code != 0xfc
797
              && code != 0xfd && code != 0xfe && code != 0xff)
798
            continue;
799
 
800
          /* We also have to be sure there is no symbol/label
801
             at the unconditional branch.  */
802
          if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
803
                                            irel->r_offset + 1))
804
            continue;
805
 
806
          /* Note that we've changed the relocs, section contents, etc.  */
807
          elf_section_data (sec)->relocs = internal_relocs;
808
          elf_section_data (sec)->this_hdr.contents = contents;
809
          symtab_hdr->contents = (unsigned char *) isymbuf;
810
 
811
          /* Reverse the condition of the first branch.  */
812
          switch (code)
813
            {
814
            case 0xfc:
815
              code = 0xfd;
816
              break;
817
            case 0xfd:
818
              code = 0xfc;
819
              break;
820
            case 0xfe:
821
              code = 0xff;
822
              break;
823
            case 0xff:
824
              code = 0xfe;
825
              break;
826
            case 0xe8:
827
              code = 0xe9;
828
              break;
829
            case 0xe9:
830
              code = 0xe8;
831
              break;
832
            case 0xe0:
833
              code = 0xe2;
834
              break;
835
            case 0xe2:
836
              code = 0xe0;
837
              break;
838
            case 0xe3:
839
              code = 0xe1;
840
              break;
841
            case 0xe1:
842
              code = 0xe3;
843
              break;
844
            case 0xe4:
845
              code = 0xe6;
846
              break;
847
            case 0xe6:
848
              code = 0xe4;
849
              break;
850
            case 0xe7:
851
              code = 0xe5;
852
              break;
853
            case 0xe5:
854
              code = 0xe7;
855
              break;
856
            case 0xec:
857
              code = 0xed;
858
              break;
859
            case 0xed:
860
              code = 0xec;
861
              break;
862
            case 0xee:
863
              code = 0xef;
864
              break;
865
            case 0xef:
866
              code = 0xee;
867
              break;
868
            }
869
          bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
870
 
871
          /* Set the reloc type and symbol for the first branch
872
             from the second branch.  */
873
          irel->r_info = nrel->r_info;
874
 
875
          /* Make the reloc for the second branch a null reloc.  */
876
          nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
877
                                       R_MN10200_NONE);
878
 
879
          /* Delete two bytes of data.  */
880
          if (!mn10200_elf_relax_delete_bytes (abfd, sec,
881
                                               irel->r_offset + 1, 2))
882
            goto error_return;
883
 
884
          /* That will change things, so, we should relax again.
885
             Note that this is not required, and it may be slow.  */
886
          *again = TRUE;
887
        }
888
 
889
      /* Try to turn a 24bit immediate, displacement or absolute address
890
         into a 16bit immediate, displacement or absolute address.  */
891
      if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
892
        {
893
          bfd_vma value = symval;
894
 
895
          /* See if the value will fit in 16 bits.
896
             We allow any 16bit match here.  We prune those we can't
897
             handle below.  */
898
          if ((long) value < 0x7fff && (long) value > -0x8000)
899
            {
900
              unsigned char code;
901
 
902
              /* All insns which have 24bit operands are 5 bytes long,
903
                 the first byte will always be 0xf4, but we double check
904
                 it just in case.  */
905
 
906
              /* Get the first opcode.  */
907
              code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
908
 
909
              if (code != 0xf4)
910
                continue;
911
 
912
              /* Get the second opcode.  */
913
              code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
914
 
915
              switch (code & 0xfc)
916
                {
917
                /* mov imm24,dn -> mov imm16,dn */
918
                case 0x70:
919
                  /* Not safe if the high bit is on as relaxing may
920
                     move the value out of high mem and thus not fit
921
                     in a signed 16bit value.  */
922
                  if (value & 0x8000)
923
                    continue;
924
 
925
                  /* Note that we've changed the relocation contents, etc.  */
926
                  elf_section_data (sec)->relocs = internal_relocs;
927
                  elf_section_data (sec)->this_hdr.contents = contents;
928
                  symtab_hdr->contents = (unsigned char *) isymbuf;
929
 
930
                  /* Fix the opcode.  */
931
                  bfd_put_8 (abfd, 0xf8 + (code & 0x03),
932
                             contents + irel->r_offset - 2);
933
 
934
                  /* Fix the relocation's type.  */
935
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
936
                                               R_MN10200_16);
937
 
938
                  /* The opcode got shorter too, so we have to fix the
939
                     offset.  */
940
                  irel->r_offset -= 1;
941
 
942
                  /* Delete two bytes of data.  */
943
                  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
944
                                                       irel->r_offset + 1, 2))
945
                    goto error_return;
946
 
947
                  /* That will change things, so, we should relax again.
948
                     Note that this is not required, and it may be slow.  */
949
                  *again = TRUE;
950
                  break;
951
 
952
                /* mov imm24,an -> mov imm16,an
953
                   cmp imm24,an -> cmp imm16,an
954
                   mov (abs24),dn -> mov (abs16),dn
955
                   mov dn,(abs24) -> mov dn,(abs16)
956
                   movb dn,(abs24) -> movb dn,(abs16)
957
                   movbu (abs24),dn -> movbu (abs16),dn */
958
                case 0x74:
959
                case 0x7c:
960
                case 0xc0:
961
                case 0x40:
962
                case 0x44:
963
                case 0xc8:
964
                  /* Note that we've changed the relocation contents, etc.  */
965
                  elf_section_data (sec)->relocs = internal_relocs;
966
                  elf_section_data (sec)->this_hdr.contents = contents;
967
                  symtab_hdr->contents = (unsigned char *) isymbuf;
968
 
969
                  if ((code & 0xfc) == 0x74)
970
                    code = 0xdc + (code & 0x03);
971
                  else if ((code & 0xfc) == 0x7c)
972
                    code = 0xec + (code & 0x03);
973
                  else if ((code & 0xfc) == 0xc0)
974
                    code = 0xc8 + (code & 0x03);
975
                  else if ((code & 0xfc) == 0x40)
976
                    code = 0xc0 + (code & 0x03);
977
                  else if ((code & 0xfc) == 0x44)
978
                    code = 0xc4 + (code & 0x03);
979
                  else if ((code & 0xfc) == 0xc8)
980
                    code = 0xcc + (code & 0x03);
981
 
982
                  /* Fix the opcode.  */
983
                  bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
984
 
985
                  /* Fix the relocation's type.  */
986
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
987
                                               R_MN10200_16);
988
 
989
                  /* The opcode got shorter too, so we have to fix the
990
                     offset.  */
991
                  irel->r_offset -= 1;
992
 
993
                  /* Delete two bytes of data.  */
994
                  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
995
                                                       irel->r_offset + 1, 2))
996
                    goto error_return;
997
 
998
                  /* That will change things, so, we should relax again.
999
                     Note that this is not required, and it may be slow.  */
1000
                  *again = TRUE;
1001
                  break;
1002
 
1003
                /* cmp imm24,dn -> cmp imm16,dn
1004
                   mov (abs24),an -> mov (abs16),an
1005
                   mov an,(abs24) -> mov an,(abs16)
1006
                   add imm24,dn -> add imm16,dn
1007
                   add imm24,an -> add imm16,an
1008
                   sub imm24,dn -> sub imm16,dn
1009
                   sub imm24,an -> sub imm16,an
1010
                   And all d24->d16 in memory ops.  */
1011
                case 0x78:
1012
                case 0xd0:
1013
                case 0x50:
1014
                case 0x60:
1015
                case 0x64:
1016
                case 0x68:
1017
                case 0x6c:
1018
                case 0x80:
1019
                case 0xf0:
1020
                case 0x00:
1021
                case 0x10:
1022
                case 0xb0:
1023
                case 0x30:
1024
                case 0xa0:
1025
                case 0x20:
1026
                case 0x90:
1027
                  /* Not safe if the high bit is on as relaxing may
1028
                     move the value out of high mem and thus not fit
1029
                     in a signed 16bit value.  */
1030
                  if (((code & 0xfc) == 0x78
1031
                       || (code & 0xfc) == 0x60
1032
                       || (code & 0xfc) == 0x64
1033
                       || (code & 0xfc) == 0x68
1034
                       || (code & 0xfc) == 0x6c
1035
                       || (code & 0xfc) == 0x80
1036
                       || (code & 0xfc) == 0xf0
1037
                       || (code & 0xfc) == 0x00
1038
                       || (code & 0xfc) == 0x10
1039
                       || (code & 0xfc) == 0xb0
1040
                       || (code & 0xfc) == 0x30
1041
                       || (code & 0xfc) == 0xa0
1042
                       || (code & 0xfc) == 0x20
1043
                       || (code & 0xfc) == 0x90)
1044
                      && (value & 0x8000) != 0)
1045
                    continue;
1046
 
1047
                  /* Note that we've changed the relocation contents, etc.  */
1048
                  elf_section_data (sec)->relocs = internal_relocs;
1049
                  elf_section_data (sec)->this_hdr.contents = contents;
1050
                  symtab_hdr->contents = (unsigned char *) isymbuf;
1051
 
1052
                  /* Fix the opcode.  */
1053
                  bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
1054
 
1055
                  if ((code & 0xfc) == 0x78)
1056
                    code = 0x48 + (code & 0x03);
1057
                  else if ((code & 0xfc) == 0xd0)
1058
                    code = 0x30 + (code & 0x03);
1059
                  else if ((code & 0xfc) == 0x50)
1060
                    code = 0x20 + (code & 0x03);
1061
                  else if ((code & 0xfc) == 0x60)
1062
                    code = 0x18 + (code & 0x03);
1063
                  else if ((code & 0xfc) == 0x64)
1064
                    code = 0x08 + (code & 0x03);
1065
                  else if ((code & 0xfc) == 0x68)
1066
                    code = 0x1c + (code & 0x03);
1067
                  else if ((code & 0xfc) == 0x6c)
1068
                    code = 0x0c + (code & 0x03);
1069
                  else if ((code & 0xfc) == 0x80)
1070
                    code = 0xc0 + (code & 0x07);
1071
                  else if ((code & 0xfc) == 0xf0)
1072
                    code = 0xb0 + (code & 0x07);
1073
                  else if ((code & 0xfc) == 0x00)
1074
                    code = 0x80 + (code & 0x07);
1075
                  else if ((code & 0xfc) == 0x10)
1076
                    code = 0xa0 + (code & 0x07);
1077
                  else if ((code & 0xfc) == 0xb0)
1078
                    code = 0x70 + (code & 0x07);
1079
                  else if ((code & 0xfc) == 0x30)
1080
                    code = 0x60 + (code & 0x07);
1081
                  else if ((code & 0xfc) == 0xa0)
1082
                    code = 0xd0 + (code & 0x07);
1083
                  else if ((code & 0xfc) == 0x20)
1084
                    code = 0x90 + (code & 0x07);
1085
                  else if ((code & 0xfc) == 0x90)
1086
                    code = 0x50 + (code & 0x07);
1087
 
1088
                  bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1089
 
1090
                  /* Fix the relocation's type.  */
1091
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1092
                                               R_MN10200_16);
1093
 
1094
                  /* Delete one bytes of data.  */
1095
                  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1096
                                                       irel->r_offset + 2, 1))
1097
                    goto error_return;
1098
 
1099
                  /* That will change things, so, we should relax again.
1100
                     Note that this is not required, and it may be slow.  */
1101
                  *again = TRUE;
1102
                  break;
1103
 
1104
                /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
1105
                case 0xc4:
1106
                  /* Note that we've changed the reldection contents, etc.  */
1107
                  elf_section_data (sec)->relocs = internal_relocs;
1108
                  elf_section_data (sec)->this_hdr.contents = contents;
1109
                  symtab_hdr->contents = (unsigned char *) isymbuf;
1110
 
1111
                  bfd_put_8 (abfd, 0xcc + (code & 0x03),
1112
                             contents + irel->r_offset - 2);
1113
 
1114
                  bfd_put_8 (abfd, 0xb8 + (code & 0x03),
1115
                             contents + irel->r_offset - 1);
1116
 
1117
                  /* Fix the relocation's type.  */
1118
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1119
                                               R_MN10200_16);
1120
 
1121
                  /* The reloc will be applied one byte in front of its
1122
                     current location.  */
1123
                  irel->r_offset -= 1;
1124
 
1125
                  /* Delete one bytes of data.  */
1126
                  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1127
                                                       irel->r_offset + 2, 1))
1128
                    goto error_return;
1129
 
1130
                  /* That will change things, so, we should relax again.
1131
                     Note that this is not required, and it may be slow.  */
1132
                  *again = TRUE;
1133
                  break;
1134
                }
1135
            }
1136
        }
1137
    }
1138
 
1139
  if (isymbuf != NULL
1140
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1141
    {
1142
      if (! link_info->keep_memory)
1143
        free (isymbuf);
1144
      else
1145
        {
1146
          /* Cache the symbols for elf_link_input_bfd.  */
1147
          symtab_hdr->contents = (unsigned char *) isymbuf;
1148
        }
1149
    }
1150
 
1151
  if (contents != NULL
1152
      && elf_section_data (sec)->this_hdr.contents != contents)
1153
    {
1154
      if (! link_info->keep_memory)
1155
        free (contents);
1156
      else
1157
        {
1158
          /* Cache the section contents for elf_link_input_bfd.  */
1159
          elf_section_data (sec)->this_hdr.contents = contents;
1160
        }
1161
    }
1162
 
1163
  if (internal_relocs != NULL
1164
      && elf_section_data (sec)->relocs != internal_relocs)
1165
    free (internal_relocs);
1166
 
1167
  return TRUE;
1168
 
1169
 error_return:
1170
  if (isymbuf != NULL
1171
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1172
    free (isymbuf);
1173
  if (contents != NULL
1174
      && elf_section_data (sec)->this_hdr.contents != contents)
1175
    free (contents);
1176
  if (internal_relocs != NULL
1177
      && elf_section_data (sec)->relocs != internal_relocs)
1178
    free (internal_relocs);
1179
 
1180
  return FALSE;
1181
}
1182
 
1183
/* Delete some bytes from a section while relaxing.  */
1184
 
1185
static bfd_boolean
1186
mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
1187
     bfd *abfd;
1188
     asection *sec;
1189
     bfd_vma addr;
1190
     int count;
1191
{
1192
  Elf_Internal_Shdr *symtab_hdr;
1193
  unsigned int sec_shndx;
1194
  bfd_byte *contents;
1195
  Elf_Internal_Rela *irel, *irelend;
1196
  Elf_Internal_Rela *irelalign;
1197
  bfd_vma toaddr;
1198
  Elf_Internal_Sym *isym;
1199
  Elf_Internal_Sym *isymend;
1200
  struct elf_link_hash_entry **sym_hashes;
1201
  struct elf_link_hash_entry **end_hashes;
1202
  unsigned int symcount;
1203
 
1204
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1205
 
1206
  contents = elf_section_data (sec)->this_hdr.contents;
1207
 
1208
  /* The deletion must stop at the next ALIGN reloc for an aligment
1209
     power larger than the number of bytes we are deleting.  */
1210
 
1211
  irelalign = NULL;
1212
  toaddr = sec->size;
1213
 
1214
  irel = elf_section_data (sec)->relocs;
1215
  irelend = irel + sec->reloc_count;
1216
 
1217
  /* Actually delete the bytes.  */
1218
  memmove (contents + addr, contents + addr + count,
1219
           (size_t) (toaddr - addr - count));
1220
  sec->size -= count;
1221
 
1222
  /* Adjust all the relocs.  */
1223
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1224
    {
1225
      /* Get the new reloc address.  */
1226
      if ((irel->r_offset > addr
1227
           && irel->r_offset < toaddr))
1228
        irel->r_offset -= count;
1229
    }
1230
 
1231
  /* Adjust the local symbols defined in this section.  */
1232
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1233
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1234
  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1235
    {
1236
      if (isym->st_shndx == sec_shndx
1237
          && isym->st_value > addr
1238
          && isym->st_value < toaddr)
1239
        isym->st_value -= count;
1240
    }
1241
 
1242
  /* Now adjust the global symbols defined in this section.  */
1243
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1244
              - symtab_hdr->sh_info);
1245
  sym_hashes = elf_sym_hashes (abfd);
1246
  end_hashes = sym_hashes + symcount;
1247
  for (; sym_hashes < end_hashes; sym_hashes++)
1248
    {
1249
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1250
      if ((sym_hash->root.type == bfd_link_hash_defined
1251
           || sym_hash->root.type == bfd_link_hash_defweak)
1252
          && sym_hash->root.u.def.section == sec
1253
          && sym_hash->root.u.def.value > addr
1254
          && sym_hash->root.u.def.value < toaddr)
1255
        {
1256
          sym_hash->root.u.def.value -= count;
1257
        }
1258
    }
1259
 
1260
  return TRUE;
1261
}
1262
 
1263
/* Return TRUE if a symbol exists at the given address, else return
1264
   FALSE.  */
1265
static bfd_boolean
1266
mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
1267
     bfd *abfd;
1268
     asection *sec;
1269
     Elf_Internal_Sym *isym;
1270
     bfd_vma addr;
1271
{
1272
  Elf_Internal_Shdr *symtab_hdr;
1273
  unsigned int sec_shndx;
1274
  Elf_Internal_Sym *isymend;
1275
  struct elf_link_hash_entry **sym_hashes;
1276
  struct elf_link_hash_entry **end_hashes;
1277
  unsigned int symcount;
1278
 
1279
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1280
 
1281
  /* Examine all the local symbols.  */
1282
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1283
  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1284
    {
1285
      if (isym->st_shndx == sec_shndx
1286
          && isym->st_value == addr)
1287
        return TRUE;
1288
    }
1289
 
1290
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1291
              - symtab_hdr->sh_info);
1292
  sym_hashes = elf_sym_hashes (abfd);
1293
  end_hashes = sym_hashes + symcount;
1294
  for (; sym_hashes < end_hashes; sym_hashes++)
1295
    {
1296
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1297
      if ((sym_hash->root.type == bfd_link_hash_defined
1298
           || sym_hash->root.type == bfd_link_hash_defweak)
1299
          && sym_hash->root.u.def.section == sec
1300
          && sym_hash->root.u.def.value == addr)
1301
        return TRUE;
1302
    }
1303
 
1304
  return FALSE;
1305
}
1306
 
1307
/* This is a version of bfd_generic_get_relocated_section_contents
1308
   which uses mn10200_elf_relocate_section.  */
1309
 
1310
static bfd_byte *
1311
mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
1312
                                            data, relocatable, symbols)
1313
     bfd *output_bfd;
1314
     struct bfd_link_info *link_info;
1315
     struct bfd_link_order *link_order;
1316
     bfd_byte *data;
1317
     bfd_boolean relocatable;
1318
     asymbol **symbols;
1319
{
1320
  Elf_Internal_Shdr *symtab_hdr;
1321
  asection *input_section = link_order->u.indirect.section;
1322
  bfd *input_bfd = input_section->owner;
1323
  asection **sections = NULL;
1324
  Elf_Internal_Rela *internal_relocs = NULL;
1325
  Elf_Internal_Sym *isymbuf = NULL;
1326
 
1327
  /* We only need to handle the case of relaxing, or of having a
1328
     particular set of section contents, specially.  */
1329
  if (relocatable
1330
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1331
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1332
                                                       link_order, data,
1333
                                                       relocatable,
1334
                                                       symbols);
1335
 
1336
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1337
 
1338
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1339
          (size_t) input_section->size);
1340
 
1341
  if ((input_section->flags & SEC_RELOC) != 0
1342
      && input_section->reloc_count > 0)
1343
    {
1344
      Elf_Internal_Sym *isym;
1345
      Elf_Internal_Sym *isymend;
1346
      asection **secpp;
1347
      bfd_size_type amt;
1348
 
1349
      internal_relocs = (_bfd_elf_link_read_relocs
1350
                         (input_bfd, input_section, (PTR) NULL,
1351
                          (Elf_Internal_Rela *) NULL, FALSE));
1352
      if (internal_relocs == NULL)
1353
        goto error_return;
1354
 
1355
      if (symtab_hdr->sh_info != 0)
1356
        {
1357
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1358
          if (isymbuf == NULL)
1359
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1360
                                            symtab_hdr->sh_info, 0,
1361
                                            NULL, NULL, NULL);
1362
          if (isymbuf == NULL)
1363
            goto error_return;
1364
        }
1365
 
1366
      amt = symtab_hdr->sh_info;
1367
      amt *= sizeof (asection *);
1368
      sections = (asection **) bfd_malloc (amt);
1369
      if (sections == NULL && amt != 0)
1370
        goto error_return;
1371
 
1372
      isymend = isymbuf + symtab_hdr->sh_info;
1373
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1374
        {
1375
          asection *isec;
1376
 
1377
          if (isym->st_shndx == SHN_UNDEF)
1378
            isec = bfd_und_section_ptr;
1379
          else if (isym->st_shndx == SHN_ABS)
1380
            isec = bfd_abs_section_ptr;
1381
          else if (isym->st_shndx == SHN_COMMON)
1382
            isec = bfd_com_section_ptr;
1383
          else
1384
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1385
 
1386
          *secpp = isec;
1387
        }
1388
 
1389
      if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
1390
                                     input_section, data, internal_relocs,
1391
                                     isymbuf, sections))
1392
        goto error_return;
1393
 
1394
      if (sections != NULL)
1395
        free (sections);
1396
      if (isymbuf != NULL
1397
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1398
        free (isymbuf);
1399
      if (elf_section_data (input_section)->relocs != internal_relocs)
1400
        free (internal_relocs);
1401
    }
1402
 
1403
  return data;
1404
 
1405
 error_return:
1406
  if (sections != NULL)
1407
    free (sections);
1408
  if (isymbuf != NULL
1409
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1410
    free (isymbuf);
1411
  if (internal_relocs != NULL
1412
      && elf_section_data (input_section)->relocs != internal_relocs)
1413
    free (internal_relocs);
1414
  return NULL;
1415
}
1416
 
1417
#define TARGET_LITTLE_SYM       bfd_elf32_mn10200_vec
1418
#define TARGET_LITTLE_NAME      "elf32-mn10200"
1419
#define ELF_ARCH                bfd_arch_mn10200
1420
#define ELF_MACHINE_CODE        EM_MN10200
1421
#define ELF_MACHINE_ALT1        EM_CYGNUS_MN10200
1422
#define ELF_MAXPAGESIZE         0x1000
1423
 
1424
#define elf_backend_rela_normal 1
1425
#define elf_info_to_howto       mn10200_info_to_howto
1426
#define elf_info_to_howto_rel   0
1427
#define elf_backend_relocate_section mn10200_elf_relocate_section
1428
#define bfd_elf32_bfd_relax_section     mn10200_elf_relax_section
1429
#define bfd_elf32_bfd_get_relocated_section_contents \
1430
                                mn10200_elf_get_relocated_section_contents
1431
 
1432
#define elf_symbol_leading_char '_'
1433
 
1434
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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