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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [coff-w65.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* BFD back-end for WDC 65816 COFF binaries.
2
   Copyright 1995, 96, 1997 Free Software Foundation, Inc.
3
   Written by Steve Chamberlain, <sac@cygnus.com>.
4
 
5
This file is part of BFD, the Binary File Descriptor library.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "bfd.h"
22
#include "sysdep.h"
23
#include "libbfd.h"
24
#include "bfdlink.h"
25
#include "coff/w65.h"
26
#include "coff/internal.h"
27
#include "libcoff.h"
28
 
29
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
30
static reloc_howto_type howto_table[] =
31
{
32
  HOWTO (R_W65_ABS8,    0,  0, 8, false, 0, complain_overflow_bitfield, 0, "abs8", true, 0x000000ff, 0x000000ff, false),
33
  HOWTO (R_W65_ABS16,   1,  0, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false),
34
  HOWTO (R_W65_ABS24,   0,  2, 32, false, 0, complain_overflow_bitfield, 0, "abs24", true, 0x00ffffff, 0x00ffffff, false),
35
  HOWTO (R_W65_ABS8S8,  0,  0, 8, false, 0, complain_overflow_bitfield, 0, ">abs8", true, 0x000000ff, 0x000000ff, false),
36
  HOWTO (R_W65_ABS8S16, 0,  0, 8, false, 0, complain_overflow_bitfield, 0, "^abs8", true, 0x000000ff, 0x000000ff, false),
37
  HOWTO (R_W65_ABS16S8, 1,  0, 16, false, 0, complain_overflow_bitfield, 0, ">abs16", true, 0x0000ffff, 0x0000ffff, false),
38
  HOWTO (R_W65_ABS16S16,1,  0, 16, false, 0, complain_overflow_bitfield, 0, "^abs16", true, 0x0000ffff, 0x0000ffff, false),
39
  HOWTO (R_W65_PCR8,    0,  0, 8, false, 0, complain_overflow_bitfield, 0, "pcrel8", true, 0x000000ff, 0x000000ff, true),
40
  HOWTO (R_W65_PCR16,   1,  0, 16, false, 0, complain_overflow_bitfield, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, true),
41
  HOWTO (R_W65_DP,    0,  0, 8, false, 0, complain_overflow_bitfield, 0, "dp", true, 0x000000ff, 0x000000ff, false),
42
 
43
};
44
 
45
 
46
/* Turn a howto into a reloc number */
47
 
48
#define SELECT_RELOC(x,howto) \
49
  { x.r_type = select_reloc(howto); }
50
 
51
#define BADMAG(x) (W65BADMAG(x))
52
#define W65 1                   /* Customize coffcode.h */
53
#define __A_MAGIC_SET__
54
 
55
 
56
/* Code to swap in the reloc */
57
#define SWAP_IN_RELOC_OFFSET   bfd_h_get_32
58
#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
59
#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
60
  dst->r_stuff[0] = 'S'; \
61
  dst->r_stuff[1] = 'C';
62
 
63
 
64
static int
65
select_reloc (howto)
66
     reloc_howto_type *howto;
67
{
68
  return howto->type ;
69
}
70
 
71
/* Code to turn a r_type into a howto ptr, uses the above howto table
72
   */
73
 
74
static void
75
rtype2howto (internal, dst)
76
     arelent *internal;
77
     struct internal_reloc *dst;
78
{
79
      internal->howto = howto_table + dst->r_type - 1;
80
}
81
 
82
#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
83
 
84
 
85
/* Perform any necessary magic to the addend in a reloc entry */
86
 
87
 
88
#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
89
 cache_ptr->addend =  ext_reloc.r_offset;
90
 
91
 
92
#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
93
 reloc_processing(relent, reloc, symbols, abfd, section)
94
 
95
static void
96
reloc_processing (relent, reloc, symbols, abfd, section)
97
     arelent * relent;
98
     struct internal_reloc *reloc;
99
     asymbol ** symbols;
100
     bfd * abfd;
101
     asection * section;
102
{
103
  relent->address = reloc->r_vaddr;
104
  rtype2howto (relent, reloc);
105
 
106
  if (((int) reloc->r_symndx) > 0)
107
    {
108
      relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
109
    }
110
  else
111
    {
112
      relent->sym_ptr_ptr = (asymbol **)&(bfd_abs_symbol);
113
    }
114
 
115
 
116
 
117
  relent->addend = reloc->r_offset;
118
 
119
  relent->address -= section->vma;
120
  /*  relent->section = 0;*/
121
}
122
 
123
 
124
static int
125
h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info)
126
     bfd *abfd;
127
     asection *input_section;
128
     arelent *reloc;
129
     unsigned int shrink;
130
     struct bfd_link_info *link_info;
131
{
132
  bfd_vma value;
133
  bfd_vma dot;
134
  bfd_vma gap;
135
 
136
  /* The address of the thing to be relocated will have moved back by
137
   the size of the shrink  - but we don't change reloc->address here,
138
   since we need it to know where the relocation lives in the source
139
   uncooked section */
140
 
141
  /*  reloc->address -= shrink;   conceptual */
142
 
143
  bfd_vma address = reloc->address - shrink;
144
 
145
 
146
  switch (reloc->howto->type)
147
    {
148
    case R_MOV16B2:
149
    case R_JMP2:
150
      shrink+=2;
151
      break;
152
 
153
      /* Thing is a move one byte */
154
    case R_MOV16B1:
155
      value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
156
 
157
      if (value >= 0xff00)
158
        {
159
 
160
          /* Change the reloc type from 16bit, possible 8 to 8bit
161
             possible 16 */
162
          reloc->howto = reloc->howto + 1;
163
          /* The place to relc moves back by one */
164
          /* This will be two bytes smaller in the long run */
165
          shrink +=2 ;
166
          bfd_perform_slip(abfd, 2, input_section, address);
167
        }
168
 
169
      break;
170
      /* This is the 24 bit branch which could become an 8 bitter,
171
       the relocation points to the first byte of the insn, not the
172
       actual data */
173
 
174
    case R_JMPL1:
175
      value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
176
 
177
      dot = input_section->output_section->vma +
178
        input_section->output_offset + address;
179
 
180
      /* See if the address we're looking at within 127 bytes of where
181
         we are, if so then we can use a small branch rather than the
182
         jump we were going to */
183
 
184
      gap = value - dot ;
185
 
186
      if (-120 < (long)gap && (long)gap < 120 )
187
        {
188
 
189
          /* Change the reloc type from 24bit, possible 8 to 8bit
190
             possible 32 */
191
          reloc->howto = reloc->howto + 1;
192
          /* This will be two bytes smaller in the long run */
193
          shrink +=2 ;
194
          bfd_perform_slip(abfd, 2, input_section, address);
195
        }
196
      break;
197
 
198
    case R_JMP1:
199
 
200
      value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
201
 
202
      dot = input_section->output_section->vma +
203
        input_section->output_offset + address;
204
 
205
      /* See if the address we're looking at within 127 bytes of where
206
         we are, if so then we can use a small branch rather than the
207
         jump we were going to */
208
 
209
      gap = value - (dot - shrink);
210
 
211
 
212
      if (-120 < (long)gap && (long)gap < 120 )
213
        {
214
 
215
          /* Change the reloc type from 16bit, possible 8 to 8bit
216
             possible 16 */
217
          reloc->howto = reloc->howto + 1;
218
          /* The place to relc moves back by one */
219
 
220
          /* This will be two bytes smaller in the long run */
221
          shrink +=2 ;
222
          bfd_perform_slip(abfd, 2, input_section, address);
223
        }
224
      break;
225
    }
226
 
227
 
228
  return shrink;
229
}
230
 
231
 
232
/* First phase of a relaxing link */
233
 
234
/* Reloc types
235
   large                small
236
   R_MOV16B1            R_MOV16B2       mov.b with 16bit or 8 bit address
237
   R_JMP1               R_JMP2          jmp or pcrel branch
238
   R_JMPL1              R_JMPL_B8       24jmp or pcrel branch
239
   R_MOV24B1            R_MOV24B2       24 or 8 bit reloc for mov.b
240
 
241
*/
242
 
243
static void
244
h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
245
                           dst_ptr)
246
     bfd *abfd;
247
     struct bfd_link_info *link_info;
248
     struct bfd_link_order *link_order;
249
     arelent *reloc;
250
     bfd_byte *data;
251
     unsigned int *src_ptr;
252
     unsigned int *dst_ptr;
253
{
254
  unsigned int src_address = *src_ptr;
255
  unsigned int dst_address = *dst_ptr;
256
  asection *input_section = link_order->u.indirect.section;
257
 
258
  switch (reloc->howto->type)
259
    {
260
    case R_W65_ABS8:
261
    case R_W65_DP:
262
      {
263
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
264
                                                       input_section);
265
        bfd_put_8 (abfd, gap, data + dst_address);
266
        dst_address += 1;
267
        src_address += 1;
268
      }
269
      break;
270
 
271
    case R_W65_ABS8S8:
272
      {
273
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
274
                                                       input_section);
275
        gap >>= 8;
276
        bfd_put_8 (abfd, gap, data + dst_address);
277
        dst_address += 1;
278
        src_address += 1;
279
      }
280
      break;
281
 
282
    case R_W65_ABS8S16:
283
      {
284
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
285
                                                       input_section);
286
        gap >>=16;
287
        bfd_put_8 (abfd, gap, data + dst_address);
288
        dst_address += 1;
289
        src_address += 1;
290
      }
291
      break;
292
 
293
    case R_W65_ABS16:
294
      {
295
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
296
                                                       input_section);
297
 
298
        bfd_put_16 (abfd, gap, data + dst_address);
299
        dst_address += 2;
300
        src_address += 2;
301
      }
302
      break;
303
    case R_W65_ABS16S8:
304
      {
305
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
306
                                                       input_section);
307
        gap >>= 8;
308
        bfd_put_16 (abfd, gap, data + dst_address);
309
        dst_address += 2;
310
        src_address += 2;
311
      }
312
      break;
313
    case R_W65_ABS16S16:
314
      {
315
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
316
                                                       input_section);
317
        gap >>= 16;
318
        bfd_put_16 (abfd, gap, data + dst_address);
319
        dst_address += 2;
320
        src_address += 2;
321
      }
322
      break;
323
 
324
    case R_W65_ABS24:
325
      {
326
        unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
327
                                                       input_section);
328
        bfd_put_16 (abfd, gap, data + dst_address);
329
        bfd_put_8 (abfd, gap>>16, data+dst_address+2);
330
        dst_address += 3;
331
        src_address += 3;
332
      }
333
      break;
334
 
335
    case R_W65_PCR8:
336
      {
337
        int gap = bfd_coff_reloc16_get_value (reloc, link_info,
338
                                              input_section);
339
        bfd_vma dot = link_order->offset
340
          + dst_address
341
            + link_order->u.indirect.section->output_section->vma;
342
 
343
        gap -= dot + 1;
344
        if (gap < -128 || gap > 127) {
345
          if (! ((*link_info->callbacks->reloc_overflow)
346
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
347
                  reloc->howto->name, reloc->addend, input_section->owner,
348
                  input_section, reloc->address)))
349
            abort();
350
        }
351
        bfd_put_8 (abfd, gap, data + dst_address);
352
        dst_address += 1;
353
        src_address += 1;
354
      }
355
      break;
356
 
357
    case R_W65_PCR16:
358
      {
359
        bfd_vma gap = bfd_coff_reloc16_get_value (reloc, link_info,
360
                                                  input_section);
361
        bfd_vma dot = link_order->offset
362
          + dst_address
363
            + link_order->u.indirect.section->output_section->vma;
364
 
365
 
366
        /* This wraps within the page, so ignore the relativeness, look at the
367
           high part */
368
        if ((gap & 0xf0000) != (dot & 0xf0000)) {
369
          if (! ((*link_info->callbacks->reloc_overflow)
370
                 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
371
                  reloc->howto->name, reloc->addend, input_section->owner,
372
                  input_section, reloc->address)))
373
            abort();
374
        }
375
 
376
        gap -= dot + 2;
377
        bfd_put_16 (abfd, gap, data + dst_address);
378
        dst_address += 2;
379
        src_address += 2;
380
      }
381
      break;
382
    default:
383
      printf(_("ignoring reloc %s\n"), reloc->howto->name);
384
      break;
385
 
386
    }
387
  *src_ptr = src_address;
388
  *dst_ptr = dst_address;
389
 
390
}
391
 
392
#define coff_reloc16_extra_cases h8300_reloc16_extra_cases
393
#define coff_reloc16_estimate h8300_reloc16_estimate
394
 
395
#include "coffcode.h"
396
 
397
 
398
#undef coff_bfd_get_relocated_section_contents
399
#undef coff_bfd_relax_section
400
#define coff_bfd_get_relocated_section_contents \
401
  bfd_coff_reloc16_get_relocated_section_contents
402
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
403
 
404
CREATE_LITTLE_COFF_TARGET_VEC (w65_vec, "coff-w95", 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.