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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [aout-ns32k.c] - Blame information for rev 84

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for ns32k a.out-ish binaries.
2
   Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
3
   2002, 2003, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
4
   Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "bfd.h"
24
#include "aout/aout64.h"
25
#include "ns32k.h"
26
 
27
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
28
   remove whitespace added here, and thus will fail to concatenate
29
   the tokens.  */
30
#define MYNS(OP) CONCAT2 (ns32kaout_,OP)
31
 
32
reloc_howto_type * MYNS (bfd_reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
33
reloc_howto_type * MYNS (bfd_reloc_name_lookup) (bfd *, const char *);
34
bfd_boolean        MYNS (write_object_contents) (bfd *);
35
 
36
/* Avoid multiple definitions from aoutx if supporting
37
   standard a.out format(s) as well as this one.  */
38
#define NAME(x,y) CONCAT3 (ns32kaout,_32_,y)
39
 
40
void bfd_ns32k_arch (void);
41
 
42
#include "libaout.h"
43
 
44
#define MY(OP) MYNS (OP)
45
 
46
#define MY_swap_std_reloc_in   MY (swap_std_reloc_in)
47
#define MY_swap_std_reloc_out  MY (swap_std_reloc_out)
48
 
49
/* The ns32k series is ah, unusual, when it comes to relocation.
50
   There are three storage methods for relocatable objects.  There
51
   are displacements, immediate operands and ordinary twos complement
52
   data. Of these, only the last fits into the standard relocation
53
   scheme.  Immediate operands are stored huffman encoded and
54
   immediate operands are stored big endian (where as the natural byte
55
   order is little endian for this architecture).
56
 
57
   Note that the ns32k displacement storage method is orthogonal to
58
   whether the relocation is pc relative or not. The "displacement"
59
   storage scheme is used for essentially all address constants. The
60
   displacement can be relative to zero (absolute displacement),
61
   relative to the pc (pc relative), the stack pointer, the frame
62
   pointer, the static base register and general purpose register etc.
63
 
64
   For example:
65
 
66
   sym1: .long .         # pc relative 2's complement
67
   sym1: .long foo       # 2's complement not pc relative
68
 
69
   self:  movd @self, r0 # pc relative displacement
70
          movd foo, r0   # non pc relative displacement
71
 
72
   self:  movd self, r0  # pc relative immediate
73
          movd foo, r0   # non pc relative immediate
74
 
75
   In addition, for historical reasons the encoding of the relocation types
76
   in the a.out format relocation entries is such that even the relocation
77
   methods which are standard are not encoded the standard way.  */
78
 
79
reloc_howto_type MY (howto_table)[] =
80
{
81
  /* ns32k immediate operands.  */
82
  HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
83
         _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
84
         TRUE, 0x000000ff,0x000000ff, FALSE),
85
  HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
86
         _bfd_ns32k_reloc_imm,  "NS32K_IMM_16",
87
         TRUE, 0x0000ffff,0x0000ffff, FALSE),
88
  HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
89
         _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
90
         TRUE, 0xffffffff,0xffffffff, FALSE),
91
  HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed,
92
         _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
93
         TRUE, 0x000000ff, 0x000000ff, FALSE),
94
  HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed,
95
         _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
96
         TRUE, 0x0000ffff,0x0000ffff, FALSE),
97
  HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
98
         _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
99
         TRUE, 0xffffffff,0xffffffff, FALSE),
100
 
101
  /* ns32k displacements.  */
102
  HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, FALSE, 0, complain_overflow_signed,
103
         _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
104
         TRUE, 0x000000ff,0x000000ff, FALSE),
105
  HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, FALSE, 0, complain_overflow_signed,
106
         _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
107
         TRUE, 0x0000ffff, 0x0000ffff, FALSE),
108
  HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, FALSE, 0, complain_overflow_signed,
109
         _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
110
         TRUE, 0xffffffff, 0xffffffff, FALSE),
111
  HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, TRUE, 0, complain_overflow_signed,
112
           _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
113
         TRUE, 0x000000ff,0x000000ff, FALSE),
114
  HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, TRUE, 0, complain_overflow_signed,
115
         _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
116
         TRUE, 0x0000ffff,0x0000ffff, FALSE),
117
  HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, TRUE, 0, complain_overflow_signed,
118
         _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
119
         TRUE, 0xffffffff,0xffffffff, FALSE),
120
 
121
  /* Normal 2's complement.  */
122
  HOWTO (BFD_RELOC_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,0,
123
         "8", TRUE, 0x000000ff,0x000000ff, FALSE),
124
  HOWTO (BFD_RELOC_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,0,
125
         "16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
126
  HOWTO (BFD_RELOC_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,
127
         "32", TRUE, 0xffffffff,0xffffffff, FALSE),
128
  HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0,
129
         "PCREL_8", TRUE, 0x000000ff,0x000000ff, FALSE),
130
  HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0,
131
         "PCREL_16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
132
  HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0,
133
         "PCREL_32", TRUE, 0xffffffff,0xffffffff, FALSE),
134
};
135
 
136
#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY (howto_table) + 14)
137
 
138
#define RELOC_STD_BITS_NS32K_TYPE_BIG           0x06
139
#define RELOC_STD_BITS_NS32K_TYPE_LITTLE        0x60
140
#define RELOC_STD_BITS_NS32K_TYPE_SH_BIG        1
141
#define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE     5
142
 
143
static reloc_howto_type *
144
MY (reloc_howto) (bfd *abfd ATTRIBUTE_UNUSED,
145
                  struct reloc_std_external *rel,
146
                  int *r_index,
147
                  int *r_extern,
148
                  int *r_pcrel)
149
{
150
  unsigned int r_length;
151
  int r_ns32k_type;
152
 
153
  *r_index =  ((rel->r_index[2] << 16)
154
               | (rel->r_index[1] << 8)
155
               |  rel->r_index[0] );
156
  *r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
157
  *r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
158
  r_length  =  ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
159
                >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
160
  r_ns32k_type  =  ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE)
161
                    >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
162
  return (MY (howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type);
163
}
164
 
165
#define MY_reloc_howto(BFD, REL, IN, EX, PC) \
166
  MY (reloc_howto) (BFD, REL, &IN, &EX, &PC)
167
 
168
static void
169
MY (put_reloc) (bfd *abfd,
170
                int r_extern,
171
                int r_index,
172
                bfd_vma value,
173
                reloc_howto_type *howto,
174
                struct reloc_std_external *reloc)
175
{
176
  unsigned int r_length;
177
  int r_pcrel;
178
  int r_ns32k_type;
179
 
180
  PUT_WORD (abfd, value, reloc->r_address);
181
  r_length = howto->size ;      /* Size as a power of two.  */
182
  r_pcrel  = (int) howto->pc_relative; /* Relative to PC?  */
183
  r_ns32k_type = (howto - MY (howto_table) )/6;
184
 
185
  reloc->r_index[2] = r_index >> 16;
186
  reloc->r_index[1] = r_index >> 8;
187
  reloc->r_index[0] = r_index;
188
  reloc->r_type[0] =
189
    (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
190
      | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
191
        | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE)
192
          | (r_ns32k_type <<  RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
193
}
194
 
195
#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
196
  MY (put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC)
197
 
198
#define STAT_FOR_EXEC
199
 
200
#define MY_final_link_relocate _bfd_ns32k_final_link_relocate
201
#define MY_relocate_contents   _bfd_ns32k_relocate_contents
202
 
203
static void MY_swap_std_reloc_in (bfd *, struct reloc_std_external *, arelent *, asymbol **, bfd_size_type);
204
static void MY_swap_std_reloc_out (bfd *, arelent *, struct reloc_std_external *);
205
 
206
#include "aoutx.h"
207
 
208
reloc_howto_type *
209
MY (bfd_reloc_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code)
210
{
211
#define ENTRY(i,j)      case i: return &MY (howto_table)[j]
212
 
213
  int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
214
 
215
  BFD_ASSERT (ext == 0);
216
  if (code == BFD_RELOC_CTOR)
217
    switch (bfd_arch_bits_per_address (abfd))
218
      {
219
      case 32:
220
        code = BFD_RELOC_32;
221
        break;
222
      default:
223
        break;
224
      }
225
  switch (code)
226
    {
227
      ENTRY (BFD_RELOC_NS32K_IMM_8, 0);
228
      ENTRY (BFD_RELOC_NS32K_IMM_16, 1);
229
      ENTRY (BFD_RELOC_NS32K_IMM_32, 2);
230
      ENTRY (BFD_RELOC_NS32K_IMM_8_PCREL, 3);
231
      ENTRY (BFD_RELOC_NS32K_IMM_16_PCREL, 4);
232
      ENTRY (BFD_RELOC_NS32K_IMM_32_PCREL, 5);
233
      ENTRY (BFD_RELOC_NS32K_DISP_8, 6);
234
      ENTRY (BFD_RELOC_NS32K_DISP_16, 7);
235
      ENTRY (BFD_RELOC_NS32K_DISP_32, 8);
236
      ENTRY (BFD_RELOC_NS32K_DISP_8_PCREL, 9);
237
      ENTRY (BFD_RELOC_NS32K_DISP_16_PCREL, 10);
238
      ENTRY (BFD_RELOC_NS32K_DISP_32_PCREL, 11);
239
      ENTRY (BFD_RELOC_8, 12);
240
      ENTRY (BFD_RELOC_16, 13);
241
      ENTRY (BFD_RELOC_32, 14);
242
      ENTRY (BFD_RELOC_8_PCREL, 15);
243
      ENTRY (BFD_RELOC_16_PCREL, 16);
244
      ENTRY (BFD_RELOC_32_PCREL, 17);
245
    default:
246
      return NULL;
247
    }
248
#undef ENTRY
249
}
250
 
251
reloc_howto_type *
252
MY (bfd_reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
253
                            const char *r_name)
254
{
255
  unsigned int i;
256
 
257
  for (i = 0;
258
       i < sizeof (MY (howto_table)) / sizeof (MY (howto_table)[0]);
259
       i++)
260
    if (MY (howto_table)[i].name != NULL
261
        && strcasecmp (MY (howto_table)[i].name, r_name) == 0)
262
      return &MY (howto_table)[i];
263
 
264
  return NULL;
265
}
266
 
267
static void
268
MY_swap_std_reloc_in (bfd *abfd,
269
                      struct reloc_std_external *bytes,
270
                      arelent *cache_ptr,
271
                      asymbol **symbols,
272
                      bfd_size_type symcount ATTRIBUTE_UNUSED)
273
{
274
  int r_index;
275
  int r_extern;
276
  int r_pcrel;
277
  struct aoutdata  *su = &(abfd->tdata.aout_data->a);
278
 
279
  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
280
 
281
  /* Now the fun stuff.  */
282
  cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel);
283
 
284
  MOVE_ADDRESS (0);
285
}
286
 
287
static void
288
MY_swap_std_reloc_out (bfd *abfd,
289
                       arelent *g,
290
                       struct reloc_std_external *natptr)
291
{
292
  int r_index;
293
  asymbol *sym = *(g->sym_ptr_ptr);
294
  int r_extern;
295
  asection *output_section = sym->section->output_section;
296
 
297
  /* Name was clobbered by aout_write_syms to be symbol index.  */
298
 
299
  /* If this relocation is relative to a symbol then set the
300
     r_index to the symbols index, and the r_extern bit.
301
 
302
     Absolute symbols can come in in two ways, either as an offset
303
     from the abs section, or as a symbol which has an abs value.
304
     Check for that here.  */
305
  if (bfd_is_com_section (output_section)
306
      || output_section == &bfd_abs_section
307
      || output_section == &bfd_und_section)
308
    {
309
      if (bfd_abs_section.symbol == sym)
310
        {
311
          /* Whoops, looked like an abs symbol, but is really an offset
312
             from the abs section.  */
313
          r_index = 0;
314
          r_extern = 0;
315
        }
316
      else
317
        {
318
          /* Fill in symbol.  */
319
          r_extern = 1;
320
#undef KEEPIT
321
#define KEEPIT udata.i
322
          r_index =  (*(g->sym_ptr_ptr))->KEEPIT;
323
#undef KEEPIT
324
        }
325
    }
326
  else
327
    {
328
      /* Just an ordinary section.  */
329
      r_extern = 0;
330
      r_index  = output_section->target_index;
331
    }
332
 
333
  MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
334
}
335
 
336
bfd_reloc_status_type
337
_bfd_ns32k_relocate_contents (reloc_howto_type *howto,
338
                              bfd *input_bfd,
339
                              bfd_vma relocation,
340
                              bfd_byte *location)
341
{
342
  int r_ns32k_type = (howto - MY (howto_table)) / 6;
343
  bfd_vma (*get_data) (bfd_byte *, int);
344
  void (*put_data) (bfd_vma, bfd_byte *, int);
345
 
346
  switch (r_ns32k_type)
347
    {
348
    case 0:
349
      get_data = _bfd_ns32k_get_immediate;
350
      put_data = _bfd_ns32k_put_immediate;
351
      break;
352
    case 1:
353
      get_data = _bfd_ns32k_get_displacement;
354
      put_data = _bfd_ns32k_put_displacement;
355
      break;
356
    case 2:
357
      return _bfd_relocate_contents (howto, input_bfd, relocation,
358
                                    location);
359
    default:
360
      return bfd_reloc_notsupported;
361
    }
362
  return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
363
                                       location, get_data, put_data);
364
}

powered by: WebSVN 2.1.0

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