* configure.host: Recognize aix4 explicitly.
[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 */
3af0f479 256 char *name;
cdbfad1c
ILT
257
258 /*
259 * First, read in the number of relocation
260 * entries for this symbol
261 */
25057836
JL
262 if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
263 return false;
cdbfad1c
ILT
264
265 rcount = bfd_get_32 (abfd, temp);
266
267 /*
268 * Next, read in the length of the symbol
269 */
270
271 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
272 != sizeof (symlength))
25057836 273 return false;
cdbfad1c 274 sym -> symbol.the_bfd = abfd;
3af0f479
ILT
275 name = bfd_alloc (abfd, symlength + 1);
276 if (name == NULL)
9783e04a 277 {
25057836 278 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
279 return false;
280 }
cdbfad1c
ILT
281
282 /*
283 * Then read in the symbol
284 */
285
3af0f479 286 if (bfd_read (name, symlength, 1, abfd) != symlength)
25057836 287 return false;
3af0f479
ILT
288 name[symlength] = '\0';
289 sym -> symbol.name = name;
cdbfad1c
ILT
290 sym -> symbol.flags = 0;
291 sym -> symbol.value = 0;
292 sym -> symbol.section = &bfd_und_section;
293
294 /*
295 * Next, start reading in the relocs.
296 */
297
298 nlm_relocs = ((struct nlm_relent *)
299 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
9783e04a
DM
300 if (!nlm_relocs)
301 {
25057836 302 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
303 return false;
304 }
cdbfad1c
ILT
305 sym -> relocs = nlm_relocs;
306 sym -> rcnt = 0;
307 while (sym -> rcnt < rcount)
308 {
309 asection *section;
310
311 if (nlm_sparc_read_reloc (abfd, sym, &section,
312 &nlm_relocs -> reloc)
313 == false)
314 return false;
315 nlm_relocs -> section = section;
316 nlm_relocs++;
317 sym -> rcnt++;
318 }
319 return true;
320}
321
322static boolean
323nlm_sparc_write_import (abfd, sec, rel)
324 bfd *abfd;
325 asection *sec;
326 arelent *rel;
327{
328 char temp[4];
df561b14
SEF
329 asection *code, *data, *bss, *symsec;
330 bfd_vma base;
331
332 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
333 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
334 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
335 symsec = (*rel->sym_ptr_ptr)->section;
336
337 if (symsec == code) {
338 base = 0;
339 } else if (symsec == data) {
340 base = bfd_section_size (abfd, code);
341 } else if (symsec == bss) {
342 base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
343 } else
344 base = 0;
cdbfad1c 345
df561b14
SEF
346#ifdef DEBUG
347 fprintf (stderr, "%s: <%x, 1>\n\t",
348 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
349#endif
350 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
cdbfad1c
ILT
351 bfd_write ((PTR)temp, 4, 1, abfd);
352 bfd_put_32 (abfd, 1, temp);
353 bfd_write ((PTR)temp, 4, 1, abfd);
354 if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
355 return false;
356 return true;
357}
358
359/* Write out an external reference. */
360
361static boolean
362nlm_sparc_write_external (abfd, count, sym, relocs)
363 bfd *abfd;
364 bfd_size_type count;
365 asymbol *sym;
366 struct reloc_and_sec *relocs;
367{
368 int i;
369 bfd_byte len;
370 unsigned char temp[NLM_TARGET_LONG_SIZE];
371
372 bfd_put_32 (abfd, count, temp);
373 if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
25057836 374 return false;
cdbfad1c
ILT
375
376 len = strlen (sym->name);
377 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
378 || bfd_write (sym->name, len, 1, abfd) != len)
25057836 379 return false;
cdbfad1c
ILT
380
381 for (i = 0; i < count; i++)
382 {
383 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
384 relocs[i].rel) == false)
385 return false;
386 }
387
388 return true;
389}
390
df561b14
SEF
391static boolean
392nlm_sparc_write_export (abfd, sym, value)
393 bfd *abfd;
394 asymbol *sym;
395 bfd_vma value;
396{
397 bfd_byte len;
398 bfd_byte temp[4];
399
400#ifdef DEBUG
401 fprintf (stderr, "%s: <%x, %d, %s>\n",
402 __FUNCTION__, value, strlen (sym->name), sym->name);
403#endif
404 bfd_put_32 (abfd, value, temp);
405 len = strlen (sym->name);
406
407 if (bfd_write (temp, 4, 1, abfd) != 4
408 || bfd_write (&len, 1, 1, abfd) != 1
409 || bfd_write (sym->name, len, 1, abfd) != len)
25057836 410 return false;
df561b14
SEF
411
412 return true;
413}
414
cdbfad1c
ILT
415#undef nlm_swap_fixed_header_in
416#undef nlm_swap_fixed_header_out
417
418#include "nlmswap.h"
419
420static const struct nlm_backend_data nlm32_sparc_backend =
421{
422 "NetWare SPARC Module \032",
423 sizeof (Nlm32_sparc_External_Fixed_Header),
424 0, /* optional_prefix_size */
425 bfd_arch_sparc,
426 0,
df561b14 427 false,
cdbfad1c
ILT
428 0, /* backend_object_p */
429 0, /* write_prefix_func */
430 nlm_sparc_read_reloc,
431 nlm_sparc_mangle_relocs,
432 nlm_sparc_read_import,
433 nlm_sparc_write_import,
434 0, /* set_public_section */
435 0, /* get_public_offset */
436 nlm_swap_fixed_header_in,
437 nlm_swap_fixed_header_out,
438 nlm_sparc_write_external,
df561b14 439 nlm_sparc_write_export
cdbfad1c
ILT
440};
441
442#define TARGET_BIG_NAME "nlm32-sparc"
443#define TARGET_BIG_SYM nlmNAME(sparc_vec)
444#define TARGET_BACKEND_DATA &nlm32_sparc_backend
445
446#include "nlm-target.h"
This page took 0.169681 seconds and 4 git commands to generate.