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

Subversion Repositories or1k_old

[/] [or1k_old/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [elf32-h8300.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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