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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [nlm32-sparc.c] - Blame information for rev 148

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

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

powered by: WebSVN 2.1.0

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