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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [aout-ns32k.c] - Blame information for rev 1783

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

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

powered by: WebSVN 2.1.0

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