1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright (C) 1993 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., 675 Mass Ave, Cambridge, MA 02139, 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 *));
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,
56 R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
63 static CONST char *CONST reloc_type_names[] =
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",
75 "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
81 static reloc_howto_type nlm32_sparc_howto_table[] =
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),
109 /* Read a NetWare sparc reloc. */
111 struct nlm32_sparc_reloc_ext {
112 unsigned char offset[4];
113 unsigned char addend[4];
114 unsigned char type[1];
115 unsigned char pad1[3];
119 nlm_sparc_read_reloc (abfd, sym, secp, rel)
121 nlmNAME(symbol_type) *sym;
130 struct nlm32_sparc_reloc_ext tmp_reloc;
131 asection *code_sec, *data_sec;
133 if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
136 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
137 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
141 val = bfd_get_32 (abfd, tmp_reloc.offset);
142 addend = bfd_get_32 (abfd, tmp_reloc.addend);
143 type = bfd_get_8 (abfd, tmp_reloc.type);
146 rel->addend = addend;
150 index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
152 if (nlm32_sparc_howto_table[index].type == type) {
153 rel->howto = &nlm32_sparc_howto_table[index];
158 fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
159 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
165 /* Write a NetWare sparc reloc. */
168 nlm_sparc_write_reloc (abfd, sec, rel)
174 struct nlm32_sparc_reloc_ext tmp_reloc;
177 reloc_howto_type *tmp;
181 index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
183 tmp = &nlm32_sparc_howto_table[index];
185 if (tmp->rightshift == rel->howto->rightshift
186 && tmp->size == rel->howto->size
187 && tmp->bitsize == rel->howto->bitsize
188 && tmp->pc_relative == rel->howto->pc_relative
189 && tmp->bitpos == rel->howto->bitpos
190 && tmp->src_mask == rel->howto->src_mask
191 && tmp->dst_mask == rel->howto->dst_mask) {
200 * Netware wants a list of relocs for each address.
208 /* The value we write out is the offset into the appropriate
209 segment. This offset is the section vma, adjusted by the vma of
210 the lowest section in that segment, plus the address of the
213 val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
215 val = bfd_get_section_vma (abfd, sec) + rel->address;
219 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
220 __FUNCTION__, val, rel->addend, rel->howto->type);
222 bfd_put_32 (abfd, val, tmp_reloc.offset);
223 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
224 bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type);
226 if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
234 /* Mangle relocs for SPARC NetWare. We can just use the standard
238 nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
248 /* 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
263 if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
266 rcount = bfd_get_32 (abfd, temp);
269 * Next, read in the length of the symbol
272 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
273 != sizeof (symlength))
275 sym -> symbol.the_bfd = abfd;
276 sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
277 if (!sym -> symbol.name)
279 bfd_set_error (bfd_error_no_memory);
284 * Then read in the symbol
287 if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
290 sym -> symbol.flags = 0;
291 sym -> symbol.value = 0;
292 sym -> symbol.section = &bfd_und_section;
295 * Next, start reading in the relocs.
298 nlm_relocs = ((struct nlm_relent *)
299 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
302 bfd_set_error (bfd_error_no_memory);
305 sym -> relocs = nlm_relocs;
307 while (sym -> rcnt < rcount)
311 if (nlm_sparc_read_reloc (abfd, sym, §ion,
312 &nlm_relocs -> reloc)
315 nlm_relocs -> section = section;
323 nlm_sparc_write_import (abfd, sec, rel)
329 asection *code, *data, *bss, *symsec;
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;
337 if (symsec == code) {
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);
347 fprintf (stderr, "%s: <%x, 1>\n\t",
348 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
350 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
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)
359 /* Write out an external reference. */
362 nlm_sparc_write_external (abfd, count, sym, relocs)
366 struct reloc_and_sec *relocs;
370 unsigned char temp[NLM_TARGET_LONG_SIZE];
372 bfd_put_32 (abfd, count, temp);
373 if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
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)
381 for (i = 0; i < count; i++)
383 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
384 relocs[i].rel) == false)
392 nlm_sparc_write_export (abfd, sym, value)
401 fprintf (stderr, "%s: <%x, %d, %s>\n",
402 __FUNCTION__, value, strlen (sym->name), sym->name);
404 bfd_put_32 (abfd, value, temp);
405 len = strlen (sym->name);
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)
415 #undef nlm_swap_fixed_header_in
416 #undef nlm_swap_fixed_header_out
420 static const struct nlm_backend_data nlm32_sparc_backend =
422 "NetWare SPARC Module \032",
423 sizeof (Nlm32_sparc_External_Fixed_Header),
424 0, /* optional_prefix_size */
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,
439 nlm_sparc_write_export
442 #define TARGET_BIG_NAME "nlm32-sparc"
443 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
444 #define TARGET_BACKEND_DATA &nlm32_sparc_backend
446 #include "nlm-target.h"