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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [coff-z8k.c] - Blame information for rev 38

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

Line No. Rev Author Line
1 38 julius
/* BFD back-end for Zilog Z800n COFF binaries.
2
   Copyright 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
3
   2004, 2005, 2007 Free Software Foundation, Inc.
4
   Contributed by Cygnus Support.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
#include "sysdep.h"
25
#include "bfd.h"
26
#include "libbfd.h"
27
#include "bfdlink.h"
28
#include "coff/z8k.h"
29
#include "coff/internal.h"
30
#include "libcoff.h"
31
 
32
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
33
 
34
static reloc_howto_type r_imm32 =
35
HOWTO (R_IMM32, 0, 2, 32, FALSE, 0,
36
       complain_overflow_bitfield, 0, "r_imm32", TRUE, 0xffffffff,
37
       0xffffffff, FALSE);
38
 
39
static reloc_howto_type r_imm4l =
40
HOWTO (R_IMM4L, 0, 0, 4, FALSE, 0,
41
       complain_overflow_bitfield, 0, "r_imm4l", TRUE, 0xf, 0xf, FALSE);
42
 
43
static reloc_howto_type r_da =
44
HOWTO (R_IMM16, 0, 1, 16, FALSE, 0,
45
       complain_overflow_bitfield, 0, "r_da", TRUE, 0x0000ffff, 0x0000ffff,
46
       FALSE);
47
 
48
static reloc_howto_type r_imm8 =
49
HOWTO (R_IMM8, 0, 0, 8, FALSE, 0,
50
       complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff,
51
       FALSE);
52
 
53
static reloc_howto_type r_rel16 =
54
HOWTO (R_REL16, 0, 1, 16, FALSE, 0,
55
       complain_overflow_bitfield, 0, "r_rel16", TRUE, 0x0000ffff, 0x0000ffff,
56
       TRUE);
57
 
58
static reloc_howto_type r_jr =
59
HOWTO (R_JR, 1, 0, 8, TRUE, 0, complain_overflow_signed, 0,
60
       "r_jr", TRUE, 0xff, 0xff, TRUE);
61
 
62
static reloc_howto_type r_disp7 =
63
HOWTO (R_DISP7, 0, 0, 7, TRUE, 0, complain_overflow_bitfield, 0,
64
       "r_disp7", TRUE, 0x7f, 0x7f, TRUE);
65
 
66
static reloc_howto_type r_callr =
67
HOWTO (R_CALLR, 1, 1, 12, TRUE, 0, complain_overflow_signed, 0,
68
       "r_callr", TRUE, 0xfff, 0xfff, TRUE);
69
 
70
#define BADMAG(x) Z8KBADMAG(x)
71
#define Z8K 1                   /* Customize coffcode.h.  */
72
#define __A_MAGIC_SET__
73
 
74
/* Code to swap in the reloc.  */
75
#define SWAP_IN_RELOC_OFFSET    H_GET_32
76
#define SWAP_OUT_RELOC_OFFSET   H_PUT_32
77
#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
78
  dst->r_stuff[0] = 'S'; \
79
  dst->r_stuff[1] = 'C';
80
 
81
/* Code to turn a r_type into a howto ptr, uses the above howto table.  */
82
 
83
static void
84
rtype2howto (arelent *internal, struct internal_reloc *dst)
85
{
86
  switch (dst->r_type)
87
    {
88
    default:
89
      abort ();
90
      break;
91
    case R_IMM8:
92
      internal->howto = &r_imm8;
93
      break;
94
     case R_IMM16:
95
      internal->howto = &r_da;
96
      break;
97
    case R_JR:
98
      internal->howto = &r_jr;
99
      break;
100
    case R_DISP7:
101
      internal->howto = &r_disp7;
102
      break;
103
    case R_CALLR:
104
      internal->howto = &r_callr;
105
      break;
106
    case R_REL16:
107
      internal->howto = &r_rel16;
108
      break;
109
    case R_IMM32:
110
      internal->howto = &r_imm32;
111
      break;
112
    case R_IMM4L:
113
      internal->howto = &r_imm4l;
114
      break;
115
    }
116
}
117
 
118
#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
119
 
120
static reloc_howto_type *
121
coff_z8k_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
122
                            bfd_reloc_code_real_type code)
123
{
124
  switch (code)
125
    {
126
    case BFD_RELOC_8:           return & r_imm8;
127
    case BFD_RELOC_16:          return & r_da;
128
    case BFD_RELOC_32:          return & r_imm32;
129
    case BFD_RELOC_8_PCREL:     return & r_jr;
130
    case BFD_RELOC_16_PCREL:    return & r_rel16;
131
    case BFD_RELOC_Z8K_DISP7:   return & r_disp7;
132
    case BFD_RELOC_Z8K_CALLR:   return & r_callr;
133
    case BFD_RELOC_Z8K_IMM4L:   return & r_imm4l;
134
    default:                    BFD_FAIL ();
135
      return 0;
136
    }
137
}
138
 
139
static reloc_howto_type *
140
coff_z8k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
141
                            const char *r_name)
142
{
143
  if (strcasecmp (r_imm8.name, r_name) == 0)
144
    return &r_imm8;
145
  if (strcasecmp (r_da.name, r_name) == 0)
146
    return &r_da;
147
  if (strcasecmp (r_imm32.name, r_name) == 0)
148
    return &r_imm32;
149
  if (strcasecmp (r_jr.name, r_name) == 0)
150
    return &r_jr;
151
  if (strcasecmp (r_rel16.name, r_name) == 0)
152
    return &r_rel16;
153
  if (strcasecmp (r_disp7.name, r_name) == 0)
154
    return &r_disp7;
155
  if (strcasecmp (r_callr.name, r_name) == 0)
156
    return &r_callr;
157
  if (strcasecmp (r_imm4l.name, r_name) == 0)
158
    return &r_imm4l;
159
 
160
  return NULL;
161
}
162
 
163
/* Perform any necessary magic to the addend in a reloc entry.  */
164
 
165
#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
166
 cache_ptr->addend =  ext_reloc.r_offset;
167
 
168
#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
169
 reloc_processing(relent, reloc, symbols, abfd, section)
170
 
171
static void
172
reloc_processing (arelent *relent,
173
                  struct internal_reloc *reloc,
174
                  asymbol **symbols,
175
                  bfd *abfd,
176
                  asection *section)
177
{
178
  relent->address = reloc->r_vaddr;
179
  rtype2howto (relent, reloc);
180
 
181
  if (reloc->r_symndx > 0)
182
    relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
183
  else
184
    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
185
 
186
  relent->addend = reloc->r_offset;
187
  relent->address -= section->vma;
188
}
189
 
190
static void
191
extra_case (bfd *in_abfd,
192
            struct bfd_link_info *link_info,
193
            struct bfd_link_order *link_order,
194
            arelent *reloc,
195
            bfd_byte *data,
196
            unsigned int *src_ptr,
197
            unsigned int *dst_ptr)
198
{
199
  asection * input_section = link_order->u.indirect.section;
200
 
201
  switch (reloc->howto->type)
202
    {
203
    case R_IMM8:
204
      bfd_put_8 (in_abfd,
205
                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
206
                 data + *dst_ptr);
207
      (*dst_ptr) += 1;
208
      (*src_ptr) += 1;
209
      break;
210
 
211
    case R_IMM32:
212
      /* If no flags are set, assume immediate value.  */
213
      if (! (*reloc->sym_ptr_ptr)->section->flags)
214
        {
215
          bfd_put_32 (in_abfd,
216
                      bfd_coff_reloc16_get_value (reloc, link_info,
217
                                                  input_section),
218
                      data + *dst_ptr);
219
        }
220
      else
221
        {
222
          bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
223
                                                    input_section);
224
          /* Addresses are 23 bit, and the layout of those in a 32-bit
225
             value is as follows:
226
               1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA
227
             (A - address bits,  x - ignore).  */
228
          dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
229
          bfd_put_32 (in_abfd, dst, data + *dst_ptr);
230
        }
231
      (*dst_ptr) += 4;
232
      (*src_ptr) += 4;
233
      break;
234
 
235
    case R_IMM4L:
236
      bfd_put_8 (in_abfd,
237
                 ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
238
                  | (0x0f
239
                     & bfd_coff_reloc16_get_value (reloc, link_info,
240
                                                   input_section))),
241
                 data + *dst_ptr);
242
      (*dst_ptr) += 1;
243
      (*src_ptr) += 1;
244
      break;
245
 
246
    case R_IMM16:
247
      bfd_put_16 (in_abfd,
248
                  bfd_coff_reloc16_get_value (reloc, link_info, input_section),
249
                  data + *dst_ptr);
250
      (*dst_ptr) += 2;
251
      (*src_ptr) += 2;
252
      break;
253
 
254
    case R_JR:
255
      {
256
        bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
257
                                                  input_section);
258
        bfd_vma dot = (*dst_ptr
259
                       + input_section->output_offset
260
                       + input_section->output_section->vma);
261
        int gap = dst - dot - 1;  /* -1, since we're in the odd byte of the
262
                                     word and the pc's been incremented.  */
263
 
264
        if (gap & 1)
265
          abort ();
266
        gap /= 2;
267
        if (gap > 128 || gap < -128)
268
          {
269
            if (! ((*link_info->callbacks->reloc_overflow)
270
                   (link_info, NULL,
271
                    bfd_asymbol_name (*reloc->sym_ptr_ptr),
272
                    reloc->howto->name, reloc->addend, input_section->owner,
273
                    input_section, reloc->address)))
274
              abort ();
275
          }
276
        bfd_put_8 (in_abfd, gap, data + *dst_ptr);
277
        (*dst_ptr)++;
278
        (*src_ptr)++;
279
        break;
280
      }
281
 
282
    case R_DISP7:
283
      {
284
        bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
285
                                                  input_section);
286
        bfd_vma dot = (*dst_ptr
287
                       + input_section->output_offset
288
                       + input_section->output_section->vma);
289
        int gap = dst - dot - 1;  /* -1, since we're in the odd byte of the
290
                                     word and the pc's been incremented.  */
291
 
292
        if (gap & 1)
293
          abort ();
294
        gap /= 2;
295
 
296
        if (gap > 0 || gap < -127)
297
          {
298
            if (! ((*link_info->callbacks->reloc_overflow)
299
                   (link_info, NULL,
300
                    bfd_asymbol_name (*reloc->sym_ptr_ptr),
301
                    reloc->howto->name, reloc->addend, input_section->owner,
302
                    input_section, reloc->address)))
303
              abort ();
304
          }
305
        bfd_put_8 (in_abfd,
306
                   (bfd_get_8 ( in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f),
307
                   data + *dst_ptr);
308
        (*dst_ptr)++;
309
        (*src_ptr)++;
310
        break;
311
      }
312
 
313
    case R_CALLR:
314
      {
315
        bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
316
                                                  input_section);
317
        bfd_vma dot = (*dst_ptr
318
                       + input_section->output_offset
319
                       + input_section->output_section->vma);
320
        int gap = dst - dot - 2;
321
 
322
        if (gap & 1)
323
          abort ();
324
        if (gap > 4096 || gap < -4095)
325
          {
326
            if (! ((*link_info->callbacks->reloc_overflow)
327
                   (link_info, NULL,
328
                    bfd_asymbol_name (*reloc->sym_ptr_ptr),
329
                    reloc->howto->name, reloc->addend, input_section->owner,
330
                    input_section, reloc->address)))
331
              abort ();
332
          }
333
        gap /= 2;
334
        bfd_put_16 (in_abfd,
335
                    (bfd_get_16 ( in_abfd, data + *dst_ptr) & 0xf000) | (-gap & 0x0fff),
336
                    data + *dst_ptr);
337
        (*dst_ptr) += 2;
338
        (*src_ptr) += 2;
339
        break;
340
      }
341
 
342
    case R_REL16:
343
      {
344
        bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
345
                                                  input_section);
346
        bfd_vma dot = (*dst_ptr
347
                       + input_section->output_offset
348
                       + input_section->output_section->vma);
349
        int gap = dst - dot - 2;
350
 
351
        if (gap > 32767 || gap < -32768)
352
          {
353
            if (! ((*link_info->callbacks->reloc_overflow)
354
                   (link_info, NULL,
355
                    bfd_asymbol_name (*reloc->sym_ptr_ptr),
356
                    reloc->howto->name, reloc->addend, input_section->owner,
357
                    input_section, reloc->address)))
358
              abort ();
359
          }
360
        bfd_put_16 (in_abfd, (bfd_vma) gap, data + *dst_ptr);
361
        (*dst_ptr) += 2;
362
        (*src_ptr) += 2;
363
        break;
364
      }
365
 
366
    default:
367
      abort ();
368
    }
369
}
370
 
371
#define coff_reloc16_extra_cases    extra_case
372
#define coff_bfd_reloc_type_lookup  coff_z8k_reloc_type_lookup
373
#define coff_bfd_reloc_name_lookup coff_z8k_reloc_name_lookup
374
 
375
#include "coffcode.h"
376
 
377
#undef  coff_bfd_get_relocated_section_contents
378
#define coff_bfd_get_relocated_section_contents \
379
  bfd_coff_reloc16_get_relocated_section_contents
380
 
381
#undef  coff_bfd_relax_section
382
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
383
 
384
CREATE_BIG_COFF_TARGET_VEC (z8kcoff_vec, "coff-z8k", 0, 0, '_', NULL, COFF_SWAP_TABLE)

powered by: WebSVN 2.1.0

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