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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [bfd/] [elf32-h8300.c] - Blame information for rev 298

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

Line No. Rev Author Line
1 205 julius
/* BFD back-end for Renesas H8/300 ELF binaries.
2
   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
3
   2007, 2009 Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/h8.h"
27
 
28
static reloc_howto_type *elf32_h8_reloc_type_lookup
29
  (bfd *abfd, bfd_reloc_code_real_type code);
30
static void elf32_h8_info_to_howto
31
  (bfd *, arelent *, Elf_Internal_Rela *);
32
static void elf32_h8_info_to_howto_rel
33
  (bfd *, arelent *, Elf_Internal_Rela *);
34
static unsigned long elf32_h8_mach (flagword);
35
static void elf32_h8_final_write_processing (bfd *, bfd_boolean);
36
static bfd_boolean elf32_h8_object_p (bfd *);
37
static bfd_boolean elf32_h8_merge_private_bfd_data (bfd *, bfd *);
38
static bfd_boolean elf32_h8_relax_section
39
  (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
40
static bfd_boolean elf32_h8_relax_delete_bytes
41
  (bfd *, asection *, bfd_vma, int);
42
static bfd_boolean elf32_h8_symbol_address_p (bfd *, asection *, bfd_vma);
43
static bfd_byte *elf32_h8_get_relocated_section_contents
44
  (bfd *, struct bfd_link_info *, struct bfd_link_order *,
45
   bfd_byte *, bfd_boolean, asymbol **);
46
static bfd_reloc_status_type elf32_h8_final_link_relocate
47
  (unsigned long, bfd *, bfd *, asection *,
48
   bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
49
   struct bfd_link_info *, asection *, int);
50
static bfd_boolean elf32_h8_relocate_section
51
  (bfd *, struct bfd_link_info *, bfd *, asection *,
52
   bfd_byte *, Elf_Internal_Rela *,
53
   Elf_Internal_Sym *, asection **);
54
static bfd_reloc_status_type special
55
  (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
56
 
57
/* This does not include any relocation information, but should be
58
   good enough for GDB or objdump to read the file.  */
59
 
60
static reloc_howto_type h8_elf_howto_table[] = {
61
#define R_H8_NONE_X 0
62
  HOWTO (R_H8_NONE,             /* type */
63
         0,                      /* rightshift */
64
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
65
         0,                      /* bitsize */
66
         FALSE,                 /* pc_relative */
67
         0,                      /* bitpos */
68
         complain_overflow_dont,/* complain_on_overflow */
69
         special,               /* special_function */
70
         "R_H8_NONE",           /* name */
71
         FALSE,                 /* partial_inplace */
72
         0,                      /* src_mask */
73
         0,                      /* dst_mask */
74
         FALSE),                /* pcrel_offset */
75
#define R_H8_DIR32_X (R_H8_NONE_X + 1)
76
  HOWTO (R_H8_DIR32,            /* type */
77
         0,                      /* rightshift */
78
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
79
         32,                    /* bitsize */
80
         FALSE,                 /* pc_relative */
81
         0,                      /* bitpos */
82
         complain_overflow_dont,/* complain_on_overflow */
83
         special,               /* special_function */
84
         "R_H8_DIR32",          /* name */
85
         FALSE,                 /* partial_inplace */
86
         0,                      /* src_mask */
87
         0xffffffff,            /* dst_mask */
88
         FALSE),                /* pcrel_offset */
89
#define R_H8_DIR16_X (R_H8_DIR32_X + 1)
90
  HOWTO (R_H8_DIR16,            /* type */
91
         0,                      /* rightshift */
92
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
93
         16,                    /* bitsize */
94
         FALSE,                 /* pc_relative */
95
         0,                      /* bitpos */
96
         complain_overflow_dont,/* complain_on_overflow */
97
         special,               /* special_function */
98
         "R_H8_DIR16",          /* name */
99
         FALSE,                 /* partial_inplace */
100
         0,                      /* src_mask */
101
         0x0000ffff,            /* dst_mask */
102
         FALSE),                /* pcrel_offset */
103
#define R_H8_DIR8_X (R_H8_DIR16_X + 1)
104
  HOWTO (R_H8_DIR8,             /* type */
105
         0,                      /* rightshift */
106
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
107
         8,                     /* bitsize */
108
         FALSE,                 /* pc_relative */
109
         0,                      /* bitpos */
110
         complain_overflow_dont,/* complain_on_overflow */
111
         special,               /* special_function */
112
         "R_H8_DIR8",           /* name */
113
         FALSE,                 /* partial_inplace */
114
         0,                      /* src_mask */
115
         0x000000ff,            /* dst_mask */
116
         FALSE),                /* pcrel_offset */
117
#define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
118
  HOWTO (R_H8_DIR16A8,          /* type */
119
         0,                      /* rightshift */
120
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
121
         16,                    /* bitsize */
122
         FALSE,                 /* pc_relative */
123
         0,                      /* bitpos */
124
         complain_overflow_bitfield, /* complain_on_overflow */
125
         special,               /* special_function */
126
         "R_H8_DIR16A8",        /* name */
127
         FALSE,                 /* partial_inplace */
128
         0,                      /* src_mask */
129
         0x0000ffff,            /* dst_mask */
130
         FALSE),                /* pcrel_offset */
131
#define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
132
  HOWTO (R_H8_DIR16R8,          /* type */
133
         0,                      /* rightshift */
134
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
135
         16,                    /* bitsize */
136
         FALSE,                 /* pc_relative */
137
         0,                      /* bitpos */
138
         complain_overflow_bitfield, /* complain_on_overflow */
139
         special,               /* special_function */
140
         "R_H8_DIR16R8",        /* name */
141
         FALSE,                 /* partial_inplace */
142
         0,                      /* src_mask */
143
         0x0000ffff,            /* dst_mask */
144
         FALSE),                /* pcrel_offset */
145
#define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
146
  HOWTO (R_H8_DIR24A8,          /* type */
147
         0,                      /* rightshift */
148
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
149
         24,                    /* bitsize */
150
         FALSE,                 /* pc_relative */
151
         0,                      /* bitpos */
152
         complain_overflow_bitfield, /* complain_on_overflow */
153
         special,               /* special_function */
154
         "R_H8_DIR24A8",        /* name */
155
         TRUE,                  /* partial_inplace */
156
         0xff000000,            /* src_mask */
157
         0x00ffffff,            /* dst_mask */
158
         FALSE),                /* pcrel_offset */
159
#define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
160
  HOWTO (R_H8_DIR24R8,          /* type */
161
         0,                      /* rightshift */
162
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
163
         24,                    /* bitsize */
164
         FALSE,                 /* pc_relative */
165
         0,                      /* bitpos */
166
         complain_overflow_bitfield, /* complain_on_overflow */
167
         special,               /* special_function */
168
         "R_H8_DIR24R8",        /* name */
169
         TRUE,                  /* partial_inplace */
170
         0xff000000,            /* src_mask */
171
         0x00ffffff,            /* dst_mask */
172
         FALSE),                /* pcrel_offset */
173
#define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
174
  HOWTO (R_H8_DIR32A16,         /* type */
175
         0,                      /* rightshift */
176
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
177
         32,                    /* bitsize */
178
         FALSE,                 /* pc_relative */
179
         0,                      /* bitpos */
180
         complain_overflow_dont,/* complain_on_overflow */
181
         special,               /* special_function */
182
         "R_H8_DIR32A16",       /* name */
183
         FALSE,                 /* partial_inplace */
184
         0,                      /* src_mask */
185
         0xffffffff,            /* dst_mask */
186
         FALSE),                /* pcrel_offset */
187
#define R_H8_PCREL16_X (R_H8_DIR32A16_X + 1)
188
  HOWTO (R_H8_PCREL16,          /* type */
189
         0,                      /* rightshift */
190
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
191
         16,                    /* bitsize */
192
         TRUE,                  /* pc_relative */
193
         0,                      /* bitpos */
194
         complain_overflow_signed,/* complain_on_overflow */
195
         special,               /* special_function */
196
         "R_H8_PCREL16",        /* name */
197
         FALSE,                 /* partial_inplace */
198
         0xffff,                /* src_mask */
199
         0xffff,                /* dst_mask */
200
         TRUE),                 /* pcrel_offset */
201
#define R_H8_PCREL8_X (R_H8_PCREL16_X + 1)
202
  HOWTO (R_H8_PCREL8,           /* type */
203
         0,                      /* rightshift */
204
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
205
         8,                     /* bitsize */
206
         TRUE,                  /* pc_relative */
207
         0,                      /* bitpos */
208
         complain_overflow_signed,/* complain_on_overflow */
209
         special,               /* special_function */
210
         "R_H8_PCREL8",         /* name */
211
         FALSE,                 /* partial_inplace */
212
         0xff,                  /* src_mask */
213
         0xff,                  /* dst_mask */
214
         TRUE),                 /* pcrel_offset */
215
};
216
 
217
/* This structure is used to map BFD reloc codes to H8 ELF relocs.  */
218
 
219
struct elf_reloc_map {
220
  bfd_reloc_code_real_type bfd_reloc_val;
221
  unsigned char howto_index;
222
};
223
 
224
/* An array mapping BFD reloc codes to H8 ELF relocs.  */
225
 
226
static const struct elf_reloc_map h8_reloc_map[] = {
227
  { BFD_RELOC_NONE, R_H8_NONE_X },
228
  { BFD_RELOC_32, R_H8_DIR32_X },
229
  { BFD_RELOC_16, R_H8_DIR16_X },
230
  { BFD_RELOC_8, R_H8_DIR8_X },
231
  { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
232
  { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
233
  { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
234
  { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
235
  { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
236
  { BFD_RELOC_16_PCREL, R_H8_PCREL16_X },
237
  { BFD_RELOC_8_PCREL, R_H8_PCREL8_X },
238
};
239
 
240
 
241
static reloc_howto_type *
242
elf32_h8_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
243
                            bfd_reloc_code_real_type code)
244
{
245
  unsigned int i;
246
 
247
  for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
248
    {
249
      if (h8_reloc_map[i].bfd_reloc_val == code)
250
        return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
251
    }
252
  return NULL;
253
}
254
 
255
static reloc_howto_type *
256
elf32_h8_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
257
                            const char *r_name)
258
{
259
  unsigned int i;
260
 
261
  for (i = 0;
262
       i < sizeof (h8_elf_howto_table) / sizeof (h8_elf_howto_table[0]);
263
       i++)
264
    if (h8_elf_howto_table[i].name != NULL
265
        && strcasecmp (h8_elf_howto_table[i].name, r_name) == 0)
266
      return &h8_elf_howto_table[i];
267
 
268
  return NULL;
269
}
270
 
271
static void
272
elf32_h8_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
273
                        Elf_Internal_Rela *elf_reloc)
274
{
275
  unsigned int r;
276
  unsigned int i;
277
 
278
  r = ELF32_R_TYPE (elf_reloc->r_info);
279
  for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
280
    if (h8_elf_howto_table[i].type == r)
281
      {
282
        bfd_reloc->howto = &h8_elf_howto_table[i];
283
        return;
284
      }
285
  abort ();
286
}
287
 
288
static void
289
elf32_h8_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
290
                            Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
291
{
292
  unsigned int r;
293
 
294
  abort ();
295
  r = ELF32_R_TYPE (elf_reloc->r_info);
296
  bfd_reloc->howto = &h8_elf_howto_table[r];
297
}
298
 
299
/* Special handling for H8/300 relocs.
300
   We only come here for pcrel stuff and return normally if not an -r link.
301
   When doing -r, we can't do any arithmetic for the pcrel stuff, because
302
   we support relaxing on the H8/300 series chips.  */
303
static bfd_reloc_status_type
304
special (bfd *abfd ATTRIBUTE_UNUSED,
305
         arelent *reloc_entry ATTRIBUTE_UNUSED,
306
         asymbol *symbol ATTRIBUTE_UNUSED,
307
         PTR data ATTRIBUTE_UNUSED,
308
         asection *input_section ATTRIBUTE_UNUSED,
309
         bfd *output_bfd,
310
         char **error_message ATTRIBUTE_UNUSED)
311
{
312
  if (output_bfd == (bfd *) NULL)
313
    return bfd_reloc_continue;
314
 
315
  /* Adjust the reloc address to that in the output section.  */
316
  reloc_entry->address += input_section->output_offset;
317
  return bfd_reloc_ok;
318
}
319
 
320
/* Perform a relocation as part of a final link.  */
321
static bfd_reloc_status_type
322
elf32_h8_final_link_relocate (unsigned long r_type, bfd *input_bfd,
323
                              bfd *output_bfd ATTRIBUTE_UNUSED,
324
                              asection *input_section ATTRIBUTE_UNUSED,
325
                              bfd_byte *contents, bfd_vma offset,
326
                              bfd_vma value, bfd_vma addend,
327
                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
328
                              asection *sym_sec ATTRIBUTE_UNUSED,
329
                              int is_local ATTRIBUTE_UNUSED)
330
{
331
  bfd_byte *hit_data = contents + offset;
332
 
333
  switch (r_type)
334
    {
335
    case R_H8_NONE:
336
      return bfd_reloc_ok;
337
 
338
    case R_H8_DIR32:
339
    case R_H8_DIR32A16:
340
    case R_H8_DIR24A8:
341
      value += addend;
342
      bfd_put_32 (input_bfd, value, hit_data);
343
      return bfd_reloc_ok;
344
 
345
    case R_H8_DIR16:
346
    case R_H8_DIR16A8:
347
    case R_H8_DIR16R8:
348
      value += addend;
349
      bfd_put_16 (input_bfd, value, hit_data);
350
      return bfd_reloc_ok;
351
 
352
    /* AKA R_RELBYTE */
353
    case R_H8_DIR8:
354
      value += addend;
355
 
356
      bfd_put_8 (input_bfd, value, hit_data);
357
      return bfd_reloc_ok;
358
 
359
    case R_H8_DIR24R8:
360
      value += addend;
361
 
362
      /* HIT_DATA is the address for the first byte for the relocated
363
         value.  Subtract 1 so that we can manipulate the data in 32-bit
364
         hunks.  */
365
      hit_data--;
366
 
367
      /* Clear out the top byte in value.  */
368
      value &= 0xffffff;
369
 
370
      /* Retrieve the type byte for value from the section contents.  */
371
      value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
372
 
373
      /* Now scribble it out in one 32-bit hunk.  */
374
      bfd_put_32 (input_bfd, value, hit_data);
375
      return bfd_reloc_ok;
376
 
377
    case R_H8_PCREL16:
378
      value -= (input_section->output_section->vma
379
                + input_section->output_offset);
380
      value -= offset;
381
      value += addend;
382
 
383
      /* The value is relative to the start of the instruction,
384
         not the relocation offset.  Subtract 2 to account for
385
         this minor issue.  */
386
      value -= 2;
387
 
388
      bfd_put_16 (input_bfd, value, hit_data);
389
      return bfd_reloc_ok;
390
 
391
    case R_H8_PCREL8:
392
      value -= (input_section->output_section->vma
393
                + input_section->output_offset);
394
      value -= offset;
395
      value += addend;
396
 
397
      /* The value is relative to the start of the instruction,
398
         not the relocation offset.  Subtract 1 to account for
399
         this minor issue.  */
400
      value -= 1;
401
 
402
      bfd_put_8 (input_bfd, value, hit_data);
403
      return bfd_reloc_ok;
404
 
405
    default:
406
      return bfd_reloc_notsupported;
407
    }
408
}
409
 
410
/* Relocate an H8 ELF section.  */
411
static bfd_boolean
412
elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
413
                           bfd *input_bfd, asection *input_section,
414
                           bfd_byte *contents, Elf_Internal_Rela *relocs,
415
                           Elf_Internal_Sym *local_syms,
416
                           asection **local_sections)
417
{
418
  Elf_Internal_Shdr *symtab_hdr;
419
  struct elf_link_hash_entry **sym_hashes;
420
  Elf_Internal_Rela *rel, *relend;
421
 
422
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
423
  sym_hashes = elf_sym_hashes (input_bfd);
424
 
425
  rel = relocs;
426
  relend = relocs + input_section->reloc_count;
427
  for (; rel < relend; rel++)
428
    {
429
      unsigned int r_type;
430
      unsigned long r_symndx;
431
      Elf_Internal_Sym *sym;
432
      asection *sec;
433
      struct elf_link_hash_entry *h;
434
      bfd_vma relocation;
435
      bfd_reloc_status_type r;
436
      arelent bfd_reloc;
437
      reloc_howto_type *howto;
438
 
439
      elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
440
      howto = bfd_reloc.howto;
441
 
442
      r_symndx = ELF32_R_SYM (rel->r_info);
443
      r_type = ELF32_R_TYPE (rel->r_info);
444
      h = NULL;
445
      sym = NULL;
446
      sec = NULL;
447
      if (r_symndx < symtab_hdr->sh_info)
448
        {
449
          sym = local_syms + r_symndx;
450
          sec = local_sections[r_symndx];
451
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
452
        }
453
      else
454
        {
455
          bfd_boolean unresolved_reloc, warned;
456
 
457
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
458
                                   r_symndx, symtab_hdr, sym_hashes,
459
                                   h, sec, relocation,
460
                                   unresolved_reloc, warned);
461
        }
462
 
463
      if (sec != NULL && elf_discarded_section (sec))
464
        {
465
          /* For relocs against symbols from removed linkonce sections,
466
             or sections discarded by a linker script, we just want the
467
             section contents zeroed.  Avoid any special processing.  */
468
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
469
          rel->r_info = 0;
470
          rel->r_addend = 0;
471
          continue;
472
        }
473
 
474
      if (info->relocatable)
475
        continue;
476
 
477
      r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
478
                                        input_section,
479
                                        contents, rel->r_offset,
480
                                        relocation, rel->r_addend,
481
                                        info, sec, h == NULL);
482
 
483
      if (r != bfd_reloc_ok)
484
        {
485
          const char *name;
486
          const char *msg = (const char *) 0;
487
 
488
          if (h != NULL)
489
            name = h->root.root.string;
490
          else
491
            {
492
              name = (bfd_elf_string_from_elf_section
493
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
494
              if (name == NULL || *name == '\0')
495
                name = bfd_section_name (input_bfd, sec);
496
            }
497
 
498
          switch (r)
499
            {
500
            case bfd_reloc_overflow:
501
              if (! ((*info->callbacks->reloc_overflow)
502
                     (info, (h ? &h->root : NULL), name, howto->name,
503
                      (bfd_vma) 0, input_bfd, input_section,
504
                      rel->r_offset)))
505
                return FALSE;
506
              break;
507
 
508
            case bfd_reloc_undefined:
509
              if (! ((*info->callbacks->undefined_symbol)
510
                     (info, name, input_bfd, input_section,
511
                      rel->r_offset, TRUE)))
512
                return FALSE;
513
              break;
514
 
515
            case bfd_reloc_outofrange:
516
              msg = _("internal error: out of range error");
517
              goto common_error;
518
 
519
            case bfd_reloc_notsupported:
520
              msg = _("internal error: unsupported relocation error");
521
              goto common_error;
522
 
523
            case bfd_reloc_dangerous:
524
              msg = _("internal error: dangerous error");
525
              goto common_error;
526
 
527
            default:
528
              msg = _("internal error: unknown error");
529
              /* fall through */
530
 
531
            common_error:
532
              if (!((*info->callbacks->warning)
533
                    (info, msg, name, input_bfd, input_section,
534
                     rel->r_offset)))
535
                return FALSE;
536
              break;
537
            }
538
        }
539
    }
540
 
541
  return TRUE;
542
}
543
 
544
/* Object files encode the specific H8 model they were compiled
545
   for in the ELF flags field.
546
 
547
   Examine that field and return the proper BFD machine type for
548
   the object file.  */
549
static unsigned long
550
elf32_h8_mach (flagword flags)
551
{
552
  switch (flags & EF_H8_MACH)
553
    {
554
    case E_H8_MACH_H8300:
555
    default:
556
      return bfd_mach_h8300;
557
 
558
    case E_H8_MACH_H8300H:
559
      return bfd_mach_h8300h;
560
 
561
    case E_H8_MACH_H8300S:
562
      return bfd_mach_h8300s;
563
 
564
    case E_H8_MACH_H8300HN:
565
      return bfd_mach_h8300hn;
566
 
567
    case E_H8_MACH_H8300SN:
568
      return bfd_mach_h8300sn;
569
 
570
    case E_H8_MACH_H8300SX:
571
      return bfd_mach_h8300sx;
572
 
573
    case E_H8_MACH_H8300SXN:
574
      return bfd_mach_h8300sxn;
575
    }
576
}
577
 
578
/* The final processing done just before writing out a H8 ELF object
579
   file.  We use this opportunity to encode the BFD machine type
580
   into the flags field in the object file.  */
581
 
582
static void
583
elf32_h8_final_write_processing (bfd *abfd,
584
                                 bfd_boolean linker ATTRIBUTE_UNUSED)
585
{
586
  unsigned long val;
587
 
588
  switch (bfd_get_mach (abfd))
589
    {
590
    default:
591
    case bfd_mach_h8300:
592
      val = E_H8_MACH_H8300;
593
      break;
594
 
595
    case bfd_mach_h8300h:
596
      val = E_H8_MACH_H8300H;
597
      break;
598
 
599
    case bfd_mach_h8300s:
600
      val = E_H8_MACH_H8300S;
601
      break;
602
 
603
    case bfd_mach_h8300hn:
604
      val = E_H8_MACH_H8300HN;
605
      break;
606
 
607
    case bfd_mach_h8300sn:
608
      val = E_H8_MACH_H8300SN;
609
      break;
610
 
611
    case bfd_mach_h8300sx:
612
      val = E_H8_MACH_H8300SX;
613
      break;
614
 
615
    case bfd_mach_h8300sxn:
616
      val = E_H8_MACH_H8300SXN;
617
      break;
618
    }
619
 
620
  elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
621
  elf_elfheader (abfd)->e_flags |= val;
622
}
623
 
624
/* Return nonzero if ABFD represents a valid H8 ELF object file; also
625
   record the encoded machine type found in the ELF flags.  */
626
 
627
static bfd_boolean
628
elf32_h8_object_p (bfd *abfd)
629
{
630
  bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
631
                             elf32_h8_mach (elf_elfheader (abfd)->e_flags));
632
  return TRUE;
633
}
634
 
635
/* Merge backend specific data from an object file to the output
636
   object file when linking.  The only data we need to copy at this
637
   time is the architecture/machine information.  */
638
 
639
static bfd_boolean
640
elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
641
{
642
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
643
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
644
    return TRUE;
645
 
646
  if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
647
      && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
648
    {
649
      if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
650
                               bfd_get_mach (ibfd)))
651
        return FALSE;
652
    }
653
 
654
  return TRUE;
655
}
656
 
657
/* This function handles relaxing for the H8..
658
 
659
   There are a few relaxing opportunities available on the H8:
660
 
661
     jmp/jsr:24    ->    bra/bsr:8              2 bytes
662
     The jmp may be completely eliminated if the previous insn is a
663
     conditional branch to the insn after the jump.  In that case
664
     we invert the branch and delete the jump and save 4 bytes.
665
 
666
     bCC:16          ->    bCC:8                  2 bytes
667
     bsr:16          ->    bsr:8                  2 bytes
668
 
669
     bset:16         ->    bset:8                 2 bytes
670
     bset:24/32      ->    bset:8                 4 bytes
671
     (also applicable to other bit manipulation instructions)
672
 
673
     mov.b:16        ->    mov.b:8                2 bytes
674
     mov.b:24/32     ->    mov.b:8                4 bytes
675
 
676
     bset:24/32      ->    bset:16                2 bytes
677
     (also applicable to other bit manipulation instructions)
678
 
679
     mov.[bwl]:24/32 ->    mov.[bwl]:16           2 bytes */
680
 
681
static bfd_boolean
682
elf32_h8_relax_section (bfd *abfd, asection *sec,
683
                        struct bfd_link_info *link_info, bfd_boolean *again)
684
{
685
  Elf_Internal_Shdr *symtab_hdr;
686
  Elf_Internal_Rela *internal_relocs;
687
  Elf_Internal_Rela *irel, *irelend;
688
  bfd_byte *contents = NULL;
689
  Elf_Internal_Sym *isymbuf = NULL;
690
  static asection *last_input_section = NULL;
691
  static Elf_Internal_Rela *last_reloc = NULL;
692
 
693
  /* Assume nothing changes.  */
694
  *again = FALSE;
695
 
696
  /* We don't have to do anything for a relocatable link, if
697
     this section does not have relocs, or if this is not a
698
     code section.  */
699
  if (link_info->relocatable
700
      || (sec->flags & SEC_RELOC) == 0
701
      || sec->reloc_count == 0
702
      || (sec->flags & SEC_CODE) == 0)
703
    return TRUE;
704
 
705
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
706
 
707
  /* Get a copy of the native relocations.  */
708
  internal_relocs = (_bfd_elf_link_read_relocs
709
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
710
                      link_info->keep_memory));
711
  if (internal_relocs == NULL)
712
    goto error_return;
713
 
714
  if (sec != last_input_section)
715
    last_reloc = NULL;
716
 
717
  last_input_section = sec;
718
 
719
  /* Walk through the relocs looking for relaxing opportunities.  */
720
  irelend = internal_relocs + sec->reloc_count;
721
  for (irel = internal_relocs; irel < irelend; irel++)
722
    {
723
      bfd_vma symval;
724
 
725
      {
726
        arelent bfd_reloc;
727
        reloc_howto_type *h;
728
 
729
        elf32_h8_info_to_howto (abfd, &bfd_reloc, irel);
730
        h = bfd_reloc.howto;
731
      }
732
      /* Keep track of the previous reloc so that we can delete
733
         some long jumps created by the compiler.  */
734
      if (irel != internal_relocs)
735
        last_reloc = irel - 1;
736
 
737
      if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
738
          && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
739
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
740
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
741
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
742
        continue;
743
 
744
      /* Get the section contents if we haven't done so already.  */
745
      if (contents == NULL)
746
        {
747
          /* Get cached copy if it exists.  */
748
          if (elf_section_data (sec)->this_hdr.contents != NULL)
749
            contents = elf_section_data (sec)->this_hdr.contents;
750
          else
751
            {
752
              /* Go get them off disk.  */
753
              if (!bfd_malloc_and_get_section (abfd, sec, &contents))
754
                goto error_return;
755
            }
756
        }
757
 
758
      /* Read this BFD's local symbols if we haven't done so already.  */
759
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
760
        {
761
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
762
          if (isymbuf == NULL)
763
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
764
                                            symtab_hdr->sh_info, 0,
765
                                            NULL, NULL, NULL);
766
          if (isymbuf == NULL)
767
            goto error_return;
768
        }
769
 
770
      /* Get the value of the symbol referred to by the reloc.  */
771
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
772
        {
773
          /* A local symbol.  */
774
          Elf_Internal_Sym *isym;
775
          asection *sym_sec;
776
 
777
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
778
          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
779
          symval = isym->st_value;
780
          /* If the reloc is absolute, it will not have
781
             a symbol or section associated with it.  */
782
          if (sym_sec)
783
            symval += sym_sec->output_section->vma
784
              + sym_sec->output_offset;
785
        }
786
      else
787
        {
788
          unsigned long indx;
789
          struct elf_link_hash_entry *h;
790
 
791
          /* An external symbol.  */
792
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
793
          h = elf_sym_hashes (abfd)[indx];
794
          BFD_ASSERT (h != NULL);
795
          if (h->root.type != bfd_link_hash_defined
796
              && h->root.type != bfd_link_hash_defweak)
797
            {
798
              /* This appears to be a reference to an undefined
799
                 symbol.  Just ignore it--it will be caught by the
800
                 regular reloc processing.  */
801
              continue;
802
            }
803
 
804
          symval = (h->root.u.def.value
805
                    + h->root.u.def.section->output_section->vma
806
                    + h->root.u.def.section->output_offset);
807
        }
808
 
809
      /* For simplicity of coding, we are going to modify the section
810
         contents, the section relocs, and the BFD symbol table.  We
811
         must tell the rest of the code not to free up this
812
         information.  It would be possible to instead create a table
813
         of changes which have to be made, as is done in coff-mips.c;
814
         that would be more work, but would require less memory when
815
         the linker is run.  */
816
      switch (ELF32_R_TYPE (irel->r_info))
817
        {
818
        /* Try to turn a 24-bit absolute branch/call into an 8-bit
819
           pc-relative branch/call.  */
820
        case R_H8_DIR24R8:
821
          {
822
            bfd_vma value = symval + irel->r_addend;
823
            bfd_vma dot, gap;
824
 
825
            /* Get the address of this instruction.  */
826
            dot = (sec->output_section->vma
827
                   + sec->output_offset + irel->r_offset - 1);
828
 
829
            /* Compute the distance from this insn to the branch target.  */
830
            gap = value - dot;
831
 
832
            /* If the distance is within -126..+130 inclusive, then we can
833
               relax this jump.  +130 is valid since the target will move
834
               two bytes closer if we do relax this branch.  */
835
            if ((int) gap >= -126 && (int) gap <= 130)
836
              {
837
                unsigned char code;
838
 
839
                /* Note that we've changed the relocs, section contents,
840
                   etc.  */
841
                elf_section_data (sec)->relocs = internal_relocs;
842
                elf_section_data (sec)->this_hdr.contents = contents;
843
                symtab_hdr->contents = (unsigned char *) isymbuf;
844
 
845
                /* Get the instruction code being relaxed.  */
846
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
847
 
848
                /* If the previous instruction conditionally jumped around
849
                   this instruction, we may be able to reverse the condition
850
                   and redirect the previous instruction to the target of
851
                   this instruction.
852
 
853
                   Such sequences are used by the compiler to deal with
854
                   long conditional branches.
855
 
856
                   Only perform this optimisation for jumps (code 0x5a) not
857
                   subroutine calls, as otherwise it could transform:
858
 
859
                                     mov.w   r0,r0
860
                                     beq     .L1
861
                                     jsr     @_bar
862
                              .L1:   rts
863
                              _bar:  rts
864
                   into:
865
                                     mov.w   r0,r0
866
                                     bne     _bar
867
                                     rts
868
                              _bar:  rts
869
 
870
                   which changes the call (jsr) into a branch (bne).  */
871
                if (code == 0x5a
872
                    && (int) gap <= 130
873
                    && (int) gap >= -128
874
                    && last_reloc
875
                    && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
876
                    && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
877
                  {
878
                    bfd_vma last_value;
879
                    asection *last_sym_sec;
880
                    Elf_Internal_Sym *last_sym;
881
 
882
                    /* We will need to examine the symbol used by the
883
                       previous relocation.  */
884
 
885
                    last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
886
                    last_sym_sec
887
                      = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
888
                    last_value = (last_sym->st_value
889
                                  + last_sym_sec->output_section->vma
890
                                  + last_sym_sec->output_offset);
891
 
892
                    /* Verify that the previous relocation was for a
893
                       branch around this instruction and that no symbol
894
                       exists at the current location.  */
895
                    if (last_value == dot + 4
896
                        && last_reloc->r_offset + 2 == irel->r_offset
897
                        && ! elf32_h8_symbol_address_p (abfd, sec, dot))
898
                      {
899
                        /* We can eliminate this jump.  Twiddle the
900
                           previous relocation as necessary.  */
901
                        irel->r_info
902
                          = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
903
                                          ELF32_R_TYPE (R_H8_NONE));
904
 
905
                        last_reloc->r_info
906
                          = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
907
                                          ELF32_R_TYPE (R_H8_PCREL8));
908
                        last_reloc->r_addend = irel->r_addend;
909
 
910
                        code = bfd_get_8 (abfd,
911
                                          contents + last_reloc->r_offset - 1);
912
                        code ^= 1;
913
                        bfd_put_8 (abfd,
914
                                   code,
915
                        contents + last_reloc->r_offset - 1);
916
 
917
                        /* Delete four bytes of data.  */
918
                        if (!elf32_h8_relax_delete_bytes (abfd, sec,
919
                                                          irel->r_offset - 1,
920
                                                          4))
921
                          goto error_return;
922
 
923
                        *again = TRUE;
924
                        break;
925
                      }
926
                  }
927
 
928
                if (code == 0x5e)
929
                  /* This is jsr.  */
930
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
931
                else if (code == 0x5a)
932
                  /* This is jmp.  */
933
                  bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
934
                else
935
                  abort ();
936
 
937
                /* Fix the relocation's type.  */
938
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
939
                                             R_H8_PCREL8);
940
 
941
                /* Delete two bytes of data.  */
942
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
943
                                                  irel->r_offset + 1, 2))
944
                  goto error_return;
945
 
946
                /* That will change things, so, we should relax again.
947
                   Note that this is not required, and it may be slow.  */
948
                *again = TRUE;
949
              }
950
            break;
951
          }
952
 
953
        /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
954
           branch.  */
955
        case R_H8_PCREL16:
956
          {
957
            bfd_vma value = symval + irel->r_addend;
958
            bfd_vma dot;
959
            bfd_vma gap;
960
 
961
            /* Get the address of this instruction.  */
962
            dot = (sec->output_section->vma
963
                   + sec->output_offset
964
                   + irel->r_offset - 2);
965
 
966
            gap = value - dot;
967
 
968
            /* If the distance is within -126..+130 inclusive, then we can
969
               relax this jump.  +130 is valid since the target will move
970
               two bytes closer if we do relax this branch.  */
971
            if ((int) gap >= -126 && (int) gap <= 130)
972
              {
973
                unsigned char code;
974
 
975
                /* Note that we've changed the relocs, section contents,
976
                   etc.  */
977
                elf_section_data (sec)->relocs = internal_relocs;
978
                elf_section_data (sec)->this_hdr.contents = contents;
979
                symtab_hdr->contents = (unsigned char *) isymbuf;
980
 
981
                /* Get the opcode.  */
982
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
983
 
984
                if (code == 0x58)
985
                  {
986
                    /* bCC:16 -> bCC:8 */
987
                    /* Get the second byte of the original insn, which
988
                       contains the condition code.  */
989
                    code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
990
 
991
                    /* Compute the fisrt byte of the relaxed
992
                       instruction.  The original sequence 0x58 0xX0
993
                       is relaxed to 0x4X, where X represents the
994
                       condition code.  */
995
                    code &= 0xf0;
996
                    code >>= 4;
997
                    code |= 0x40;
998
                    bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
999
                  }
1000
                else if (code == 0x5c)
1001
                  /* This is bsr.  */
1002
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
1003
                else
1004
                  /* Might be MOVSD.  */
1005
                  break;
1006
 
1007
                /* Fix the relocation's type.  */
1008
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1009
                                             R_H8_PCREL8);
1010
                irel->r_offset--;
1011
 
1012
                /* Delete two bytes of data.  */
1013
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1014
                                                  irel->r_offset + 1, 2))
1015
                  goto error_return;
1016
 
1017
                /* That will change things, so, we should relax again.
1018
                   Note that this is not required, and it may be slow.  */
1019
                *again = TRUE;
1020
              }
1021
            break;
1022
          }
1023
 
1024
        /* This is a 16-bit absolute address in one of the following
1025
           instructions:
1026
 
1027
             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1028
             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1029
             "mov.b"
1030
 
1031
           We may relax this into an 8-bit absolute address if it's in
1032
           the right range.  */
1033
        case R_H8_DIR16A8:
1034
          {
1035
            bfd_vma value;
1036
 
1037
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1038
            if (value >= 0xffffff00u)
1039
              {
1040
                unsigned char code;
1041
                unsigned char temp_code;
1042
 
1043
                /* Note that we've changed the relocs, section contents,
1044
                   etc.  */
1045
                elf_section_data (sec)->relocs = internal_relocs;
1046
                elf_section_data (sec)->this_hdr.contents = contents;
1047
                symtab_hdr->contents = (unsigned char *) isymbuf;
1048
 
1049
                /* Get the opcode.  */
1050
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1051
 
1052
                /* All instructions with R_H8_DIR16A8 start with
1053
                   0x6a.  */
1054
                if (code != 0x6a)
1055
                  abort ();
1056
 
1057
                temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1058
                /* If this is a mov.b instruction, clear the lower
1059
                   nibble, which contains the source/destination
1060
                   register number.  */
1061
                if ((temp_code & 0x10) != 0x10)
1062
                  temp_code &= 0xf0;
1063
 
1064
                switch (temp_code)
1065
                  {
1066
                  case 0x00:
1067
                    /* This is mov.b @aa:16,Rd.  */
1068
                    bfd_put_8 (abfd, (code & 0xf) | 0x20,
1069
                               contents + irel->r_offset - 2);
1070
                    break;
1071
                  case 0x80:
1072
                    /* This is mov.b Rs,@aa:16.  */
1073
                    bfd_put_8 (abfd, (code & 0xf) | 0x30,
1074
                               contents + irel->r_offset - 2);
1075
                    break;
1076
                  case 0x18:
1077
                    /* This is a bit-maniputation instruction that
1078
                       stores one bit into memory, one of "bclr",
1079
                       "bist", "bnot", "bset", and "bst".  */
1080
                    bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1081
                    break;
1082
                  case 0x10:
1083
                    /* This is a bit-maniputation instruction that
1084
                       loads one bit from memory, one of "band",
1085
                       "biand", "bild", "bior", "bixor", "bld", "bor",
1086
                       "btst", and "bxor".  */
1087
                    bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1088
                    break;
1089
                  default:
1090
                    abort ();
1091
                  }
1092
 
1093
                /* Fix the relocation's type.  */
1094
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1095
                                             R_H8_DIR8);
1096
 
1097
                /* Move the relocation.  */
1098
                irel->r_offset--;
1099
 
1100
                /* Delete two bytes of data.  */
1101
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1102
                                                  irel->r_offset + 1, 2))
1103
                  goto error_return;
1104
 
1105
                /* That will change things, so, we should relax again.
1106
                   Note that this is not required, and it may be slow.  */
1107
                *again = TRUE;
1108
              }
1109
            break;
1110
          }
1111
 
1112
        /* This is a 24-bit absolute address in one of the following
1113
           instructions:
1114
 
1115
             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1116
             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1117
             "mov.b"
1118
 
1119
           We may relax this into an 8-bit absolute address if it's in
1120
           the right range.  */
1121
        case R_H8_DIR24A8:
1122
          {
1123
            bfd_vma value;
1124
 
1125
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1126
            if (value >= 0xffffff00u)
1127
              {
1128
                unsigned char code;
1129
                unsigned char temp_code;
1130
 
1131
                /* Note that we've changed the relocs, section contents,
1132
                   etc.  */
1133
                elf_section_data (sec)->relocs = internal_relocs;
1134
                elf_section_data (sec)->this_hdr.contents = contents;
1135
                symtab_hdr->contents = (unsigned char *) isymbuf;
1136
 
1137
                /* Get the opcode.  */
1138
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1139
 
1140
                /* All instructions with R_H8_DIR24A8 start with
1141
                   0x6a.  */
1142
                if (code != 0x6a)
1143
                  abort ();
1144
 
1145
                temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1146
 
1147
                /* If this is a mov.b instruction, clear the lower
1148
                   nibble, which contains the source/destination
1149
                   register number.  */
1150
                if ((temp_code & 0x30) != 0x30)
1151
                  temp_code &= 0xf0;
1152
 
1153
                switch (temp_code)
1154
                  {
1155
                  case 0x20:
1156
                    /* This is mov.b @aa:24/32,Rd.  */
1157
                    bfd_put_8 (abfd, (code & 0xf) | 0x20,
1158
                               contents + irel->r_offset - 2);
1159
                    break;
1160
                  case 0xa0:
1161
                    /* This is mov.b Rs,@aa:24/32.  */
1162
                    bfd_put_8 (abfd, (code & 0xf) | 0x30,
1163
                               contents + irel->r_offset - 2);
1164
                    break;
1165
                  case 0x38:
1166
                    /* This is a bit-maniputation instruction that
1167
                       stores one bit into memory, one of "bclr",
1168
                       "bist", "bnot", "bset", and "bst".  */
1169
                    bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1170
                    break;
1171
                  case 0x30:
1172
                    /* This is a bit-maniputation instruction that
1173
                       loads one bit from memory, one of "band",
1174
                       "biand", "bild", "bior", "bixor", "bld", "bor",
1175
                       "btst", and "bxor".  */
1176
                    bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1177
                    break;
1178
                  default:
1179
                    abort();
1180
                  }
1181
 
1182
                /* Fix the relocation's type.  */
1183
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1184
                                             R_H8_DIR8);
1185
                irel->r_offset--;
1186
 
1187
                /* Delete two bytes of data.  */
1188
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1189
                                                  irel->r_offset + 1, 4))
1190
                  goto error_return;
1191
 
1192
                /* That will change things, so, we should relax again.
1193
                   Note that this is not required, and it may be slow.  */
1194
                *again = TRUE;
1195
                break;
1196
              }
1197
          }
1198
 
1199
          /* Fall through.  */
1200
 
1201
          /* This is a 24-/32-bit absolute address in one of the
1202
             following instructions:
1203
 
1204
               "band", "bclr", "biand", "bild", "bior", "bist",
1205
               "bixor", "bld", "bnot", "bor", "bset", "bst", "btst",
1206
               "bxor", "ldc.w", "stc.w" and "mov.[bwl]"
1207
 
1208
             We may relax this into an 16-bit absolute address if it's
1209
             in the right range.  */
1210
        case R_H8_DIR32A16:
1211
          {
1212
            bfd_vma value;
1213
 
1214
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1215
            if (value <= 0x7fff || value >= 0xffff8000u)
1216
              {
1217
                unsigned char code;
1218
                unsigned char op0, op1, op2, op3;
1219
                unsigned char *op_ptr;
1220
 
1221
                /* Note that we've changed the relocs, section contents,
1222
                   etc.  */
1223
                elf_section_data (sec)->relocs = internal_relocs;
1224
                elf_section_data (sec)->this_hdr.contents = contents;
1225
                symtab_hdr->contents = (unsigned char *) isymbuf;
1226
 
1227
                if (irel->r_offset >= 4)
1228
                  {
1229
                    /* Check for 4-byte MOVA relaxation.  */
1230
                    int second_reloc = 0;
1231
 
1232
                    op_ptr = contents + irel->r_offset - 4;
1233
 
1234
                    if (last_reloc)
1235
                      {
1236
                        arelent bfd_reloc;
1237
                        reloc_howto_type *h;
1238
                        bfd_vma last_reloc_size;
1239
 
1240
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc);
1241
                        h = bfd_reloc.howto;
1242
                        last_reloc_size = 1 << h->size;
1243
                        if (last_reloc->r_offset + last_reloc_size
1244
                            == irel->r_offset)
1245
                          {
1246
                            op_ptr -= last_reloc_size;
1247
                            second_reloc = 1;
1248
                          }
1249
                      }
1250
                    if (irel < irelend)
1251
                      {
1252
                        Elf_Internal_Rela *next_reloc = irel + 1;
1253
                        arelent bfd_reloc;
1254
                        reloc_howto_type *h;
1255
                        bfd_vma next_reloc_size;
1256
 
1257
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc);
1258
                        h = bfd_reloc.howto;
1259
                        next_reloc_size = 1 << h->size;
1260
                        if (next_reloc->r_offset + next_reloc_size
1261
                            == irel->r_offset)
1262
                          {
1263
                            op_ptr -= next_reloc_size;
1264
                            second_reloc = 1;
1265
                          }
1266
                      }
1267
 
1268
                    op0 = bfd_get_8 (abfd, op_ptr + 0);
1269
                    op1 = bfd_get_8 (abfd, op_ptr + 1);
1270
                    op2 = bfd_get_8 (abfd, op_ptr + 2);
1271
                    op3 = bfd_get_8 (abfd, op_ptr + 3);
1272
 
1273
                    if (op0 == 0x01
1274
                        && (op1 & 0xdf) == 0x5f
1275
                        && (op2 & 0x40) == 0x40
1276
                        && (op3 & 0x80) == 0x80)
1277
                      {
1278
                        if ((op2 & 0x08) == 0)
1279
                          second_reloc = 1;
1280
 
1281
                        if (second_reloc)
1282
                          {
1283
                            op3 &= ~0x08;
1284
                            bfd_put_8 (abfd, op3, op_ptr + 3);
1285
                          }
1286
                        else
1287
                          {
1288
                            op2 &= ~0x08;
1289
                            bfd_put_8 (abfd, op2, op_ptr + 2);
1290
                          }
1291
                        goto r_h8_dir32a16_common;
1292
                      }
1293
                  }
1294
 
1295
                /* Now check for short version of MOVA.  */
1296
                op_ptr = contents + irel->r_offset - 2;
1297
                op0 = bfd_get_8 (abfd, op_ptr + 0);
1298
                op1 = bfd_get_8 (abfd, op_ptr + 1);
1299
 
1300
                if (op0 == 0x7a
1301
                    && (op1 & 0x88) == 0x80)
1302
                  {
1303
                    op1 |= 0x08;
1304
                    bfd_put_8 (abfd, op1, op_ptr + 1);
1305
                    goto r_h8_dir32a16_common;
1306
                  }
1307
 
1308
                /* Get the opcode.  */
1309
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1310
 
1311
                /* Fix the opcode.  For all the instructions that
1312
                   belong to this relaxation, we simply need to turn
1313
                   off bit 0x20 in the previous byte.  */
1314
                code &= ~0x20;
1315
 
1316
                bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1317
 
1318
              r_h8_dir32a16_common:
1319
                /* Fix the relocation's type.  */
1320
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1321
                                             R_H8_DIR16);
1322
 
1323
                /* Delete two bytes of data.  */
1324
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1325
                                                  irel->r_offset + 1, 2))
1326
                  goto error_return;
1327
 
1328
                /* That will change things, so, we should relax again.
1329
                   Note that this is not required, and it may be slow.  */
1330
                *again = TRUE;
1331
              }
1332
            break;
1333
          }
1334
 
1335
        default:
1336
          break;
1337
        }
1338
    }
1339
 
1340
  if (isymbuf != NULL
1341
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1342
    {
1343
      if (! link_info->keep_memory)
1344
        free (isymbuf);
1345
      else
1346
        symtab_hdr->contents = (unsigned char *) isymbuf;
1347
    }
1348
 
1349
  if (contents != NULL
1350
      && elf_section_data (sec)->this_hdr.contents != contents)
1351
    {
1352
      if (! link_info->keep_memory)
1353
        free (contents);
1354
      else
1355
        {
1356
          /* Cache the section contents for elf_link_input_bfd.  */
1357
          elf_section_data (sec)->this_hdr.contents = contents;
1358
        }
1359
    }
1360
 
1361
  if (internal_relocs != NULL
1362
      && elf_section_data (sec)->relocs != internal_relocs)
1363
    free (internal_relocs);
1364
 
1365
  return TRUE;
1366
 
1367
 error_return:
1368
  if (isymbuf != NULL
1369
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1370
    free (isymbuf);
1371
  if (contents != NULL
1372
      && elf_section_data (sec)->this_hdr.contents != contents)
1373
    free (contents);
1374
  if (internal_relocs != NULL
1375
      && elf_section_data (sec)->relocs != internal_relocs)
1376
    free (internal_relocs);
1377
  return FALSE;
1378
}
1379
 
1380
/* Delete some bytes from a section while relaxing.  */
1381
 
1382
static bfd_boolean
1383
elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
1384
{
1385
  Elf_Internal_Shdr *symtab_hdr;
1386
  unsigned int sec_shndx;
1387
  bfd_byte *contents;
1388
  Elf_Internal_Rela *irel, *irelend;
1389
  Elf_Internal_Rela *irelalign;
1390
  Elf_Internal_Sym *isym;
1391
  Elf_Internal_Sym *isymend;
1392
  bfd_vma toaddr;
1393
  struct elf_link_hash_entry **sym_hashes;
1394
  struct elf_link_hash_entry **end_hashes;
1395
  unsigned int symcount;
1396
 
1397
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1398
 
1399
  contents = elf_section_data (sec)->this_hdr.contents;
1400
 
1401
  /* The deletion must stop at the next ALIGN reloc for an aligment
1402
     power larger than the number of bytes we are deleting.  */
1403
 
1404
  irelalign = NULL;
1405
  toaddr = sec->size;
1406
 
1407
  irel = elf_section_data (sec)->relocs;
1408
  irelend = irel + sec->reloc_count;
1409
 
1410
  /* Actually delete the bytes.  */
1411
  memmove (contents + addr, contents + addr + count,
1412
           (size_t) (toaddr - addr - count));
1413
  sec->size -= count;
1414
 
1415
  /* Adjust all the relocs.  */
1416
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1417
    {
1418
      /* Get the new reloc address.  */
1419
      if ((irel->r_offset > addr
1420
           && irel->r_offset < toaddr))
1421
        irel->r_offset -= count;
1422
    }
1423
 
1424
  /* Adjust the local symbols defined in this section.  */
1425
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1426
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1427
  isymend = isym + symtab_hdr->sh_info;
1428
  for (; isym < isymend; isym++)
1429
    {
1430
      if (isym->st_shndx == sec_shndx
1431
          && isym->st_value > addr
1432
          && isym->st_value < toaddr)
1433
        isym->st_value -= count;
1434
    }
1435
 
1436
  /* Now adjust the global symbols defined in this section.  */
1437
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1438
              - symtab_hdr->sh_info);
1439
  sym_hashes = elf_sym_hashes (abfd);
1440
  end_hashes = sym_hashes + symcount;
1441
  for (; sym_hashes < end_hashes; sym_hashes++)
1442
    {
1443
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1444
      if ((sym_hash->root.type == bfd_link_hash_defined
1445
           || sym_hash->root.type == bfd_link_hash_defweak)
1446
          && sym_hash->root.u.def.section == sec
1447
          && sym_hash->root.u.def.value > addr
1448
          && sym_hash->root.u.def.value < toaddr)
1449
        {
1450
          sym_hash->root.u.def.value -= count;
1451
        }
1452
    }
1453
 
1454
  return TRUE;
1455
}
1456
 
1457
/* Return TRUE if a symbol exists at the given address, else return
1458
   FALSE.  */
1459
static bfd_boolean
1460
elf32_h8_symbol_address_p (bfd *abfd, asection *sec, bfd_vma addr)
1461
{
1462
  Elf_Internal_Shdr *symtab_hdr;
1463
  unsigned int sec_shndx;
1464
  Elf_Internal_Sym *isym;
1465
  Elf_Internal_Sym *isymend;
1466
  struct elf_link_hash_entry **sym_hashes;
1467
  struct elf_link_hash_entry **end_hashes;
1468
  unsigned int symcount;
1469
 
1470
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1471
 
1472
  /* Examine all the symbols.  */
1473
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1474
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1475
  isymend = isym + symtab_hdr->sh_info;
1476
  for (; isym < isymend; isym++)
1477
    {
1478
      if (isym->st_shndx == sec_shndx
1479
          && isym->st_value == addr)
1480
        return TRUE;
1481
    }
1482
 
1483
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1484
              - symtab_hdr->sh_info);
1485
  sym_hashes = elf_sym_hashes (abfd);
1486
  end_hashes = sym_hashes + symcount;
1487
  for (; sym_hashes < end_hashes; sym_hashes++)
1488
    {
1489
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1490
      if ((sym_hash->root.type == bfd_link_hash_defined
1491
           || sym_hash->root.type == bfd_link_hash_defweak)
1492
          && sym_hash->root.u.def.section == sec
1493
          && sym_hash->root.u.def.value == addr)
1494
        return TRUE;
1495
    }
1496
 
1497
  return FALSE;
1498
}
1499
 
1500
/* This is a version of bfd_generic_get_relocated_section_contents
1501
   which uses elf32_h8_relocate_section.  */
1502
 
1503
static bfd_byte *
1504
elf32_h8_get_relocated_section_contents (bfd *output_bfd,
1505
                                         struct bfd_link_info *link_info,
1506
                                         struct bfd_link_order *link_order,
1507
                                         bfd_byte *data,
1508
                                         bfd_boolean relocatable,
1509
                                         asymbol **symbols)
1510
{
1511
  Elf_Internal_Shdr *symtab_hdr;
1512
  asection *input_section = link_order->u.indirect.section;
1513
  bfd *input_bfd = input_section->owner;
1514
  asection **sections = NULL;
1515
  Elf_Internal_Rela *internal_relocs = NULL;
1516
  Elf_Internal_Sym *isymbuf = NULL;
1517
 
1518
  /* We only need to handle the case of relaxing, or of having a
1519
     particular set of section contents, specially.  */
1520
  if (relocatable
1521
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1522
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1523
                                                       link_order, data,
1524
                                                       relocatable,
1525
                                                       symbols);
1526
 
1527
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1528
 
1529
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1530
          (size_t) input_section->size);
1531
 
1532
  if ((input_section->flags & SEC_RELOC) != 0
1533
      && input_section->reloc_count > 0)
1534
    {
1535
      asection **secpp;
1536
      Elf_Internal_Sym *isym, *isymend;
1537
      bfd_size_type amt;
1538
 
1539
      internal_relocs = (_bfd_elf_link_read_relocs
1540
                         (input_bfd, input_section, (PTR) NULL,
1541
                          (Elf_Internal_Rela *) NULL, FALSE));
1542
      if (internal_relocs == NULL)
1543
        goto error_return;
1544
 
1545
      if (symtab_hdr->sh_info != 0)
1546
        {
1547
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1548
          if (isymbuf == NULL)
1549
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1550
                                            symtab_hdr->sh_info, 0,
1551
                                            NULL, NULL, NULL);
1552
          if (isymbuf == NULL)
1553
            goto error_return;
1554
        }
1555
 
1556
      amt = symtab_hdr->sh_info;
1557
      amt *= sizeof (asection *);
1558
      sections = (asection **) bfd_malloc (amt);
1559
      if (sections == NULL && amt != 0)
1560
        goto error_return;
1561
 
1562
      isymend = isymbuf + symtab_hdr->sh_info;
1563
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1564
        {
1565
          asection *isec;
1566
 
1567
          if (isym->st_shndx == SHN_UNDEF)
1568
            isec = bfd_und_section_ptr;
1569
          else if (isym->st_shndx == SHN_ABS)
1570
            isec = bfd_abs_section_ptr;
1571
          else if (isym->st_shndx == SHN_COMMON)
1572
            isec = bfd_com_section_ptr;
1573
          else
1574
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1575
 
1576
          *secpp = isec;
1577
        }
1578
 
1579
      if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
1580
                                       input_section, data, internal_relocs,
1581
                                       isymbuf, sections))
1582
        goto error_return;
1583
 
1584
      if (sections != NULL)
1585
        free (sections);
1586
      if (isymbuf != NULL
1587
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1588
        free (isymbuf);
1589
      if (elf_section_data (input_section)->relocs != internal_relocs)
1590
        free (internal_relocs);
1591
    }
1592
 
1593
  return data;
1594
 
1595
 error_return:
1596
  if (sections != NULL)
1597
    free (sections);
1598
  if (isymbuf != NULL
1599
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1600
    free (isymbuf);
1601
  if (internal_relocs != NULL
1602
      && elf_section_data (input_section)->relocs != internal_relocs)
1603
    free (internal_relocs);
1604
  return NULL;
1605
}
1606
 
1607
 
1608
#define TARGET_BIG_SYM                  bfd_elf32_h8300_vec
1609
#define TARGET_BIG_NAME                 "elf32-h8300"
1610
#define ELF_ARCH                        bfd_arch_h8300
1611
#define ELF_MACHINE_CODE                EM_H8_300
1612
#define ELF_MAXPAGESIZE                 0x1
1613
#define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
1614
#define bfd_elf32_bfd_reloc_name_lookup elf32_h8_reloc_name_lookup
1615
#define elf_info_to_howto               elf32_h8_info_to_howto
1616
#define elf_info_to_howto_rel           elf32_h8_info_to_howto_rel
1617
 
1618
/* So we can set/examine bits in e_flags to get the specific
1619
   H8 architecture in use.  */
1620
#define elf_backend_final_write_processing \
1621
  elf32_h8_final_write_processing
1622
#define elf_backend_object_p \
1623
  elf32_h8_object_p
1624
#define bfd_elf32_bfd_merge_private_bfd_data \
1625
  elf32_h8_merge_private_bfd_data
1626
 
1627
/* ??? when elf_backend_relocate_section is not defined, elf32-target.h
1628
   defaults to using _bfd_generic_link_hash_table_create, but
1629
   bfd_elf_size_dynamic_sections uses
1630
   dynobj = elf_hash_table (info)->dynobj;
1631
   and thus requires an elf hash table.  */
1632
#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
1633
 
1634
/* Use an H8 specific linker, not the ELF generic linker.  */
1635
#define elf_backend_relocate_section elf32_h8_relocate_section
1636
#define elf_backend_rela_normal         1
1637
#define elf_backend_can_gc_sections     1
1638
 
1639
/* And relaxing stuff.  */
1640
#define bfd_elf32_bfd_relax_section     elf32_h8_relax_section
1641
#define bfd_elf32_bfd_get_relocated_section_contents \
1642
                                elf32_h8_get_relocated_section_contents
1643
 
1644
 
1645
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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