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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [nlm32-sparc.c] - Blame information for rev 1770

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

Line No. Rev Author Line
1 578 markom
/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2
   Copyright 1993, 1994, 2000 Free Software Foundation, Inc.
3
 
4
This file is part of BFD, the Binary File Descriptor library.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
 
20
#include "bfd.h"
21
#include "sysdep.h"
22
#include "libbfd.h"
23
 
24
#define ARCH_SIZE 32
25
 
26
#include "nlm/sparc32-ext.h"
27
#define Nlm_External_Fixed_Header       Nlm32_sparc_External_Fixed_Header
28
 
29
#include "libnlm.h"
30
 
31
static boolean nlm_sparc_read_reloc
32
  PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
33
static boolean nlm_sparc_write_reloc
34
  PARAMS ((bfd *, asection *, arelent *));
35
static boolean nlm_sparc_mangle_relocs
36
  PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
37
static boolean nlm_sparc_read_import
38
  PARAMS ((bfd *, nlmNAME(symbol_type) *));
39
static boolean nlm_sparc_write_import
40
  PARAMS ((bfd *, asection *, arelent *));
41
static boolean nlm_sparc_write_external
42
  PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
43
 
44
enum reloc_type
45
  {
46
    R_SPARC_NONE = 0,
47
    R_SPARC_8,          R_SPARC_16,             R_SPARC_32,
48
    R_SPARC_DISP8,      R_SPARC_DISP16,         R_SPARC_DISP32,
49
    R_SPARC_WDISP30,    R_SPARC_WDISP22,
50
    R_SPARC_HI22,       R_SPARC_22,
51
    R_SPARC_13,         R_SPARC_LO10,
52
    R_SPARC_GOT10,      R_SPARC_GOT13,          R_SPARC_GOT22,
53
    R_SPARC_PC10,       R_SPARC_PC22,
54
    R_SPARC_WPLT30,
55
    R_SPARC_COPY,
56
    R_SPARC_GLOB_DAT,   R_SPARC_JMP_SLOT,
57
    R_SPARC_RELATIVE,
58
    R_SPARC_UA32,
59
    R_SPARC_max
60
  };
61
 
62
#if 0
63
static CONST char *CONST reloc_type_names[] =
64
{
65
  "R_SPARC_NONE",
66
  "R_SPARC_8",          "R_SPARC_16",           "R_SPARC_32",
67
  "R_SPARC_DISP8",      "R_SPARC_DISP16",       "R_SPARC_DISP32",
68
  "R_SPARC_WDISP30",    "R_SPARC_WDISP22",
69
  "R_SPARC_HI22",       "R_SPARC_22",
70
  "R_SPARC_13",         "R_SPARC_LO10",
71
  "R_SPARC_GOT10",      "R_SPARC_GOT13",        "R_SPARC_GOT22",
72
  "R_SPARC_PC10",       "R_SPARC_PC22",
73
  "R_SPARC_WPLT30",
74
  "R_SPARC_COPY",
75
  "R_SPARC_GLOB_DAT",   "R_SPARC_JMP_SLOT",
76
  "R_SPARC_RELATIVE",
77
  "R_SPARC_UA32",
78
};
79
#endif
80
 
81
static reloc_howto_type nlm32_sparc_howto_table[] =
82
{
83
  HOWTO(R_SPARC_NONE,    0,0, 0,false,0,complain_overflow_dont,    0,"R_SPARC_NONE",    false,0,0x00000000,true),
84
  HOWTO(R_SPARC_8,       0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8",       false,0,0x000000ff,true),
85
  HOWTO(R_SPARC_16,      0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16",      false,0,0x0000ffff,true),
86
  HOWTO(R_SPARC_32,      0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32",      false,0,0xffffffff,true),
87
  HOWTO(R_SPARC_DISP8,   0,0, 8,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP8",   false,0,0x000000ff,true),
88
  HOWTO(R_SPARC_DISP16,  0,1,16,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP16",  false,0,0x0000ffff,true),
89
  HOWTO(R_SPARC_DISP32,  0,2,32,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP32",  false,0,0x00ffffff,true),
90
  HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed,  0,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
91
  HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed,  0,"R_SPARC_WDISP22", false,0,0x003fffff,true),
92
  HOWTO(R_SPARC_HI22,   10,2,22,false,0,complain_overflow_dont,    0,"R_SPARC_HI22",    false,0,0x003fffff,true),
93
  HOWTO(R_SPARC_22,      0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22",      false,0,0x003fffff,true),
94
  HOWTO(R_SPARC_13,      0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13",      false,0,0x00001fff,true),
95
  HOWTO(R_SPARC_LO10,    0,2,10,false,0,complain_overflow_dont,    0,"R_SPARC_LO10",    false,0,0x000003ff,true),
96
  HOWTO(R_SPARC_GOT10,   0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10",   false,0,0x000003ff,true),
97
  HOWTO(R_SPARC_GOT13,   0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13",   false,0,0x00001fff,true),
98
  HOWTO(R_SPARC_GOT22,  10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22",   false,0,0x003fffff,true),
99
  HOWTO(R_SPARC_PC10,    0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10",    false,0,0x000003ff,true),
100
  HOWTO(R_SPARC_PC22,    0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22",    false,0,0x003fffff,true),
101
  HOWTO(R_SPARC_WPLT30,  0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_WPLT30",  false,0,0x00000000,true),
102
  HOWTO(R_SPARC_COPY,    0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_COPY",    false,0,0x00000000,true),
103
  HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
104
  HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
105
  HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_RELATIVE",false,0,0x00000000,true),
106
  HOWTO(R_SPARC_UA32,    0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_UA32",    false,0,0x00000000,true),
107
};
108
 
109
/* Read a NetWare sparc reloc.  */
110
 
111
struct nlm32_sparc_reloc_ext {
112
  unsigned char offset[4];
113
  unsigned char addend[4];
114
  unsigned char type[1];
115
  unsigned char pad1[3];
116
};
117
 
118
static boolean
119
nlm_sparc_read_reloc (abfd, sym, secp, rel)
120
     bfd *abfd;
121
     nlmNAME(symbol_type) *sym ATTRIBUTE_UNUSED;
122
     asection **secp;
123
     arelent *rel;
124
{
125
  bfd_vma val, addend;
126
  unsigned int index;
127
  unsigned int type;
128
  struct nlm32_sparc_reloc_ext tmp_reloc;
129
  asection *code_sec, *data_sec;
130
 
131
  if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
132
    return false;
133
 
134
  code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
135
  data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
136
 
137
  *secp = code_sec;
138
 
139
  val = bfd_get_32 (abfd, tmp_reloc.offset);
140
  addend = bfd_get_32 (abfd, tmp_reloc.addend);
141
  type = bfd_get_8 (abfd, tmp_reloc.type);
142
 
143
  rel->address = val;
144
  rel->addend = addend;
145
  rel->howto = NULL;
146
 
147
  for (index = 0;
148
       index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
149
       index++)
150
    if (nlm32_sparc_howto_table[index].type == type) {
151
      rel->howto = &nlm32_sparc_howto_table[index];
152
      break;
153
    }
154
 
155
#ifdef DEBUG
156
  fprintf (stderr, "%s:  address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
157
           __FUNCTION__, rel->address, rel->addend, type, rel->howto);
158
#endif
159
  return true;
160
 
161
}
162
 
163
/* Write a NetWare sparc reloc.  */
164
 
165
static boolean
166
nlm_sparc_write_reloc (abfd, sec, rel)
167
     bfd *abfd;
168
     asection *sec;
169
     arelent *rel;
170
{
171
  bfd_vma val;
172
  struct nlm32_sparc_reloc_ext tmp_reloc;
173
  unsigned int index;
174
  int type = -1;
175
  reloc_howto_type *tmp;
176
 
177
  for (index = 0;
178
       index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
179
       index++) {
180
    tmp = &nlm32_sparc_howto_table[index];
181
 
182
    if (tmp->rightshift == rel->howto->rightshift
183
        && tmp->size == rel->howto->size
184
        && tmp->bitsize == rel->howto->bitsize
185
        && tmp->pc_relative == rel->howto->pc_relative
186
        && tmp->bitpos == rel->howto->bitpos
187
        && tmp->src_mask == rel->howto->src_mask
188
        && tmp->dst_mask == rel->howto->dst_mask) {
189
      type = tmp->type;
190
      break;
191
    }
192
  }
193
  if (type == -1)
194
    abort ();
195
 
196
  /*
197
   * Netware wants a list of relocs for each address.
198
   * Format is:
199
   *    long    offset
200
   *    long    addend
201
   *    char    type
202
   * That should be it.
203
   */
204
 
205
  /* The value we write out is the offset into the appropriate
206
     segment.  This offset is the section vma, adjusted by the vma of
207
     the lowest section in that segment, plus the address of the
208
     relocation.  */
209
#if 0
210
  val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
211
#else
212
  val = bfd_get_section_vma (abfd, sec) + rel->address;
213
#endif
214
 
215
#ifdef DEBUG
216
  fprintf (stderr, "%s:  val = %08lx, addend = %08lx, type = %d\n",
217
           __FUNCTION__, val, rel->addend, rel->howto->type);
218
#endif
219
  bfd_put_32 (abfd, val, tmp_reloc.offset);
220
  bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
221
  bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
222
 
223
  if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
224
    return false;
225
 
226
  return true;
227
}
228
 
229
/* Mangle relocs for SPARC NetWare.  We can just use the standard
230
   SPARC relocs.  */
231
 
232
static boolean
233
nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
234
     bfd *abfd ATTRIBUTE_UNUSED;
235
     asection *sec ATTRIBUTE_UNUSED;
236
     PTR data ATTRIBUTE_UNUSED;
237
     bfd_vma offset ATTRIBUTE_UNUSED;
238
     bfd_size_type count ATTRIBUTE_UNUSED;
239
{
240
  return true;
241
}
242
 
243
/* Read a NetWare sparc import record */
244
static boolean
245
nlm_sparc_read_import (abfd, sym)
246
     bfd *abfd;
247
     nlmNAME(symbol_type) *sym;
248
{
249
  struct nlm_relent *nlm_relocs;        /* relocation records for symbol */
250
  bfd_size_type rcount;                 /* number of relocs */
251
  bfd_byte temp[NLM_TARGET_LONG_SIZE];  /* temporary 32-bit value */
252
  unsigned char symlength;              /* length of symbol name */
253
  char *name;
254
 
255
  /*
256
   * First, read in the number of relocation
257
   * entries for this symbol
258
   */
259
  if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
260
    return false;
261
 
262
  rcount = bfd_get_32 (abfd, temp);
263
 
264
  /*
265
   * Next, read in the length of the symbol
266
   */
267
 
268
  if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
269
      != sizeof (symlength))
270
    return false;
271
  sym -> symbol.the_bfd = abfd;
272
  name = bfd_alloc (abfd, symlength + 1);
273
  if (name == NULL)
274
    return false;
275
 
276
  /*
277
   * Then read in the symbol
278
   */
279
 
280
  if (bfd_read (name, symlength, 1, abfd) != symlength)
281
    return false;
282
  name[symlength] = '\0';
283
  sym -> symbol.name = name;
284
  sym -> symbol.flags = 0;
285
  sym -> symbol.value = 0;
286
  sym -> symbol.section = bfd_und_section_ptr;
287
 
288
  /*
289
   * Next, start reading in the relocs.
290
   */
291
 
292
  nlm_relocs = ((struct nlm_relent *)
293
                bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
294
  if (!nlm_relocs)
295
    return false;
296
  sym -> relocs = nlm_relocs;
297
  sym -> rcnt = 0;
298
  while (sym -> rcnt < rcount)
299
    {
300
      asection *section;
301
 
302
      if (nlm_sparc_read_reloc (abfd, sym, &section,
303
                              &nlm_relocs -> reloc)
304
          == false)
305
        return false;
306
      nlm_relocs -> section = section;
307
      nlm_relocs++;
308
      sym -> rcnt++;
309
    }
310
  return true;
311
}
312
 
313
static boolean
314
nlm_sparc_write_import (abfd, sec, rel)
315
     bfd *abfd;
316
     asection *sec;
317
     arelent *rel;
318
{
319
  char temp[4];
320
  asection *code, *data, *bss, *symsec;
321
  bfd_vma base;
322
 
323
  code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
324
  data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
325
  bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
326
  symsec = (*rel->sym_ptr_ptr)->section;
327
 
328
  if (symsec == code) {
329
    base = 0;
330
  } else if (symsec == data) {
331
    base = bfd_section_size (abfd, code);
332
  } else if (symsec == bss) {
333
    base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
334
  } else
335
    base = 0;
336
 
337
#ifdef DEBUG
338
  fprintf (stderr, "%s:  <%x, 1>\n\t",
339
           __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
340
#endif
341
  bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
342
  if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
343
    return false;
344
  bfd_put_32 (abfd, 1, temp);
345
  if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
346
    return false;
347
  if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
348
    return false;
349
  return true;
350
}
351
 
352
/* Write out an external reference.  */
353
 
354
static boolean
355
nlm_sparc_write_external (abfd, count, sym, relocs)
356
     bfd *abfd;
357
     bfd_size_type count;
358
     asymbol *sym;
359
     struct reloc_and_sec *relocs;
360
{
361
  unsigned int i;
362
  bfd_byte len;
363
  unsigned char temp[NLM_TARGET_LONG_SIZE];
364
 
365
  bfd_put_32 (abfd, count, temp);
366
  if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
367
    return false;
368
 
369
  len = strlen (sym->name);
370
  if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof (bfd_byte))
371
      || bfd_write (sym->name, len, 1, abfd) != len)
372
    return false;
373
 
374
  for (i = 0; i < count; i++)
375
    {
376
      if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
377
                                 relocs[i].rel) == false)
378
        return false;
379
    }
380
 
381
  return true;
382
}
383
 
384
static boolean
385
nlm_sparc_write_export (abfd, sym, value)
386
     bfd *abfd;
387
     asymbol *sym;
388
     bfd_vma value;
389
{
390
  bfd_byte len;
391
  bfd_byte temp[4];
392
 
393
#ifdef DEBUG
394
  fprintf (stderr, "%s: <%x, %d, %s>\n",
395
           __FUNCTION__, value, strlen (sym->name), sym->name);
396
#endif
397
  bfd_put_32 (abfd, value, temp);
398
  len = strlen (sym->name);
399
 
400
  if (bfd_write (temp, 4, 1, abfd) != 4
401
      || bfd_write (&len, 1, 1, abfd) != 1
402
      || bfd_write (sym->name, len, 1, abfd) != len)
403
    return false;
404
 
405
  return true;
406
}
407
 
408
#undef nlm_swap_fixed_header_in
409
#undef nlm_swap_fixed_header_out
410
 
411
#include "nlmswap.h"
412
 
413
static const struct nlm_backend_data nlm32_sparc_backend =
414
{
415
  "NetWare SPARC Module   \032",
416
  sizeof (Nlm32_sparc_External_Fixed_Header),
417
  0,     /* optional_prefix_size */
418
  bfd_arch_sparc,
419
  0,
420
  false,
421
  0,     /* backend_object_p */
422
  0,     /* write_prefix_func */
423
  nlm_sparc_read_reloc,
424
  nlm_sparc_mangle_relocs,
425
  nlm_sparc_read_import,
426
  nlm_sparc_write_import,
427
  0,     /* set_public_section */
428
  0,     /* get_public_offset */
429
  nlm_swap_fixed_header_in,
430
  nlm_swap_fixed_header_out,
431
  nlm_sparc_write_external,
432
  nlm_sparc_write_export
433
};
434
 
435
#define TARGET_BIG_NAME         "nlm32-sparc"
436
#define TARGET_BIG_SYM          nlmNAME(sparc_vec)
437
#define TARGET_BACKEND_DATA             &nlm32_sparc_backend
438
 
439
#include "nlm-target.h"

powered by: WebSVN 2.1.0

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