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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [bfd/] [aout-ns32k.c] - Blame information for rev 1780

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

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

powered by: WebSVN 2.1.0

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