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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [nlm32-sparc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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