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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* BFD back-end for ns32k a.out-ish binaries.
2
   Copyright (C) 1990, 91, 92, 94, 95, 96, 1998 Free Software Foundation, Inc.
3
   Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
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
#define BYTES_IN_WORD 4
22
 
23
#include "bfd.h"
24
#include "aout/aout64.h"
25
#include "ns32k.h"
26
 
27
#define MYNS(OP) CAT(ns32kaout_,OP)
28
reloc_howto_type *
29
MYNS(bfd_reloc_type_lookup)
30
  PARAMS((bfd *abfd AND
31
          bfd_reloc_code_real_type code));
32
 
33
boolean
34
MYNS(write_object_contents)
35
  PARAMS((bfd *abfd));
36
 
37
/* Avoid multiple definitions from aoutx if supporting standard a.out format(s)
38
 * as well as this one
39
 */
40
#define NAME(x,y) CAT3(ns32kaout,_32_,y)
41
 
42
void bfd_ns32k_arch PARAMS ((void));
43
 
44
#include "libaout.h"
45
 
46
#define MY(OP) MYNS(OP)
47
 
48
#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
49
#define MY_swap_std_reloc_out MY(swap_std_reloc_out)
50
 
51
static void
52
MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes,
53
                              arelent *cache_ptr, asymbol **symbols,
54
                              bfd_size_type symcount));
55
 
56
static void
57
MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g,
58
                               struct reloc_std_external *natptr));
59
 
60
/* The ns32k series is ah, unusual, when it comes to relocation.
61
 * There are three storage methods for relocateable objects.  There
62
 * are displacements, immediate operands and ordinary twos complement
63
 * data. Of these, only the last fits into the standard relocation
64
 * scheme.  Immediate operands are stored huffman encoded and
65
 * immediate operands are stored big endian (where as the natural byte
66
 * order is little endian for this achitecture).
67
 
68
 * Note that the ns32k displacement storage method is orthogonal to
69
 * whether the relocation is pc relative or not. The "displacement"
70
 * storage scheme is used for essentially all address constants. The
71
 * displacement can be relative to zero (absolute displacement),
72
 * relative to the pc (pc relative), the stack pointer, the frame
73
 * pointer, the static base register and general purpose register etc.
74
 
75
 * For example:
76
 *
77
 *  sym1: .long .       # pc relative 2's complement
78
 *  sym1: .long foo     # 2's complement not pc relative
79
 *
80
 *  self:  movd @self, r0 # pc relative displacement
81
 *         movd foo, r0 # non pc relative displacement
82
 *
83
 *  self:  movd self, r0 # pc relative immediate
84
 *         movd foo, r0 # non pc relative immediate
85
 *
86
 * In addition, for historical reasons the encoding of the relocation types
87
 * in the a.out format relocation entries is such that even the relocation
88
 * methods which are standard are not encoded the standard way.
89
 *
90
 */
91
 
92
reloc_howto_type MY(howto_table)[] =
93
{
94
  /* ns32k immediate operands */
95
  HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true,
96
         _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
97
         true, 0x000000ff,0x000000ff, false),
98
  HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true,
99
         _bfd_ns32k_reloc_imm,  "NS32K_IMM_16",
100
         true, 0x0000ffff,0x0000ffff, false),
101
  HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true,
102
         _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
103
         true, 0xffffffff,0xffffffff, false),
104
  HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false,
105
         _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
106
         true, 0x000000ff, 0x000000ff, false),
107
  HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false,
108
         _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
109
         true, 0x0000ffff,0x0000ffff, false),
110
  HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false,
111
         _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
112
         true, 0xffffffff,0xffffffff, false),
113
 
114
  /* ns32k displacements */
115
  HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true,
116
         _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
117
         true, 0x000000ff,0x000000ff, false),
118
  HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true,
119
         _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
120
         true, 0x0000ffff, 0x0000ffff, false),
121
  HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true,
122
         _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
123
         true, 0xffffffff, 0xffffffff, false),
124
  HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false,
125
         _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
126
         true, 0x000000ff,0x000000ff, false),
127
  HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false,
128
         _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
129
         true, 0x0000ffff,0x0000ffff, false),
130
  HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false,
131
         _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
132
         true, 0xffffffff,0xffffffff, false),
133
 
134
  /* Normal 2's complement */
135
  HOWTO (BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,
136
         "8", true, 0x000000ff,0x000000ff, false),
137
  HOWTO (BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,
138
         "16", true, 0x0000ffff,0x0000ffff, false),
139
  HOWTO (BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,
140
         "32", true, 0xffffffff,0xffffffff, false),
141
  HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0,
142
         "PCREL_8", true, 0x000000ff,0x000000ff, false),
143
  HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0,
144
         "PCREL_16", true, 0x0000ffff,0x0000ffff, false),
145
  HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0,
146
         "PCREL_32", true, 0xffffffff,0xffffffff, false),
147
};
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
 
263
static void
264
MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
265
     bfd *abfd;
266
     struct reloc_std_external *bytes;
267
     arelent *cache_ptr;
268
     asymbol **symbols;
269
     bfd_size_type symcount ATTRIBUTE_UNUSED;
270
{
271
  int r_index;
272
  int r_extern;
273
  int r_pcrel;
274
  struct aoutdata  *su = &(abfd->tdata.aout_data->a);
275
 
276
  cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
277
 
278
  /* now the fun stuff */
279
 
280
  cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel);
281
 
282
  MOVE_ADDRESS(0);
283
}
284
 
285
static void
286
MY_swap_std_reloc_out (abfd, g, natptr)
287
     bfd *abfd;
288
     arelent *g;
289
     struct reloc_std_external *natptr;
290
{
291
  int r_index;
292
  asymbol *sym = *(g->sym_ptr_ptr);
293
  int r_extern;
294
  unsigned int r_addend;
295
  asection *output_section = sym->section->output_section;
296
 
297
  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
298
 
299
  /* name was clobbered by aout_write_syms to be symbol index */
300
 
301
  /* If this relocation is relative to a symbol then set the
302
     r_index to the symbols index, and the r_extern bit.
303
 
304
     Absolute symbols can come in in two ways, either as an offset
305
     from the abs section, or as a symbol which has an abs value.
306
     Check for that here.  */
307
 
308
  if (bfd_is_com_section (output_section)
309
      || output_section == &bfd_abs_section
310
      || output_section == &bfd_und_section)
311
    {
312
      if (bfd_abs_section.symbol == sym)
313
        {
314
          /* Whoops, looked like an abs symbol, but is really an offset
315
             from the abs section */
316
          r_index = 0;
317
          r_extern = 0;
318
        }
319
      else
320
        {
321
          /* Fill in symbol */
322
          r_extern = 1;
323
#undef KEEPIT
324
#define KEEPIT udata.i
325
          r_index =  (*(g->sym_ptr_ptr))->KEEPIT;
326
#undef KEEPIT     
327
        }
328
    }
329
  else
330
    {
331
      /* Just an ordinary section */
332
      r_extern = 0;
333
      r_index  = output_section->target_index;
334
    }
335
 
336
  MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
337
}
338
 
339
bfd_reloc_status_type
340
_bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
341
     reloc_howto_type *howto;
342
     bfd *input_bfd;
343
     bfd_vma relocation;
344
     bfd_byte *location;
345
{
346
  int r_ns32k_type = (howto - MY(howto_table)) / 6;
347
  long (*get_data) PARAMS ((bfd_byte *, long, long));
348
  int (*put_data) PARAMS ((long, bfd_byte *, long, long));
349
 
350
  switch (r_ns32k_type)
351
    {
352
    case 0:
353
      get_data = _bfd_ns32k_get_immediate;
354
      put_data = _bfd_ns32k_put_immediate;
355
      break;
356
    case 1:
357
      get_data = _bfd_ns32k_get_displacement;
358
      put_data = _bfd_ns32k_put_displacement;
359
      break;
360
    case 2:
361
      return _bfd_relocate_contents (howto, input_bfd, relocation,
362
                                    location);
363
      /* NOT REACHED */
364
      break;
365
    default:
366
      return bfd_reloc_notsupported;
367
    }
368
  return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
369
                                       location, get_data, put_data);
370
}

powered by: WebSVN 2.1.0

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