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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [bfd/] [elf32-h8300.c] - Blame information for rev 816

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

Line No. Rev Author Line
1 330 jeremybenn
/* 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
        {
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
 
728
        elf32_h8_info_to_howto (abfd, &bfd_reloc, irel);
729
      }
730
      /* Keep track of the previous reloc so that we can delete
731
         some long jumps created by the compiler.  */
732
      if (irel != internal_relocs)
733
        last_reloc = irel - 1;
734
 
735
      if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
736
          && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
737
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
738
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
739
          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
740
        continue;
741
 
742
      /* Get the section contents if we haven't done so already.  */
743
      if (contents == NULL)
744
        {
745
          /* Get cached copy if it exists.  */
746
          if (elf_section_data (sec)->this_hdr.contents != NULL)
747
            contents = elf_section_data (sec)->this_hdr.contents;
748
          else
749
            {
750
              /* Go get them off disk.  */
751
              if (!bfd_malloc_and_get_section (abfd, sec, &contents))
752
                goto error_return;
753
            }
754
        }
755
 
756
      /* Read this BFD's local symbols if we haven't done so already.  */
757
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
758
        {
759
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
760
          if (isymbuf == NULL)
761
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
762
                                            symtab_hdr->sh_info, 0,
763
                                            NULL, NULL, NULL);
764
          if (isymbuf == NULL)
765
            goto error_return;
766
        }
767
 
768
      /* Get the value of the symbol referred to by the reloc.  */
769
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
770
        {
771
          /* A local symbol.  */
772
          Elf_Internal_Sym *isym;
773
          asection *sym_sec;
774
 
775
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
776
          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
777
          symval = isym->st_value;
778
          /* If the reloc is absolute, it will not have
779
             a symbol or section associated with it.  */
780
          if (sym_sec)
781
            symval += sym_sec->output_section->vma
782
              + sym_sec->output_offset;
783
        }
784
      else
785
        {
786
          unsigned long indx;
787
          struct elf_link_hash_entry *h;
788
 
789
          /* An external symbol.  */
790
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
791
          h = elf_sym_hashes (abfd)[indx];
792
          BFD_ASSERT (h != NULL);
793
          if (h->root.type != bfd_link_hash_defined
794
              && h->root.type != bfd_link_hash_defweak)
795
            {
796
              /* This appears to be a reference to an undefined
797
                 symbol.  Just ignore it--it will be caught by the
798
                 regular reloc processing.  */
799
              continue;
800
            }
801
 
802
          symval = (h->root.u.def.value
803
                    + h->root.u.def.section->output_section->vma
804
                    + h->root.u.def.section->output_offset);
805
        }
806
 
807
      /* For simplicity of coding, we are going to modify the section
808
         contents, the section relocs, and the BFD symbol table.  We
809
         must tell the rest of the code not to free up this
810
         information.  It would be possible to instead create a table
811
         of changes which have to be made, as is done in coff-mips.c;
812
         that would be more work, but would require less memory when
813
         the linker is run.  */
814
      switch (ELF32_R_TYPE (irel->r_info))
815
        {
816
        /* Try to turn a 24-bit absolute branch/call into an 8-bit
817
           pc-relative branch/call.  */
818
        case R_H8_DIR24R8:
819
          {
820
            bfd_vma value = symval + irel->r_addend;
821
            bfd_vma dot, gap;
822
 
823
            /* Get the address of this instruction.  */
824
            dot = (sec->output_section->vma
825
                   + sec->output_offset + irel->r_offset - 1);
826
 
827
            /* Compute the distance from this insn to the branch target.  */
828
            gap = value - dot;
829
 
830
            /* If the distance is within -126..+130 inclusive, then we can
831
               relax this jump.  +130 is valid since the target will move
832
               two bytes closer if we do relax this branch.  */
833
            if ((int) gap >= -126 && (int) gap <= 130)
834
              {
835
                unsigned char code;
836
 
837
                /* Note that we've changed the relocs, section contents,
838
                   etc.  */
839
                elf_section_data (sec)->relocs = internal_relocs;
840
                elf_section_data (sec)->this_hdr.contents = contents;
841
                symtab_hdr->contents = (unsigned char *) isymbuf;
842
 
843
                /* Get the instruction code being relaxed.  */
844
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
845
 
846
                /* If the previous instruction conditionally jumped around
847
                   this instruction, we may be able to reverse the condition
848
                   and redirect the previous instruction to the target of
849
                   this instruction.
850
 
851
                   Such sequences are used by the compiler to deal with
852
                   long conditional branches.
853
 
854
                   Only perform this optimisation for jumps (code 0x5a) not
855
                   subroutine calls, as otherwise it could transform:
856
 
857
                                     mov.w   r0,r0
858
                                     beq     .L1
859
                                     jsr     @_bar
860
                              .L1:   rts
861
                              _bar:  rts
862
                   into:
863
                                     mov.w   r0,r0
864
                                     bne     _bar
865
                                     rts
866
                              _bar:  rts
867
 
868
                   which changes the call (jsr) into a branch (bne).  */
869
                if (code == 0x5a
870
                    && (int) gap <= 130
871
                    && (int) gap >= -128
872
                    && last_reloc
873
                    && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
874
                    && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
875
                  {
876
                    bfd_vma last_value;
877
                    asection *last_sym_sec;
878
                    Elf_Internal_Sym *last_sym;
879
 
880
                    /* We will need to examine the symbol used by the
881
                       previous relocation.  */
882
 
883
                    last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
884
                    last_sym_sec
885
                      = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
886
                    last_value = (last_sym->st_value
887
                                  + last_sym_sec->output_section->vma
888
                                  + last_sym_sec->output_offset);
889
 
890
                    /* Verify that the previous relocation was for a
891
                       branch around this instruction and that no symbol
892
                       exists at the current location.  */
893
                    if (last_value == dot + 4
894
                        && last_reloc->r_offset + 2 == irel->r_offset
895
                        && ! elf32_h8_symbol_address_p (abfd, sec, dot))
896
                      {
897
                        /* We can eliminate this jump.  Twiddle the
898
                           previous relocation as necessary.  */
899
                        irel->r_info
900
                          = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
901
                                          ELF32_R_TYPE (R_H8_NONE));
902
 
903
                        last_reloc->r_info
904
                          = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
905
                                          ELF32_R_TYPE (R_H8_PCREL8));
906
                        last_reloc->r_addend = irel->r_addend;
907
 
908
                        code = bfd_get_8 (abfd,
909
                                          contents + last_reloc->r_offset - 1);
910
                        code ^= 1;
911
                        bfd_put_8 (abfd,
912
                                   code,
913
                        contents + last_reloc->r_offset - 1);
914
 
915
                        /* Delete four bytes of data.  */
916
                        if (!elf32_h8_relax_delete_bytes (abfd, sec,
917
                                                          irel->r_offset - 1,
918
                                                          4))
919
                          goto error_return;
920
 
921
                        *again = TRUE;
922
                        break;
923
                      }
924
                  }
925
 
926
                if (code == 0x5e)
927
                  /* This is jsr.  */
928
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
929
                else if (code == 0x5a)
930
                  /* This is jmp.  */
931
                  bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
932
                else
933
                  abort ();
934
 
935
                /* Fix the relocation's type.  */
936
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
937
                                             R_H8_PCREL8);
938
 
939
                /* Delete two bytes of data.  */
940
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
941
                                                  irel->r_offset + 1, 2))
942
                  goto error_return;
943
 
944
                /* That will change things, so, we should relax again.
945
                   Note that this is not required, and it may be slow.  */
946
                *again = TRUE;
947
              }
948
            break;
949
          }
950
 
951
        /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
952
           branch.  */
953
        case R_H8_PCREL16:
954
          {
955
            bfd_vma value = symval + irel->r_addend;
956
            bfd_vma dot;
957
            bfd_vma gap;
958
 
959
            /* Get the address of this instruction.  */
960
            dot = (sec->output_section->vma
961
                   + sec->output_offset
962
                   + irel->r_offset - 2);
963
 
964
            gap = value - dot;
965
 
966
            /* If the distance is within -126..+130 inclusive, then we can
967
               relax this jump.  +130 is valid since the target will move
968
               two bytes closer if we do relax this branch.  */
969
            if ((int) gap >= -126 && (int) gap <= 130)
970
              {
971
                unsigned char code;
972
 
973
                /* Note that we've changed the relocs, section contents,
974
                   etc.  */
975
                elf_section_data (sec)->relocs = internal_relocs;
976
                elf_section_data (sec)->this_hdr.contents = contents;
977
                symtab_hdr->contents = (unsigned char *) isymbuf;
978
 
979
                /* Get the opcode.  */
980
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
981
 
982
                if (code == 0x58)
983
                  {
984
                    /* bCC:16 -> bCC:8 */
985
                    /* Get the second byte of the original insn, which
986
                       contains the condition code.  */
987
                    code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
988
 
989
                    /* Compute the fisrt byte of the relaxed
990
                       instruction.  The original sequence 0x58 0xX0
991
                       is relaxed to 0x4X, where X represents the
992
                       condition code.  */
993
                    code &= 0xf0;
994
                    code >>= 4;
995
                    code |= 0x40;
996
                    bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
997
                  }
998
                else if (code == 0x5c)
999
                  /* This is bsr.  */
1000
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
1001
                else
1002
                  /* Might be MOVSD.  */
1003
                  break;
1004
 
1005
                /* Fix the relocation's type.  */
1006
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1007
                                             R_H8_PCREL8);
1008
                irel->r_offset--;
1009
 
1010
                /* Delete two bytes of data.  */
1011
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1012
                                                  irel->r_offset + 1, 2))
1013
                  goto error_return;
1014
 
1015
                /* That will change things, so, we should relax again.
1016
                   Note that this is not required, and it may be slow.  */
1017
                *again = TRUE;
1018
              }
1019
            break;
1020
          }
1021
 
1022
        /* This is a 16-bit absolute address in one of the following
1023
           instructions:
1024
 
1025
             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1026
             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1027
             "mov.b"
1028
 
1029
           We may relax this into an 8-bit absolute address if it's in
1030
           the right range.  */
1031
        case R_H8_DIR16A8:
1032
          {
1033
            bfd_vma value;
1034
 
1035
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1036
            if (value >= 0xffffff00u)
1037
              {
1038
                unsigned char code;
1039
                unsigned char temp_code;
1040
 
1041
                /* Note that we've changed the relocs, section contents,
1042
                   etc.  */
1043
                elf_section_data (sec)->relocs = internal_relocs;
1044
                elf_section_data (sec)->this_hdr.contents = contents;
1045
                symtab_hdr->contents = (unsigned char *) isymbuf;
1046
 
1047
                /* Get the opcode.  */
1048
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1049
 
1050
                /* All instructions with R_H8_DIR16A8 start with
1051
                   0x6a.  */
1052
                if (code != 0x6a)
1053
                  abort ();
1054
 
1055
                temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1056
                /* If this is a mov.b instruction, clear the lower
1057
                   nibble, which contains the source/destination
1058
                   register number.  */
1059
                if ((temp_code & 0x10) != 0x10)
1060
                  temp_code &= 0xf0;
1061
 
1062
                switch (temp_code)
1063
                  {
1064
                  case 0x00:
1065
                    /* This is mov.b @aa:16,Rd.  */
1066
                    bfd_put_8 (abfd, (code & 0xf) | 0x20,
1067
                               contents + irel->r_offset - 2);
1068
                    break;
1069
                  case 0x80:
1070
                    /* This is mov.b Rs,@aa:16.  */
1071
                    bfd_put_8 (abfd, (code & 0xf) | 0x30,
1072
                               contents + irel->r_offset - 2);
1073
                    break;
1074
                  case 0x18:
1075
                    /* This is a bit-maniputation instruction that
1076
                       stores one bit into memory, one of "bclr",
1077
                       "bist", "bnot", "bset", and "bst".  */
1078
                    bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1079
                    break;
1080
                  case 0x10:
1081
                    /* This is a bit-maniputation instruction that
1082
                       loads one bit from memory, one of "band",
1083
                       "biand", "bild", "bior", "bixor", "bld", "bor",
1084
                       "btst", and "bxor".  */
1085
                    bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1086
                    break;
1087
                  default:
1088
                    abort ();
1089
                  }
1090
 
1091
                /* Fix the relocation's type.  */
1092
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1093
                                             R_H8_DIR8);
1094
 
1095
                /* Move the relocation.  */
1096
                irel->r_offset--;
1097
 
1098
                /* Delete two bytes of data.  */
1099
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1100
                                                  irel->r_offset + 1, 2))
1101
                  goto error_return;
1102
 
1103
                /* That will change things, so, we should relax again.
1104
                   Note that this is not required, and it may be slow.  */
1105
                *again = TRUE;
1106
              }
1107
            break;
1108
          }
1109
 
1110
        /* This is a 24-bit absolute address in one of the following
1111
           instructions:
1112
 
1113
             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1114
             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1115
             "mov.b"
1116
 
1117
           We may relax this into an 8-bit absolute address if it's in
1118
           the right range.  */
1119
        case R_H8_DIR24A8:
1120
          {
1121
            bfd_vma value;
1122
 
1123
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1124
            if (value >= 0xffffff00u)
1125
              {
1126
                unsigned char code;
1127
                unsigned char temp_code;
1128
 
1129
                /* Note that we've changed the relocs, section contents,
1130
                   etc.  */
1131
                elf_section_data (sec)->relocs = internal_relocs;
1132
                elf_section_data (sec)->this_hdr.contents = contents;
1133
                symtab_hdr->contents = (unsigned char *) isymbuf;
1134
 
1135
                /* Get the opcode.  */
1136
                code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1137
 
1138
                /* All instructions with R_H8_DIR24A8 start with
1139
                   0x6a.  */
1140
                if (code != 0x6a)
1141
                  abort ();
1142
 
1143
                temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1144
 
1145
                /* If this is a mov.b instruction, clear the lower
1146
                   nibble, which contains the source/destination
1147
                   register number.  */
1148
                if ((temp_code & 0x30) != 0x30)
1149
                  temp_code &= 0xf0;
1150
 
1151
                switch (temp_code)
1152
                  {
1153
                  case 0x20:
1154
                    /* This is mov.b @aa:24/32,Rd.  */
1155
                    bfd_put_8 (abfd, (code & 0xf) | 0x20,
1156
                               contents + irel->r_offset - 2);
1157
                    break;
1158
                  case 0xa0:
1159
                    /* This is mov.b Rs,@aa:24/32.  */
1160
                    bfd_put_8 (abfd, (code & 0xf) | 0x30,
1161
                               contents + irel->r_offset - 2);
1162
                    break;
1163
                  case 0x38:
1164
                    /* This is a bit-maniputation instruction that
1165
                       stores one bit into memory, one of "bclr",
1166
                       "bist", "bnot", "bset", and "bst".  */
1167
                    bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1168
                    break;
1169
                  case 0x30:
1170
                    /* This is a bit-maniputation instruction that
1171
                       loads one bit from memory, one of "band",
1172
                       "biand", "bild", "bior", "bixor", "bld", "bor",
1173
                       "btst", and "bxor".  */
1174
                    bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1175
                    break;
1176
                  default:
1177
                    abort();
1178
                  }
1179
 
1180
                /* Fix the relocation's type.  */
1181
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1182
                                             R_H8_DIR8);
1183
                irel->r_offset--;
1184
 
1185
                /* Delete two bytes of data.  */
1186
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1187
                                                  irel->r_offset + 1, 4))
1188
                  goto error_return;
1189
 
1190
                /* That will change things, so, we should relax again.
1191
                   Note that this is not required, and it may be slow.  */
1192
                *again = TRUE;
1193
                break;
1194
              }
1195
          }
1196
 
1197
          /* Fall through.  */
1198
 
1199
          /* This is a 24-/32-bit absolute address in one of the
1200
             following instructions:
1201
 
1202
               "band", "bclr", "biand", "bild", "bior", "bist",
1203
               "bixor", "bld", "bnot", "bor", "bset", "bst", "btst",
1204
               "bxor", "ldc.w", "stc.w" and "mov.[bwl]"
1205
 
1206
             We may relax this into an 16-bit absolute address if it's
1207
             in the right range.  */
1208
        case R_H8_DIR32A16:
1209
          {
1210
            bfd_vma value;
1211
 
1212
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1213
            if (value <= 0x7fff || value >= 0xffff8000u)
1214
              {
1215
                unsigned char code;
1216
                unsigned char op0, op1, op2, op3;
1217
                unsigned char *op_ptr;
1218
 
1219
                /* Note that we've changed the relocs, section contents,
1220
                   etc.  */
1221
                elf_section_data (sec)->relocs = internal_relocs;
1222
                elf_section_data (sec)->this_hdr.contents = contents;
1223
                symtab_hdr->contents = (unsigned char *) isymbuf;
1224
 
1225
                if (irel->r_offset >= 4)
1226
                  {
1227
                    /* Check for 4-byte MOVA relaxation.  */
1228
                    int second_reloc = 0;
1229
 
1230
                    op_ptr = contents + irel->r_offset - 4;
1231
 
1232
                    if (last_reloc)
1233
                      {
1234
                        arelent bfd_reloc;
1235
                        reloc_howto_type *h;
1236
                        bfd_vma last_reloc_size;
1237
 
1238
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc);
1239
                        h = bfd_reloc.howto;
1240
                        last_reloc_size = 1 << h->size;
1241
                        if (last_reloc->r_offset + last_reloc_size
1242
                            == irel->r_offset)
1243
                          {
1244
                            op_ptr -= last_reloc_size;
1245
                            second_reloc = 1;
1246
                          }
1247
                      }
1248
                    if (irel < irelend)
1249
                      {
1250
                        Elf_Internal_Rela *next_reloc = irel + 1;
1251
                        arelent bfd_reloc;
1252
                        reloc_howto_type *h;
1253
                        bfd_vma next_reloc_size;
1254
 
1255
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc);
1256
                        h = bfd_reloc.howto;
1257
                        next_reloc_size = 1 << h->size;
1258
                        if (next_reloc->r_offset + next_reloc_size
1259
                            == irel->r_offset)
1260
                          {
1261
                            op_ptr -= next_reloc_size;
1262
                            second_reloc = 1;
1263
                          }
1264
                      }
1265
 
1266
                    op0 = bfd_get_8 (abfd, op_ptr + 0);
1267
                    op1 = bfd_get_8 (abfd, op_ptr + 1);
1268
                    op2 = bfd_get_8 (abfd, op_ptr + 2);
1269
                    op3 = bfd_get_8 (abfd, op_ptr + 3);
1270
 
1271
                    if (op0 == 0x01
1272
                        && (op1 & 0xdf) == 0x5f
1273
                        && (op2 & 0x40) == 0x40
1274
                        && (op3 & 0x80) == 0x80)
1275
                      {
1276
                        if ((op2 & 0x08) == 0)
1277
                          second_reloc = 1;
1278
 
1279
                        if (second_reloc)
1280
                          {
1281
                            op3 &= ~0x08;
1282
                            bfd_put_8 (abfd, op3, op_ptr + 3);
1283
                          }
1284
                        else
1285
                          {
1286
                            op2 &= ~0x08;
1287
                            bfd_put_8 (abfd, op2, op_ptr + 2);
1288
                          }
1289
                        goto r_h8_dir32a16_common;
1290
                      }
1291
                  }
1292
 
1293
                /* Now check for short version of MOVA.  */
1294
                op_ptr = contents + irel->r_offset - 2;
1295
                op0 = bfd_get_8 (abfd, op_ptr + 0);
1296
                op1 = bfd_get_8 (abfd, op_ptr + 1);
1297
 
1298
                if (op0 == 0x7a
1299
                    && (op1 & 0x88) == 0x80)
1300
                  {
1301
                    op1 |= 0x08;
1302
                    bfd_put_8 (abfd, op1, op_ptr + 1);
1303
                    goto r_h8_dir32a16_common;
1304
                  }
1305
 
1306
                /* Get the opcode.  */
1307
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1308
 
1309
                /* Fix the opcode.  For all the instructions that
1310
                   belong to this relaxation, we simply need to turn
1311
                   off bit 0x20 in the previous byte.  */
1312
                code &= ~0x20;
1313
 
1314
                bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1315
 
1316
              r_h8_dir32a16_common:
1317
                /* Fix the relocation's type.  */
1318
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1319
                                             R_H8_DIR16);
1320
 
1321
                /* Delete two bytes of data.  */
1322
                if (!elf32_h8_relax_delete_bytes (abfd, sec,
1323
                                                  irel->r_offset + 1, 2))
1324
                  goto error_return;
1325
 
1326
                /* That will change things, so, we should relax again.
1327
                   Note that this is not required, and it may be slow.  */
1328
                *again = TRUE;
1329
              }
1330
            break;
1331
          }
1332
 
1333
        default:
1334
          break;
1335
        }
1336
    }
1337
 
1338
  if (isymbuf != NULL
1339
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1340
    {
1341
      if (! link_info->keep_memory)
1342
        free (isymbuf);
1343
      else
1344
        symtab_hdr->contents = (unsigned char *) isymbuf;
1345
    }
1346
 
1347
  if (contents != NULL
1348
      && elf_section_data (sec)->this_hdr.contents != contents)
1349
    {
1350
      if (! link_info->keep_memory)
1351
        free (contents);
1352
      else
1353
        {
1354
          /* Cache the section contents for elf_link_input_bfd.  */
1355
          elf_section_data (sec)->this_hdr.contents = contents;
1356
        }
1357
    }
1358
 
1359
  if (internal_relocs != NULL
1360
      && elf_section_data (sec)->relocs != internal_relocs)
1361
    free (internal_relocs);
1362
 
1363
  return TRUE;
1364
 
1365
 error_return:
1366
  if (isymbuf != NULL
1367
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1368
    free (isymbuf);
1369
  if (contents != NULL
1370
      && elf_section_data (sec)->this_hdr.contents != contents)
1371
    free (contents);
1372
  if (internal_relocs != NULL
1373
      && elf_section_data (sec)->relocs != internal_relocs)
1374
    free (internal_relocs);
1375
  return FALSE;
1376
}
1377
 
1378
/* Delete some bytes from a section while relaxing.  */
1379
 
1380
static bfd_boolean
1381
elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
1382
{
1383
  Elf_Internal_Shdr *symtab_hdr;
1384
  unsigned int sec_shndx;
1385
  bfd_byte *contents;
1386
  Elf_Internal_Rela *irel, *irelend;
1387
  Elf_Internal_Sym *isym;
1388
  Elf_Internal_Sym *isymend;
1389
  bfd_vma toaddr;
1390
  struct elf_link_hash_entry **sym_hashes;
1391
  struct elf_link_hash_entry **end_hashes;
1392
  unsigned int symcount;
1393
 
1394
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1395
 
1396
  contents = elf_section_data (sec)->this_hdr.contents;
1397
 
1398
  toaddr = sec->size;
1399
 
1400
  irel = elf_section_data (sec)->relocs;
1401
  irelend = irel + sec->reloc_count;
1402
 
1403
  /* Actually delete the bytes.  */
1404
  memmove (contents + addr, contents + addr + count,
1405
           (size_t) (toaddr - addr - count));
1406
  sec->size -= count;
1407
 
1408
  /* Adjust all the relocs.  */
1409
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1410
    {
1411
      /* Get the new reloc address.  */
1412
      if ((irel->r_offset > addr
1413
           && irel->r_offset < toaddr))
1414
        irel->r_offset -= count;
1415
    }
1416
 
1417
  /* Adjust the local symbols defined in this section.  */
1418
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1419
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1420
  isymend = isym + symtab_hdr->sh_info;
1421
  for (; isym < isymend; isym++)
1422
    {
1423
      if (isym->st_shndx == sec_shndx
1424
          && isym->st_value > addr
1425
          && isym->st_value < toaddr)
1426
        isym->st_value -= count;
1427
    }
1428
 
1429
  /* Now adjust the global symbols defined in this section.  */
1430
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1431
              - symtab_hdr->sh_info);
1432
  sym_hashes = elf_sym_hashes (abfd);
1433
  end_hashes = sym_hashes + symcount;
1434
  for (; sym_hashes < end_hashes; sym_hashes++)
1435
    {
1436
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1437
      if ((sym_hash->root.type == bfd_link_hash_defined
1438
           || sym_hash->root.type == bfd_link_hash_defweak)
1439
          && sym_hash->root.u.def.section == sec
1440
          && sym_hash->root.u.def.value > addr
1441
          && sym_hash->root.u.def.value < toaddr)
1442
        {
1443
          sym_hash->root.u.def.value -= count;
1444
        }
1445
    }
1446
 
1447
  return TRUE;
1448
}
1449
 
1450
/* Return TRUE if a symbol exists at the given address, else return
1451
   FALSE.  */
1452
static bfd_boolean
1453
elf32_h8_symbol_address_p (bfd *abfd, asection *sec, bfd_vma addr)
1454
{
1455
  Elf_Internal_Shdr *symtab_hdr;
1456
  unsigned int sec_shndx;
1457
  Elf_Internal_Sym *isym;
1458
  Elf_Internal_Sym *isymend;
1459
  struct elf_link_hash_entry **sym_hashes;
1460
  struct elf_link_hash_entry **end_hashes;
1461
  unsigned int symcount;
1462
 
1463
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1464
 
1465
  /* Examine all the symbols.  */
1466
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1467
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1468
  isymend = isym + symtab_hdr->sh_info;
1469
  for (; isym < isymend; isym++)
1470
    {
1471
      if (isym->st_shndx == sec_shndx
1472
          && isym->st_value == addr)
1473
        return TRUE;
1474
    }
1475
 
1476
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1477
              - symtab_hdr->sh_info);
1478
  sym_hashes = elf_sym_hashes (abfd);
1479
  end_hashes = sym_hashes + symcount;
1480
  for (; sym_hashes < end_hashes; sym_hashes++)
1481
    {
1482
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1483
      if ((sym_hash->root.type == bfd_link_hash_defined
1484
           || sym_hash->root.type == bfd_link_hash_defweak)
1485
          && sym_hash->root.u.def.section == sec
1486
          && sym_hash->root.u.def.value == addr)
1487
        return TRUE;
1488
    }
1489
 
1490
  return FALSE;
1491
}
1492
 
1493
/* This is a version of bfd_generic_get_relocated_section_contents
1494
   which uses elf32_h8_relocate_section.  */
1495
 
1496
static bfd_byte *
1497
elf32_h8_get_relocated_section_contents (bfd *output_bfd,
1498
                                         struct bfd_link_info *link_info,
1499
                                         struct bfd_link_order *link_order,
1500
                                         bfd_byte *data,
1501
                                         bfd_boolean relocatable,
1502
                                         asymbol **symbols)
1503
{
1504
  Elf_Internal_Shdr *symtab_hdr;
1505
  asection *input_section = link_order->u.indirect.section;
1506
  bfd *input_bfd = input_section->owner;
1507
  asection **sections = NULL;
1508
  Elf_Internal_Rela *internal_relocs = NULL;
1509
  Elf_Internal_Sym *isymbuf = NULL;
1510
 
1511
  /* We only need to handle the case of relaxing, or of having a
1512
     particular set of section contents, specially.  */
1513
  if (relocatable
1514
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1515
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1516
                                                       link_order, data,
1517
                                                       relocatable,
1518
                                                       symbols);
1519
 
1520
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1521
 
1522
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1523
          (size_t) input_section->size);
1524
 
1525
  if ((input_section->flags & SEC_RELOC) != 0
1526
      && input_section->reloc_count > 0)
1527
    {
1528
      asection **secpp;
1529
      Elf_Internal_Sym *isym, *isymend;
1530
      bfd_size_type amt;
1531
 
1532
      internal_relocs = (_bfd_elf_link_read_relocs
1533
                         (input_bfd, input_section, (PTR) NULL,
1534
                          (Elf_Internal_Rela *) NULL, FALSE));
1535
      if (internal_relocs == NULL)
1536
        goto error_return;
1537
 
1538
      if (symtab_hdr->sh_info != 0)
1539
        {
1540
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1541
          if (isymbuf == NULL)
1542
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1543
                                            symtab_hdr->sh_info, 0,
1544
                                            NULL, NULL, NULL);
1545
          if (isymbuf == NULL)
1546
            goto error_return;
1547
        }
1548
 
1549
      amt = symtab_hdr->sh_info;
1550
      amt *= sizeof (asection *);
1551
      sections = (asection **) bfd_malloc (amt);
1552
      if (sections == NULL && amt != 0)
1553
        goto error_return;
1554
 
1555
      isymend = isymbuf + symtab_hdr->sh_info;
1556
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1557
        {
1558
          asection *isec;
1559
 
1560
          if (isym->st_shndx == SHN_UNDEF)
1561
            isec = bfd_und_section_ptr;
1562
          else if (isym->st_shndx == SHN_ABS)
1563
            isec = bfd_abs_section_ptr;
1564
          else if (isym->st_shndx == SHN_COMMON)
1565
            isec = bfd_com_section_ptr;
1566
          else
1567
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1568
 
1569
          *secpp = isec;
1570
        }
1571
 
1572
      if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
1573
                                       input_section, data, internal_relocs,
1574
                                       isymbuf, sections))
1575
        goto error_return;
1576
 
1577
      if (sections != NULL)
1578
        free (sections);
1579
      if (isymbuf != NULL
1580
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1581
        free (isymbuf);
1582
      if (elf_section_data (input_section)->relocs != internal_relocs)
1583
        free (internal_relocs);
1584
    }
1585
 
1586
  return data;
1587
 
1588
 error_return:
1589
  if (sections != NULL)
1590
    free (sections);
1591
  if (isymbuf != NULL
1592
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1593
    free (isymbuf);
1594
  if (internal_relocs != NULL
1595
      && elf_section_data (input_section)->relocs != internal_relocs)
1596
    free (internal_relocs);
1597
  return NULL;
1598
}
1599
 
1600
 
1601
#define TARGET_BIG_SYM                  bfd_elf32_h8300_vec
1602
#define TARGET_BIG_NAME                 "elf32-h8300"
1603
#define ELF_ARCH                        bfd_arch_h8300
1604
#define ELF_MACHINE_CODE                EM_H8_300
1605
#define ELF_MAXPAGESIZE                 0x1
1606
#define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
1607
#define bfd_elf32_bfd_reloc_name_lookup elf32_h8_reloc_name_lookup
1608
#define elf_info_to_howto               elf32_h8_info_to_howto
1609
#define elf_info_to_howto_rel           elf32_h8_info_to_howto_rel
1610
 
1611
/* So we can set/examine bits in e_flags to get the specific
1612
   H8 architecture in use.  */
1613
#define elf_backend_final_write_processing \
1614
  elf32_h8_final_write_processing
1615
#define elf_backend_object_p \
1616
  elf32_h8_object_p
1617
#define bfd_elf32_bfd_merge_private_bfd_data \
1618
  elf32_h8_merge_private_bfd_data
1619
 
1620
/* ??? when elf_backend_relocate_section is not defined, elf32-target.h
1621
   defaults to using _bfd_generic_link_hash_table_create, but
1622
   bfd_elf_size_dynamic_sections uses
1623
   dynobj = elf_hash_table (info)->dynobj;
1624
   and thus requires an elf hash table.  */
1625
#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
1626
 
1627
/* Use an H8 specific linker, not the ELF generic linker.  */
1628
#define elf_backend_relocate_section elf32_h8_relocate_section
1629
#define elf_backend_rela_normal         1
1630
#define elf_backend_can_gc_sections     1
1631
 
1632
/* And relaxing stuff.  */
1633
#define bfd_elf32_bfd_relax_section     elf32_h8_relax_section
1634
#define bfd_elf32_bfd_get_relocated_section_contents \
1635
                                elf32_h8_get_relocated_section_contents
1636
 
1637
#define elf_symbol_leading_char '_'
1638
 
1639
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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