1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 ATTRIBUTE_UNUSED;
128 struct nlm32_sparc_reloc_ext tmp_reloc;
129 asection *code_sec, *data_sec;
131 if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
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);
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);
144 rel->addend = addend;
148 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
150 if (nlm32_sparc_howto_table[index].type == type) {
151 rel->howto = &nlm32_sparc_howto_table[index];
156 fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
157 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
163 /* Write a NetWare sparc reloc. */
166 nlm_sparc_write_reloc (abfd, sec, rel)
172 struct nlm32_sparc_reloc_ext tmp_reloc;
175 reloc_howto_type *tmp;
178 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
180 tmp = &nlm32_sparc_howto_table[index];
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) {
197 * Netware wants a list of relocs for each address.
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
210 val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
212 val = bfd_get_section_vma (abfd, sec) + rel->address;
216 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
217 __FUNCTION__, val, rel->addend, rel->howto->type);
219 bfd_put_32 (abfd, val, tmp_reloc.offset);
220 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
221 bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
223 if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
229 /* Mangle relocs for SPARC NetWare. We can just use the standard
233 nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
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;
243 /* Read a NetWare sparc import record */
245 nlm_sparc_read_import (abfd, sym)
247 nlmNAME(symbol_type) *sym;
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 */
256 * First, read in the number of relocation
257 * entries for this symbol
259 if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
262 rcount = bfd_get_32 (abfd, temp);
265 * Next, read in the length of the symbol
268 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
269 != sizeof (symlength))
271 sym -> symbol.the_bfd = abfd;
272 name = bfd_alloc (abfd, symlength + 1);
277 * Then read in the symbol
280 if (bfd_read (name, symlength, 1, abfd) != symlength)
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;
289 * Next, start reading in the relocs.
292 nlm_relocs = ((struct nlm_relent *)
293 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
296 sym -> relocs = nlm_relocs;
298 while (sym -> rcnt < rcount)
302 if (nlm_sparc_read_reloc (abfd, sym, §ion,
303 &nlm_relocs -> reloc)
306 nlm_relocs -> section = section;
314 nlm_sparc_write_import (abfd, sec, rel)
320 asection *code, *data, *bss, *symsec;
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;
328 if (symsec == code) {
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);
338 fprintf (stderr, "%s: <%x, 1>\n\t",
339 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
341 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
342 if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
344 bfd_put_32 (abfd, 1, temp);
345 if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
347 if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
352 /* Write out an external reference. */
355 nlm_sparc_write_external (abfd, count, sym, relocs)
359 struct reloc_and_sec *relocs;
363 unsigned char temp[NLM_TARGET_LONG_SIZE];
365 bfd_put_32 (abfd, count, temp);
366 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
369 len = strlen (sym->name);
370 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof (bfd_byte))
371 || bfd_write (sym->name, len, 1, abfd) != len)
374 for (i = 0; i < count; i++)
376 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
377 relocs[i].rel) == false)
385 nlm_sparc_write_export (abfd, sym, value)
394 fprintf (stderr, "%s: <%x, %d, %s>\n",
395 __FUNCTION__, value, strlen (sym->name), sym->name);
397 bfd_put_32 (abfd, value, temp);
398 len = strlen (sym->name);
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)
408 #undef nlm_swap_fixed_header_in
409 #undef nlm_swap_fixed_header_out
413 static const struct nlm_backend_data nlm32_sparc_backend =
415 "NetWare SPARC Module \032",
416 sizeof (Nlm32_sparc_External_Fixed_Header),
417 0, /* optional_prefix_size */
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
435 #define TARGET_BIG_NAME "nlm32-sparc"
436 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
437 #define TARGET_BACKEND_DATA &nlm32_sparc_backend
439 #include "nlm-target.h"