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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [nlm32-sparc.c] - Blame information for rev 1771

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

Line No. Rev Author Line
1 104 markom
/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2
   Copyright (C) 1993, 1994, 1995, 1999 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
 
178
  for (index = 0;
179
       index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
180
       index++) {
181
    tmp = &nlm32_sparc_howto_table[index];
182
 
183
    if (tmp->rightshift == rel->howto->rightshift
184
        && tmp->size == rel->howto->size
185
        && tmp->bitsize == rel->howto->bitsize
186
        && tmp->pc_relative == rel->howto->pc_relative
187
        && tmp->bitpos == rel->howto->bitpos
188
        && tmp->src_mask == rel->howto->src_mask
189
        && tmp->dst_mask == rel->howto->dst_mask) {
190
      type = tmp->type;
191
      break;
192
    }
193
  }
194
  if (type == -1)
195
    abort();
196
 
197
  /*
198
   * Netware wants a list of relocs for each address.
199
   * Format is:
200
   *    long    offset
201
   *    long    addend
202
   *    char    type
203
   * That should be it.
204
   */
205
 
206
  /* The value we write out is the offset into the appropriate
207
     segment.  This offset is the section vma, adjusted by the vma of
208
     the lowest section in that segment, plus the address of the
209
     relocation.  */
210
#if 0
211
  val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
212
#else
213
  val = bfd_get_section_vma (abfd, sec) + rel->address;
214
#endif
215
 
216
#ifdef DEBUG
217
  fprintf (stderr, "%s:  val = %08lx, addend = %08lx, type = %d\n",
218
           __FUNCTION__, val, rel->addend, rel->howto->type);
219
#endif
220
  bfd_put_32 (abfd, val, tmp_reloc.offset);
221
  bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
222
  bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type);
223
 
224
  if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
225
    return false;
226
 
227
  return true;
228
}
229
 
230
/* Mangle relocs for SPARC NetWare.  We can just use the standard
231
   SPARC relocs.  */
232
 
233
static boolean
234
nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
235
     bfd *abfd ATTRIBUTE_UNUSED;
236
     asection *sec ATTRIBUTE_UNUSED;
237
     PTR data ATTRIBUTE_UNUSED;
238
     bfd_vma offset ATTRIBUTE_UNUSED;
239
     bfd_size_type count ATTRIBUTE_UNUSED;
240
{
241
  return true;
242
}
243
 
244
/* Read a NetWare sparc import record */
245
static boolean
246
nlm_sparc_read_import (abfd, sym)
247
     bfd *abfd;
248
     nlmNAME(symbol_type) *sym;
249
{
250
  struct nlm_relent *nlm_relocs;        /* relocation records for symbol */
251
  bfd_size_type rcount;                 /* number of relocs */
252
  bfd_byte temp[NLM_TARGET_LONG_SIZE];  /* temporary 32-bit value */
253
  unsigned char symlength;              /* length of symbol name */
254
  char *name;
255
 
256
  /*
257
   * First, read in the number of relocation
258
   * entries for this symbol
259
   */
260
  if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
261
    return false;
262
 
263
  rcount = bfd_get_32 (abfd, temp);
264
 
265
  /*
266
   * Next, read in the length of the symbol
267
   */
268
 
269
  if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
270
      != sizeof (symlength))
271
    return false;
272
  sym -> symbol.the_bfd = abfd;
273
  name = bfd_alloc (abfd, symlength + 1);
274
  if (name == NULL)
275
    return false;
276
 
277
  /*
278
   * Then read in the symbol
279
   */
280
 
281
  if (bfd_read (name, symlength, 1, abfd) != symlength)
282
    return false;
283
  name[symlength] = '\0';
284
  sym -> symbol.name = name;
285
  sym -> symbol.flags = 0;
286
  sym -> symbol.value = 0;
287
  sym -> symbol.section = bfd_und_section_ptr;
288
 
289
  /*
290
   * Next, start reading in the relocs.
291
   */
292
 
293
  nlm_relocs = ((struct nlm_relent *)
294
                bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
295
  if (!nlm_relocs)
296
    return false;
297
  sym -> relocs = nlm_relocs;
298
  sym -> rcnt = 0;
299
  while (sym -> rcnt < rcount)
300
    {
301
      asection *section;
302
 
303
      if (nlm_sparc_read_reloc (abfd, sym, &section,
304
                              &nlm_relocs -> reloc)
305
          == false)
306
        return false;
307
      nlm_relocs -> section = section;
308
      nlm_relocs++;
309
      sym -> rcnt++;
310
    }
311
  return true;
312
}
313
 
314
static boolean
315
nlm_sparc_write_import (abfd, sec, rel)
316
     bfd *abfd;
317
     asection *sec;
318
     arelent *rel;
319
{
320
  char temp[4];
321
  asection *code, *data, *bss, *symsec;
322
  bfd_vma base;
323
 
324
  code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
325
  data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
326
  bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
327
  symsec = (*rel->sym_ptr_ptr)->section;
328
 
329
  if (symsec == code) {
330
    base = 0;
331
  } else if (symsec == data) {
332
    base = bfd_section_size (abfd, code);
333
  } else if (symsec == bss) {
334
    base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
335
  } else
336
    base = 0;
337
 
338
#ifdef DEBUG
339
  fprintf (stderr, "%s:  <%x, 1>\n\t",
340
           __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
341
#endif
342
  bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
343
  if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
344
    return false;
345
  bfd_put_32 (abfd, 1, temp);
346
  if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
347
    return false;
348
  if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
349
    return false;
350
  return true;
351
}
352
 
353
/* Write out an external reference.  */
354
 
355
static boolean
356
nlm_sparc_write_external (abfd, count, sym, relocs)
357
     bfd *abfd;
358
     bfd_size_type count;
359
     asymbol *sym;
360
     struct reloc_and_sec *relocs;
361
{
362
  unsigned int i;
363
  bfd_byte len;
364
  unsigned char temp[NLM_TARGET_LONG_SIZE];
365
 
366
  bfd_put_32 (abfd, count, temp);
367
  if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
368
    return false;
369
 
370
  len = strlen (sym->name);
371
  if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
372
      || bfd_write (sym->name, len, 1, abfd) != len)
373
    return false;
374
 
375
  for (i = 0; i < count; i++)
376
    {
377
      if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
378
                                 relocs[i].rel) == false)
379
        return false;
380
    }
381
 
382
  return true;
383
}
384
 
385
static boolean
386
nlm_sparc_write_export (abfd, sym, value)
387
     bfd *abfd;
388
     asymbol *sym;
389
     bfd_vma value;
390
{
391
  bfd_byte len;
392
  bfd_byte temp[4];
393
 
394
#ifdef DEBUG
395
  fprintf (stderr, "%s: <%x, %d, %s>\n",
396
           __FUNCTION__, value, strlen (sym->name), sym->name);
397
#endif
398
  bfd_put_32 (abfd, value, temp);
399
  len = strlen (sym->name);
400
 
401
  if (bfd_write (temp, 4, 1, abfd) != 4
402
      || bfd_write (&len, 1, 1, abfd) != 1
403
      || bfd_write (sym->name, len, 1, abfd) != len)
404
    return false;
405
 
406
  return true;
407
}
408
 
409
#undef nlm_swap_fixed_header_in
410
#undef nlm_swap_fixed_header_out
411
 
412
#include "nlmswap.h"
413
 
414
static const struct nlm_backend_data nlm32_sparc_backend =
415
{
416
  "NetWare SPARC Module   \032",
417
  sizeof (Nlm32_sparc_External_Fixed_Header),
418
  0,     /* optional_prefix_size */
419
  bfd_arch_sparc,
420
  0,
421
  false,
422
  0,     /* backend_object_p */
423
  0,     /* write_prefix_func */
424
  nlm_sparc_read_reloc,
425
  nlm_sparc_mangle_relocs,
426
  nlm_sparc_read_import,
427
  nlm_sparc_write_import,
428
  0,     /* set_public_section */
429
  0,     /* get_public_offset */
430
  nlm_swap_fixed_header_in,
431
  nlm_swap_fixed_header_out,
432
  nlm_sparc_write_external,
433
  nlm_sparc_write_export
434
};
435
 
436
#define TARGET_BIG_NAME         "nlm32-sparc"
437
#define TARGET_BIG_SYM          nlmNAME(sparc_vec)
438
#define TARGET_BACKEND_DATA             &nlm32_sparc_backend
439
 
440
#include "nlm-target.h"

powered by: WebSVN 2.1.0

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