1
/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2
Copyright 1993, 1994, 2000, 2001, 2002 Free Software Foundation, Inc.
4
This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
26
#include "nlm/sparc32-ext.h"
27
#define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
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));
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,
58
R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
65
static const char *const reloc_type_names[] =
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",
77
"R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
83
static reloc_howto_type nlm32_sparc_howto_table[] =
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),
111
/* Read a NetWare sparc reloc. */
113
struct nlm32_sparc_reloc_ext
115
unsigned char offset[4];
116
unsigned char addend[4];
117
unsigned char type[1];
118
unsigned char pad1[3];
122
nlm_sparc_read_reloc (abfd, sym, secp, rel)
124
nlmNAME(symbol_type) *sym ATTRIBUTE_UNUSED;
131
struct nlm32_sparc_reloc_ext tmp_reloc;
132
asection *code_sec, *data_sec;
134
if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
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);
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);
147
rel->addend = addend;
151
index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
153
if (nlm32_sparc_howto_table[index].type == type)
155
rel->howto = &nlm32_sparc_howto_table[index];
160
fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
161
__FUNCTION__, rel->address, rel->addend, type, rel->howto);
167
/* Write a NetWare sparc reloc. */
170
nlm_sparc_write_reloc (abfd, sec, rel)
176
struct nlm32_sparc_reloc_ext tmp_reloc;
179
reloc_howto_type *tmp;
182
index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
185
tmp = &nlm32_sparc_howto_table[index];
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)
202
/* Netware wants a list of relocs for each address.
207
That should be it. */
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
214
val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
216
val = bfd_get_section_vma (abfd, sec) + rel->address;
220
fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
221
__FUNCTION__, val, rel->addend, rel->howto->type);
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);
227
if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
233
/* Mangle relocs for SPARC NetWare. We can just use the standard
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;
247
/* Read a NetWare sparc import record. */
250
nlm_sparc_read_import (abfd, sym)
252
nlmNAME(symbol_type) *sym;
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. */
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)
265
rcount = bfd_get_32 (abfd, temp);
267
/* Next, read in the length of the symbol. */
269
if (bfd_bread ((PTR) &symlength, (bfd_size_type) sizeof (symlength), abfd)
270
!= sizeof (symlength))
272
sym -> symbol.the_bfd = abfd;
273
name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
277
/* Then read in the symbol. */
279
if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
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;
287
/* Next, start reading in the relocs. */
289
nlm_relocs = ((struct nlm_relent *)
290
bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
293
sym -> relocs = nlm_relocs;
295
while (sym -> rcnt < rcount)
299
if (! nlm_sparc_read_reloc (abfd, sym, §ion, &nlm_relocs -> reloc))
301
nlm_relocs -> section = section;
310
nlm_sparc_write_import (abfd, sec, rel)
316
asection *code, *data, *bss, *symsec;
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;
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);
334
fprintf (stderr, "%s: <%x, 1>\n\t",
335
__FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
337
bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
338
if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
340
bfd_put_32 (abfd, (bfd_vma) 1, temp);
341
if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
343
if (! nlm_sparc_write_reloc (abfd, sec, rel))
348
/* Write out an external reference. */
351
nlm_sparc_write_external (abfd, count, sym, relocs)
355
struct reloc_and_sec *relocs;
359
unsigned char temp[NLM_TARGET_LONG_SIZE];
361
bfd_put_32 (abfd, count, temp);
362
if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
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)
371
for (i = 0; i < count; i++)
373
if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
381
nlm_sparc_write_export (abfd, sym, value)
390
fprintf (stderr, "%s: <%x, %d, %s>\n",
391
__FUNCTION__, value, strlen (sym->name), sym->name);
393
bfd_put_32 (abfd, value, temp);
394
len = strlen (sym->name);
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)
404
#undef nlm_swap_fixed_header_in
405
#undef nlm_swap_fixed_header_out
409
static const struct nlm_backend_data nlm32_sparc_backend =
411
"NetWare SPARC Module \032",
412
sizeof (Nlm32_sparc_External_Fixed_Header),
413
0, /* optional_prefix_size */
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
431
#define TARGET_BIG_NAME "nlm32-sparc"
432
#define TARGET_BIG_SYM nlmNAME(sparc_vec)
433
#define TARGET_BACKEND_DATA & nlm32_sparc_backend
435
#include "nlm-target.h"