* remote.c, remote-mon.c, remote-utils.c, remote-utils.h,
[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{
125 bfd_byte temp[4];
126 bfd_vma val, addend;
127 const char *name;
128 int index;
129 unsigned int type;
130 struct nlm32_sparc_reloc_ext tmp_reloc;
df561b14 131 asection *code_sec, *data_sec;
cdbfad1c
ILT
132
133 if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12) {
134 bfd_error = system_call_error;
135 return false;
136 }
137
df561b14
SEF
138 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
139 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
140
141 *secp = code_sec;
cdbfad1c
ILT
142
143 val = bfd_get_32 (abfd, tmp_reloc.offset);
144 addend = bfd_get_32 (abfd, tmp_reloc.addend);
145 type = bfd_get_8 (abfd, tmp_reloc.type);
146
147 rel->address = val;
148 rel->addend = addend;
149 rel->howto = NULL;
150
151 for (index = 0;
152 index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
153 index++)
154 if (nlm32_sparc_howto_table[index].type == type) {
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",
df561b14 161 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
cdbfad1c
ILT
162#endif
163 return true;
164
165}
166
167/* Write a NetWare sparc reloc. */
168
169static boolean
170nlm_sparc_write_reloc (abfd, sec, rel)
171 bfd *abfd;
172 asection *sec;
173 arelent *rel;
174{
175 bfd_vma val;
9783e04a 176 struct nlm32_sparc_reloc_ext tmp_reloc;
cdbfad1c
ILT
177 int index;
178 int type = -1;
179 reloc_howto_type *tmp;
180
181
182 for (index = 0;
183 index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
184 index++) {
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 type = tmp->type;
195 break;
196 }
197 }
198 if (type == -1)
199 abort();
200
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
210 /* The value we write out is the offset into the appropriate
211 segment. This offset is the section vma, adjusted by the vma of
212 the lowest section in that segment, plus the address of the
213 relocation. */
df561b14
SEF
214#if 0
215 val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
216#else
cdbfad1c 217 val = bfd_get_section_vma (abfd, sec) + rel->address;
df561b14 218#endif
cdbfad1c
ILT
219
220#ifdef DEBUG
221 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
df561b14 222 __FUNCTION__, val, rel->addend, rel->howto->type);
cdbfad1c
ILT
223#endif
224 bfd_put_32 (abfd, val, tmp_reloc.offset);
225 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
226 bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type);
227
228 if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
229 {
230 abort();
231 }
232
233 return true;
234}
235
236/* Mangle relocs for SPARC NetWare. We can just use the standard
237 SPARC relocs. */
238
239static boolean
240nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
241 bfd *abfd;
242 asection *sec;
243 PTR data;
244 bfd_vma offset;
245 bfd_size_type count;
246{
247 return true;
248}
249
250/* Read a NetWare sparc import record */
251static boolean
252nlm_sparc_read_import (abfd, sym)
253 bfd *abfd;
254 nlmNAME(symbol_type) *sym;
255{
256 struct nlm_relent *nlm_relocs; /* relocation records for symbol */
257 bfd_size_type rcount; /* number of relocs */
258 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
259 unsigned char symlength; /* length of symbol name */
260
261 /*
262 * First, read in the number of relocation
263 * entries for this symbol
264 */
265 if (bfd_read ((PTR) temp, 4, 1, abfd)
266 != 4)
267 {
268 bfd_error = system_call_error;
269 return (false);
270 }
271
272 rcount = bfd_get_32 (abfd, temp);
273
274 /*
275 * Next, read in the length of the symbol
276 */
277
278 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
279 != sizeof (symlength))
280 {
281 bfd_error = system_call_error;
282 return (false);
283 }
284 sym -> symbol.the_bfd = abfd;
285 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
9783e04a
DM
286 if (!sym -> symbol.name)
287 {
288 bfd_error = no_memory;
289 return false;
290 }
cdbfad1c
ILT
291
292 /*
293 * Then read in the symbol
294 */
295
296 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
297 != symlength)
298 {
299 bfd_error = system_call_error;
300 return (false);
301 }
302 sym -> symbol.flags = 0;
303 sym -> symbol.value = 0;
304 sym -> symbol.section = &bfd_und_section;
305
306 /*
307 * Next, start reading in the relocs.
308 */
309
310 nlm_relocs = ((struct nlm_relent *)
311 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
9783e04a
DM
312 if (!nlm_relocs)
313 {
314 bfd_error = no_memory;
315 return false;
316 }
cdbfad1c
ILT
317 sym -> relocs = nlm_relocs;
318 sym -> rcnt = 0;
319 while (sym -> rcnt < rcount)
320 {
321 asection *section;
322
323 if (nlm_sparc_read_reloc (abfd, sym, &section,
324 &nlm_relocs -> reloc)
325 == false)
326 return false;
327 nlm_relocs -> section = section;
328 nlm_relocs++;
329 sym -> rcnt++;
330 }
331 return true;
332}
333
334static boolean
335nlm_sparc_write_import (abfd, sec, rel)
336 bfd *abfd;
337 asection *sec;
338 arelent *rel;
339{
340 char temp[4];
df561b14
SEF
341 asection *code, *data, *bss, *symsec;
342 bfd_vma base;
343
344 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
345 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
346 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
347 symsec = (*rel->sym_ptr_ptr)->section;
348
349 if (symsec == code) {
350 base = 0;
351 } else if (symsec == data) {
352 base = bfd_section_size (abfd, code);
353 } else if (symsec == bss) {
354 base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
355 } else
356 base = 0;
cdbfad1c 357
df561b14
SEF
358#ifdef DEBUG
359 fprintf (stderr, "%s: <%x, 1>\n\t",
360 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
361#endif
362 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
cdbfad1c
ILT
363 bfd_write ((PTR)temp, 4, 1, abfd);
364 bfd_put_32 (abfd, 1, temp);
365 bfd_write ((PTR)temp, 4, 1, abfd);
366 if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
367 return false;
368 return true;
369}
370
371/* Write out an external reference. */
372
373static boolean
374nlm_sparc_write_external (abfd, count, sym, relocs)
375 bfd *abfd;
376 bfd_size_type count;
377 asymbol *sym;
378 struct reloc_and_sec *relocs;
379{
380 int i;
381 bfd_byte len;
382 unsigned char temp[NLM_TARGET_LONG_SIZE];
383
384 bfd_put_32 (abfd, count, temp);
385 if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
386 {
387 bfd_error = system_call_error;
388 return false;
389 }
390
391 len = strlen (sym->name);
392 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
393 || bfd_write (sym->name, len, 1, abfd) != len)
394 {
395 bfd_error = system_call_error;
396 return false;
397 }
398
399 for (i = 0; i < count; i++)
400 {
401 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
402 relocs[i].rel) == false)
403 return false;
404 }
405
406 return true;
407}
408
df561b14
SEF
409static boolean
410nlm_sparc_write_export (abfd, sym, value)
411 bfd *abfd;
412 asymbol *sym;
413 bfd_vma value;
414{
415 bfd_byte len;
416 bfd_byte temp[4];
417
418#ifdef DEBUG
419 fprintf (stderr, "%s: <%x, %d, %s>\n",
420 __FUNCTION__, value, strlen (sym->name), sym->name);
421#endif
422 bfd_put_32 (abfd, value, temp);
423 len = strlen (sym->name);
424
425 if (bfd_write (temp, 4, 1, abfd) != 4
426 || bfd_write (&len, 1, 1, abfd) != 1
427 || bfd_write (sym->name, len, 1, abfd) != len)
428 {
429 bfd_error = system_call_error;
430 return false;
431 }
432
433 return true;
434}
435
cdbfad1c
ILT
436#undef nlm_swap_fixed_header_in
437#undef nlm_swap_fixed_header_out
438
439#include "nlmswap.h"
440
441static const struct nlm_backend_data nlm32_sparc_backend =
442{
443 "NetWare SPARC Module \032",
444 sizeof (Nlm32_sparc_External_Fixed_Header),
445 0, /* optional_prefix_size */
446 bfd_arch_sparc,
447 0,
df561b14 448 false,
cdbfad1c
ILT
449 0, /* backend_object_p */
450 0, /* write_prefix_func */
451 nlm_sparc_read_reloc,
452 nlm_sparc_mangle_relocs,
453 nlm_sparc_read_import,
454 nlm_sparc_write_import,
455 0, /* set_public_section */
456 0, /* get_public_offset */
457 nlm_swap_fixed_header_in,
458 nlm_swap_fixed_header_out,
459 nlm_sparc_write_external,
df561b14 460 nlm_sparc_write_export
cdbfad1c
ILT
461};
462
463#define TARGET_BIG_NAME "nlm32-sparc"
464#define TARGET_BIG_SYM nlmNAME(sparc_vec)
465#define TARGET_BACKEND_DATA &nlm32_sparc_backend
466
467#include "nlm-target.h"
This page took 0.049297 seconds and 4 git commands to generate.