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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [bfd/] [elf32-m32c.c] - Blame information for rev 327

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

Line No. Rev Author Line
1 227 jeremybenn
/* M16C/M32C specific support for 32-bit ELF.
2
   Copyright (C) 2005, 2006, 2007, 2008, 2009
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "libbfd.h"
24
#include "elf-bfd.h"
25
#include "elf/m32c.h"
26
#include "libiberty.h"
27
 
28
/* Forward declarations.  */
29
static reloc_howto_type * m32c_reloc_type_lookup
30
  (bfd *, bfd_reloc_code_real_type);
31
static void m32c_info_to_howto_rela
32
  (bfd *, arelent *, Elf_Internal_Rela *);
33
static bfd_boolean m32c_elf_relocate_section
34
  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
35
static bfd_boolean m32c_elf_check_relocs
36
  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
37
static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
38
#ifdef DEBUG
39
char * m32c_get_reloc (long reloc);
40
void dump_symtab (bfd *, void *, void *);
41
#endif
42
static bfd_boolean m32c_elf_relax_section
43
(bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
44
 
45
 
46
static reloc_howto_type m32c_elf_howto_table [] =
47
{
48
  /* This reloc does nothing.  */
49
  HOWTO (R_M32C_NONE,           /* type */
50
         0,                      /* rightshift */
51
         0,                      /* 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_M32C_NONE",         /* name */
58
         FALSE,                 /* partial_inplace */
59
         0,                      /* src_mask */
60
         0,                      /* dst_mask */
61
         FALSE),                /* pcrel_offset */
62
 
63
  /* GCC intentionally overflows these next two in order to work
64
     around limitations in the addressing modes, so don't complain
65
     about overflow.  */
66
  HOWTO (R_M32C_16,             /* type */
67
         0,                      /* rightshift */
68
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
69
         16,                    /* bitsize */
70
         FALSE,                 /* pc_relative */
71
         0,                      /* bitpos */
72
         complain_overflow_dont, /* complain_on_overflow */
73
         bfd_elf_generic_reloc, /* special_function */
74
         "R_M32C_16",           /* name */
75
         FALSE,                 /* partial_inplace */
76
         0,                      /* src_mask */
77
         0xffff,                /* dst_mask */
78
         FALSE),                /* pcrel_offset */
79
 
80
  HOWTO (R_M32C_24,             /* type */
81
         0,                      /* rightshift */
82
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
83
         24,                    /* bitsize */
84
         FALSE,                 /* pc_relative */
85
         0,                      /* bitpos */
86
         complain_overflow_dont, /* complain_on_overflow */
87
         bfd_elf_generic_reloc, /* special_function */
88
         "R_M32C_24",           /* name */
89
         FALSE,                 /* partial_inplace */
90
         0,                      /* src_mask */
91
         0xffffff,              /* dst_mask */
92
         FALSE),                /* pcrel_offset */
93
 
94
  HOWTO (R_M32C_32,             /* type */
95
         0,                      /* rightshift */
96
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
97
         32,                    /* bitsize */
98
         FALSE,                 /* pc_relative */
99
         0,                      /* bitpos */
100
         complain_overflow_bitfield, /* complain_on_overflow */
101
         bfd_elf_generic_reloc, /* special_function */
102
         "R_M32C_32",           /* name */
103
         FALSE,                 /* partial_inplace */
104
         0,                      /* src_mask */
105
         0xffffffff,            /* dst_mask */
106
         FALSE),                /* pcrel_offset */
107
 
108
  HOWTO (R_M32C_8_PCREL,        /* type */
109
         0,                      /* rightshift */
110
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
111
         8,                     /* bitsize */
112
         TRUE,                  /* pc_relative */
113
         0,                      /* bitpos */
114
         complain_overflow_signed, /* complain_on_overflow */
115
         bfd_elf_generic_reloc, /* special_function */
116
         "R_M32C_8_PCREL",      /* name */
117
         FALSE,                 /* partial_inplace */
118
         0,              /* src_mask */
119
         0xff,                  /* dst_mask */
120
         TRUE),                 /* pcrel_offset */
121
 
122
  HOWTO (R_M32C_16_PCREL,       /* type */
123
         0,                      /* rightshift */
124
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
125
         16,                    /* bitsize */
126
         TRUE,                  /* pc_relative */
127
         0,                      /* bitpos */
128
         complain_overflow_signed, /* complain_on_overflow */
129
         bfd_elf_generic_reloc, /* special_function */
130
         "R_M32C_16_PCREL",     /* name */
131
         FALSE,                 /* partial_inplace */
132
         0,              /* src_mask */
133
         0xffff,                /* dst_mask */
134
         TRUE),                 /* pcrel_offset */
135
 
136
  HOWTO (R_M32C_8,              /* type */
137
         0,                      /* rightshift */
138
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
139
         8,                     /* bitsize */
140
         FALSE,                 /* pc_relative */
141
         0,                      /* bitpos */
142
         complain_overflow_unsigned, /* complain_on_overflow */
143
         bfd_elf_generic_reloc, /* special_function */
144
         "R_M32C_8",            /* name */
145
         FALSE,                 /* partial_inplace */
146
         0,              /* src_mask */
147
         0xff,                  /* dst_mask */
148
         FALSE),                /* pcrel_offset */
149
 
150
  HOWTO (R_M32C_LO16,           /* type */
151
         0,                      /* rightshift */
152
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
153
         16,                    /* bitsize */
154
         FALSE,                 /* pc_relative */
155
         0,                      /* bitpos */
156
         complain_overflow_dont, /* complain_on_overflow */
157
         bfd_elf_generic_reloc, /* special_function */
158
         "R_M32C_LO16",         /* name */
159
         FALSE,                 /* partial_inplace */
160
         0,              /* src_mask */
161
         0xffff,                /* dst_mask */
162
         FALSE),                /* pcrel_offset */
163
 
164
  HOWTO (R_M32C_HI8,            /* type */
165
         0,                      /* rightshift */
166
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
167
         8,                     /* bitsize */
168
         FALSE,                 /* pc_relative */
169
         0,                      /* bitpos */
170
         complain_overflow_dont, /* complain_on_overflow */
171
         bfd_elf_generic_reloc, /* special_function */
172
         "R_M32C_HI8",          /* name */
173
         FALSE,                 /* partial_inplace */
174
         0,              /* src_mask */
175
         0xff,                  /* dst_mask */
176
         FALSE),                /* pcrel_offset */
177
 
178
  HOWTO (R_M32C_HI16,           /* type */
179
         0,                      /* rightshift */
180
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
181
         16,                    /* bitsize */
182
         FALSE,                 /* pc_relative */
183
         0,                      /* bitpos */
184
         complain_overflow_dont, /* complain_on_overflow */
185
         bfd_elf_generic_reloc, /* special_function */
186
         "R_M32C_HI16",         /* name */
187
         FALSE,                 /* partial_inplace */
188
         0,              /* src_mask */
189
         0xffff,                /* dst_mask */
190
         FALSE),                /* pcrel_offset */
191
 
192
  HOWTO (R_M32C_RL_JUMP,        /* type */
193
         0,                      /* rightshift */
194
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
195
         0,                      /* bitsize */
196
         FALSE,                 /* pc_relative */
197
         0,                      /* bitpos */
198
         complain_overflow_signed, /* complain_on_overflow */
199
         bfd_elf_generic_reloc, /* special_function */
200
         "R_M32C_RL_JUMP",      /* name */
201
         FALSE,                 /* partial_inplace */
202
         0,              /* src_mask */
203
         0,                      /* dst_mask */
204
         FALSE),                /* pcrel_offset */
205
 
206
  HOWTO (R_M32C_RL_1ADDR,       /* type */
207
         0,                      /* rightshift */
208
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
209
         0,                      /* bitsize */
210
         FALSE,                 /* pc_relative */
211
         0,                      /* bitpos */
212
         complain_overflow_signed, /* complain_on_overflow */
213
         bfd_elf_generic_reloc, /* special_function */
214
         "R_M32C_RL_1ADDR",     /* name */
215
         FALSE,                 /* partial_inplace */
216
         0,              /* src_mask */
217
         0,                      /* dst_mask */
218
         FALSE),                /* pcrel_offset */
219
 
220
  HOWTO (R_M32C_RL_2ADDR,       /* type */
221
         0,                      /* rightshift */
222
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
223
         0,                      /* bitsize */
224
         FALSE,                 /* pc_relative */
225
         0,                      /* bitpos */
226
         complain_overflow_signed, /* complain_on_overflow */
227
         bfd_elf_generic_reloc, /* special_function */
228
         "R_M32C_RL_2ADDR",     /* name */
229
         FALSE,                 /* partial_inplace */
230
         0,              /* src_mask */
231
         0,                      /* dst_mask */
232
         FALSE),                /* pcrel_offset */
233
 
234
};
235
 
236
/* Map BFD reloc types to M32C ELF reloc types.  */
237
 
238
struct m32c_reloc_map
239
{
240
  bfd_reloc_code_real_type bfd_reloc_val;
241
  unsigned int m32c_reloc_val;
242
};
243
 
244
static const struct m32c_reloc_map m32c_reloc_map [] =
245
{
246
  { BFD_RELOC_NONE,             R_M32C_NONE },
247
  { BFD_RELOC_16,               R_M32C_16 },
248
  { BFD_RELOC_24,               R_M32C_24 },
249
  { BFD_RELOC_32,               R_M32C_32 },
250
  { BFD_RELOC_8_PCREL,          R_M32C_8_PCREL },
251
  { BFD_RELOC_16_PCREL,         R_M32C_16_PCREL },
252
  { BFD_RELOC_8,                R_M32C_8 },
253
  { BFD_RELOC_LO16,             R_M32C_LO16 },
254
  { BFD_RELOC_HI16,             R_M32C_HI16 },
255
  { BFD_RELOC_M32C_HI8,         R_M32C_HI8 },
256
  { BFD_RELOC_M32C_RL_JUMP,     R_M32C_RL_JUMP },
257
  { BFD_RELOC_M32C_RL_1ADDR,    R_M32C_RL_1ADDR },
258
  { BFD_RELOC_M32C_RL_2ADDR,    R_M32C_RL_2ADDR }
259
};
260
 
261
static reloc_howto_type *
262
m32c_reloc_type_lookup
263
    (bfd *                    abfd ATTRIBUTE_UNUSED,
264
     bfd_reloc_code_real_type code)
265
{
266
  unsigned int i;
267
 
268
  for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
269
    if (m32c_reloc_map [i].bfd_reloc_val == code)
270
      return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
271
 
272
  return NULL;
273
}
274
 
275
static reloc_howto_type *
276
m32c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
277
{
278
  unsigned int i;
279
 
280
  for (i = 0;
281
       i < sizeof (m32c_elf_howto_table) / sizeof (m32c_elf_howto_table[0]);
282
       i++)
283
    if (m32c_elf_howto_table[i].name != NULL
284
        && strcasecmp (m32c_elf_howto_table[i].name, r_name) == 0)
285
      return &m32c_elf_howto_table[i];
286
 
287
  return NULL;
288
}
289
 
290
/* Set the howto pointer for an M32C ELF reloc.  */
291
 
292
static void
293
m32c_info_to_howto_rela
294
    (bfd *               abfd ATTRIBUTE_UNUSED,
295
     arelent *           cache_ptr,
296
     Elf_Internal_Rela * dst)
297
{
298
  unsigned int r_type;
299
 
300
  r_type = ELF32_R_TYPE (dst->r_info);
301
  BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
302
  cache_ptr->howto = & m32c_elf_howto_table [r_type];
303
}
304
 
305
 
306
 
307
/* Relocate an M32C ELF section.
308
   There is some attempt to make this function usable for many architectures,
309
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
310
   if only to serve as a learning tool.
311
 
312
   The RELOCATE_SECTION function is called by the new ELF backend linker
313
   to handle the relocations for a section.
314
 
315
   The relocs are always passed as Rela structures; if the section
316
   actually uses Rel structures, the r_addend field will always be
317
   zero.
318
 
319
   This function is responsible for adjusting the section contents as
320
   necessary, and (if using Rela relocs and generating a relocatable
321
   output file) adjusting the reloc addend as necessary.
322
 
323
   This function does not have to worry about setting the reloc
324
   address or the reloc symbol index.
325
 
326
   LOCAL_SYMS is a pointer to the swapped in local symbols.
327
 
328
   LOCAL_SECTIONS is an array giving the section in the input file
329
   corresponding to the st_shndx field of each local symbol.
330
 
331
   The global hash table entry for the global symbols can be found
332
   via elf_sym_hashes (input_bfd).
333
 
334
   When generating relocatable output, this function must handle
335
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
336
   going to be the section symbol corresponding to the output
337
   section, which means that the addend must be adjusted
338
   accordingly.  */
339
 
340
static bfd_boolean
341
m32c_elf_relocate_section
342
    (bfd *                   output_bfd ATTRIBUTE_UNUSED,
343
     struct bfd_link_info *  info,
344
     bfd *                   input_bfd,
345
     asection *              input_section,
346
     bfd_byte *              contents,
347
     Elf_Internal_Rela *     relocs,
348
     Elf_Internal_Sym *      local_syms,
349
     asection **             local_sections)
350
{
351
  Elf_Internal_Shdr *           symtab_hdr;
352
  struct elf_link_hash_entry ** sym_hashes;
353
  Elf_Internal_Rela *           rel;
354
  Elf_Internal_Rela *           relend;
355
  bfd *dynobj;
356
  asection *splt;
357
 
358
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
359
  sym_hashes = elf_sym_hashes (input_bfd);
360
  relend     = relocs + input_section->reloc_count;
361
 
362
  dynobj = elf_hash_table (info)->dynobj;
363
  splt = NULL;
364
  if (dynobj != NULL)
365
    splt = bfd_get_section_by_name (dynobj, ".plt");
366
 
367
  for (rel = relocs; rel < relend; rel ++)
368
    {
369
      reloc_howto_type *           howto;
370
      unsigned long                r_symndx;
371
      Elf_Internal_Sym *           sym;
372
      asection *                   sec;
373
      struct elf_link_hash_entry * h;
374
      bfd_vma                      relocation;
375
      bfd_reloc_status_type        r;
376
      const char *                 name = NULL;
377
      int                          r_type;
378
 
379
      r_type = ELF32_R_TYPE (rel->r_info);
380
 
381
      /* These are only used for relaxing; we don't actually relocate
382
         anything with them, so skip them.  */
383
      if (r_type == R_M32C_RL_JUMP
384
          || r_type == R_M32C_RL_1ADDR
385
          || r_type == R_M32C_RL_2ADDR)
386
        continue;
387
 
388
      r_symndx = ELF32_R_SYM (rel->r_info);
389
 
390
      howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
391
      h      = NULL;
392
      sym    = NULL;
393
      sec    = NULL;
394
      relocation = 0;
395
 
396
      if (r_symndx < symtab_hdr->sh_info)
397
        {
398
          sym = local_syms + r_symndx;
399
          sec = local_sections [r_symndx];
400
          relocation = (sec->output_section->vma
401
                        + sec->output_offset
402
                        + sym->st_value);
403
 
404
          name = bfd_elf_string_from_elf_section
405
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
406
          name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
407
        }
408
      else
409
        {
410
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
411
 
412
          while (h->root.type == bfd_link_hash_indirect
413
                 || h->root.type == bfd_link_hash_warning)
414
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
415
 
416
          name = h->root.root.string;
417
 
418
          if (h->root.type == bfd_link_hash_defined
419
              || h->root.type == bfd_link_hash_defweak)
420
            {
421
              sec = h->root.u.def.section;
422
              relocation = (h->root.u.def.value
423
                            + sec->output_section->vma
424
                            + sec->output_offset);
425
            }
426
          else if (h->root.type == bfd_link_hash_undefweak)
427
            ;
428
          else if (!info->relocatable)
429
            {
430
              if (! ((*info->callbacks->undefined_symbol)
431
                     (info, h->root.root.string, input_bfd,
432
                      input_section, rel->r_offset, TRUE)))
433
                return FALSE;
434
            }
435
        }
436
 
437
      if (sec != NULL && elf_discarded_section (sec))
438
        {
439
          /* For relocs against symbols from removed linkonce sections,
440
             or sections discarded by a linker script, we just want the
441
             section contents zeroed.  Avoid any special processing.  */
442
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
443
          rel->r_info = 0;
444
          rel->r_addend = 0;
445
          continue;
446
        }
447
 
448
      if (info->relocatable)
449
        {
450
          /* This is a relocatable link.  We don't have to change
451
             anything, unless the reloc is against a section symbol,
452
             in which case we have to adjust according to where the
453
             section symbol winds up in the output section.  */
454
          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
455
            rel->r_addend += sec->output_offset;
456
          continue;
457
        }
458
 
459
      switch (ELF32_R_TYPE (rel->r_info))
460
        {
461
        case R_M32C_16:
462
          {
463
            bfd_vma *plt_offset;
464
 
465
            if (h != NULL)
466
              plt_offset = &h->plt.offset;
467
            else
468
              plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
469
 
470
            /*      printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
471
                    relocation, *plt_offset);*/
472
            if (relocation <= 0xffff)
473
              {
474
                /* If the symbol is in range for a 16-bit address, we should
475
                   have deallocated the plt entry in relax_section.  */
476
                BFD_ASSERT (*plt_offset == (bfd_vma) -1);
477
              }
478
            else
479
              {
480
                /* If the symbol is out of range for a 16-bit address,
481
                   we must have allocated a plt entry.  */
482
                BFD_ASSERT (*plt_offset != (bfd_vma) -1);
483
 
484
                /* If this is the first time we've processed this symbol,
485
                   fill in the plt entry with the correct symbol address.  */
486
                if ((*plt_offset & 1) == 0)
487
                  {
488
                    unsigned int x;
489
 
490
                    x = 0x000000fc;  /* jmpf */
491
                    x |= (relocation << 8) & 0xffffff00;
492
                    bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
493
                    *plt_offset |= 1;
494
                  }
495
 
496
                relocation = (splt->output_section->vma
497
                              + splt->output_offset
498
                              + (*plt_offset & -2));
499
                if (name)
500
                {
501
                  char *newname = bfd_malloc (strlen(name)+5);
502
                  strcpy (newname, name);
503
                  strcat(newname, ".plt");
504
                  _bfd_generic_link_add_one_symbol (info,
505
                                                    input_bfd,
506
                                                    newname,
507
                                                    BSF_FUNCTION | BSF_WEAK,
508
                                                    splt,
509
                                                    (*plt_offset & -2),
510
                                                    0,
511
                                                    1,
512
                                                    0,
513
                                                    0);
514
                }
515
              }
516
          }
517
          break;
518
 
519
        case R_M32C_HI8:
520
        case R_M32C_HI16:
521
          relocation >>= 16;
522
          break;
523
        }
524
 
525
#if 0
526
      printf ("relocate %s at %06lx relocation %06lx addend %ld  ",
527
              m32c_elf_howto_table[ELF32_R_TYPE(rel->r_info)].name,
528
              rel->r_offset + input_section->output_section->vma + input_section->output_offset,
529
              relocation, rel->r_addend);
530
      {
531
        int i;
532
        for (i=0; i<4; i++)
533
          printf (" %02x", contents[rel->r_offset+i]);
534
        printf ("\n");
535
      }
536
#endif
537
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
538
                                    contents, rel->r_offset, relocation,
539
                                    rel->r_addend);
540
 
541
      if (r != bfd_reloc_ok)
542
        {
543
          const char * msg = (const char *) NULL;
544
 
545
          switch (r)
546
            {
547
            case bfd_reloc_overflow:
548
              r = info->callbacks->reloc_overflow
549
                (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
550
                 input_bfd, input_section, rel->r_offset);
551
              break;
552
 
553
            case bfd_reloc_undefined:
554
              r = info->callbacks->undefined_symbol
555
                (info, name, input_bfd, input_section, rel->r_offset,
556
                 TRUE);
557
              break;
558
 
559
            case bfd_reloc_outofrange:
560
              msg = _("internal error: out of range error");
561
              break;
562
 
563
            case bfd_reloc_notsupported:
564
              msg = _("internal error: unsupported relocation error");
565
              break;
566
 
567
            case bfd_reloc_dangerous:
568
              msg = _("internal error: dangerous relocation");
569
              break;
570
 
571
            default:
572
              msg = _("internal error: unknown error");
573
              break;
574
            }
575
 
576
          if (msg)
577
            r = info->callbacks->warning
578
              (info, msg, name, input_bfd, input_section, rel->r_offset);
579
 
580
          if (! r)
581
            return FALSE;
582
        }
583
    }
584
 
585
  return TRUE;
586
}
587
 
588
/* We support 16-bit pointers to code above 64k by generating a thunk
589
   below 64k containing a JMP instruction to the final address.  */
590
 
591
static bfd_boolean
592
m32c_elf_check_relocs
593
    (bfd *                     abfd,
594
     struct bfd_link_info *    info,
595
     asection *                sec,
596
     const Elf_Internal_Rela * relocs)
597
{
598
  Elf_Internal_Shdr *           symtab_hdr;
599
  struct elf_link_hash_entry ** sym_hashes;
600
  const Elf_Internal_Rela *     rel;
601
  const Elf_Internal_Rela *     rel_end;
602
  bfd_vma *local_plt_offsets;
603
  asection *splt;
604
  bfd *dynobj;
605
 
606
  if (info->relocatable)
607
    return TRUE;
608
 
609
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
610
  sym_hashes = elf_sym_hashes (abfd);
611
  local_plt_offsets = elf_local_got_offsets (abfd);
612
  splt = NULL;
613
  dynobj = elf_hash_table(info)->dynobj;
614
 
615
  rel_end = relocs + sec->reloc_count;
616
  for (rel = relocs; rel < rel_end; rel++)
617
    {
618
      struct elf_link_hash_entry *h;
619
      unsigned long r_symndx;
620
      bfd_vma *offset;
621
 
622
      r_symndx = ELF32_R_SYM (rel->r_info);
623
      if (r_symndx < symtab_hdr->sh_info)
624
        h = NULL;
625
      else
626
        {
627
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
628
          while (h->root.type == bfd_link_hash_indirect
629
                 || h->root.type == bfd_link_hash_warning)
630
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
631
        }
632
 
633
      switch (ELF32_R_TYPE (rel->r_info))
634
        {
635
          /* This relocation describes a 16-bit pointer to a function.
636
             We may need to allocate a thunk in low memory; reserve memory
637
             for it now.  */
638
        case R_M32C_16:
639
          if (dynobj == NULL)
640
            elf_hash_table (info)->dynobj = dynobj = abfd;
641
          if (splt == NULL)
642
            {
643
              splt = bfd_get_section_by_name (dynobj, ".plt");
644
              if (splt == NULL)
645
                {
646
                  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
647
                                    | SEC_IN_MEMORY | SEC_LINKER_CREATED
648
                                    | SEC_READONLY | SEC_CODE);
649
                  splt = bfd_make_section_with_flags (dynobj, ".plt", flags);
650
                  if (splt == NULL
651
                      || ! bfd_set_section_alignment (dynobj, splt, 1))
652
                    return FALSE;
653
                }
654
            }
655
 
656
          if (h != NULL)
657
            offset = &h->plt.offset;
658
          else
659
            {
660
              if (local_plt_offsets == NULL)
661
                {
662
                  size_t size;
663
                  unsigned int i;
664
 
665
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
666
                  local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
667
                  if (local_plt_offsets == NULL)
668
                    return FALSE;
669
                  elf_local_got_offsets (abfd) = local_plt_offsets;
670
 
671
                  for (i = 0; i < symtab_hdr->sh_info; i++)
672
                    local_plt_offsets[i] = (bfd_vma) -1;
673
                }
674
              offset = &local_plt_offsets[r_symndx];
675
            }
676
 
677
          if (*offset == (bfd_vma) -1)
678
            {
679
              *offset = splt->size;
680
              splt->size += 4;
681
            }
682
          break;
683
        }
684
    }
685
 
686
  return TRUE;
687
}
688
 
689
/* This must exist if dynobj is ever set.  */
690
 
691
static bfd_boolean
692
m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
693
                                  struct bfd_link_info *info)
694
{
695
  bfd *dynobj;
696
  asection *splt;
697
 
698
  /* As an extra sanity check, verify that all plt entries have
699
     been filled in.  */
700
 
701
  if ((dynobj = elf_hash_table (info)->dynobj) != NULL
702
      && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
703
    {
704
      bfd_byte *contents = splt->contents;
705
      unsigned int i, size = splt->size;
706
      for (i = 0; i < size; i += 4)
707
        {
708
          unsigned int x = bfd_get_32 (dynobj, contents + i);
709
          BFD_ASSERT (x != 0);
710
        }
711
    }
712
 
713
  return TRUE;
714
}
715
 
716
static bfd_boolean
717
m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
718
                               struct bfd_link_info *info)
719
{
720
  bfd *dynobj;
721
  asection *splt;
722
 
723
  if (info->relocatable)
724
    return TRUE;
725
 
726
  dynobj = elf_hash_table (info)->dynobj;
727
  if (dynobj == NULL)
728
    return TRUE;
729
 
730
  splt = bfd_get_section_by_name (dynobj, ".plt");
731
  BFD_ASSERT (splt != NULL);
732
 
733
  splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
734
  if (splt->contents == NULL)
735
    return FALSE;
736
 
737
  return TRUE;
738
}
739
 
740
/* Function to set the ELF flag bits.  */
741
 
742
static bfd_boolean
743
m32c_elf_set_private_flags (bfd *abfd, flagword flags)
744
{
745
  elf_elfheader (abfd)->e_flags = flags;
746
  elf_flags_init (abfd) = TRUE;
747
  return TRUE;
748
}
749
 
750
/* Merge backend specific data from an object file to the output
751
   object file when linking.  */
752
 
753
static bfd_boolean
754
m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
755
{
756
  flagword old_flags, old_partial;
757
  flagword new_flags, new_partial;
758
  bfd_boolean error = FALSE;
759
  char new_opt[80];
760
  char old_opt[80];
761
 
762
  new_opt[0] = old_opt[0] = '\0';
763
  new_flags = elf_elfheader (ibfd)->e_flags;
764
  old_flags = elf_elfheader (obfd)->e_flags;
765
 
766
#ifdef DEBUG
767
  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
768
                         old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
769
                         bfd_get_filename (ibfd));
770
#endif
771
 
772
  if (!elf_flags_init (obfd))
773
    {
774
      /* First call, no flags set.  */
775
      elf_flags_init (obfd) = TRUE;
776
      elf_elfheader (obfd)->e_flags = new_flags;
777
    }
778
 
779
  else if (new_flags == old_flags)
780
    /* Compatible flags are ok.  */
781
    ;
782
 
783
  else          /* Possibly incompatible flags.  */
784
    {
785
      /* Warn if different cpu is used (allow a specific cpu to override
786
         the generic cpu).  */
787
      new_partial = (new_flags & EF_M32C_CPU_MASK);
788
      old_partial = (old_flags & EF_M32C_CPU_MASK);
789
      if (new_partial == old_partial)
790
        ;
791
 
792
      else
793
        {
794
          switch (new_partial)
795
            {
796
            default:              strcat (new_opt, " -m16c");   break;
797
            case EF_M32C_CPU_M16C:      strcat (new_opt, " -m16c");  break;
798
            case EF_M32C_CPU_M32C:  strcat (new_opt, " -m32c");  break;
799
            }
800
 
801
          switch (old_partial)
802
            {
803
            default:              strcat (old_opt, " -m16c");   break;
804
            case EF_M32C_CPU_M16C:      strcat (old_opt, " -m16c");  break;
805
            case EF_M32C_CPU_M32C:  strcat (old_opt, " -m32c");  break;
806
            }
807
        }
808
 
809
      /* Print out any mismatches from above.  */
810
      if (new_opt[0])
811
        {
812
          error = TRUE;
813
          (*_bfd_error_handler)
814
            (_("%s: compiled with %s and linked with modules compiled with %s"),
815
             bfd_get_filename (ibfd), new_opt, old_opt);
816
        }
817
 
818
      new_flags &= ~ EF_M32C_ALL_FLAGS;
819
      old_flags &= ~ EF_M32C_ALL_FLAGS;
820
 
821
      /* Warn about any other mismatches.  */
822
      if (new_flags != old_flags)
823
        {
824
          error = TRUE;
825
          (*_bfd_error_handler)
826
            (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
827
             bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
828
        }
829
    }
830
 
831
  if (error)
832
    bfd_set_error (bfd_error_bad_value);
833
 
834
  return !error;
835
}
836
 
837
 
838
static bfd_boolean
839
m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
840
{
841
  FILE *file = (FILE *) ptr;
842
  flagword flags;
843
 
844
  BFD_ASSERT (abfd != NULL && ptr != NULL);
845
 
846
  /* Print normal ELF private data.  */
847
  _bfd_elf_print_private_bfd_data (abfd, ptr);
848
 
849
  flags = elf_elfheader (abfd)->e_flags;
850
  fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
851
 
852
  switch (flags & EF_M32C_CPU_MASK)
853
    {
854
    default:                                                    break;
855
    case EF_M32C_CPU_M16C:      fprintf (file, " -m16c");       break;
856
    case EF_M32C_CPU_M32C:  fprintf (file, " -m32c");   break;
857
    }
858
 
859
  fputc ('\n', file);
860
  return TRUE;
861
}
862
 
863
/* Return the MACH for an e_flags value.  */
864
 
865
static int
866
elf32_m32c_machine (bfd *abfd)
867
{
868
  switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
869
    {
870
    case EF_M32C_CPU_M16C:      return bfd_mach_m16c;
871
    case EF_M32C_CPU_M32C:      return bfd_mach_m32c;
872
    }
873
 
874
  return bfd_mach_m16c;
875
}
876
 
877
static bfd_boolean
878
m32c_elf_object_p (bfd *abfd)
879
{
880
  bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
881
                             elf32_m32c_machine (abfd));
882
  return TRUE;
883
}
884
 
885
 
886
#ifdef DEBUG
887
void
888
dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
889
{
890
  size_t locsymcount;
891
  Elf_Internal_Sym *isymbuf;
892
  Elf_Internal_Sym *isymend;
893
  Elf_Internal_Sym *isym;
894
  Elf_Internal_Shdr *symtab_hdr;
895
  bfd_boolean free_internal = 0, free_external = 0;
896
  char * st_info_str;
897
  char * st_info_stb_str;
898
  char * st_other_str;
899
  char * st_shndx_str;
900
 
901
  if (! internal_syms)
902
    {
903
      internal_syms = bfd_malloc (1000);
904
      free_internal = 1;
905
    }
906
  if (! external_syms)
907
    {
908
      external_syms = bfd_malloc (1000);
909
      free_external = 1;
910
    }
911
 
912
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
913
  locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
914
  if (free_internal)
915
    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
916
                                    symtab_hdr->sh_info, 0,
917
                                    internal_syms, external_syms, NULL);
918
  else
919
    isymbuf = internal_syms;
920
  isymend = isymbuf + locsymcount;
921
 
922
  for (isym = isymbuf ; isym < isymend ; isym++)
923
    {
924
      switch (ELF_ST_TYPE (isym->st_info))
925
        {
926
        case STT_FUNC: st_info_str = "STT_FUNC";
927
        case STT_SECTION: st_info_str = "STT_SECTION";
928
        case STT_FILE: st_info_str = "STT_FILE";
929
        case STT_OBJECT: st_info_str = "STT_OBJECT";
930
        case STT_TLS: st_info_str = "STT_TLS";
931
        default: st_info_str = "";
932
        }
933
      switch (ELF_ST_BIND (isym->st_info))
934
        {
935
        case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
936
        case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
937
        default: st_info_stb_str = "";
938
        }
939
      switch (ELF_ST_VISIBILITY (isym->st_other))
940
        {
941
        case STV_DEFAULT: st_other_str = "STV_DEFAULT";
942
        case STV_INTERNAL: st_other_str = "STV_INTERNAL";
943
        case STV_PROTECTED: st_other_str = "STV_PROTECTED";
944
        default: st_other_str = "";
945
        }
946
      switch (isym->st_shndx)
947
        {
948
        case SHN_ABS: st_shndx_str = "SHN_ABS";
949
        case SHN_COMMON: st_shndx_str = "SHN_COMMON";
950
        case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
951
        default: st_shndx_str = "";
952
        }
953
 
954
      printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
955
              "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
956
              isym,
957
              (unsigned long) isym->st_value,
958
              (unsigned long) isym->st_size,
959
              isym->st_name,
960
              bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
961
                                               isym->st_name),
962
              isym->st_info, st_info_str, st_info_stb_str,
963
              isym->st_other, st_other_str,
964
              isym->st_shndx, st_shndx_str);
965
    }
966
  if (free_internal)
967
    free (internal_syms);
968
  if (free_external)
969
    free (external_syms);
970
}
971
 
972
char *
973
m32c_get_reloc (long reloc)
974
{
975
  if (0 <= reloc && reloc < R_M32C_max)
976
    return m32c_elf_howto_table[reloc].name;
977
  else
978
    return "";
979
}
980
#endif /* DEBUG */
981
 
982
/* Handle relaxing.  */
983
 
984
/* A subroutine of m32c_elf_relax_section.  If the global symbol H
985
   is within the low 64k, remove any entry for it in the plt.  */
986
 
987
struct relax_plt_data
988
{
989
  asection *splt;
990
  bfd_boolean *again;
991
};
992
 
993
static bfd_boolean
994
m32c_relax_plt_check (struct elf_link_hash_entry *h,
995
                      PTR xdata)
996
{
997
  struct relax_plt_data *data = (struct relax_plt_data *) xdata;
998
 
999
  if (h->root.type == bfd_link_hash_warning)
1000
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1001
 
1002
  if (h->plt.offset != (bfd_vma) -1)
1003
    {
1004
      bfd_vma address;
1005
 
1006
      if (h->root.type == bfd_link_hash_undefined
1007
          || h->root.type == bfd_link_hash_undefweak)
1008
        address = 0;
1009
      else
1010
        address = (h->root.u.def.section->output_section->vma
1011
                   + h->root.u.def.section->output_offset
1012
                   + h->root.u.def.value);
1013
 
1014
      if (address <= 0xffff)
1015
        {
1016
          h->plt.offset = -1;
1017
          data->splt->size -= 4;
1018
          *data->again = TRUE;
1019
        }
1020
    }
1021
 
1022
  return TRUE;
1023
}
1024
 
1025
/* A subroutine of m32c_elf_relax_section.  If the global symbol H
1026
   previously had a plt entry, give it a new entry offset.  */
1027
 
1028
static bfd_boolean
1029
m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
1030
                        PTR xdata)
1031
{
1032
  bfd_vma *entry = (bfd_vma *) xdata;
1033
 
1034
  if (h->root.type == bfd_link_hash_warning)
1035
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1036
 
1037
  if (h->plt.offset != (bfd_vma) -1)
1038
    {
1039
      h->plt.offset = *entry;
1040
      *entry += 4;
1041
    }
1042
 
1043
  return TRUE;
1044
}
1045
 
1046
static bfd_boolean
1047
m32c_elf_relax_plt_section (bfd *dynobj,
1048
                            asection *splt,
1049
                            struct bfd_link_info *info,
1050
                            bfd_boolean *again)
1051
{
1052
  struct relax_plt_data relax_plt_data;
1053
  bfd *ibfd;
1054
 
1055
  /* Assume nothing changes.  */
1056
  *again = FALSE;
1057
 
1058
  if (info->relocatable)
1059
    return TRUE;
1060
 
1061
  /* We only relax the .plt section at the moment.  */
1062
  if (dynobj != elf_hash_table (info)->dynobj
1063
      || strcmp (splt->name, ".plt") != 0)
1064
    return TRUE;
1065
 
1066
  /* Quick check for an empty plt.  */
1067
  if (splt->size == 0)
1068
    return TRUE;
1069
 
1070
  /* Map across all global symbols; see which ones happen to
1071
     fall in the low 64k.  */
1072
  relax_plt_data.splt = splt;
1073
  relax_plt_data.again = again;
1074
  elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
1075
                          &relax_plt_data);
1076
 
1077
  /* Likewise for local symbols, though that's somewhat less convenient
1078
     as we have to walk the list of input bfds and swap in symbol data.  */
1079
  for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1080
    {
1081
      bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1082
      Elf_Internal_Shdr *symtab_hdr;
1083
      Elf_Internal_Sym *isymbuf = NULL;
1084
      unsigned int idx;
1085
 
1086
      if (! local_plt_offsets)
1087
        continue;
1088
 
1089
      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1090
      if (symtab_hdr->sh_info != 0)
1091
        {
1092
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1093
          if (isymbuf == NULL)
1094
            isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1095
                                            symtab_hdr->sh_info, 0,
1096
                                            NULL, NULL, NULL);
1097
          if (isymbuf == NULL)
1098
            return FALSE;
1099
        }
1100
 
1101
      for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1102
        {
1103
          Elf_Internal_Sym *isym;
1104
          asection *tsec;
1105
          bfd_vma address;
1106
 
1107
          if (local_plt_offsets[idx] == (bfd_vma) -1)
1108
            continue;
1109
 
1110
          isym = &isymbuf[idx];
1111
          if (isym->st_shndx == SHN_UNDEF)
1112
            continue;
1113
          else if (isym->st_shndx == SHN_ABS)
1114
            tsec = bfd_abs_section_ptr;
1115
          else if (isym->st_shndx == SHN_COMMON)
1116
            tsec = bfd_com_section_ptr;
1117
          else
1118
            tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1119
 
1120
          address = (tsec->output_section->vma
1121
                     + tsec->output_offset
1122
                     + isym->st_value);
1123
          if (address <= 0xffff)
1124
            {
1125
              local_plt_offsets[idx] = -1;
1126
              splt->size -= 4;
1127
              *again = TRUE;
1128
            }
1129
        }
1130
 
1131
      if (isymbuf != NULL
1132
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1133
        {
1134
          if (! info->keep_memory)
1135
            free (isymbuf);
1136
          else
1137
            {
1138
              /* Cache the symbols for elf_link_input_bfd.  */
1139
              symtab_hdr->contents = (unsigned char *) isymbuf;
1140
            }
1141
        }
1142
    }
1143
 
1144
  /* If we changed anything, walk the symbols again to reallocate
1145
     .plt entry addresses.  */
1146
  if (*again && splt->size > 0)
1147
    {
1148
      bfd_vma entry = 0;
1149
 
1150
      elf_link_hash_traverse (elf_hash_table (info),
1151
                              m32c_relax_plt_realloc, &entry);
1152
 
1153
      for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1154
        {
1155
          bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1156
          unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1157
          unsigned int idx;
1158
 
1159
          if (! local_plt_offsets)
1160
            continue;
1161
 
1162
          for (idx = 0; idx < nlocals; ++idx)
1163
            if (local_plt_offsets[idx] != (bfd_vma) -1)
1164
              {
1165
                local_plt_offsets[idx] = entry;
1166
                entry += 4;
1167
              }
1168
        }
1169
    }
1170
 
1171
  return TRUE;
1172
}
1173
 
1174
static int
1175
compare_reloc (const void *e1, const void *e2)
1176
{
1177
  const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
1178
  const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
1179
 
1180
  if (i1->r_offset == i2->r_offset)
1181
    return 0;
1182
  else
1183
    return i1->r_offset < i2->r_offset ? -1 : 1;
1184
}
1185
 
1186
#define OFFSET_FOR_RELOC(rel) m32c_offset_for_reloc (abfd, rel, symtab_hdr, shndx_buf, intsyms)
1187
static bfd_vma
1188
m32c_offset_for_reloc (bfd *abfd,
1189
                       Elf_Internal_Rela *rel,
1190
                       Elf_Internal_Shdr *symtab_hdr,
1191
                       Elf_External_Sym_Shndx *shndx_buf,
1192
                       Elf_Internal_Sym *intsyms)
1193
{
1194
  bfd_vma symval;
1195
 
1196
  /* Get the value of the symbol referred to by the reloc.  */
1197
  if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
1198
    {
1199
      /* A local symbol.  */
1200
      Elf_Internal_Sym *isym;
1201
      Elf_External_Sym_Shndx *shndx;
1202
      asection *ssec;
1203
 
1204
 
1205
      isym = intsyms + ELF32_R_SYM (rel->r_info);
1206
      ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1207
      shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (rel->r_info) : 0);
1208
 
1209
      symval = isym->st_value;
1210
      if (ssec)
1211
        symval += ssec->output_section->vma
1212
          + ssec->output_offset;
1213
    }
1214
  else
1215
    {
1216
      unsigned long indx;
1217
      struct elf_link_hash_entry *h;
1218
 
1219
      /* An external symbol.  */
1220
      indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
1221
      h = elf_sym_hashes (abfd)[indx];
1222
      BFD_ASSERT (h != NULL);
1223
 
1224
      if (h->root.type != bfd_link_hash_defined
1225
          && h->root.type != bfd_link_hash_defweak)
1226
        /* This appears to be a reference to an undefined
1227
           symbol.  Just ignore it--it will be caught by the
1228
           regular reloc processing.  */
1229
        return 0;
1230
 
1231
      symval = (h->root.u.def.value
1232
                + h->root.u.def.section->output_section->vma
1233
                + h->root.u.def.section->output_offset);
1234
    }
1235
  return symval;
1236
}
1237
 
1238
static int bytes_saved = 0;
1239
 
1240
static int bytes_to_reloc[] = {
1241
  R_M32C_NONE,
1242
  R_M32C_8,
1243
  R_M32C_16,
1244
  R_M32C_24,
1245
  R_M32C_32
1246
};
1247
 
1248
/* What we use the bits in a relax reloc addend (R_M32C_RL_*) for.  */
1249
 
1250
/* Mask for the number of relocs associated with this insn.  */
1251
#define RLA_RELOCS              0x0000000f
1252
/* Number of bytes gas emitted (before gas's relaxing) */
1253
#define RLA_NBYTES              0x00000ff0
1254
 
1255
/* If the displacement is within the given range and the new encoding
1256
   differs from the old encoding (the index), then the insn can be
1257
   relaxed to the new encoding.  */
1258
typedef struct {
1259
  int bytes;
1260
  unsigned int max_disp;
1261
  unsigned char new_encoding;
1262
} EncodingTable;
1263
 
1264
static EncodingTable m16c_addr_encodings[] = {
1265
  { 0,   0,  0 }, /* R0 */
1266
  { 0,   0,  1 }, /* R1 */
1267
  { 0,   0,  2 }, /* R2 */
1268
  { 0,   0,  3 }, /* R3 */
1269
  { 0,   0,  4 }, /* A0 */
1270
  { 0,   0,  5 }, /* A1 */
1271
  { 0,   0,  6 }, /* [A0] */
1272
  { 0,   0,  7 }, /* [A1] */
1273
  { 1,   0,  6 }, /* udsp:8[A0] */
1274
  { 1,   0,  7 }, /* udsp:8[A1] */
1275
  { 1,   0, 10 }, /* udsp:8[SB] */
1276
  { 1,   0, 11 }, /* sdsp:8[FB] */
1277
  { 2, 255,  8 }, /* udsp:16[A0] */
1278
  { 2, 255,  9 }, /* udsp:16[A1] */
1279
  { 2, 255, 10 }, /* udsp:16[SB] */
1280
  { 2,   0, 15 }, /* abs:16 */
1281
};
1282
 
1283
static EncodingTable m16c_jmpaddr_encodings[] = {
1284
  { 0,   0,  0 }, /* R0 */
1285
  { 0,   0,  1 }, /* R1 */
1286
  { 0,   0,  2 }, /* R2 */
1287
  { 0,   0,  3 }, /* R3 */
1288
  { 0,   0,  4 }, /* A0 */
1289
  { 0,   0,  5 }, /* A1 */
1290
  { 0,   0,  6 }, /* [A0] */
1291
  { 0,   0,  7 }, /* [A1] */
1292
  { 1,   0,  6 }, /* udsp:8[A0] */
1293
  { 1,   0,  7 }, /* udsp:8[A1] */
1294
  { 1,   0, 10 }, /* udsp:8[SB] */
1295
  { 1,   0, 11 }, /* sdsp:8[FB] */
1296
  { 3, 255,  8 }, /* udsp:20[A0] */
1297
  { 3, 255,  9 }, /* udsp:20[A1] */
1298
  { 2, 255, 10 }, /* udsp:16[SB] */
1299
  { 2,   0, 15 }, /* abs:16 */
1300
};
1301
 
1302
static EncodingTable m32c_addr_encodings[] = {
1303
  { 0,     0,  0 }, /* [A0] */
1304
  { 0,     0,  1 }, /* [A1] */
1305
  { 0,     0,  2 }, /* A0 */
1306
  { 0,     0,  3 }, /* A1 */
1307
  { 1,     0,  0 }, /* udsp:8[A0] */
1308
  { 1,     0,  1 }, /* udsp:8[A1] */
1309
  { 1,     0,  6 }, /* udsp:8[SB] */
1310
  { 1,     0,  7 }, /* sdsp:8[FB] */
1311
  { 2,   255,  4 }, /* udsp:16[A0] */
1312
  { 2,   255,  5 }, /* udsp:16[A1] */
1313
  { 2,   255,  6 }, /* udsp:16[SB] */
1314
  { 2,   127,  7 }, /* sdsp:16[FB] */
1315
  { 3, 65535, 8 }, /* udsp:24[A0] */
1316
  { 3, 65535, 9 }, /* udsp:24[A1] */
1317
  { 3, 65535, 15 }, /* abs24 */
1318
  { 2,     0, 15 }, /* abs16 */
1319
  { 0,     0, 16 }, /* R2 */
1320
  { 0,     0, 17 }, /* R3 */
1321
  { 0,     0, 18 }, /* R0 */
1322
  { 0,     0, 19 }, /* R1 */
1323
  { 0,     0, 20 }, /*  */
1324
  { 0,     0, 21 }, /*  */
1325
  { 0,     0, 22 }, /*  */
1326
  { 0,     0, 23 }, /*  */
1327
  { 0,     0, 24 }, /*  */
1328
  { 0,     0, 25 }, /*  */
1329
  { 0,     0, 26 }, /*  */
1330
  { 0,     0, 27 }, /*  */
1331
  { 0,     0, 28 }, /*  */
1332
  { 0,     0, 29 }, /*  */
1333
  { 0,     0, 30 }, /*  */
1334
  { 0,     0, 31 }, /*  */
1335
};
1336
 
1337
static bfd_boolean
1338
m32c_elf_relax_section
1339
    (bfd *                  abfd,
1340
     asection *             sec,
1341
     struct bfd_link_info * link_info,
1342
     bfd_boolean *          again)
1343
{
1344
  Elf_Internal_Shdr *symtab_hdr;
1345
  Elf_Internal_Shdr *shndx_hdr;
1346
  Elf_Internal_Rela *internal_relocs;
1347
  Elf_Internal_Rela *free_relocs = NULL;
1348
  Elf_Internal_Rela *irel, *irelend, *srel;
1349
  bfd_byte * contents = NULL;
1350
  bfd_byte * free_contents = NULL;
1351
  Elf_Internal_Sym *intsyms = NULL;
1352
  Elf_Internal_Sym *free_intsyms = NULL;
1353
  Elf_External_Sym_Shndx *shndx_buf = NULL;
1354
  int machine;
1355
 
1356
  if (abfd == elf_hash_table (link_info)->dynobj
1357
      && strcmp (sec->name, ".plt") == 0)
1358
    return m32c_elf_relax_plt_section (abfd, sec, link_info, again);
1359
 
1360
  /* Assume nothing changes.  */
1361
  *again = FALSE;
1362
 
1363
  machine = elf32_m32c_machine (abfd);
1364
 
1365
  /* We don't have to do anything for a relocatable link, if
1366
     this section does not have relocs, or if this is not a
1367
     code section.  */
1368
  if (link_info->relocatable
1369
      || (sec->flags & SEC_RELOC) == 0
1370
      || sec->reloc_count == 0
1371
      || (sec->flags & SEC_CODE) == 0)
1372
    return TRUE;
1373
 
1374
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1375
  shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1376
 
1377
  /* Get the section contents.  */
1378
  if (elf_section_data (sec)->this_hdr.contents != NULL)
1379
    contents = elf_section_data (sec)->this_hdr.contents;
1380
  /* Go get them off disk.  */
1381
  else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1382
    goto error_return;
1383
 
1384
  /* Read this BFD's symbols.  */
1385
  /* Get cached copy if it exists.  */
1386
  if (symtab_hdr->contents != NULL)
1387
    {
1388
      intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
1389
    }
1390
  else
1391
    {
1392
      intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
1393
      symtab_hdr->contents = (bfd_byte *) intsyms;
1394
    }
1395
 
1396
  if (shndx_hdr->sh_size != 0)
1397
    {
1398
      bfd_size_type amt;
1399
 
1400
      amt = symtab_hdr->sh_info;
1401
      amt *= sizeof (Elf_External_Sym_Shndx);
1402
      shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
1403
      if (shndx_buf == NULL)
1404
        goto error_return;
1405
      if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
1406
          || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
1407
        goto error_return;
1408
      shndx_hdr->contents = (bfd_byte *) shndx_buf;
1409
    }
1410
 
1411
  /* Get a copy of the native relocations.  */
1412
  internal_relocs = (_bfd_elf_link_read_relocs
1413
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
1414
                      link_info->keep_memory));
1415
  if (internal_relocs == NULL)
1416
    goto error_return;
1417
  if (! link_info->keep_memory)
1418
    free_relocs = internal_relocs;
1419
 
1420
  /* The RL_ relocs must be just before the operand relocs they go
1421
     with, so we must sort them to guarantee this.  */
1422
  qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
1423
         compare_reloc);
1424
 
1425
  /* Walk through them looking for relaxing opportunities.  */
1426
  irelend = internal_relocs + sec->reloc_count;
1427
 
1428
  for (irel = internal_relocs; irel < irelend; irel++)
1429
    {
1430
      bfd_vma symval;
1431
      unsigned char *insn, *gap, *einsn;
1432
      bfd_vma pc;
1433
      bfd_signed_vma pcrel;
1434
      int relax_relocs;
1435
      int gap_size;
1436
      int new_type;
1437
      int posn;
1438
      int enc;
1439
      EncodingTable *enctbl;
1440
      EncodingTable *e;
1441
 
1442
      if (ELF32_R_TYPE(irel->r_info) != R_M32C_RL_JUMP
1443
          && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_1ADDR
1444
          && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_2ADDR)
1445
        continue;
1446
 
1447
      srel = irel;
1448
 
1449
      /* There will always be room for the relaxed insn, since it is smaller
1450
         than the one it would replace.  */
1451
      BFD_ASSERT (irel->r_offset < sec->size);
1452
 
1453
      insn = contents + irel->r_offset;
1454
      relax_relocs = irel->r_addend % 16;
1455
 
1456
      /* Ok, we only have three relocs we care about, and they're all
1457
         fake.  The lower four bits of the addend is always the number
1458
         of following relocs (hence the qsort above) that are assigned
1459
         to this opcode.  The next 8 bits of the addend indicates the
1460
         number of bytes in the insn.  We use the rest of them
1461
         ourselves as flags for the more expensive operations (defines
1462
         above).  The three relocs are:
1463
 
1464
         RL_JUMP: This marks all direct jump insns.  We check the
1465
                displacement and replace them with shorter jumps if
1466
                they're in range.  We also use this to find JMP.S
1467
                insns and manually shorten them when we delete bytes.
1468
                We have to decode these insns to figure out what to
1469
                do.
1470
 
1471
         RL_1ADDR: This is a :G or :Q insn, which has a single
1472
                "standard" operand.  We have to extract the type
1473
                field, see if it's a wide displacement, then figure
1474
                out if we can replace it with a narrow displacement.
1475
                We don't have to decode these insns.
1476
 
1477
         RL_2ADDR: Similarly, but two "standard" operands.  Note that
1478
                r_addend may still be 1, as standard operands don't
1479
                always have displacements.  Gas shouldn't give us one
1480
                with zero operands, but since we don't know which one
1481
                has the displacement, we check them both anyway.
1482
 
1483
         These all point to the beginning of the insn itself, not the
1484
         operands.
1485
 
1486
         Note that we only relax one step at a time, relying on the
1487
         linker to call us repeatedly.  Thus, there is no code for
1488
         JMP.A->JMP.B although that will happen in two steps.
1489
         Likewise, for 2ADDR relaxes, we do one operand per cycle.
1490
      */
1491
 
1492
      /* Get the value of the symbol referred to by the reloc.  Just
1493
         in case this is the last reloc in the list, use the RL's
1494
         addend to choose between this reloc (no addend) or the next
1495
         (yes addend, which means at least one following reloc).  */
1496
      srel = irel + (relax_relocs ? 1 : 0);
1497
      symval = OFFSET_FOR_RELOC (srel);
1498
 
1499
      /* Setting gap_size nonzero is the flag which means "something
1500
         shrunk".  */
1501
      gap_size = 0;
1502
      gap = NULL;
1503
      new_type = ELF32_R_TYPE(srel->r_info);
1504
 
1505
      pc = sec->output_section->vma + sec->output_offset
1506
        + srel->r_offset;
1507
      pcrel = symval - pc + srel->r_addend;
1508
 
1509
      if (machine == bfd_mach_m16c)
1510
        {
1511
          /* R8C / M16C */
1512
 
1513
          switch (ELF32_R_TYPE(irel->r_info))
1514
            {
1515
 
1516
            case R_M32C_RL_JUMP:
1517
              switch (insn[0])
1518
                {
1519
                case 0xfe: /* jmp.b */
1520
                  if (pcrel >= 2 && pcrel <= 9)
1521
                    {
1522
                      /* Relax JMP.B -> JMP.S.  We need to get rid of
1523
                         the following reloc though. */
1524
                      insn[0] = 0x60 | (pcrel - 2);
1525
                      new_type = R_M32C_NONE;
1526
                      irel->r_addend = 0x10;
1527
                      gap_size = 1;
1528
                      gap = insn + 1;
1529
                    }
1530
                  break;
1531
 
1532
                case 0xf4: /* jmp.w */
1533
                  /* 128 is allowed because it will be one byte closer
1534
                     after relaxing.  Likewise for all other pc-rel
1535
                     jumps.  */
1536
                  if (pcrel <= 128 && pcrel >= -128)
1537
                    {
1538
                      /* Relax JMP.W -> JMP.B */
1539
                      insn[0] = 0xfe;
1540
                      insn[1] = 0;
1541
                      new_type = R_M32C_8_PCREL;
1542
                      gap_size = 1;
1543
                      gap = insn + 2;
1544
                    }
1545
                  break;
1546
 
1547
                case 0xfc: /* jmp.a */
1548
                  if (pcrel <= 32768 && pcrel >= -32768)
1549
                    {
1550
                      /* Relax JMP.A -> JMP.W */
1551
                      insn[0] = 0xf4;
1552
                      insn[1] = 0;
1553
                      insn[2] = 0;
1554
                      new_type = R_M32C_16_PCREL;
1555
                      gap_size = 1;
1556
                      gap = insn + 3;
1557
                    }
1558
                  break;
1559
 
1560
                case 0xfd: /* jsr.a */
1561
                  if (pcrel <= 32768 && pcrel >= -32768)
1562
                    {
1563
                      /* Relax JSR.A -> JSR.W */
1564
                      insn[0] = 0xf5;
1565
                      insn[1] = 0;
1566
                      insn[2] = 0;
1567
                      new_type = R_M32C_16_PCREL;
1568
                      gap_size = 1;
1569
                      gap = insn + 3;
1570
                    }
1571
                  break;
1572
                }
1573
              break;
1574
 
1575
            case R_M32C_RL_2ADDR:
1576
              /* xxxx xxxx srce dest [src-disp] [dest-disp]*/
1577
 
1578
              enctbl = m16c_addr_encodings;
1579
              posn = 2;
1580
              enc = (insn[1] >> 4) & 0x0f;
1581
              e = & enctbl[enc];
1582
 
1583
              if (srel->r_offset == irel->r_offset + posn
1584
                  && e->new_encoding != enc
1585
                  && symval <= e->max_disp)
1586
                {
1587
                  insn[1] &= 0x0f;
1588
                  insn[1] |= e->new_encoding << 4;
1589
                  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1590
                  gap = insn + posn + enctbl[e->new_encoding].bytes;
1591
                  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1592
                  break;
1593
                }
1594
              if (relax_relocs == 2)
1595
                srel ++;
1596
              posn += e->bytes;
1597
 
1598
              goto try_1addr_16;
1599
 
1600
            case R_M32C_RL_1ADDR:
1601
              /* xxxx xxxx xxxx dest [disp] */
1602
 
1603
              enctbl = m16c_addr_encodings;
1604
              posn = 2;
1605
 
1606
              /* Check the opcode for jumps.  We know it's safe to
1607
                 do this because all 2ADDR insns are at least two
1608
                 bytes long.  */
1609
              enc = insn[0] * 256 + insn[1];
1610
              enc &= 0xfff0;
1611
              if (enc == 0x7d20
1612
                  || enc == 0x7d00
1613
                  || enc == 0x7d30
1614
                  || enc == 0x7d10)
1615
                {
1616
                  enctbl = m16c_jmpaddr_encodings;
1617
                }
1618
 
1619
            try_1addr_16:
1620
              /* srel, posn, and enc must be set here.  */
1621
 
1622
              symval = OFFSET_FOR_RELOC (srel);
1623
              enc = insn[1] & 0x0f;
1624
              e = & enctbl[enc];
1625
 
1626
              if (srel->r_offset == irel->r_offset + posn
1627
                  && e->new_encoding != enc
1628
                  && symval <= e->max_disp)
1629
                {
1630
                  insn[1] &= 0xf0;
1631
                  insn[1] |= e->new_encoding;
1632
                  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1633
                  gap = insn + posn + enctbl[e->new_encoding].bytes;
1634
                  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1635
                  break;
1636
                }
1637
 
1638
              break;
1639
 
1640
            } /* Ends switch (reloc type) for m16c.  */
1641
        }
1642
      else /* machine == bfd_mach_m32c */
1643
        {
1644
          /* M32CM / M32C */
1645
 
1646
          switch (ELF32_R_TYPE(irel->r_info))
1647
            {
1648
 
1649
            case R_M32C_RL_JUMP:
1650
              switch (insn[0])
1651
                {
1652
                case 0xbb: /* jmp.b */
1653
                  if (pcrel >= 2 && pcrel <= 9)
1654
                    {
1655
                      int p = pcrel - 2;
1656
                      /* Relax JMP.B -> JMP.S.  We need to get rid of
1657
                         the following reloc though. */
1658
                      insn[0] = 0x4a | ((p << 3) & 0x30) | (p & 1);
1659
                      new_type = R_M32C_NONE;
1660
                      irel->r_addend = 0x10;
1661
                      gap_size = 1;
1662
                      gap = insn + 1;
1663
                    }
1664
                  break;
1665
 
1666
                case 0xce: /* jmp.w */
1667
                  if (pcrel <= 128 && pcrel >= -128)
1668
                    {
1669
                      /* Relax JMP.W -> JMP.B */
1670
                      insn[0] = 0xbb;
1671
                      insn[1] = 0;
1672
                      new_type = R_M32C_8_PCREL;
1673
                      gap_size = 1;
1674
                      gap = insn + 2;
1675
                    }
1676
                  break;
1677
 
1678
                case 0xcc: /* jmp.a */
1679
                  if (pcrel <= 32768 && pcrel >= -32768)
1680
                    {
1681
                      /* Relax JMP.A -> JMP.W */
1682
                      insn[0] = 0xce;
1683
                      insn[1] = 0;
1684
                      insn[2] = 0;
1685
                      new_type = R_M32C_16_PCREL;
1686
                      gap_size = 1;
1687
                      gap = insn + 3;
1688
                    }
1689
                  break;
1690
 
1691
                case 0xcd: /* jsr.a */
1692
                  if (pcrel <= 32768 && pcrel >= -32768)
1693
                    {
1694
                      /* Relax JSR.A -> JSR.W */
1695
                      insn[0] = 0xcf;
1696
                      insn[1] = 0;
1697
                      insn[2] = 0;
1698
                      new_type = R_M32C_16_PCREL;
1699
                      gap_size = 1;
1700
                      gap = insn + 3;
1701
                    }
1702
                  break;
1703
                }
1704
              break;
1705
 
1706
            case R_M32C_RL_2ADDR:
1707
              /* xSSS DDDx DDSS xxxx [src-disp] [dest-disp]*/
1708
 
1709
              einsn = insn;
1710
              posn = 2;
1711
              if (einsn[0] == 1)
1712
                {
1713
                  /* prefix; remove it as far as the RL reloc is concerned.  */
1714
                  einsn ++;
1715
                  posn ++;
1716
                }
1717
 
1718
              enctbl = m32c_addr_encodings;
1719
              enc = ((einsn[0] & 0x70) >> 2) | ((einsn[1] & 0x30) >> 4);
1720
              e = & enctbl[enc];
1721
 
1722
              if (srel->r_offset == irel->r_offset + posn
1723
                  && e->new_encoding != enc
1724
                  && symval <= e->max_disp)
1725
                {
1726
                  einsn[0] &= 0x8f;
1727
                  einsn[0] |= (e->new_encoding & 0x1c) << 2;
1728
                  einsn[1] &= 0xcf;
1729
                  einsn[1] |= (e->new_encoding & 0x03) << 4;
1730
                  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1731
                  gap = insn + posn + enctbl[e->new_encoding].bytes;
1732
                  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1733
                  break;
1734
                }
1735
              if (relax_relocs == 2)
1736
                  srel ++;
1737
              posn += e->bytes;
1738
 
1739
              goto try_1addr_32;
1740
 
1741
            case R_M32C_RL_1ADDR:
1742
              /* xxxx DDDx DDxx xxxx [disp] */
1743
 
1744
              einsn = insn;
1745
              posn = 2;
1746
              if (einsn[0] == 1)
1747
                {
1748
                  /* prefix; remove it as far as the RL reloc is concerned.  */
1749
                  einsn ++;
1750
                  posn ++;
1751
                }
1752
 
1753
              enctbl = m32c_addr_encodings;
1754
 
1755
            try_1addr_32:
1756
              /* srel, posn, and enc must be set here.  */
1757
 
1758
              symval = OFFSET_FOR_RELOC (srel);
1759
              enc = ((einsn[0] & 0x0e) << 1) |  ((einsn[1] & 0xc0) >> 6);
1760
              e = & enctbl[enc];
1761
 
1762
              if (srel->r_offset == irel->r_offset + posn
1763
                  && e->new_encoding != enc
1764
                  && symval <= e->max_disp)
1765
                {
1766
                  einsn[0] &= 0xf1;
1767
                  einsn[0] |= (e->new_encoding & 0x1c) >> 1;
1768
                  einsn[1] &= 0x3f;
1769
                  einsn[1] |= (e->new_encoding & 0x03) << 6;
1770
                  gap_size = e->bytes - enctbl[e->new_encoding].bytes;
1771
                  gap = insn + posn + enctbl[e->new_encoding].bytes;
1772
                  new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
1773
                  break;
1774
                }
1775
 
1776
              break;
1777
 
1778
            } /* Ends switch (reloc type) for m32c.  */
1779
        }
1780
 
1781
      if (gap_size == 0)
1782
        continue;
1783
 
1784
      *again = TRUE;
1785
 
1786
      srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), new_type);
1787
 
1788
      /* Note that we've changed the relocs, section contents, etc.  */
1789
      elf_section_data (sec)->relocs = internal_relocs;
1790
      free_relocs = NULL;
1791
 
1792
      elf_section_data (sec)->this_hdr.contents = contents;
1793
      free_contents = NULL;
1794
 
1795
      symtab_hdr->contents = (bfd_byte *) intsyms;
1796
      free_intsyms = NULL;
1797
 
1798
      bytes_saved += gap_size;
1799
 
1800
      if (! m32c_elf_relax_delete_bytes(abfd, sec, gap - contents, gap_size))
1801
        goto error_return;
1802
 
1803
    } /* next relocation */
1804
 
1805
  if (free_relocs != NULL)
1806
    {
1807
      free (free_relocs);
1808
      free_relocs = NULL;
1809
    }
1810
 
1811
  if (free_contents != NULL)
1812
    {
1813
      if (! link_info->keep_memory)
1814
        free (free_contents);
1815
      /* Cache the section contents for elf_link_input_bfd.  */
1816
      else
1817
        elf_section_data (sec)->this_hdr.contents = contents;
1818
 
1819
      free_contents = NULL;
1820
    }
1821
 
1822
  if (shndx_buf != NULL)
1823
    {
1824
      shndx_hdr->contents = NULL;
1825
      free (shndx_buf);
1826
    }
1827
 
1828
  if (free_intsyms != NULL)
1829
    {
1830
      if (! link_info->keep_memory)
1831
        free (free_intsyms);
1832
      /* Cache the symbols for elf_link_input_bfd.  */
1833
      else
1834
        {
1835
        symtab_hdr->contents = NULL /* (unsigned char *) intsyms*/;
1836
        }
1837
 
1838
      free_intsyms = NULL;
1839
    }
1840
 
1841
  return TRUE;
1842
 
1843
 error_return:
1844
  if (free_relocs != NULL)
1845
    free (free_relocs);
1846
  if (free_contents != NULL)
1847
    free (free_contents);
1848
  if (shndx_buf != NULL)
1849
    {
1850
      shndx_hdr->contents = NULL;
1851
      free (shndx_buf);
1852
    }
1853
  if (free_intsyms != NULL)
1854
    free (free_intsyms);
1855
  return FALSE;
1856
}
1857
 
1858
/* Delete some bytes from a section while relaxing.  */
1859
 
1860
static bfd_boolean
1861
m32c_elf_relax_delete_bytes
1862
 (bfd *      abfd,
1863
  asection * sec,
1864
  bfd_vma    addr,
1865
  int        count)
1866
{
1867
  Elf_Internal_Shdr *symtab_hdr;
1868
  Elf_Internal_Shdr *shndx_hdr;
1869
  int sec_shndx;
1870
  bfd_byte *contents;
1871
  Elf_Internal_Rela *irel;
1872
  Elf_Internal_Rela *irelend;
1873
  Elf_Internal_Rela *irelalign;
1874
  bfd_vma toaddr;
1875
  Elf_Internal_Sym *isym;
1876
  Elf_Internal_Sym *isymend;
1877
  Elf_Internal_Sym *intsyms;
1878
  Elf_External_Sym_Shndx *shndx_buf;
1879
  Elf_External_Sym_Shndx *shndx;
1880
  struct elf_link_hash_entry ** sym_hashes;
1881
  struct elf_link_hash_entry ** end_hashes;
1882
  unsigned int                  symcount;
1883
 
1884
  contents   = elf_section_data (sec)->this_hdr.contents;
1885
 
1886
  /* The deletion must stop at the next ALIGN reloc for an aligment
1887
     power larger than the number of bytes we are deleting.  */
1888
  irelalign = NULL;
1889
  toaddr = sec->size;
1890
 
1891
  irel = elf_section_data (sec)->relocs;
1892
  irelend = irel + sec->reloc_count;
1893
 
1894
  /* Actually delete the bytes.  */
1895
  memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
1896
  sec->size -= count;
1897
 
1898
  /* Adjust all the relocs.  */
1899
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
1900
    {
1901
      /* Get the new reloc address.  */
1902
      if (irel->r_offset > addr && irel->r_offset < toaddr)
1903
        irel->r_offset -= count;
1904
 
1905
      if (ELF32_R_TYPE(irel->r_info) == R_M32C_RL_JUMP
1906
          && irel->r_addend == 0x10 /* one byte insn, no relocs */
1907
          && irel->r_offset + 1 < addr
1908
          && irel->r_offset + 7 > addr)
1909
        {
1910
          bfd_vma disp;
1911
          unsigned char *insn = &contents[irel->r_offset];
1912
          disp = *insn;
1913
          /* This is a JMP.S, which we have to manually update. */
1914
          if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
1915
            {
1916
              if ((*insn & 0xf8) != 0x60)
1917
                continue;
1918
              disp = (disp & 7);
1919
            }
1920
          else
1921
            {
1922
              if ((*insn & 0xce) != 0x4a)
1923
                continue;
1924
              disp = ((disp & 0x30) >> 3) | (disp & 1);
1925
            }
1926
          if (irel->r_offset + disp + 2 >= addr+count)
1927
            {
1928
              disp -= count;
1929
              if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
1930
                {
1931
                  *insn = (*insn & 0xf8) | disp;
1932
                }
1933
              else
1934
                {
1935
                  *insn = (*insn & 0xce) | ((disp & 6) << 3) | (disp & 1);
1936
                }
1937
            }
1938
        }
1939
    }
1940
 
1941
  /* Adjust the local symbols defined in this section.  */
1942
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1943
  intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
1944
  isym = intsyms;
1945
  isymend = isym + symtab_hdr->sh_info;
1946
 
1947
  sec_shndx  = _bfd_elf_section_from_bfd_section (abfd, sec);
1948
  shndx_hdr  = & elf_tdata (abfd)->symtab_shndx_hdr;
1949
  shndx_buf  = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
1950
  shndx = shndx_buf;
1951
 
1952
  for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
1953
    {
1954
      /* If the symbol is in the range of memory we just moved, we
1955
         have to adjust its value.  */
1956
      if ((int) isym->st_shndx == sec_shndx
1957
          && isym->st_value > addr
1958
          && isym->st_value < toaddr)
1959
        {
1960
          isym->st_value -= count;
1961
        }
1962
      /* If the symbol *spans* the bytes we just deleted (i.e. it's
1963
         *end* is in the moved bytes but it's *start* isn't), then we
1964
         must adjust its size.  */
1965
      if ((int) isym->st_shndx == sec_shndx
1966
            && isym->st_value < addr
1967
          && isym->st_value + isym->st_size > addr
1968
          && isym->st_value + isym->st_size < toaddr)
1969
        {
1970
          isym->st_size -= count;
1971
        }
1972
    }
1973
 
1974
  /* Now adjust the global symbols defined in this section.  */
1975
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1976
              - symtab_hdr->sh_info);
1977
  sym_hashes = elf_sym_hashes (abfd);
1978
  //  sym_hashes += symtab_hdr->sh_info;
1979
  end_hashes = sym_hashes + symcount;
1980
 
1981
  for (; sym_hashes < end_hashes; sym_hashes ++)
1982
    {
1983
      struct elf_link_hash_entry * sym_hash = * sym_hashes;
1984
 
1985
      if (sym_hash &&
1986
          (sym_hash->root.type == bfd_link_hash_defined
1987
           || sym_hash->root.type == bfd_link_hash_defweak)
1988
          && sym_hash->root.u.def.section == sec)
1989
        {
1990
          if (sym_hash->root.u.def.value > addr
1991
              && sym_hash->root.u.def.value < toaddr)
1992
            {
1993
              sym_hash->root.u.def.value -= count;
1994
            }
1995
          if (sym_hash->root.u.def.value < addr
1996
              && sym_hash->root.u.def.value + sym_hash->size > addr
1997
              && sym_hash->root.u.def.value + sym_hash->size < toaddr)
1998
            {
1999
              sym_hash->size -= count;
2000
            }
2001
        }
2002
    }
2003
 
2004
  return TRUE;
2005
}
2006
 
2007
/* This is for versions of gcc prior to 4.3.  */
2008
static unsigned int
2009
_bfd_m32c_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
2010
{
2011
  if ((elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK) == EF_M32C_CPU_M16C)
2012
    return 2;
2013
  return 4;
2014
}
2015
 
2016
 
2017
 
2018
#define ELF_ARCH                bfd_arch_m32c
2019
#define ELF_MACHINE_CODE        EM_M32C
2020
#define ELF_MACHINE_ALT1        EM_M32C_OLD
2021
#define ELF_MAXPAGESIZE         0x1000
2022
 
2023
#if 0
2024
#define TARGET_BIG_SYM          bfd_elf32_m32c_vec
2025
#define TARGET_BIG_NAME         "elf32-m32c"
2026
#else
2027
#define TARGET_LITTLE_SYM               bfd_elf32_m32c_vec
2028
#define TARGET_LITTLE_NAME              "elf32-m32c"
2029
#endif
2030
 
2031
#define elf_info_to_howto_rel                   NULL
2032
#define elf_info_to_howto                       m32c_info_to_howto_rela
2033
#define elf_backend_object_p                    m32c_elf_object_p
2034
#define elf_backend_relocate_section            m32c_elf_relocate_section
2035
#define elf_backend_check_relocs                m32c_elf_check_relocs
2036
#define elf_backend_object_p                    m32c_elf_object_p
2037
#define elf_symbol_leading_char                 ('_')
2038
#define elf_backend_always_size_sections \
2039
  m32c_elf_always_size_sections
2040
#define elf_backend_finish_dynamic_sections \
2041
  m32c_elf_finish_dynamic_sections
2042
 
2043
#define elf_backend_can_gc_sections             1
2044
#define elf_backend_eh_frame_address_size _bfd_m32c_elf_eh_frame_address_size
2045
 
2046
#define bfd_elf32_bfd_reloc_type_lookup         m32c_reloc_type_lookup
2047
#define bfd_elf32_bfd_reloc_name_lookup m32c_reloc_name_lookup
2048
#define bfd_elf32_bfd_relax_section             m32c_elf_relax_section
2049
#define bfd_elf32_bfd_set_private_flags         m32c_elf_set_private_flags
2050
#define bfd_elf32_bfd_merge_private_bfd_data    m32c_elf_merge_private_bfd_data
2051
#define bfd_elf32_bfd_print_private_bfd_data    m32c_elf_print_private_bfd_data
2052
 
2053
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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