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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [coff-h8300.c] - Blame information for rev 1771

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

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