Missing BFD_RELOC_26.
[deliverable/binutils-gdb.git] / bfd / nlm32-sparc.c
CommitLineData
cdbfad1c
ILT
1/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright (C) 1993 Free Software Foundation, Inc.
3
4This file is part of BFD, the Binary File Descriptor library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
31static boolean nlm_sparc_read_reloc
32 PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
33static boolean nlm_sparc_write_reloc
34 PARAMS ((bfd *, asection *, arelent *));
35static boolean nlm_sparc_mangle_relocs
36 PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
37static boolean nlm_sparc_read_import
38 PARAMS ((bfd *, nlmNAME(symbol_type) *));
39static boolean nlm_sparc_write_import
40 PARAMS ((bfd *, asection *, arelent *));
41static boolean nlm_sparc_write_external
42 PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
43
44enum 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
63static 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
81static 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
111struct 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
118static boolean
119nlm_sparc_read_reloc (abfd, sym, secp, rel)
120 bfd *abfd;
121 nlmNAME(symbol_type) *sym;
122 asection **secp;
123 arelent *rel;
124{
cdbfad1c 125 bfd_vma val, addend;
cdbfad1c
ILT
126 int index;
127 unsigned int type;
128 struct nlm32_sparc_reloc_ext tmp_reloc;
df561b14 129 asection *code_sec, *data_sec;
cdbfad1c 130
25057836 131 if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
cdbfad1c 132 return false;
cdbfad1c 133
df561b14
SEF
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;
cdbfad1c
ILT
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",
df561b14 157 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
cdbfad1c
ILT
158#endif
159 return true;
160
161}
162
163/* Write a NetWare sparc reloc. */
164
165static boolean
166nlm_sparc_write_reloc (abfd, sec, rel)
167 bfd *abfd;
168 asection *sec;
169 arelent *rel;
170{
171 bfd_vma val;
9783e04a 172 struct nlm32_sparc_reloc_ext tmp_reloc;
cdbfad1c
ILT
173 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. */
df561b14
SEF
210#if 0
211 val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
212#else
cdbfad1c 213 val = bfd_get_section_vma (abfd, sec) + rel->address;
df561b14 214#endif
cdbfad1c
ILT
215
216#ifdef DEBUG
217 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
df561b14 218 __FUNCTION__, val, rel->addend, rel->howto->type);
cdbfad1c
ILT
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 {
226 abort();
227 }
228
229 return true;
230}
231
232/* Mangle relocs for SPARC NetWare. We can just use the standard
233 SPARC relocs. */
234
235static boolean
236nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
237 bfd *abfd;
238 asection *sec;
239 PTR data;
240 bfd_vma offset;
241 bfd_size_type count;
242{
243 return true;
244}
245
246/* Read a NetWare sparc import record */
247static boolean
248nlm_sparc_read_import (abfd, sym)
249 bfd *abfd;
250 nlmNAME(symbol_type) *sym;
251{
252 struct nlm_relent *nlm_relocs; /* relocation records for symbol */
253 bfd_size_type rcount; /* number of relocs */
254 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
255 unsigned char symlength; /* length of symbol name */
256
257 /*
258 * First, read in the number of relocation
259 * entries for this symbol
260 */
25057836
JL
261 if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
262 return false;
cdbfad1c
ILT
263
264 rcount = bfd_get_32 (abfd, temp);
265
266 /*
267 * Next, read in the length of the symbol
268 */
269
270 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
271 != sizeof (symlength))
25057836 272 return false;
cdbfad1c
ILT
273 sym -> symbol.the_bfd = abfd;
274 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
9783e04a
DM
275 if (!sym -> symbol.name)
276 {
25057836 277 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
278 return false;
279 }
cdbfad1c
ILT
280
281 /*
282 * Then read in the symbol
283 */
284
285 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
286 != symlength)
25057836 287 return false;
cdbfad1c
ILT
288 sym -> symbol.flags = 0;
289 sym -> symbol.value = 0;
290 sym -> symbol.section = &bfd_und_section;
291
292 /*
293 * Next, start reading in the relocs.
294 */
295
296 nlm_relocs = ((struct nlm_relent *)
297 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
9783e04a
DM
298 if (!nlm_relocs)
299 {
25057836 300 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
301 return false;
302 }
cdbfad1c
ILT
303 sym -> relocs = nlm_relocs;
304 sym -> rcnt = 0;
305 while (sym -> rcnt < rcount)
306 {
307 asection *section;
308
309 if (nlm_sparc_read_reloc (abfd, sym, &section,
310 &nlm_relocs -> reloc)
311 == false)
312 return false;
313 nlm_relocs -> section = section;
314 nlm_relocs++;
315 sym -> rcnt++;
316 }
317 return true;
318}
319
320static boolean
321nlm_sparc_write_import (abfd, sec, rel)
322 bfd *abfd;
323 asection *sec;
324 arelent *rel;
325{
326 char temp[4];
df561b14
SEF
327 asection *code, *data, *bss, *symsec;
328 bfd_vma base;
329
330 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
331 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
332 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
333 symsec = (*rel->sym_ptr_ptr)->section;
334
335 if (symsec == code) {
336 base = 0;
337 } else if (symsec == data) {
338 base = bfd_section_size (abfd, code);
339 } else if (symsec == bss) {
340 base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
341 } else
342 base = 0;
cdbfad1c 343
df561b14
SEF
344#ifdef DEBUG
345 fprintf (stderr, "%s: <%x, 1>\n\t",
346 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
347#endif
348 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
cdbfad1c
ILT
349 bfd_write ((PTR)temp, 4, 1, abfd);
350 bfd_put_32 (abfd, 1, temp);
351 bfd_write ((PTR)temp, 4, 1, abfd);
352 if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
353 return false;
354 return true;
355}
356
357/* Write out an external reference. */
358
359static boolean
360nlm_sparc_write_external (abfd, count, sym, relocs)
361 bfd *abfd;
362 bfd_size_type count;
363 asymbol *sym;
364 struct reloc_and_sec *relocs;
365{
366 int i;
367 bfd_byte len;
368 unsigned char temp[NLM_TARGET_LONG_SIZE];
369
370 bfd_put_32 (abfd, count, temp);
371 if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
25057836 372 return false;
cdbfad1c
ILT
373
374 len = strlen (sym->name);
375 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
376 || bfd_write (sym->name, len, 1, abfd) != len)
25057836 377 return false;
cdbfad1c
ILT
378
379 for (i = 0; i < count; i++)
380 {
381 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
382 relocs[i].rel) == false)
383 return false;
384 }
385
386 return true;
387}
388
df561b14
SEF
389static boolean
390nlm_sparc_write_export (abfd, sym, value)
391 bfd *abfd;
392 asymbol *sym;
393 bfd_vma value;
394{
395 bfd_byte len;
396 bfd_byte temp[4];
397
398#ifdef DEBUG
399 fprintf (stderr, "%s: <%x, %d, %s>\n",
400 __FUNCTION__, value, strlen (sym->name), sym->name);
401#endif
402 bfd_put_32 (abfd, value, temp);
403 len = strlen (sym->name);
404
405 if (bfd_write (temp, 4, 1, abfd) != 4
406 || bfd_write (&len, 1, 1, abfd) != 1
407 || bfd_write (sym->name, len, 1, abfd) != len)
25057836 408 return false;
df561b14
SEF
409
410 return true;
411}
412
cdbfad1c
ILT
413#undef nlm_swap_fixed_header_in
414#undef nlm_swap_fixed_header_out
415
416#include "nlmswap.h"
417
418static const struct nlm_backend_data nlm32_sparc_backend =
419{
420 "NetWare SPARC Module \032",
421 sizeof (Nlm32_sparc_External_Fixed_Header),
422 0, /* optional_prefix_size */
423 bfd_arch_sparc,
424 0,
df561b14 425 false,
cdbfad1c
ILT
426 0, /* backend_object_p */
427 0, /* write_prefix_func */
428 nlm_sparc_read_reloc,
429 nlm_sparc_mangle_relocs,
430 nlm_sparc_read_import,
431 nlm_sparc_write_import,
432 0, /* set_public_section */
433 0, /* get_public_offset */
434 nlm_swap_fixed_header_in,
435 nlm_swap_fixed_header_out,
436 nlm_sparc_write_external,
df561b14 437 nlm_sparc_write_export
cdbfad1c
ILT
438};
439
440#define TARGET_BIG_NAME "nlm32-sparc"
441#define TARGET_BIG_SYM nlmNAME(sparc_vec)
442#define TARGET_BACKEND_DATA &nlm32_sparc_backend
443
444#include "nlm-target.h"
This page took 0.063189 seconds and 4 git commands to generate.