1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 2000, 2001 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 *));
43 static boolean nlm_sparc_write_export
44 PARAMS ((bfd *, asymbol *, bfd_vma));
49 R_SPARC_8, R_SPARC_16, R_SPARC_32,
50 R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
51 R_SPARC_WDISP30, R_SPARC_WDISP22,
52 R_SPARC_HI22, R_SPARC_22,
53 R_SPARC_13, R_SPARC_LO10,
54 R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
55 R_SPARC_PC10, R_SPARC_PC22,
58 R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
65 static CONST char *CONST reloc_type_names[] =
68 "R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
69 "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
70 "R_SPARC_WDISP30", "R_SPARC_WDISP22",
71 "R_SPARC_HI22", "R_SPARC_22",
72 "R_SPARC_13", "R_SPARC_LO10",
73 "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
74 "R_SPARC_PC10", "R_SPARC_PC22",
77 "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
83 static reloc_howto_type nlm32_sparc_howto_table[] =
85 HOWTO (R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, 0,"R_SPARC_NONE", false,0,0x00000000,true),
86 HOWTO (R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8", false,0,0x000000ff,true),
87 HOWTO (R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16", false,0,0x0000ffff,true),
88 HOWTO (R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32", false,0,0xffffffff,true),
89 HOWTO (R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP8", false,0,0x000000ff,true),
90 HOWTO (R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP16", false,0,0x0000ffff,true),
91 HOWTO (R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP32", false,0,0x00ffffff,true),
92 HOWTO (R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
93 HOWTO (R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP22", false,0,0x003fffff,true),
94 HOWTO (R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, 0,"R_SPARC_HI22", false,0,0x003fffff,true),
95 HOWTO (R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22", false,0,0x003fffff,true),
96 HOWTO (R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13", false,0,0x00001fff,true),
97 HOWTO (R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, 0,"R_SPARC_LO10", false,0,0x000003ff,true),
98 HOWTO (R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10", false,0,0x000003ff,true),
99 HOWTO (R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13", false,0,0x00001fff,true),
100 HOWTO (R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22", false,0,0x003fffff,true),
101 HOWTO (R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10", false,0,0x000003ff,true),
102 HOWTO (R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22", false,0,0x003fffff,true),
103 HOWTO (R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_WPLT30", false,0,0x00000000,true),
104 HOWTO (R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_COPY", false,0,0x00000000,true),
105 HOWTO (R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
106 HOWTO (R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
107 HOWTO (R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_RELATIVE",false,0,0x00000000,true),
108 HOWTO (R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_UA32", false,0,0x00000000,true),
111 /* Read a NetWare sparc reloc. */
113 struct nlm32_sparc_reloc_ext
115 unsigned char offset[4];
116 unsigned char addend[4];
117 unsigned char type[1];
118 unsigned char pad1[3];
122 nlm_sparc_read_reloc (abfd, sym, secp, rel)
124 nlmNAME(symbol_type) *sym ATTRIBUTE_UNUSED;
131 struct nlm32_sparc_reloc_ext tmp_reloc;
132 asection *code_sec, *data_sec;
134 if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
137 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
138 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
142 val = bfd_get_32 (abfd, tmp_reloc.offset);
143 addend = bfd_get_32 (abfd, tmp_reloc.addend);
144 type = bfd_get_8 (abfd, tmp_reloc.type);
147 rel->addend = addend;
151 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
153 if (nlm32_sparc_howto_table[index].type == type)
155 rel->howto = &nlm32_sparc_howto_table[index];
160 fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
161 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
167 /* Write a NetWare sparc reloc. */
170 nlm_sparc_write_reloc (abfd, sec, rel)
176 struct nlm32_sparc_reloc_ext tmp_reloc;
179 reloc_howto_type *tmp;
182 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
185 tmp = &nlm32_sparc_howto_table[index];
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)
202 /* Netware wants a list of relocs for each address.
207 That should be it. */
209 /* The value we write out is the offset into the appropriate
210 segment. This offset is the section vma, adjusted by the vma of
211 the lowest section in that segment, plus the address of the
214 val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
216 val = bfd_get_section_vma (abfd, sec) + rel->address;
220 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
221 __FUNCTION__, val, rel->addend, rel->howto->type);
223 bfd_put_32 (abfd, val, tmp_reloc.offset);
224 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
225 bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
227 if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
233 /* Mangle relocs for SPARC NetWare. We can just use the standard
237 nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
238 bfd *abfd ATTRIBUTE_UNUSED;
239 asection *sec ATTRIBUTE_UNUSED;
240 PTR data ATTRIBUTE_UNUSED;
241 bfd_vma offset ATTRIBUTE_UNUSED;
242 bfd_size_type count ATTRIBUTE_UNUSED;
247 /* 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. */
262 if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
265 rcount = bfd_get_32 (abfd, temp);
267 /* Next, read in the length of the symbol. */
269 if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
270 != sizeof (symlength))
272 sym -> symbol.the_bfd = abfd;
273 name = bfd_alloc (abfd, symlength + 1);
277 /* Then read in the symbol. */
279 if (bfd_read (name, symlength, 1, abfd) != symlength)
281 name[symlength] = '\0';
282 sym -> symbol.name = name;
283 sym -> symbol.flags = 0;
284 sym -> symbol.value = 0;
285 sym -> symbol.section = bfd_und_section_ptr;
287 /* Next, start reading in the relocs. */
289 nlm_relocs = ((struct nlm_relent *)
290 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
293 sym -> relocs = nlm_relocs;
295 while (sym -> rcnt < rcount)
299 if (nlm_sparc_read_reloc (abfd, sym, §ion,
300 &nlm_relocs -> reloc)
303 nlm_relocs -> section = section;
312 nlm_sparc_write_import (abfd, sec, rel)
318 asection *code, *data, *bss, *symsec;
321 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
322 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
323 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
324 symsec = (*rel->sym_ptr_ptr)->section;
328 else if (symsec == data)
329 base = bfd_section_size (abfd, code);
330 else if (symsec == bss)
331 base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
336 fprintf (stderr, "%s: <%x, 1>\n\t",
337 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
339 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
340 if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
342 bfd_put_32 (abfd, 1, temp);
343 if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
345 if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
350 /* Write out an external reference. */
353 nlm_sparc_write_external (abfd, count, sym, relocs)
357 struct reloc_and_sec *relocs;
361 unsigned char temp[NLM_TARGET_LONG_SIZE];
363 bfd_put_32 (abfd, count, temp);
364 if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
367 len = strlen (sym->name);
368 if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof (bfd_byte))
369 || bfd_write (sym->name, len, 1, abfd) != len)
372 for (i = 0; i < count; i++)
374 if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
375 relocs[i].rel) == false)
383 nlm_sparc_write_export (abfd, sym, value)
392 fprintf (stderr, "%s: <%x, %d, %s>\n",
393 __FUNCTION__, value, strlen (sym->name), sym->name);
395 bfd_put_32 (abfd, value, temp);
396 len = strlen (sym->name);
398 if (bfd_write (temp, 4, 1, abfd) != 4
399 || bfd_write (&len, 1, 1, abfd) != 1
400 || bfd_write (sym->name, len, 1, abfd) != len)
406 #undef nlm_swap_fixed_header_in
407 #undef nlm_swap_fixed_header_out
411 static const struct nlm_backend_data nlm32_sparc_backend =
413 "NetWare SPARC Module \032",
414 sizeof (Nlm32_sparc_External_Fixed_Header),
415 0, /* optional_prefix_size */
419 0, /* backend_object_p */
420 0, /* write_prefix_func */
421 nlm_sparc_read_reloc,
422 nlm_sparc_mangle_relocs,
423 nlm_sparc_read_import,
424 nlm_sparc_write_import,
425 0, /* set_public_section */
426 0, /* get_public_offset */
427 nlm_swap_fixed_header_in,
428 nlm_swap_fixed_header_out,
429 nlm_sparc_write_external,
430 nlm_sparc_write_export
433 #define TARGET_BIG_NAME "nlm32-sparc"
434 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
435 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
437 #include "nlm-target.h"