* config/m32r/m32r.mt (GDBSERVER_LIBS): Added ../../intl/libintl.a.
[deliverable/binutils-gdb.git] / bfd / nlm32-sparc.c
CommitLineData
252b5132 1/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
5f771d47 2 Copyright (C) 1993, 1994, 1995, 1999 Free Software Foundation, Inc.
252b5132
RH
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., 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
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,
1518639e
KH
47 R_SPARC_8, R_SPARC_16, R_SPARC_32,
48 R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
252b5132
RH
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
1518639e 81static reloc_howto_type nlm32_sparc_howto_table[] =
252b5132
RH
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;
5f771d47 121 nlmNAME(symbol_type) *sym ATTRIBUTE_UNUSED;
252b5132
RH
122 asection **secp;
123 arelent *rel;
124{
125 bfd_vma val, addend;
126 unsigned int index;
127 unsigned int type;
128 struct nlm32_sparc_reloc_ext tmp_reloc;
129 asection *code_sec, *data_sec;
130
131 if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
132 return false;
133
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;
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;
1518639e 148 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
252b5132
RH
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",
157 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
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;
172 struct nlm32_sparc_reloc_ext tmp_reloc;
173 unsigned int index;
174 int type = -1;
175 reloc_howto_type *tmp;
176
252b5132 177 for (index = 0;
1518639e 178 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
252b5132
RH
179 index++) {
180 tmp = &nlm32_sparc_howto_table[index];
181
182 if (tmp->rightshift == rel->howto->rightshift
183 && tmp->size == rel->howto->size
184 && tmp->bitsize == rel->howto->bitsize
185 && tmp->pc_relative == rel->howto->pc_relative
186 && tmp->bitpos == rel->howto->bitpos
187 && tmp->src_mask == rel->howto->src_mask
188 && tmp->dst_mask == rel->howto->dst_mask) {
189 type = tmp->type;
190 break;
191 }
192 }
193 if (type == -1)
1518639e 194 abort ();
252b5132
RH
195
196 /*
197 * Netware wants a list of relocs for each address.
198 * Format is:
199 * long offset
200 * long addend
201 * char type
202 * That should be it.
203 */
204
205 /* The value we write out is the offset into the appropriate
206 segment. This offset is the section vma, adjusted by the vma of
207 the lowest section in that segment, plus the address of the
208 relocation. */
209#if 0
210 val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
211#else
212 val = bfd_get_section_vma (abfd, sec) + rel->address;
213#endif
214
215#ifdef DEBUG
216 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
217 __FUNCTION__, val, rel->addend, rel->howto->type);
218#endif
219 bfd_put_32 (abfd, val, tmp_reloc.offset);
220 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
1518639e 221 bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
252b5132
RH
222
223 if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
224 return false;
225
226 return true;
227}
228
229/* Mangle relocs for SPARC NetWare. We can just use the standard
230 SPARC relocs. */
231
232static boolean
233nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
5f771d47
ILT
234 bfd *abfd ATTRIBUTE_UNUSED;
235 asection *sec ATTRIBUTE_UNUSED;
236 PTR data ATTRIBUTE_UNUSED;
237 bfd_vma offset ATTRIBUTE_UNUSED;
238 bfd_size_type count ATTRIBUTE_UNUSED;
252b5132
RH
239{
240 return true;
241}
242
243/* Read a NetWare sparc import record */
244static boolean
245nlm_sparc_read_import (abfd, sym)
246 bfd *abfd;
247 nlmNAME(symbol_type) *sym;
248{
249 struct nlm_relent *nlm_relocs; /* relocation records for symbol */
250 bfd_size_type rcount; /* number of relocs */
251 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
252 unsigned char symlength; /* length of symbol name */
253 char *name;
1518639e 254
252b5132
RH
255 /*
256 * First, read in the number of relocation
257 * entries for this symbol
258 */
259 if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
260 return false;
1518639e 261
252b5132 262 rcount = bfd_get_32 (abfd, temp);
1518639e 263
252b5132
RH
264 /*
265 * Next, read in the length of the symbol
266 */
1518639e 267
252b5132
RH
268 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
269 != sizeof (symlength))
270 return false;
271 sym -> symbol.the_bfd = abfd;
272 name = bfd_alloc (abfd, symlength + 1);
273 if (name == NULL)
274 return false;
1518639e 275
252b5132
RH
276 /*
277 * Then read in the symbol
278 */
1518639e 279
252b5132
RH
280 if (bfd_read (name, symlength, 1, abfd) != symlength)
281 return false;
282 name[symlength] = '\0';
283 sym -> symbol.name = name;
284 sym -> symbol.flags = 0;
285 sym -> symbol.value = 0;
286 sym -> symbol.section = bfd_und_section_ptr;
1518639e 287
252b5132
RH
288 /*
289 * Next, start reading in the relocs.
290 */
1518639e 291
252b5132
RH
292 nlm_relocs = ((struct nlm_relent *)
293 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
294 if (!nlm_relocs)
295 return false;
296 sym -> relocs = nlm_relocs;
297 sym -> rcnt = 0;
298 while (sym -> rcnt < rcount)
299 {
300 asection *section;
1518639e 301
252b5132
RH
302 if (nlm_sparc_read_reloc (abfd, sym, &section,
303 &nlm_relocs -> reloc)
304 == false)
305 return false;
306 nlm_relocs -> section = section;
307 nlm_relocs++;
308 sym -> rcnt++;
309 }
310 return true;
311}
312
313static boolean
314nlm_sparc_write_import (abfd, sec, rel)
315 bfd *abfd;
316 asection *sec;
317 arelent *rel;
318{
319 char temp[4];
320 asection *code, *data, *bss, *symsec;
321 bfd_vma base;
322
323 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
324 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
325 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
326 symsec = (*rel->sym_ptr_ptr)->section;
327
328 if (symsec == code) {
329 base = 0;
330 } else if (symsec == data) {
331 base = bfd_section_size (abfd, code);
332 } else if (symsec == bss) {
333 base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
334 } else
335 base = 0;
336
337#ifdef DEBUG
338 fprintf (stderr, "%s: <%x, 1>\n\t",
339 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
340#endif
341 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
342 if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
343 return false;
344 bfd_put_32 (abfd, 1, temp);
345 if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
346 return false;
347 if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
348 return false;
349 return true;
350}
351
352/* Write out an external reference. */
353
354static boolean
355nlm_sparc_write_external (abfd, count, sym, relocs)
356 bfd *abfd;
357 bfd_size_type count;
358 asymbol *sym;
359 struct reloc_and_sec *relocs;
360{
361 unsigned int i;
362 bfd_byte len;
363 unsigned char temp[NLM_TARGET_LONG_SIZE];
364
365 bfd_put_32 (abfd, count, temp);
1518639e 366 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
252b5132
RH
367 return false;
368
369 len = strlen (sym->name);
1518639e 370 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof (bfd_byte))
252b5132
RH
371 || bfd_write (sym->name, len, 1, abfd) != len)
372 return false;
373
374 for (i = 0; i < count; i++)
375 {
376 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
377 relocs[i].rel) == false)
378 return false;
379 }
380
381 return true;
382}
383
384static boolean
385nlm_sparc_write_export (abfd, sym, value)
386 bfd *abfd;
387 asymbol *sym;
388 bfd_vma value;
389{
390 bfd_byte len;
391 bfd_byte temp[4];
392
393#ifdef DEBUG
394 fprintf (stderr, "%s: <%x, %d, %s>\n",
395 __FUNCTION__, value, strlen (sym->name), sym->name);
396#endif
397 bfd_put_32 (abfd, value, temp);
398 len = strlen (sym->name);
399
400 if (bfd_write (temp, 4, 1, abfd) != 4
401 || bfd_write (&len, 1, 1, abfd) != 1
402 || bfd_write (sym->name, len, 1, abfd) != len)
403 return false;
404
405 return true;
406}
407
408#undef nlm_swap_fixed_header_in
409#undef nlm_swap_fixed_header_out
410
411#include "nlmswap.h"
412
413static const struct nlm_backend_data nlm32_sparc_backend =
414{
415 "NetWare SPARC Module \032",
416 sizeof (Nlm32_sparc_External_Fixed_Header),
417 0, /* optional_prefix_size */
418 bfd_arch_sparc,
419 0,
420 false,
421 0, /* backend_object_p */
422 0, /* write_prefix_func */
423 nlm_sparc_read_reloc,
424 nlm_sparc_mangle_relocs,
425 nlm_sparc_read_import,
426 nlm_sparc_write_import,
427 0, /* set_public_section */
428 0, /* get_public_offset */
429 nlm_swap_fixed_header_in,
430 nlm_swap_fixed_header_out,
431 nlm_sparc_write_external,
432 nlm_sparc_write_export
433};
434
435#define TARGET_BIG_NAME "nlm32-sparc"
436#define TARGET_BIG_SYM nlmNAME(sparc_vec)
437#define TARGET_BACKEND_DATA &nlm32_sparc_backend
438
439#include "nlm-target.h"
This page took 0.083902 seconds and 4 git commands to generate.