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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [coff-h8300.c] - Blame information for rev 1776

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

Line No. Rev Author Line
1 578 markom
/* BFD back-end for Hitachi H8/300 COFF binaries.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000
4
   Free Software Foundation, Inc.
5
   Written by Steve Chamberlain, <sac@cygnus.com>.
6
 
7
This file is part of BFD, the Binary File Descriptor library.
8
 
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
 
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include "bfd.h"
24
#include "sysdep.h"
25
#include "libbfd.h"
26
#include "bfdlink.h"
27
#include "genlink.h"
28
#include "coff/h8300.h"
29
#include "coff/internal.h"
30
#include "libcoff.h"
31
 
32
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
33
 
34
/* We derive a hash table from the basic BFD hash table to
35
   hold entries in the function vector.  Aside from the
36
   info stored by the basic hash table, we need the offset
37
   of a particular entry within the hash table as well as
38
   the offset where we'll add the next entry.  */
39
 
40
struct funcvec_hash_entry
41
{
42
  /* The basic hash table entry.  */
43
  struct bfd_hash_entry root;
44
 
45
  /* The offset within the vectors section where
46
     this entry lives.  */
47
  bfd_vma offset;
48
};
49
 
50
struct funcvec_hash_table
51
{
52
  /* The basic hash table.  */
53
  struct bfd_hash_table root;
54
 
55
  bfd *abfd;
56
 
57
  /* Offset at which we'll add the next entry.  */
58
  unsigned int offset;
59
};
60
 
61
static struct bfd_hash_entry *
62
funcvec_hash_newfunc
63
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
64
 
65
static boolean
66
funcvec_hash_table_init
67
  PARAMS ((struct funcvec_hash_table *, bfd *,
68
           struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *,
69
                                               struct bfd_hash_table *,
70
                                               const char *))));
71
 
72
/* To lookup a value in the function vector hash table.  */
73
#define funcvec_hash_lookup(table, string, create, copy) \
74
  ((struct funcvec_hash_entry *) \
75
   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
76
 
77
/* The derived h8300 COFF linker table.  Note it's derived from
78
   the generic linker hash table, not the COFF backend linker hash
79
   table!  We use this to attach additional data structures we
80
   need while linking on the h8300.  */
81
struct h8300_coff_link_hash_table
82
{
83
  /* The main hash table.  */
84
  struct generic_link_hash_table root;
85
 
86
  /* Section for the vectors table.  This gets attached to a
87
     random input bfd, we keep it here for easy access.  */
88
  asection *vectors_sec;
89
 
90
  /* Hash table of the functions we need to enter into the function
91
     vector.  */
92
  struct funcvec_hash_table *funcvec_hash_table;
93
};
94
 
95
static struct bfd_link_hash_table *h8300_coff_link_hash_table_create
96
  PARAMS ((bfd *));
97
 
98
/* Get the H8/300 COFF linker hash table from a link_info structure.  */
99
 
100
#define h8300_coff_hash_table(p) \
101
  ((struct h8300_coff_link_hash_table *) ((coff_hash_table (p))))
102
 
103
/* Initialize fields within a funcvec hash table entry.  Called whenever
104
   a new entry is added to the funcvec hash table.  */
105
 
106
static struct bfd_hash_entry *
107
funcvec_hash_newfunc (entry, gen_table, string)
108
     struct bfd_hash_entry *entry;
109
     struct bfd_hash_table *gen_table;
110
     const char *string;
111
{
112
  struct funcvec_hash_entry *ret;
113
  struct funcvec_hash_table *table;
114
 
115
  ret = (struct funcvec_hash_entry *) entry;
116
  table = (struct funcvec_hash_table *) gen_table;
117
 
118
  /* Allocate the structure if it has not already been allocated by a
119
     subclass.  */
120
  if (ret == NULL)
121
    ret = ((struct funcvec_hash_entry *)
122
           bfd_hash_allocate (gen_table,
123
                              sizeof (struct funcvec_hash_entry)));
124
  if (ret == NULL)
125
    return NULL;
126
 
127
  /* Call the allocation method of the superclass.  */
128
  ret = ((struct funcvec_hash_entry *)
129
         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string));
130
 
131
  if (ret == NULL)
132
    return NULL;
133
 
134
  /* Note where this entry will reside in the function vector table.  */
135
  ret->offset = table->offset;
136
 
137
  /* Bump the offset at which we store entries in the function
138
     vector.  We'd like to bump up the size of the vectors section,
139
     but it's not easily available here.  */
140
  if (bfd_get_mach (table->abfd) == bfd_mach_h8300)
141
    table->offset += 2;
142
  else if (bfd_get_mach (table->abfd) == bfd_mach_h8300h
143
           || bfd_get_mach (table->abfd) == bfd_mach_h8300s)
144
    table->offset += 4;
145
  else
146
    return NULL;
147
 
148
  /* Everything went OK.  */
149
  return (struct bfd_hash_entry *) ret;
150
}
151
 
152
/* Initialize the function vector hash table.  */
153
 
154
static boolean
155
funcvec_hash_table_init (table, abfd, newfunc)
156
     struct funcvec_hash_table *table;
157
     bfd *abfd;
158
     struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
159
                                                struct bfd_hash_table *,
160
                                                const char *));
161
{
162
  /* Initialize our local fields, then call the generic initialization
163
     routine.  */
164
  table->offset = 0;
165
  table->abfd = abfd;
166
  return (bfd_hash_table_init (&table->root, newfunc));
167
}
168
 
169
/* Create the derived linker hash table.  We use a derived hash table
170
   basically to hold "static" information during an h8/300 coff link
171
   without using static variables.  */
172
 
173
static struct bfd_link_hash_table *
174
h8300_coff_link_hash_table_create (abfd)
175
     bfd *abfd;
176
{
177
  struct h8300_coff_link_hash_table *ret;
178
  ret = ((struct h8300_coff_link_hash_table *)
179
         bfd_alloc (abfd, sizeof (struct h8300_coff_link_hash_table)));
180
  if (ret == NULL)
181
    return NULL;
182
  if (!_bfd_link_hash_table_init (&ret->root.root, abfd, _bfd_generic_link_hash_newfunc))
183
    {
184
      bfd_release (abfd, ret);
185
      return NULL;
186
    }
187
 
188
  /* Initialize our data.  */
189
  ret->vectors_sec = NULL;
190
  ret->funcvec_hash_table = NULL;
191
 
192
  /* OK.  Everything's intialized, return the base pointer.  */
193
  return &ret->root.root;
194
}
195
 
196
/* Special handling for H8/300 relocs.
197
   We only come here for pcrel stuff and return normally if not an -r link.
198
   When doing -r, we can't do any arithmetic for the pcrel stuff, because
199
   the code in reloc.c assumes that we can manipulate the targets of
200
   the pcrel branches.  This isn't so, since the H8/300 can do relaxing,
201
   which means that the gap after the instruction may not be enough to
202
   contain the offset required for the branch, so we have to use only
203
   the addend until the final link.  */
204
 
205
static bfd_reloc_status_type
206
special (abfd, reloc_entry, symbol, data, input_section, output_bfd,
207
         error_message)
208
     bfd *abfd ATTRIBUTE_UNUSED;
209
     arelent *reloc_entry ATTRIBUTE_UNUSED;
210
     asymbol *symbol ATTRIBUTE_UNUSED;
211
     PTR data ATTRIBUTE_UNUSED;
212
     asection *input_section ATTRIBUTE_UNUSED;
213
     bfd *output_bfd;
214
     char **error_message ATTRIBUTE_UNUSED;
215
{
216
  if (output_bfd == (bfd *) NULL)
217
    return bfd_reloc_continue;
218
 
219
  /* Adjust the reloc address to that in the output section.  */
220
  reloc_entry->address += input_section->output_offset;
221
  return bfd_reloc_ok;
222
}
223
 
224
static reloc_howto_type howto_table[] =
225
{
226
  HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8", false, 0x000000ff, 0x000000ff, false),
227
  HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16", false, 0x0000ffff, 0x0000ffff, false),
228
  HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "32", false, 0xffffffff, 0xffffffff, false),
229
  HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8", false, 0x000000ff, 0x000000ff, true),
230
  HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, special, "DISP16", false, 0x0000ffff, 0x0000ffff, true),
231
  HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, special, "DISP32", false, 0xffffffff, 0xffffffff, true),
232
  HOWTO (R_MOV16B1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", false, 0x0000ffff, 0x0000ffff, false),
233
  HOWTO (R_MOV16B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", false, 0x000000ff, 0x000000ff, false),
234
  HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/pcrel", false, 0x0000ffff, 0x0000ffff, false),
235
  HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false),
236
  HOWTO (R_JMPL1, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "24/pcrell", false, 0x00ffffff, 0x00ffffff, false),
237
  HOWTO (R_JMPL2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pc8/24", false, 0x000000ff, 0x000000ff, false),
238
  HOWTO (R_MOV24B1, 0, 1, 32, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", false, 0xffffffff, 0xffffffff, false),
239
  HOWTO (R_MOV24B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", false, 0x0000ffff, 0x0000ffff, false),
240
 
241
  /* An indirect reference to a function.  This causes the function's address
242
     to be added to the function vector in lo-mem and puts the address of
243
     the function vector's entry in the jsr instruction.  */
244
  HOWTO (R_MEM_INDIRECT, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8/indirect", false, 0x000000ff, 0x000000ff, false),
245
 
246
  /* Internal reloc for relaxing.  This is created when a 16bit pc-relative
247
     branch is turned into an 8bit pc-relative branch.  */
248
  HOWTO (R_PCRWORD_B, 0, 0, 8, true, 0, complain_overflow_bitfield, special, "relaxed bCC:16", false, 0x000000ff, 0x000000ff, false),
249
 
250
  HOWTO (R_MOVL1, 0, 2, 32, false, 0, complain_overflow_bitfield,special, "32/24 relaxable move", false, 0xffffffff, 0xffffffff, false),
251
 
252
  HOWTO (R_MOVL2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "32/24 relaxed move", false, 0x0000ffff, 0x0000ffff, false),
253
 
254
  HOWTO (R_BCC_INV, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8 inverted", false, 0x000000ff, 0x000000ff, true),
255
 
256
  HOWTO (R_JMP_DEL, 0, 0, 8, true, 0, complain_overflow_signed, special, "Deleted jump", false, 0x000000ff, 0x000000ff, true),
257
};
258
 
259
/* Turn a howto into a reloc number.  */
260
 
261
#define SELECT_RELOC(x,howto) \
262
  { x.r_type = select_reloc(howto); }
263
 
264
#define BADMAG(x) (H8300BADMAG(x) && H8300HBADMAG(x) && H8300SBADMAG(x))
265
#define H8300 1                 /* Customize coffcode.h */
266
#define __A_MAGIC_SET__
267
 
268
/* Code to swap in the reloc.  */
269
#define SWAP_IN_RELOC_OFFSET   bfd_h_get_32
270
#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
271
#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
272
  dst->r_stuff[0] = 'S'; \
273
  dst->r_stuff[1] = 'C';
274
 
275
static int
276
select_reloc (howto)
277
     reloc_howto_type *howto;
278
{
279
  return howto->type;
280
}
281
 
282
/* Code to turn a r_type into a howto ptr, uses the above howto table.  */
283
 
284
static void
285
rtype2howto (internal, dst)
286
     arelent *internal;
287
     struct internal_reloc *dst;
288
{
289
  switch (dst->r_type)
290
    {
291
    case R_RELBYTE:
292
      internal->howto = howto_table + 0;
293
      break;
294
    case R_RELWORD:
295
      internal->howto = howto_table + 1;
296
      break;
297
    case R_RELLONG:
298
      internal->howto = howto_table + 2;
299
      break;
300
    case R_PCRBYTE:
301
      internal->howto = howto_table + 3;
302
      break;
303
    case R_PCRWORD:
304
      internal->howto = howto_table + 4;
305
      break;
306
    case R_PCRLONG:
307
      internal->howto = howto_table + 5;
308
      break;
309
    case R_MOV16B1:
310
      internal->howto = howto_table + 6;
311
      break;
312
    case R_MOV16B2:
313
      internal->howto = howto_table + 7;
314
      break;
315
    case R_JMP1:
316
      internal->howto = howto_table + 8;
317
      break;
318
    case R_JMP2:
319
      internal->howto = howto_table + 9;
320
      break;
321
    case R_JMPL1:
322
      internal->howto = howto_table + 10;
323
      break;
324
    case R_JMPL2:
325
      internal->howto = howto_table + 11;
326
      break;
327
    case R_MOV24B1:
328
      internal->howto = howto_table + 12;
329
      break;
330
    case R_MOV24B2:
331
      internal->howto = howto_table + 13;
332
      break;
333
    case R_MEM_INDIRECT:
334
      internal->howto = howto_table + 14;
335
      break;
336
    case R_PCRWORD_B:
337
      internal->howto = howto_table + 15;
338
      break;
339
    case R_MOVL1:
340
      internal->howto = howto_table + 16;
341
      break;
342
    case R_MOVL2:
343
      internal->howto = howto_table + 17;
344
      break;
345
    case R_BCC_INV:
346
      internal->howto = howto_table + 18;
347
      break;
348
    case R_JMP_DEL:
349
      internal->howto = howto_table + 19;
350
      break;
351
    default:
352
      abort ();
353
      break;
354
    }
355
}
356
 
357
#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
358
 
359
/* Perform any necessary magic to the addend in a reloc entry.  */
360
 
361
#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
362
 cache_ptr->addend =  ext_reloc.r_offset;
363
 
364
#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
365
 reloc_processing(relent, reloc, symbols, abfd, section)
366
 
367
static void
368
reloc_processing (relent, reloc, symbols, abfd, section)
369
     arelent *relent;
370
     struct internal_reloc *reloc;
371
     asymbol **symbols;
372
     bfd *abfd;
373
     asection *section;
374
{
375
  relent->address = reloc->r_vaddr;
376
  rtype2howto (relent, reloc);
377
 
378
  if (((int) reloc->r_symndx) > 0)
379
    {
380
      relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
381
    }
382
  else
383
    {
384
      relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
385
    }
386
 
387
  relent->addend = reloc->r_offset;
388
 
389
  relent->address -= section->vma;
390
#if 0
391
  relent->section = 0;
392
#endif
393
}
394
 
395
static boolean
396
h8300_symbol_address_p (abfd, input_section, address)
397
     bfd *abfd;
398
     asection *input_section;
399
     bfd_vma address;
400
{
401
  asymbol **s;
402
 
403
  s = _bfd_generic_link_get_symbols (abfd);
404
  BFD_ASSERT (s != (asymbol **) NULL);
405
 
406
  /* Search all the symbols for one in INPUT_SECTION with
407
     address ADDRESS.  */
408
  while (*s)
409
    {
410
      asymbol *p = *s;
411
      if (p->section == input_section
412
          && (input_section->output_section->vma
413
              + input_section->output_offset
414
              + p->value) == address)
415
        return true;
416
      s++;
417
    }
418
  return false;
419
}
420
 
421
/* If RELOC represents a relaxable instruction/reloc, change it into
422
   the relaxed reloc, notify the linker that symbol addresses
423
   have changed (bfd_perform_slip) and return how much the current
424
   section has shrunk by.
425
 
426
   FIXME: Much of this code has knowledge of the ordering of entries
427
   in the howto table.  This needs to be fixed.  */
428
 
429
static int
430
h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
431
     bfd *abfd;
432
     asection *input_section;
433
     arelent *reloc;
434
     unsigned int shrink;
435
     struct bfd_link_info *link_info;
436
{
437
  bfd_vma value;
438
  bfd_vma dot;
439
  bfd_vma gap;
440
  static asection *last_input_section = NULL;
441
  static arelent *last_reloc = NULL;
442
 
443
  /* The address of the thing to be relocated will have moved back by
444
     the size of the shrink - but we don't change reloc->address here,
445
     since we need it to know where the relocation lives in the source
446
     uncooked section.  */
447
  bfd_vma address = reloc->address - shrink;
448
 
449
  if (input_section != last_input_section)
450
    last_reloc = NULL;
451
 
452
  /* Only examine the relocs which might be relaxable.  */
453
  switch (reloc->howto->type)
454
    {
455
    /* This is the 16/24 bit absolute branch which could become an 8 bit
456
       pc-relative branch.  */
457
    case R_JMP1:
458
    case R_JMPL1:
459
      /* Get the address of the target of this branch.  */
460
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
461
 
462
      /* Get the address of the next instruction (not the reloc).  */
463
      dot = (input_section->output_section->vma
464
             + input_section->output_offset + address);
465
 
466
      /* Adjust for R_JMP1 vs R_JMPL1.  */
467
      dot += (reloc->howto->type == R_JMP1 ? 1 : 2);
468
 
469
      /* Compute the distance from this insn to the branch target.  */
470
      gap = value - dot;
471
 
472
      /* If the distance is within -128..+128 inclusive, then we can relax
473
         this jump.  +128 is valid since the target will move two bytes
474
         closer if we do relax this branch.  */
475
      if ((int)gap >= -128 && (int)gap <= 128 )
476
        {
477
          /* It's possible we may be able to eliminate this branch entirely;
478
             if the previous instruction is a branch around this instruction,
479
             and there's no label at this instruction, then we can reverse
480
             the condition on the previous branch and eliminate this jump.
481
 
482
               original:                        new:
483
                 bCC lab1                       bCC' lab2
484
                 jmp lab2
485
                lab1:                           lab1:
486
 
487
             This saves 4 bytes instead of two, and should be relatively
488
             common.  */
489
 
490
          if (gap <= 126
491
              && last_reloc
492
              && last_reloc->howto->type == R_PCRBYTE)
493
            {
494
              bfd_vma last_value;
495
              last_value = bfd_coff_reloc16_get_value (last_reloc, link_info,
496
                                                       input_section) + 1;
497
 
498
              if (last_value == dot + 2
499
                  && last_reloc->address + 1 == reloc->address
500
                  && !h8300_symbol_address_p (abfd, input_section, dot - 2))
501
                {
502
                  reloc->howto = howto_table + 19;
503
                  last_reloc->howto = howto_table + 18;
504
                  last_reloc->sym_ptr_ptr = reloc->sym_ptr_ptr;
505
                  last_reloc->addend = reloc->addend;
506
                  shrink += 4;
507
                  bfd_perform_slip (abfd, 4, input_section, address);
508
                  break;
509
                }
510
            }
511
 
512
          /* Change the reloc type.  */
513
          reloc->howto = reloc->howto + 1;
514
 
515
          /* This shrinks this section by two bytes.  */
516
          shrink += 2;
517
          bfd_perform_slip (abfd, 2, input_section, address);
518
        }
519
      break;
520
 
521
    /* This is the 16 bit pc-relative branch which could become an 8 bit
522
       pc-relative branch.  */
523
    case R_PCRWORD:
524
      /* Get the address of the target of this branch, add one to the value
525
         because the addend field in PCrel jumps is off by -1.  */
526
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section) + 1;
527
 
528
      /* Get the address of the next instruction if we were to relax.  */
529
      dot = input_section->output_section->vma +
530
        input_section->output_offset + address;
531
 
532
      /* Compute the distance from this insn to the branch target.  */
533
      gap = value - dot;
534
 
535
      /* If the distance is within -128..+128 inclusive, then we can relax
536
         this jump.  +128 is valid since the target will move two bytes
537
         closer if we do relax this branch.  */
538
      if ((int)gap >= -128 && (int)gap <= 128 )
539
        {
540
          /* Change the reloc type.  */
541
          reloc->howto = howto_table + 15;
542
 
543
          /* This shrinks this section by two bytes.  */
544
          shrink += 2;
545
          bfd_perform_slip (abfd, 2, input_section, address);
546
        }
547
      break;
548
 
549
    /* This is a 16 bit absolute address in a mov.b insn, which can
550
       become an 8 bit absolute address if it's in the right range.  */
551
    case R_MOV16B1:
552
      /* Get the address of the data referenced by this mov.b insn.  */
553
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
554
 
555
      /* The address is in 0xff00..0xffff inclusive on the h8300 or
556
         0xffff00..0xffffff inclusive on the h8300h, then we can
557
         relax this mov.b  */
558
      if ((bfd_get_mach (abfd) == bfd_mach_h8300
559
           && value >= 0xff00
560
           && value <= 0xffff)
561
          || ((bfd_get_mach (abfd) == bfd_mach_h8300h
562
               || bfd_get_mach (abfd) == bfd_mach_h8300s)
563
              && value >= 0xffff00
564
              && value <= 0xffffff))
565
        {
566
          /* Change the reloc type.  */
567
          reloc->howto = reloc->howto + 1;
568
 
569
          /* This shrinks this section by two bytes.  */
570
          shrink += 2;
571
          bfd_perform_slip (abfd, 2, input_section, address);
572
        }
573
      break;
574
 
575
    /* Similarly for a 24 bit absolute address in a mov.b.  Note that
576
       if we can't relax this into an 8 bit absolute, we'll fall through
577
       and try to relax it into a 16bit absolute.  */
578
    case R_MOV24B1:
579
      /* Get the address of the data referenced by this mov.b insn.  */
580
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
581
 
582
      /* The address is in 0xffff00..0xffffff inclusive on the h8300h,
583
         then we can relax this mov.b  */
584
      if ((bfd_get_mach (abfd) == bfd_mach_h8300h
585
           || bfd_get_mach (abfd) == bfd_mach_h8300s)
586
          && value >= 0xffff00
587
          && value <= 0xffffff)
588
        {
589
          /* Change the reloc type.  */
590
          reloc->howto = reloc->howto + 1;
591
 
592
          /* This shrinks this section by four bytes.  */
593
          shrink += 4;
594
          bfd_perform_slip (abfd, 4, input_section, address);
595
 
596
          /* Done with this reloc.  */
597
          break;
598
        }
599
 
600
      /* FALLTHROUGH and try to turn the 32/24 bit reloc into a 16 bit
601
         reloc.  */
602
 
603
    /* This is a 24/32 bit absolute address in a mov insn, which can
604
       become an 16 bit absolute address if it's in the right range.  */
605
    case R_MOVL1:
606
      /* Get the address of the data referenced by this mov insn.  */
607
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
608
 
609
      /* If this address is in 0x0000..0x7fff inclusive or
610
         0xff8000..0xffffff inclusive, then it can be relaxed.  */
611
      if (value <= 0x7fff || value >= 0xff8000)
612
        {
613
          /* Change the reloc type.  */
614
          reloc->howto = howto_table + 17;
615
 
616
          /* This shrinks this section by two bytes.  */
617
          shrink += 2;
618
          bfd_perform_slip (abfd, 2, input_section, address);
619
        }
620
      break;
621
 
622
      /* No other reloc types represent relaxing opportunities.  */
623
    default:
624
      break;
625
    }
626
 
627
  last_reloc = reloc;
628
  last_input_section = input_section;
629
  return shrink;
630
}
631
 
632
/* Handle relocations for the H8/300, including relocs for relaxed
633
   instructions.
634
 
635
   FIXME: Not all relocations check for overflow!  */
636
 
637
static void
638
h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
639
                           dst_ptr)
640
     bfd *abfd;
641
     struct bfd_link_info *link_info;
642
     struct bfd_link_order *link_order;
643
     arelent *reloc;
644
     bfd_byte *data;
645
     unsigned int *src_ptr;
646
     unsigned int *dst_ptr;
647
{
648
  unsigned int src_address = *src_ptr;
649
  unsigned int dst_address = *dst_ptr;
650
  asection *input_section = link_order->u.indirect.section;
651
  bfd_vma value;
652
  bfd_vma dot;
653
  int gap, tmp;
654
 
655
  switch (reloc->howto->type)
656
    {
657
    /* Generic 8bit pc-relative relocation.  */
658
    case R_PCRBYTE:
659
      /* Get the address of the target of this branch.  */
660
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
661
 
662
      dot = (link_order->offset
663
             + dst_address
664
             + link_order->u.indirect.section->output_section->vma);
665
 
666
      gap = value - dot;
667
 
668
      /* Sanity check.  */
669
      if (gap < -128 || gap > 126)
670
        {
671
          if (! ((*link_info->callbacks->reloc_overflow)
672
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
673
                  reloc->howto->name, reloc->addend, input_section->owner,
674
                  input_section, reloc->address)))
675
            abort ();
676
        }
677
 
678
      /* Everything looks OK.  Apply the relocation and update the
679
         src/dst address appropriately.  */
680
 
681
      bfd_put_8 (abfd, gap, data + dst_address);
682
      dst_address++;
683
      src_address++;
684
 
685
      /* All done.  */
686
      break;
687
 
688
    /* Generic 16bit pc-relative relocation.  */
689
    case R_PCRWORD:
690
      /* Get the address of the target of this branch.  */
691
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
692
 
693
      /* Get the address of the instruction (not the reloc).  */
694
      dot = (link_order->offset
695
             + dst_address
696
             + link_order->u.indirect.section->output_section->vma + 1);
697
 
698
      gap = value - dot;
699
 
700
      /* Sanity check.  */
701
      if (gap > 32766 || gap < -32768)
702
        {
703
          if (! ((*link_info->callbacks->reloc_overflow)
704
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
705
                  reloc->howto->name, reloc->addend, input_section->owner,
706
                  input_section, reloc->address)))
707
            abort ();
708
        }
709
 
710
      /* Everything looks OK.  Apply the relocation and update the
711
         src/dst address appropriately.  */
712
 
713
      bfd_put_16 (abfd, gap, data + dst_address);
714
      dst_address += 2;
715
      src_address += 2;
716
 
717
      /* All done.  */
718
      break;
719
 
720
    /* Generic 8bit absolute relocation.  */
721
    case R_RELBYTE:
722
      /* Get the address of the object referenced by this insn.  */
723
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
724
 
725
      /* Sanity check.  */
726
      if (value <= 0xff
727
          || (value >= 0x0000ff00 && value <= 0x0000ffff)
728
          || (value >= 0x00ffff00 && value <= 0x00ffffff)
729
          || (value >= 0xffffff00 && value <= 0xffffffff))
730
        {
731
          /* Everything looks OK.  Apply the relocation and update the
732
             src/dst address appropriately.  */
733
 
734
          bfd_put_8 (abfd, value & 0xff, data + dst_address);
735
          dst_address += 1;
736
          src_address += 1;
737
        }
738
      else
739
        {
740
          if (! ((*link_info->callbacks->reloc_overflow)
741
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
742
                  reloc->howto->name, reloc->addend, input_section->owner,
743
                  input_section, reloc->address)))
744
            abort ();
745
        }
746
 
747
      /* All done.  */
748
      break;
749
 
750
    /* Various simple 16bit absolute relocations.  */
751
    case R_MOV16B1:
752
    case R_JMP1:
753
    case R_RELWORD:
754
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
755
      bfd_put_16 (abfd, value, data + dst_address);
756
      dst_address += 2;
757
      src_address += 2;
758
      break;
759
 
760
    /* Various simple 24/32bit absolute relocations.  */
761
    case R_MOV24B1:
762
    case R_MOVL1:
763
    case R_RELLONG:
764
      /* Get the address of the target of this branch.  */
765
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
766
      bfd_put_32 (abfd, value, data + dst_address);
767
      dst_address += 4;
768
      src_address += 4;
769
      break;
770
 
771
    /* Another 24/32bit absolute relocation.  */
772
    case R_JMPL1:
773
      /* Get the address of the target of this branch.  */
774
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
775
 
776
      value = ((value & 0x00ffffff)
777
               | (bfd_get_32 (abfd, data + src_address) & 0xff000000));
778
      bfd_put_32 (abfd, value, data + dst_address);
779
      dst_address += 4;
780
      src_address += 4;
781
      break;
782
 
783
    /* A 16bit abolute relocation that was formerlly a 24/32bit
784
       absolute relocation.  */
785
    case R_MOVL2:
786
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
787
 
788
      /* Sanity check.  */
789
      if (value <= 0x7fff || value >= 0xff8000)
790
        {
791
          /* Insert the 16bit value into the proper location.  */
792
          bfd_put_16 (abfd, value, data + dst_address);
793
 
794
          /* Fix the opcode.  For all the move insns, we simply
795
             need to turn off bit 0x20 in the previous byte.  */
796
          data[dst_address - 1] &= ~0x20;
797
          dst_address += 2;
798
          src_address += 4;
799
        }
800
      else
801
        {
802
          if (! ((*link_info->callbacks->reloc_overflow)
803
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
804
                  reloc->howto->name, reloc->addend, input_section->owner,
805
                  input_section, reloc->address)))
806
            abort ();
807
        }
808
      break;
809
 
810
    /* A 16bit absolute branch that is now an 8-bit pc-relative branch.  */
811
    case R_JMP2:
812
      /* Get the address of the target of this branch.  */
813
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
814
 
815
      /* Get the address of the next instruction.  */
816
      dot = (link_order->offset
817
             + dst_address
818
             + link_order->u.indirect.section->output_section->vma + 1);
819
 
820
      gap = value - dot;
821
 
822
      /* Sanity check.  */
823
      if (gap < -128 || gap > 126)
824
        {
825
          if (! ((*link_info->callbacks->reloc_overflow)
826
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
827
                  reloc->howto->name, reloc->addend, input_section->owner,
828
                  input_section, reloc->address)))
829
            abort ();
830
        }
831
 
832
      /* Now fix the instruction itself.  */
833
      switch (data[dst_address - 1])
834
        {
835
        case 0x5e:
836
          /* jsr -> bsr */
837
          bfd_put_8 (abfd, 0x55, data + dst_address - 1);
838
          break;
839
        case 0x5a:
840
          /* jmp ->bra */
841
          bfd_put_8 (abfd, 0x40, data + dst_address - 1);
842
          break;
843
 
844
        default:
845
          abort ();
846
        }
847
 
848
      /* Write out the 8bit value.  */
849
      bfd_put_8 (abfd, gap, data + dst_address);
850
 
851
      dst_address += 1;
852
      src_address += 3;
853
 
854
      break;
855
 
856
    /* A 16bit pc-relative branch that is now an 8-bit pc-relative branch.  */
857
    case R_PCRWORD_B:
858
      /* Get the address of the target of this branch.  */
859
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
860
 
861
      /* Get the address of the instruction (not the reloc).  */
862
      dot = (link_order->offset
863
             + dst_address
864
             + link_order->u.indirect.section->output_section->vma - 1);
865
 
866
      gap = value - dot;
867
 
868
      /* Sanity check.  */
869
      if (gap < -128 || gap > 126)
870
        {
871
          if (! ((*link_info->callbacks->reloc_overflow)
872
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
873
                  reloc->howto->name, reloc->addend, input_section->owner,
874
                  input_section, reloc->address)))
875
            abort ();
876
        }
877
 
878
      /* Now fix the instruction.  */
879
      switch (data[dst_address - 2])
880
        {
881
        case 0x58:
882
          /* bCC:16 -> bCC:8 */
883
          /* Get the condition code from the original insn.  */
884
          tmp = data[dst_address - 1];
885
          tmp &= 0xf0;
886
          tmp >>= 4;
887
 
888
          /* Now or in the high nibble of the opcode.  */
889
          tmp |= 0x40;
890
 
891
          /* Write it.  */
892
          bfd_put_8 (abfd, tmp, data + dst_address - 2);
893
          break;
894
 
895
        case 0x5c:
896
          /* bsr:16 -> bsr:8 */
897
          bfd_put_8 (abfd, 0x55, data + dst_address - 2);
898
          break;
899
 
900
        default:
901
          abort ();
902
        }
903
 
904
        /* Output the target.  */
905
        bfd_put_8 (abfd, gap, data + dst_address - 1);
906
 
907
        /* We don't advance dst_address -- the 8bit reloc is applied at
908
           dst_address - 1, so the next insn should begin at dst_address.  */
909
        src_address += 2;
910
 
911
        break;
912
 
913
    /* Similarly for a 24bit absolute that is now 8 bits.  */
914
    case R_JMPL2:
915
      /* Get the address of the target of this branch.  */
916
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
917
 
918
      /* Get the address of the instruction (not the reloc).  */
919
      dot = (link_order->offset
920
             + dst_address
921
             + link_order->u.indirect.section->output_section->vma + 2);
922
 
923
      gap = value - dot;
924
 
925
      /* Fix the instruction.  */
926
      switch (data[src_address])
927
        {
928
        case 0x5e:
929
          /* jsr -> bsr */
930
          bfd_put_8 (abfd, 0x55, data + dst_address);
931
          break;
932
        case 0x5a:
933
          /* jmp ->bra */
934
          bfd_put_8 (abfd, 0x40, data + dst_address);
935
          break;
936
        default:
937
          abort ();
938
        }
939
 
940
      bfd_put_8 (abfd, gap, data + dst_address + 1);
941
      dst_address += 2;
942
      src_address += 4;
943
 
944
      break;
945
 
946
    /* A 16bit absolute mov.b that is now an 8bit absolute mov.b.  */
947
    case R_MOV16B2:
948
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
949
 
950
      /* Sanity check.  */
951
      if (data[dst_address - 2] != 0x6a)
952
        abort ();
953
 
954
      /* Fix up the opcode.  */
955
      switch (data[src_address - 1] & 0xf0)
956
        {
957
        case 0x00:
958
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
959
          break;
960
        case 0x80:
961
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
962
          break;
963
        default:
964
          abort ();
965
        }
966
 
967
      bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
968
      src_address += 2;
969
      break;
970
 
971
    /* Similarly for a 24bit mov.b  */
972
    case R_MOV24B2:
973
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
974
 
975
      /* Sanity check.  */
976
      if (data[dst_address - 2] != 0x6a)
977
        abort ();
978
 
979
      /* Fix up the opcode.  */
980
      switch (data[src_address - 1] & 0xf0)
981
        {
982
        case 0x20:
983
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
984
          break;
985
        case 0xa0:
986
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
987
          break;
988
        default:
989
          abort ();
990
        }
991
 
992
      bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
993
      src_address += 4;
994
      break;
995
 
996
    case R_BCC_INV:
997
      /* Get the address of the target of this branch.  */
998
      value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
999
 
1000
      dot = (link_order->offset
1001
             + dst_address
1002
             + link_order->u.indirect.section->output_section->vma) + 1;
1003
 
1004
      gap = value - dot;
1005
 
1006
      /* Sanity check.  */
1007
      if (gap < -128 || gap > 126)
1008
        {
1009
          if (! ((*link_info->callbacks->reloc_overflow)
1010
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
1011
                  reloc->howto->name, reloc->addend, input_section->owner,
1012
                  input_section, reloc->address)))
1013
            abort ();
1014
        }
1015
 
1016
      /* Everything looks OK.  Fix the condition in the instruction, apply
1017
         the relocation, and update the src/dst address appropriately.  */
1018
 
1019
      bfd_put_8 (abfd, bfd_get_8 (abfd, data + dst_address - 1) ^ 1,
1020
                 data + dst_address - 1);
1021
      bfd_put_8 (abfd, gap, data + dst_address);
1022
      dst_address++;
1023
      src_address++;
1024
 
1025
      /* All done.  */
1026
      break;
1027
 
1028
    case R_JMP_DEL:
1029
      src_address += 4;
1030
      break;
1031
 
1032
    /* An 8bit memory indirect instruction (jmp/jsr).
1033
 
1034
       There's several things that need to be done to handle
1035
       this relocation.
1036
 
1037
       If this is a reloc against the absolute symbol, then
1038
       we should handle it just R_RELBYTE.  Likewise if it's
1039
       for a symbol with a value ge 0 and le 0xff.
1040
 
1041
       Otherwise it's a jump/call through the function vector,
1042
       and the linker is expected to set up the function vector
1043
       and put the right value into the jump/call instruction.  */
1044
    case R_MEM_INDIRECT:
1045
      {
1046
        /* We need to find the symbol so we can determine it's
1047
           address in the function vector table.  */
1048
        asymbol *symbol;
1049
        bfd_vma value;
1050
        const char *name;
1051
        struct funcvec_hash_entry *h;
1052
        asection *vectors_sec = h8300_coff_hash_table (link_info)->vectors_sec;
1053
 
1054
        /* First see if this is a reloc against the absolute symbol
1055
           or against a symbol with a nonnegative value <= 0xff.  */
1056
        symbol = *(reloc->sym_ptr_ptr);
1057
        value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
1058
        if (symbol == bfd_abs_section_ptr->symbol
1059
            || value <= 0xff)
1060
          {
1061
            /* This should be handled in a manner very similar to
1062
               R_RELBYTES.   If the value is in range, then just slam
1063
               the value into the right location.  Else trigger a
1064
               reloc overflow callback.  */
1065
            if (value <= 0xff)
1066
              {
1067
                bfd_put_8 (abfd, value, data + dst_address);
1068
                dst_address += 1;
1069
                src_address += 1;
1070
              }
1071
            else
1072
              {
1073
                if (! ((*link_info->callbacks->reloc_overflow)
1074
                       (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
1075
                        reloc->howto->name, reloc->addend, input_section->owner,
1076
                        input_section, reloc->address)))
1077
                  abort ();
1078
              }
1079
            break;
1080
          }
1081
 
1082
        /* This is a jump/call through a function vector, and we're
1083
           expected to create the function vector ourselves.
1084
 
1085
           First look up this symbol in the linker hash table -- we need
1086
           the derived linker symbol which holds this symbol's index
1087
           in the function vector.  */
1088
        name = symbol->name;
1089
        if (symbol->flags & BSF_LOCAL)
1090
          {
1091
            char *new_name = bfd_malloc (strlen (name) + 9);
1092
            if (new_name == NULL)
1093
              abort ();
1094
 
1095
            strcpy (new_name, name);
1096
            sprintf (new_name + strlen (name), "_%08x",
1097
                     (int) symbol->section);
1098
            name = new_name;
1099
          }
1100
 
1101
        h = funcvec_hash_lookup (h8300_coff_hash_table (link_info)->funcvec_hash_table,
1102
                                 name, false, false);
1103
 
1104
        /* This shouldn't ever happen.  If it does that means we've got
1105
           data corruption of some kind.  Aborting seems like a reasonable
1106
           think to do here.  */
1107
        if (h == NULL || vectors_sec == NULL)
1108
          abort ();
1109
 
1110
        /* Place the address of the function vector entry into the
1111
           reloc's address.  */
1112
        bfd_put_8 (abfd,
1113
                   vectors_sec->output_offset + h->offset,
1114
                   data + dst_address);
1115
 
1116
        dst_address++;
1117
        src_address++;
1118
 
1119
        /* Now create an entry in the function vector itself.  */
1120
        if (bfd_get_mach (input_section->owner) == bfd_mach_h8300)
1121
          bfd_put_16 (abfd,
1122
                      bfd_coff_reloc16_get_value (reloc,
1123
                                                  link_info,
1124
                                                  input_section),
1125
                      vectors_sec->contents + h->offset);
1126
        else if (bfd_get_mach (input_section->owner) == bfd_mach_h8300h
1127
                 || bfd_get_mach (input_section->owner) == bfd_mach_h8300s)
1128
          bfd_put_32 (abfd,
1129
                      bfd_coff_reloc16_get_value (reloc,
1130
                                                  link_info,
1131
                                                  input_section),
1132
                      vectors_sec->contents + h->offset);
1133
        else
1134
          abort ();
1135
 
1136
        /* Gross.  We've already written the contents of the vector section
1137
           before we get here...  So we write it again with the new data.  */
1138
        bfd_set_section_contents (vectors_sec->output_section->owner,
1139
                                  vectors_sec->output_section,
1140
                                  vectors_sec->contents,
1141
                                  vectors_sec->output_offset,
1142
                                  vectors_sec->_raw_size);
1143
        break;
1144
      }
1145
 
1146
    default:
1147
      abort ();
1148
      break;
1149
 
1150
    }
1151
 
1152
  *src_ptr = src_address;
1153
  *dst_ptr = dst_address;
1154
}
1155
 
1156
/* Routine for the h8300 linker.
1157
 
1158
   This routine is necessary to handle the special R_MEM_INDIRECT
1159
   relocs on the h8300.  It's responsible for generating a vectors
1160
   section and attaching it to an input bfd as well as sizing
1161
   the vectors section.  It also creates our vectors hash table.
1162
 
1163
   It uses the generic linker routines to actually add the symbols.
1164
   from this BFD to the bfd linker hash table.  It may add a few
1165
   selected static symbols to the bfd linker hash table.  */
1166
 
1167
static boolean
1168
h8300_bfd_link_add_symbols (abfd, info)
1169
     bfd *abfd;
1170
     struct bfd_link_info *info;
1171
{
1172
  asection *sec;
1173
  struct funcvec_hash_table *funcvec_hash_table;
1174
 
1175
  /* If we haven't created a vectors section, do so now.  */
1176
  if (!h8300_coff_hash_table (info)->vectors_sec)
1177
    {
1178
      flagword flags;
1179
 
1180
      /* Make sure the appropriate flags are set, including SEC_IN_MEMORY.  */
1181
      flags = (SEC_ALLOC | SEC_LOAD
1182
               | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY);
1183
      h8300_coff_hash_table (info)->vectors_sec = bfd_make_section (abfd,
1184
                                                                    ".vectors");
1185
 
1186
      /* If the section wasn't created, or we couldn't set the flags,
1187
         quit quickly now, rather than dieing a painful death later.  */
1188
      if (! h8300_coff_hash_table (info)->vectors_sec
1189
          || ! bfd_set_section_flags (abfd,
1190
                                      h8300_coff_hash_table(info)->vectors_sec,
1191
                                      flags))
1192
        return false;
1193
 
1194
      /* Also create the vector hash table.  */
1195
      funcvec_hash_table = ((struct funcvec_hash_table *)
1196
        bfd_alloc (abfd, sizeof (struct funcvec_hash_table)));
1197
 
1198
      if (!funcvec_hash_table)
1199
        return false;
1200
 
1201
      /* And initialize the funcvec hash table.  */
1202
      if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
1203
                                    funcvec_hash_newfunc))
1204
        {
1205
          bfd_release (abfd, funcvec_hash_table);
1206
          return false;
1207
        }
1208
 
1209
      /* Store away a pointer to the funcvec hash table.  */
1210
      h8300_coff_hash_table (info)->funcvec_hash_table = funcvec_hash_table;
1211
    }
1212
 
1213
  /* Load up the function vector hash table.  */
1214
  funcvec_hash_table = h8300_coff_hash_table (info)->funcvec_hash_table;
1215
 
1216
  /* Add the symbols using the generic code.  */
1217
  _bfd_generic_link_add_symbols (abfd, info);
1218
 
1219
  /* Now scan the relocs for all the sections in this bfd; create
1220
     additional space in the .vectors section as needed.  */
1221
  for (sec = abfd->sections; sec; sec = sec->next)
1222
    {
1223
      long reloc_size, reloc_count, i;
1224
      asymbol **symbols;
1225
      arelent **relocs;
1226
 
1227
      /* Suck in the relocs, symbols & canonicalize them.  */
1228
      reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
1229
      if (reloc_size <= 0)
1230
        continue;
1231
 
1232
      relocs = (arelent **) bfd_malloc ((size_t) reloc_size);
1233
      if (!relocs)
1234
        return false;
1235
 
1236
      /* The symbols should have been read in by _bfd_generic link_add_symbols
1237
         call abovec, so we can cheat and use the pointer to them that was
1238
         saved in the above call.  */
1239
      symbols = _bfd_generic_link_get_symbols(abfd);
1240
      reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, symbols);
1241
      if (reloc_count <= 0)
1242
        {
1243
          free (relocs);
1244
          continue;
1245
        }
1246
 
1247
      /* Now walk through all the relocations in this section.  */
1248
      for (i = 0; i < reloc_count; i++)
1249
        {
1250
          arelent *reloc = relocs[i];
1251
          asymbol *symbol = *(reloc->sym_ptr_ptr);
1252
          const char *name;
1253
 
1254
          /* We've got an indirect reloc.  See if we need to add it
1255
             to the function vector table.   At this point, we have
1256
             to add a new entry for each unique symbol referenced
1257
             by an R_MEM_INDIRECT relocation except for a reloc
1258
             against the absolute section symbol.  */
1259
          if (reloc->howto->type == R_MEM_INDIRECT
1260
              && symbol != bfd_abs_section_ptr->symbol)
1261
 
1262
            {
1263
              struct funcvec_hash_entry *h;
1264
 
1265
              name = symbol->name;
1266
              if (symbol->flags & BSF_LOCAL)
1267
                {
1268
                  char *new_name = bfd_malloc (strlen (name) + 9);
1269
 
1270
                  if (new_name == NULL)
1271
                    abort ();
1272
 
1273
                  strcpy (new_name, name);
1274
                  sprintf (new_name + strlen (name), "_%08x",
1275
                           (int) symbol->section);
1276
                  name = new_name;
1277
                }
1278
 
1279
              /* Look this symbol up in the function vector hash table.  */
1280
              h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
1281
                                       name, false, false);
1282
 
1283
              /* If this symbol isn't already in the hash table, add
1284
                 it and bump up the size of the hash table.  */
1285
              if (h == NULL)
1286
                {
1287
                  h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
1288
                                           name, true, true);
1289
                  if (h == NULL)
1290
                    {
1291
                      free (relocs);
1292
                      return false;
1293
                    }
1294
 
1295
                  /* Bump the size of the vectors section.  Each vector
1296
                     takes 2 bytes on the h8300 and 4 bytes on the h8300h.  */
1297
                  if (bfd_get_mach (abfd) == bfd_mach_h8300)
1298
                    h8300_coff_hash_table (info)->vectors_sec->_raw_size += 2;
1299
                  else if (bfd_get_mach (abfd) == bfd_mach_h8300h
1300
                           || bfd_get_mach (abfd) == bfd_mach_h8300s)
1301
                    h8300_coff_hash_table (info)->vectors_sec->_raw_size += 4;
1302
                }
1303
            }
1304
        }
1305
 
1306
      /* We're done with the relocations, release them.  */
1307
      free (relocs);
1308
    }
1309
 
1310
  /* Now actually allocate some space for the function vector.  It's
1311
     wasteful to do this more than once, but this is easier.  */
1312
  if (h8300_coff_hash_table (info)->vectors_sec->_raw_size != 0)
1313
    {
1314
      /* Free the old contents.  */
1315
      if (h8300_coff_hash_table (info)->vectors_sec->contents)
1316
        free (h8300_coff_hash_table (info)->vectors_sec->contents);
1317
 
1318
      /* Allocate new contents.  */
1319
      h8300_coff_hash_table (info)->vectors_sec->contents
1320
        = bfd_malloc (h8300_coff_hash_table (info)->vectors_sec->_raw_size);
1321
    }
1322
 
1323
  return true;
1324
}
1325
 
1326
#define coff_reloc16_extra_cases h8300_reloc16_extra_cases
1327
#define coff_reloc16_estimate h8300_reloc16_estimate
1328
#define coff_bfd_link_add_symbols h8300_bfd_link_add_symbols
1329
#define coff_bfd_link_hash_table_create h8300_coff_link_hash_table_create
1330
 
1331
#define COFF_LONG_FILENAMES
1332
#include "coffcode.h"
1333
 
1334
#undef coff_bfd_get_relocated_section_contents
1335
#undef coff_bfd_relax_section
1336
#define coff_bfd_get_relocated_section_contents \
1337
  bfd_coff_reloc16_get_relocated_section_contents
1338
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
1339
 
1340
CREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL)

powered by: WebSVN 2.1.0

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