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

Subversion Repositories open8_urisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* BFD back-end for Renesas H8/300 ELF binaries.
2
   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
3
   2007, 2009, 2010 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
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
465
                                         rel, relend, howto, contents);
466
 
467
      if (info->relocatable)
468
        continue;
469
 
470
      r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
471
                                        input_section,
472
                                        contents, rel->r_offset,
473
                                        relocation, rel->r_addend,
474
                                        info, sec, h == NULL);
475
 
476
      if (r != bfd_reloc_ok)
477
        {
478
          const char *name;
479
          const char *msg = (const char *) 0;
480
 
481
          if (h != NULL)
482
            name = h->root.root.string;
483
          else
484
            {
485
              name = (bfd_elf_string_from_elf_section
486
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
487
              if (name == NULL || *name == '\0')
488
                name = bfd_section_name (input_bfd, sec);
489
            }
490
 
491
          switch (r)
492
            {
493
            case bfd_reloc_overflow:
494
              if (! ((*info->callbacks->reloc_overflow)
495
                     (info, (h ? &h->root : NULL), name, howto->name,
496
                      (bfd_vma) 0, input_bfd, input_section,
497
                      rel->r_offset)))
498
                return FALSE;
499
              break;
500
 
501
            case bfd_reloc_undefined:
502
              if (! ((*info->callbacks->undefined_symbol)
503
                     (info, name, input_bfd, input_section,
504
                      rel->r_offset, TRUE)))
505
                return FALSE;
506
              break;
507
 
508
            case bfd_reloc_outofrange:
509
              msg = _("internal error: out of range error");
510
              goto common_error;
511
 
512
            case bfd_reloc_notsupported:
513
              msg = _("internal error: unsupported relocation error");
514
              goto common_error;
515
 
516
            case bfd_reloc_dangerous:
517
              msg = _("internal error: dangerous error");
518
              goto common_error;
519
 
520
            default:
521
              msg = _("internal error: unknown error");
522
              /* fall through */
523
 
524
            common_error:
525
              if (!((*info->callbacks->warning)
526
                    (info, msg, name, input_bfd, input_section,
527
                     rel->r_offset)))
528
                return FALSE;
529
              break;
530
            }
531
        }
532
    }
533
 
534
  return TRUE;
535
}
536
 
537
/* Object files encode the specific H8 model they were compiled
538
   for in the ELF flags field.
539
 
540
   Examine that field and return the proper BFD machine type for
541
   the object file.  */
542
static unsigned long
543
elf32_h8_mach (flagword flags)
544
{
545
  switch (flags & EF_H8_MACH)
546
    {
547
    case E_H8_MACH_H8300:
548
    default:
549
      return bfd_mach_h8300;
550
 
551
    case E_H8_MACH_H8300H:
552
      return bfd_mach_h8300h;
553
 
554
    case E_H8_MACH_H8300S:
555
      return bfd_mach_h8300s;
556
 
557
    case E_H8_MACH_H8300HN:
558
      return bfd_mach_h8300hn;
559
 
560
    case E_H8_MACH_H8300SN:
561
      return bfd_mach_h8300sn;
562
 
563
    case E_H8_MACH_H8300SX:
564
      return bfd_mach_h8300sx;
565
 
566
    case E_H8_MACH_H8300SXN:
567
      return bfd_mach_h8300sxn;
568
    }
569
}
570
 
571
/* The final processing done just before writing out a H8 ELF object
572
   file.  We use this opportunity to encode the BFD machine type
573
   into the flags field in the object file.  */
574
 
575
static void
576
elf32_h8_final_write_processing (bfd *abfd,
577
                                 bfd_boolean linker ATTRIBUTE_UNUSED)
578
{
579
  unsigned long val;
580
 
581
  switch (bfd_get_mach (abfd))
582
    {
583
    default:
584
    case bfd_mach_h8300:
585
      val = E_H8_MACH_H8300;
586
      break;
587
 
588
    case bfd_mach_h8300h:
589
      val = E_H8_MACH_H8300H;
590
      break;
591
 
592
    case bfd_mach_h8300s:
593
      val = E_H8_MACH_H8300S;
594
      break;
595
 
596
    case bfd_mach_h8300hn:
597
      val = E_H8_MACH_H8300HN;
598
      break;
599
 
600
    case bfd_mach_h8300sn:
601
      val = E_H8_MACH_H8300SN;
602
      break;
603
 
604
    case bfd_mach_h8300sx:
605
      val = E_H8_MACH_H8300SX;
606
      break;
607
 
608
    case bfd_mach_h8300sxn:
609
      val = E_H8_MACH_H8300SXN;
610
      break;
611
    }
612
 
613
  elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
614
  elf_elfheader (abfd)->e_flags |= val;
615
}
616
 
617
/* Return nonzero if ABFD represents a valid H8 ELF object file; also
618
   record the encoded machine type found in the ELF flags.  */
619
 
620
static bfd_boolean
621
elf32_h8_object_p (bfd *abfd)
622
{
623
  bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
624
                             elf32_h8_mach (elf_elfheader (abfd)->e_flags));
625
  return TRUE;
626
}
627
 
628
/* Merge backend specific data from an object file to the output
629
   object file when linking.  The only data we need to copy at this
630
   time is the architecture/machine information.  */
631
 
632
static bfd_boolean
633
elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
634
{
635
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
636
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
637
    return TRUE;
638
 
639
  if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
640
      && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
641
    {
642
      if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
643
                               bfd_get_mach (ibfd)))
644
        return FALSE;
645
    }
646
 
647
  return TRUE;
648
}
649
 
650
/* This function handles relaxing for the H8..
651
 
652
   There are a few relaxing opportunities available on the H8:
653
 
654
     jmp/jsr:24    ->    bra/bsr:8              2 bytes
655
     The jmp may be completely eliminated if the previous insn is a
656
     conditional branch to the insn after the jump.  In that case
657
     we invert the branch and delete the jump and save 4 bytes.
658
 
659
     bCC:16          ->    bCC:8                  2 bytes
660
     bsr:16          ->    bsr:8                  2 bytes
661
 
662
     bset:16         ->    bset:8                 2 bytes
663
     bset:24/32      ->    bset:8                 4 bytes
664
     (also applicable to other bit manipulation instructions)
665
 
666
     mov.b:16        ->    mov.b:8                2 bytes
667
     mov.b:24/32     ->    mov.b:8                4 bytes
668
 
669
     bset:24/32      ->    bset:16                2 bytes
670
     (also applicable to other bit manipulation instructions)
671
 
672
     mov.[bwl]:24/32 ->    mov.[bwl]:16           2 bytes */
673
 
674
static bfd_boolean
675
elf32_h8_relax_section (bfd *abfd, asection *sec,
676
                        struct bfd_link_info *link_info, bfd_boolean *again)
677
{
678
  Elf_Internal_Shdr *symtab_hdr;
679
  Elf_Internal_Rela *internal_relocs;
680
  Elf_Internal_Rela *irel, *irelend;
681
  bfd_byte *contents = NULL;
682
  Elf_Internal_Sym *isymbuf = NULL;
683
  static asection *last_input_section = NULL;
684
  static Elf_Internal_Rela *last_reloc = NULL;
685
 
686
  /* Assume nothing changes.  */
687
  *again = FALSE;
688
 
689
  /* We don't have to do anything for a relocatable link, if
690
     this section does not have relocs, or if this is not a
691
     code section.  */
692
  if (link_info->relocatable
693
      || (sec->flags & SEC_RELOC) == 0
694
      || sec->reloc_count == 0
695
      || (sec->flags & SEC_CODE) == 0)
696
    return TRUE;
697
 
698
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
699
 
700
  /* Get a copy of the native relocations.  */
701
  internal_relocs = (_bfd_elf_link_read_relocs
702
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
703
                      link_info->keep_memory));
704
  if (internal_relocs == NULL)
705
    goto error_return;
706
 
707
  if (sec != last_input_section)
708
    last_reloc = NULL;
709
 
710
  last_input_section = sec;
711
 
712
  /* Walk through the relocs looking for relaxing opportunities.  */
713
  irelend = internal_relocs + sec->reloc_count;
714
  for (irel = internal_relocs; irel < irelend; irel++)
715
    {
716
      bfd_vma symval;
717
 
718
      {
719
        arelent bfd_reloc;
720
 
721
        elf32_h8_info_to_howto (abfd, &bfd_reloc, irel);
722
      }
723
      /* Keep track of the previous reloc so that we can delete
724
         some long jumps created by the compiler.  */
725
      if (irel != internal_relocs)
726
        last_reloc = irel - 1;
727
 
728
      if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
729
          && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
730
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
731
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
732
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
733
        continue;
734
 
735
      /* Get the section contents if we haven't done so already.  */
736
      if (contents == NULL)
737
        {
738
          /* Get cached copy if it exists.  */
739
          if (elf_section_data (sec)->this_hdr.contents != NULL)
740
            contents = elf_section_data (sec)->this_hdr.contents;
741
          else
742
            {
743
              /* Go get them off disk.  */
744
              if (!bfd_malloc_and_get_section (abfd, sec, &contents))
745
                goto error_return;
746
            }
747
        }
748
 
749
      /* Read this BFD's local symbols if we haven't done so already.  */
750
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
751
        {
752
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
753
          if (isymbuf == NULL)
754
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
755
                                            symtab_hdr->sh_info, 0,
756
                                            NULL, NULL, NULL);
757
          if (isymbuf == NULL)
758
            goto error_return;
759
        }
760
 
761
      /* Get the value of the symbol referred to by the reloc.  */
762
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
763
        {
764
          /* A local symbol.  */
765
          Elf_Internal_Sym *isym;
766
          asection *sym_sec;
767
 
768
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
769
          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
770
          symval = isym->st_value;
771
          /* If the reloc is absolute, it will not have
772
             a symbol or section associated with it.  */
773
          if (sym_sec)
774
            symval += sym_sec->output_section->vma
775
              + sym_sec->output_offset;
776
        }
777
      else
778
        {
779
          unsigned long indx;
780
          struct elf_link_hash_entry *h;
781
 
782
          /* An external symbol.  */
783
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
784
          h = elf_sym_hashes (abfd)[indx];
785
          BFD_ASSERT (h != NULL);
786
          if (h->root.type != bfd_link_hash_defined
787
              && h->root.type != bfd_link_hash_defweak)
788
            {
789
              /* This appears to be a reference to an undefined
790
                 symbol.  Just ignore it--it will be caught by the
791
                 regular reloc processing.  */
792
              continue;
793
            }
794
 
795
          symval = (h->root.u.def.value
796
                    + h->root.u.def.section->output_section->vma
797
                    + h->root.u.def.section->output_offset);
798
        }
799
 
800
      /* For simplicity of coding, we are going to modify the section
801
         contents, the section relocs, and the BFD symbol table.  We
802
         must tell the rest of the code not to free up this
803
         information.  It would be possible to instead create a table
804
         of changes which have to be made, as is done in coff-mips.c;
805
         that would be more work, but would require less memory when
806
         the linker is run.  */
807
      switch (ELF32_R_TYPE (irel->r_info))
808
        {
809
        /* Try to turn a 24-bit absolute branch/call into an 8-bit
810
           pc-relative branch/call.  */
811
        case R_H8_DIR24R8:
812
          {
813
            bfd_vma value = symval + irel->r_addend;
814
            bfd_vma dot, gap;
815
 
816
            /* Get the address of this instruction.  */
817
            dot = (sec->output_section->vma
818
                   + sec->output_offset + irel->r_offset - 1);
819
 
820
            /* Compute the distance from this insn to the branch target.  */
821
            gap = value - dot;
822
 
823
            /* If the distance is within -126..+130 inclusive, then we can
824
               relax this jump.  +130 is valid since the target will move
825
               two bytes closer if we do relax this branch.  */
826
            if ((int) gap >= -126 && (int) gap <= 130)
827
              {
828
                unsigned char code;
829
 
830
                /* Note that we've changed the relocs, section contents,
831
                   etc.  */
832
                elf_section_data (sec)->relocs = internal_relocs;
833
                elf_section_data (sec)->this_hdr.contents = contents;
834
                symtab_hdr->contents = (unsigned char *) isymbuf;
835
 
836
                /* Get the instruction code being relaxed.  */
837
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
838
 
839
                /* If the previous instruction conditionally jumped around
840
                   this instruction, we may be able to reverse the condition
841
                   and redirect the previous instruction to the target of
842
                   this instruction.
843
 
844
                   Such sequences are used by the compiler to deal with
845
                   long conditional branches.
846
 
847
                   Only perform this optimisation for jumps (code 0x5a) not
848
                   subroutine calls, as otherwise it could transform:
849
 
850
                                     mov.w   r0,r0
851
                                     beq     .L1
852
                                     jsr     @_bar
853
                              .L1:   rts
854
                              _bar:  rts
855
                   into:
856
                                     mov.w   r0,r0
857
                                     bne     _bar
858
                                     rts
859
                              _bar:  rts
860
 
861
                   which changes the call (jsr) into a branch (bne).  */
862
                if (code == 0x5a
863
                    && (int) gap <= 130
864
                    && (int) gap >= -128
865
                    && last_reloc
866
                    && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
867
                    && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
868
                  {
869
                    bfd_vma last_value;
870
                    asection *last_sym_sec;
871
                    Elf_Internal_Sym *last_sym;
872
 
873
                    /* We will need to examine the symbol used by the
874
                       previous relocation.  */
875
 
876
                    last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
877
                    last_sym_sec
878
                      = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
879
                    last_value = (last_sym->st_value
880
                                  + last_sym_sec->output_section->vma
881
                                  + last_sym_sec->output_offset);
882
 
883
                    /* Verify that the previous relocation was for a
884
                       branch around this instruction and that no symbol
885
                       exists at the current location.  */
886
                    if (last_value == dot + 4
887
                        && last_reloc->r_offset + 2 == irel->r_offset
888
                        && ! elf32_h8_symbol_address_p (abfd, sec, dot))
889
                      {
890
                        /* We can eliminate this jump.  Twiddle the
891
                           previous relocation as necessary.  */
892
                        irel->r_info
893
                          = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
894
                                          ELF32_R_TYPE (R_H8_NONE));
895
 
896
                        last_reloc->r_info
897
                          = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
898
                                          ELF32_R_TYPE (R_H8_PCREL8));
899
                        last_reloc->r_addend = irel->r_addend;
900
 
901
                        code = bfd_get_8 (abfd,
902
                                          contents + last_reloc->r_offset - 1);
903
                        code ^= 1;
904
                        bfd_put_8 (abfd,
905
                                   code,
906
                        contents + last_reloc->r_offset - 1);
907
 
908
                        /* Delete four bytes of data.  */
909
                        if (!elf32_h8_relax_delete_bytes (abfd, sec,
910
                                                          irel->r_offset - 1,
911
                                                          4))
912
                          goto error_return;
913
 
914
                        *again = TRUE;
915
                        break;
916
                      }
917
                  }
918
 
919
                if (code == 0x5e)
920
                  /* This is jsr.  */
921
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
922
                else if (code == 0x5a)
923
                  /* This is jmp.  */
924
                  bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
925
                else
926
                  abort ();
927
 
928
                /* Fix the relocation's type.  */
929
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
930
                                             R_H8_PCREL8);
931
 
932
                /* Delete two bytes of data.  */
933
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
934
                                                  irel->r_offset + 1, 2))
935
                  goto error_return;
936
 
937
                /* That will change things, so, we should relax again.
938
                   Note that this is not required, and it may be slow.  */
939
                *again = TRUE;
940
              }
941
            break;
942
          }
943
 
944
        /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
945
           branch.  */
946
        case R_H8_PCREL16:
947
          {
948
            bfd_vma value = symval + irel->r_addend;
949
            bfd_vma dot;
950
            bfd_vma gap;
951
 
952
            /* Get the address of this instruction.  */
953
            dot = (sec->output_section->vma
954
                   + sec->output_offset
955
                   + irel->r_offset - 2);
956
 
957
            gap = value - dot;
958
 
959
            /* If the distance is within -126..+130 inclusive, then we can
960
               relax this jump.  +130 is valid since the target will move
961
               two bytes closer if we do relax this branch.  */
962
            if ((int) gap >= -126 && (int) gap <= 130)
963
              {
964
                unsigned char code;
965
 
966
                /* Note that we've changed the relocs, section contents,
967
                   etc.  */
968
                elf_section_data (sec)->relocs = internal_relocs;
969
                elf_section_data (sec)->this_hdr.contents = contents;
970
                symtab_hdr->contents = (unsigned char *) isymbuf;
971
 
972
                /* Get the opcode.  */
973
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
974
 
975
                if (code == 0x58)
976
                  {
977
                    /* bCC:16 -> bCC:8 */
978
                    /* Get the second byte of the original insn, which
979
                       contains the condition code.  */
980
                    code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
981
 
982
                    /* Compute the fisrt byte of the relaxed
983
                       instruction.  The original sequence 0x58 0xX0
984
                       is relaxed to 0x4X, where X represents the
985
                       condition code.  */
986
                    code &= 0xf0;
987
                    code >>= 4;
988
                    code |= 0x40;
989
                    bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
990
                  }
991
                else if (code == 0x5c)
992
                  /* This is bsr.  */
993
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
994
                else
995
                  /* Might be MOVSD.  */
996
                  break;
997
 
998
                /* Fix the relocation's type.  */
999
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1000
                                             R_H8_PCREL8);
1001
                irel->r_offset--;
1002
 
1003
                /* Delete two bytes of data.  */
1004
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1005
                                                  irel->r_offset + 1, 2))
1006
                  goto error_return;
1007
 
1008
                /* That will change things, so, we should relax again.
1009
                   Note that this is not required, and it may be slow.  */
1010
                *again = TRUE;
1011
              }
1012
            break;
1013
          }
1014
 
1015
        /* This is a 16-bit absolute address in one of the following
1016
           instructions:
1017
 
1018
             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1019
             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1020
             "mov.b"
1021
 
1022
           We may relax this into an 8-bit absolute address if it's in
1023
           the right range.  */
1024
        case R_H8_DIR16A8:
1025
          {
1026
            bfd_vma value;
1027
 
1028
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1029
            if (value >= 0xffffff00u)
1030
              {
1031
                unsigned char code;
1032
                unsigned char temp_code;
1033
 
1034
                /* Note that we've changed the relocs, section contents,
1035
                   etc.  */
1036
                elf_section_data (sec)->relocs = internal_relocs;
1037
                elf_section_data (sec)->this_hdr.contents = contents;
1038
                symtab_hdr->contents = (unsigned char *) isymbuf;
1039
 
1040
                /* Get the opcode.  */
1041
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1042
 
1043
                /* All instructions with R_H8_DIR16A8 start with
1044
                   0x6a.  */
1045
                if (code != 0x6a)
1046
                  abort ();
1047
 
1048
                temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1049
                /* If this is a mov.b instruction, clear the lower
1050
                   nibble, which contains the source/destination
1051
                   register number.  */
1052
                if ((temp_code & 0x10) != 0x10)
1053
                  temp_code &= 0xf0;
1054
 
1055
                switch (temp_code)
1056
                  {
1057
                  case 0x00:
1058
                    /* This is mov.b @aa:16,Rd.  */
1059
                    bfd_put_8 (abfd, (code & 0xf) | 0x20,
1060
                               contents + irel->r_offset - 2);
1061
                    break;
1062
                  case 0x80:
1063
                    /* This is mov.b Rs,@aa:16.  */
1064
                    bfd_put_8 (abfd, (code & 0xf) | 0x30,
1065
                               contents + irel->r_offset - 2);
1066
                    break;
1067
                  case 0x18:
1068
                    /* This is a bit-maniputation instruction that
1069
                       stores one bit into memory, one of "bclr",
1070
                       "bist", "bnot", "bset", and "bst".  */
1071
                    bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1072
                    break;
1073
                  case 0x10:
1074
                    /* This is a bit-maniputation instruction that
1075
                       loads one bit from memory, one of "band",
1076
                       "biand", "bild", "bior", "bixor", "bld", "bor",
1077
                       "btst", and "bxor".  */
1078
                    bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1079
                    break;
1080
                  default:
1081
                    abort ();
1082
                  }
1083
 
1084
                /* Fix the relocation's type.  */
1085
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1086
                                             R_H8_DIR8);
1087
 
1088
                /* Move the relocation.  */
1089
                irel->r_offset--;
1090
 
1091
                /* Delete two bytes of data.  */
1092
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1093
                                                  irel->r_offset + 1, 2))
1094
                  goto error_return;
1095
 
1096
                /* That will change things, so, we should relax again.
1097
                   Note that this is not required, and it may be slow.  */
1098
                *again = TRUE;
1099
              }
1100
            break;
1101
          }
1102
 
1103
        /* This is a 24-bit absolute address in one of the following
1104
           instructions:
1105
 
1106
             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1107
             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1108
             "mov.b"
1109
 
1110
           We may relax this into an 8-bit absolute address if it's in
1111
           the right range.  */
1112
        case R_H8_DIR24A8:
1113
          {
1114
            bfd_vma value;
1115
 
1116
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1117
            if (value >= 0xffffff00u)
1118
              {
1119
                unsigned char code;
1120
                unsigned char temp_code;
1121
 
1122
                /* Note that we've changed the relocs, section contents,
1123
                   etc.  */
1124
                elf_section_data (sec)->relocs = internal_relocs;
1125
                elf_section_data (sec)->this_hdr.contents = contents;
1126
                symtab_hdr->contents = (unsigned char *) isymbuf;
1127
 
1128
                /* Get the opcode.  */
1129
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1130
 
1131
                /* All instructions with R_H8_DIR24A8 start with
1132
                   0x6a.  */
1133
                if (code != 0x6a)
1134
                  abort ();
1135
 
1136
                temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1137
 
1138
                /* If this is a mov.b instruction, clear the lower
1139
                   nibble, which contains the source/destination
1140
                   register number.  */
1141
                if ((temp_code & 0x30) != 0x30)
1142
                  temp_code &= 0xf0;
1143
 
1144
                switch (temp_code)
1145
                  {
1146
                  case 0x20:
1147
                    /* This is mov.b @aa:24/32,Rd.  */
1148
                    bfd_put_8 (abfd, (code & 0xf) | 0x20,
1149
                               contents + irel->r_offset - 2);
1150
                    break;
1151
                  case 0xa0:
1152
                    /* This is mov.b Rs,@aa:24/32.  */
1153
                    bfd_put_8 (abfd, (code & 0xf) | 0x30,
1154
                               contents + irel->r_offset - 2);
1155
                    break;
1156
                  case 0x38:
1157
                    /* This is a bit-maniputation instruction that
1158
                       stores one bit into memory, one of "bclr",
1159
                       "bist", "bnot", "bset", and "bst".  */
1160
                    bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1161
                    break;
1162
                  case 0x30:
1163
                    /* This is a bit-maniputation instruction that
1164
                       loads one bit from memory, one of "band",
1165
                       "biand", "bild", "bior", "bixor", "bld", "bor",
1166
                       "btst", and "bxor".  */
1167
                    bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1168
                    break;
1169
                  default:
1170
                    abort();
1171
                  }
1172
 
1173
                /* Fix the relocation's type.  */
1174
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1175
                                             R_H8_DIR8);
1176
                irel->r_offset--;
1177
 
1178
                /* Delete two bytes of data.  */
1179
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1180
                                                  irel->r_offset + 1, 4))
1181
                  goto error_return;
1182
 
1183
                /* That will change things, so, we should relax again.
1184
                   Note that this is not required, and it may be slow.  */
1185
                *again = TRUE;
1186
                break;
1187
              }
1188
          }
1189
 
1190
          /* Fall through.  */
1191
 
1192
          /* This is a 24-/32-bit absolute address in one of the
1193
             following instructions:
1194
 
1195
               "band", "bclr", "biand", "bild", "bior", "bist",
1196
               "bixor", "bld", "bnot", "bor", "bset", "bst", "btst",
1197
               "bxor", "ldc.w", "stc.w" and "mov.[bwl]"
1198
 
1199
             We may relax this into an 16-bit absolute address if it's
1200
             in the right range.  */
1201
        case R_H8_DIR32A16:
1202
          {
1203
            bfd_vma value;
1204
 
1205
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1206
            if (value <= 0x7fff || value >= 0xffff8000u)
1207
              {
1208
                unsigned char code;
1209
                unsigned char op0, op1, op2, op3;
1210
                unsigned char *op_ptr;
1211
 
1212
                /* Note that we've changed the relocs, section contents,
1213
                   etc.  */
1214
                elf_section_data (sec)->relocs = internal_relocs;
1215
                elf_section_data (sec)->this_hdr.contents = contents;
1216
                symtab_hdr->contents = (unsigned char *) isymbuf;
1217
 
1218
                if (irel->r_offset >= 4)
1219
                  {
1220
                    /* Check for 4-byte MOVA relaxation.  */
1221
                    int second_reloc = 0;
1222
 
1223
                    op_ptr = contents + irel->r_offset - 4;
1224
 
1225
                    if (last_reloc)
1226
                      {
1227
                        arelent bfd_reloc;
1228
                        reloc_howto_type *h;
1229
                        bfd_vma last_reloc_size;
1230
 
1231
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc);
1232
                        h = bfd_reloc.howto;
1233
                        last_reloc_size = 1 << h->size;
1234
                        if (last_reloc->r_offset + last_reloc_size
1235
                            == irel->r_offset)
1236
                          {
1237
                            op_ptr -= last_reloc_size;
1238
                            second_reloc = 1;
1239
                          }
1240
                      }
1241
                    if (irel < irelend)
1242
                      {
1243
                        Elf_Internal_Rela *next_reloc = irel + 1;
1244
                        arelent bfd_reloc;
1245
                        reloc_howto_type *h;
1246
                        bfd_vma next_reloc_size;
1247
 
1248
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc);
1249
                        h = bfd_reloc.howto;
1250
                        next_reloc_size = 1 << h->size;
1251
                        if (next_reloc->r_offset + next_reloc_size
1252
                            == irel->r_offset)
1253
                          {
1254
                            op_ptr -= next_reloc_size;
1255
                            second_reloc = 1;
1256
                          }
1257
                      }
1258
 
1259
                    op0 = bfd_get_8 (abfd, op_ptr + 0);
1260
                    op1 = bfd_get_8 (abfd, op_ptr + 1);
1261
                    op2 = bfd_get_8 (abfd, op_ptr + 2);
1262
                    op3 = bfd_get_8 (abfd, op_ptr + 3);
1263
 
1264
                    if (op0 == 0x01
1265
                        && (op1 & 0xdf) == 0x5f
1266
                        && (op2 & 0x40) == 0x40
1267
                        && (op3 & 0x80) == 0x80)
1268
                      {
1269
                        if ((op2 & 0x08) == 0)
1270
                          second_reloc = 1;
1271
 
1272
                        if (second_reloc)
1273
                          {
1274
                            op3 &= ~0x08;
1275
                            bfd_put_8 (abfd, op3, op_ptr + 3);
1276
                          }
1277
                        else
1278
                          {
1279
                            op2 &= ~0x08;
1280
                            bfd_put_8 (abfd, op2, op_ptr + 2);
1281
                          }
1282
                        goto r_h8_dir32a16_common;
1283
                      }
1284
                  }
1285
 
1286
                /* Now check for short version of MOVA.  */
1287
                op_ptr = contents + irel->r_offset - 2;
1288
                op0 = bfd_get_8 (abfd, op_ptr + 0);
1289
                op1 = bfd_get_8 (abfd, op_ptr + 1);
1290
 
1291
                if (op0 == 0x7a
1292
                    && (op1 & 0x88) == 0x80)
1293
                  {
1294
                    op1 |= 0x08;
1295
                    bfd_put_8 (abfd, op1, op_ptr + 1);
1296
                    goto r_h8_dir32a16_common;
1297
                  }
1298
 
1299
                /* Get the opcode.  */
1300
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1301
 
1302
                /* Fix the opcode.  For all the instructions that
1303
                   belong to this relaxation, we simply need to turn
1304
                   off bit 0x20 in the previous byte.  */
1305
                code &= ~0x20;
1306
 
1307
                bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1308
 
1309
              r_h8_dir32a16_common:
1310
                /* Fix the relocation's type.  */
1311
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1312
                                             R_H8_DIR16);
1313
 
1314
                /* Delete two bytes of data.  */
1315
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1316
                                                  irel->r_offset + 1, 2))
1317
                  goto error_return;
1318
 
1319
                /* That will change things, so, we should relax again.
1320
                   Note that this is not required, and it may be slow.  */
1321
                *again = TRUE;
1322
              }
1323
            break;
1324
          }
1325
 
1326
        default:
1327
          break;
1328
        }
1329
    }
1330
 
1331
  if (isymbuf != NULL
1332
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1333
    {
1334
      if (! link_info->keep_memory)
1335
        free (isymbuf);
1336
      else
1337
        symtab_hdr->contents = (unsigned char *) isymbuf;
1338
    }
1339
 
1340
  if (contents != NULL
1341
      && elf_section_data (sec)->this_hdr.contents != contents)
1342
    {
1343
      if (! link_info->keep_memory)
1344
        free (contents);
1345
      else
1346
        {
1347
          /* Cache the section contents for elf_link_input_bfd.  */
1348
          elf_section_data (sec)->this_hdr.contents = contents;
1349
        }
1350
    }
1351
 
1352
  if (internal_relocs != NULL
1353
      && elf_section_data (sec)->relocs != internal_relocs)
1354
    free (internal_relocs);
1355
 
1356
  return TRUE;
1357
 
1358
 error_return:
1359
  if (isymbuf != NULL
1360
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1361
    free (isymbuf);
1362
  if (contents != NULL
1363
      && elf_section_data (sec)->this_hdr.contents != contents)
1364
    free (contents);
1365
  if (internal_relocs != NULL
1366
      && elf_section_data (sec)->relocs != internal_relocs)
1367
    free (internal_relocs);
1368
  return FALSE;
1369
}
1370
 
1371
/* Delete some bytes from a section while relaxing.  */
1372
 
1373
static bfd_boolean
1374
elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
1375
{
1376
  Elf_Internal_Shdr *symtab_hdr;
1377
  unsigned int sec_shndx;
1378
  bfd_byte *contents;
1379
  Elf_Internal_Rela *irel, *irelend;
1380
  Elf_Internal_Sym *isym;
1381
  Elf_Internal_Sym *isymend;
1382
  bfd_vma toaddr;
1383
  struct elf_link_hash_entry **sym_hashes;
1384
  struct elf_link_hash_entry **end_hashes;
1385
  unsigned int symcount;
1386
 
1387
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1388
 
1389
  contents = elf_section_data (sec)->this_hdr.contents;
1390
 
1391
  toaddr = sec->size;
1392
 
1393
  irel = elf_section_data (sec)->relocs;
1394
  irelend = irel + sec->reloc_count;
1395
 
1396
  /* Actually delete the bytes.  */
1397
  memmove (contents + addr, contents + addr + count,
1398
           (size_t) (toaddr - addr - count));
1399
  sec->size -= count;
1400
 
1401
  /* Adjust all the relocs.  */
1402
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1403
    {
1404
      /* Get the new reloc address.  */
1405
      if ((irel->r_offset > addr
1406
           && irel->r_offset < toaddr))
1407
        irel->r_offset -= count;
1408
    }
1409
 
1410
  /* Adjust the local symbols defined in this section.  */
1411
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1412
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1413
  isymend = isym + symtab_hdr->sh_info;
1414
  for (; isym < isymend; isym++)
1415
    {
1416
      if (isym->st_shndx == sec_shndx
1417
          && isym->st_value > addr
1418
          && isym->st_value < toaddr)
1419
        isym->st_value -= count;
1420
    }
1421
 
1422
  /* Now adjust the global symbols defined in this section.  */
1423
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1424
              - symtab_hdr->sh_info);
1425
  sym_hashes = elf_sym_hashes (abfd);
1426
  end_hashes = sym_hashes + symcount;
1427
  for (; sym_hashes < end_hashes; sym_hashes++)
1428
    {
1429
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1430
      if ((sym_hash->root.type == bfd_link_hash_defined
1431
           || sym_hash->root.type == bfd_link_hash_defweak)
1432
          && sym_hash->root.u.def.section == sec
1433
          && sym_hash->root.u.def.value > addr
1434
          && sym_hash->root.u.def.value < toaddr)
1435
        {
1436
          sym_hash->root.u.def.value -= count;
1437
        }
1438
    }
1439
 
1440
  return TRUE;
1441
}
1442
 
1443
/* Return TRUE if a symbol exists at the given address, else return
1444
   FALSE.  */
1445
static bfd_boolean
1446
elf32_h8_symbol_address_p (bfd *abfd, asection *sec, bfd_vma addr)
1447
{
1448
  Elf_Internal_Shdr *symtab_hdr;
1449
  unsigned int sec_shndx;
1450
  Elf_Internal_Sym *isym;
1451
  Elf_Internal_Sym *isymend;
1452
  struct elf_link_hash_entry **sym_hashes;
1453
  struct elf_link_hash_entry **end_hashes;
1454
  unsigned int symcount;
1455
 
1456
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1457
 
1458
  /* Examine all the symbols.  */
1459
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1460
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1461
  isymend = isym + symtab_hdr->sh_info;
1462
  for (; isym < isymend; isym++)
1463
    {
1464
      if (isym->st_shndx == sec_shndx
1465
          && isym->st_value == addr)
1466
        return TRUE;
1467
    }
1468
 
1469
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1470
              - symtab_hdr->sh_info);
1471
  sym_hashes = elf_sym_hashes (abfd);
1472
  end_hashes = sym_hashes + symcount;
1473
  for (; sym_hashes < end_hashes; sym_hashes++)
1474
    {
1475
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1476
      if ((sym_hash->root.type == bfd_link_hash_defined
1477
           || sym_hash->root.type == bfd_link_hash_defweak)
1478
          && sym_hash->root.u.def.section == sec
1479
          && sym_hash->root.u.def.value == addr)
1480
        return TRUE;
1481
    }
1482
 
1483
  return FALSE;
1484
}
1485
 
1486
/* This is a version of bfd_generic_get_relocated_section_contents
1487
   which uses elf32_h8_relocate_section.  */
1488
 
1489
static bfd_byte *
1490
elf32_h8_get_relocated_section_contents (bfd *output_bfd,
1491
                                         struct bfd_link_info *link_info,
1492
                                         struct bfd_link_order *link_order,
1493
                                         bfd_byte *data,
1494
                                         bfd_boolean relocatable,
1495
                                         asymbol **symbols)
1496
{
1497
  Elf_Internal_Shdr *symtab_hdr;
1498
  asection *input_section = link_order->u.indirect.section;
1499
  bfd *input_bfd = input_section->owner;
1500
  asection **sections = NULL;
1501
  Elf_Internal_Rela *internal_relocs = NULL;
1502
  Elf_Internal_Sym *isymbuf = NULL;
1503
 
1504
  /* We only need to handle the case of relaxing, or of having a
1505
     particular set of section contents, specially.  */
1506
  if (relocatable
1507
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1508
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1509
                                                       link_order, data,
1510
                                                       relocatable,
1511
                                                       symbols);
1512
 
1513
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1514
 
1515
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1516
          (size_t) input_section->size);
1517
 
1518
  if ((input_section->flags & SEC_RELOC) != 0
1519
      && input_section->reloc_count > 0)
1520
    {
1521
      asection **secpp;
1522
      Elf_Internal_Sym *isym, *isymend;
1523
      bfd_size_type amt;
1524
 
1525
      internal_relocs = (_bfd_elf_link_read_relocs
1526
                         (input_bfd, input_section, (PTR) NULL,
1527
                          (Elf_Internal_Rela *) NULL, FALSE));
1528
      if (internal_relocs == NULL)
1529
        goto error_return;
1530
 
1531
      if (symtab_hdr->sh_info != 0)
1532
        {
1533
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1534
          if (isymbuf == NULL)
1535
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1536
                                            symtab_hdr->sh_info, 0,
1537
                                            NULL, NULL, NULL);
1538
          if (isymbuf == NULL)
1539
            goto error_return;
1540
        }
1541
 
1542
      amt = symtab_hdr->sh_info;
1543
      amt *= sizeof (asection *);
1544
      sections = (asection **) bfd_malloc (amt);
1545
      if (sections == NULL && amt != 0)
1546
        goto error_return;
1547
 
1548
      isymend = isymbuf + symtab_hdr->sh_info;
1549
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1550
        {
1551
          asection *isec;
1552
 
1553
          if (isym->st_shndx == SHN_UNDEF)
1554
            isec = bfd_und_section_ptr;
1555
          else if (isym->st_shndx == SHN_ABS)
1556
            isec = bfd_abs_section_ptr;
1557
          else if (isym->st_shndx == SHN_COMMON)
1558
            isec = bfd_com_section_ptr;
1559
          else
1560
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1561
 
1562
          *secpp = isec;
1563
        }
1564
 
1565
      if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
1566
                                       input_section, data, internal_relocs,
1567
                                       isymbuf, sections))
1568
        goto error_return;
1569
 
1570
      if (sections != NULL)
1571
        free (sections);
1572
      if (isymbuf != NULL
1573
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1574
        free (isymbuf);
1575
      if (elf_section_data (input_section)->relocs != internal_relocs)
1576
        free (internal_relocs);
1577
    }
1578
 
1579
  return data;
1580
 
1581
 error_return:
1582
  if (sections != NULL)
1583
    free (sections);
1584
  if (isymbuf != NULL
1585
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1586
    free (isymbuf);
1587
  if (internal_relocs != NULL
1588
      && elf_section_data (input_section)->relocs != internal_relocs)
1589
    free (internal_relocs);
1590
  return NULL;
1591
}
1592
 
1593
 
1594
#define TARGET_BIG_SYM                  bfd_elf32_h8300_vec
1595
#define TARGET_BIG_NAME                 "elf32-h8300"
1596
#define ELF_ARCH                        bfd_arch_h8300
1597
#define ELF_MACHINE_CODE                EM_H8_300
1598
#define ELF_MAXPAGESIZE                 0x1
1599
#define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
1600
#define bfd_elf32_bfd_reloc_name_lookup elf32_h8_reloc_name_lookup
1601
#define elf_info_to_howto               elf32_h8_info_to_howto
1602
#define elf_info_to_howto_rel           elf32_h8_info_to_howto_rel
1603
 
1604
/* So we can set/examine bits in e_flags to get the specific
1605
   H8 architecture in use.  */
1606
#define elf_backend_final_write_processing \
1607
  elf32_h8_final_write_processing
1608
#define elf_backend_object_p \
1609
  elf32_h8_object_p
1610
#define bfd_elf32_bfd_merge_private_bfd_data \
1611
  elf32_h8_merge_private_bfd_data
1612
 
1613
/* ??? when elf_backend_relocate_section is not defined, elf32-target.h
1614
   defaults to using _bfd_generic_link_hash_table_create, but
1615
   bfd_elf_size_dynamic_sections uses
1616
   dynobj = elf_hash_table (info)->dynobj;
1617
   and thus requires an elf hash table.  */
1618
#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
1619
 
1620
/* Use an H8 specific linker, not the ELF generic linker.  */
1621
#define elf_backend_relocate_section elf32_h8_relocate_section
1622
#define elf_backend_rela_normal         1
1623
#define elf_backend_can_gc_sections     1
1624
 
1625
/* And relaxing stuff.  */
1626
#define bfd_elf32_bfd_relax_section     elf32_h8_relax_section
1627
#define bfd_elf32_bfd_get_relocated_section_contents \
1628
                                elf32_h8_get_relocated_section_contents
1629
 
1630
#define elf_symbol_leading_char '_'
1631
 
1632
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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