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
;
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
;
179 index
< sizeof (nlm32_sparc_howto_table
) / sizeof(reloc_howto_type
);
181 tmp
= &nlm32_sparc_howto_table
[index
];
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
) {
198 * Netware wants a list of relocs for each address.
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
211 val
= bfd_get_section_vma (abfd
, (*rel
->sym_ptr_ptr
)->section
) + rel
->address
;
213 val
= bfd_get_section_vma (abfd
, sec
) + rel
->address
;
217 fprintf (stderr
, "%s: val = %08lx, addend = %08lx, type = %d\n",
218 __FUNCTION__
, val
, rel
->addend
, rel
->howto
->type
);
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
);
224 if (bfd_write (&tmp_reloc
, 12, 1, abfd
) != 12)
232 /* Mangle relocs for SPARC NetWare. We can just use the standard
236 nlm_sparc_mangle_relocs (abfd
, sec
, data
, offset
, count
)
246 /* Read a NetWare sparc import record */
248 nlm_sparc_read_import (abfd
, sym
)
250 nlmNAME(symbol_type
) *sym
;
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 */
258 * First, read in the number of relocation
259 * entries for this symbol
261 if (bfd_read ((PTR
) temp
, 4, 1, abfd
) != 4)
264 rcount
= bfd_get_32 (abfd
, temp
);
267 * Next, read in the length of the symbol
270 if (bfd_read ((PTR
) &symlength
, sizeof (symlength
), 1, abfd
)
271 != sizeof (symlength
))
273 sym
-> symbol
.the_bfd
= abfd
;
274 sym
-> symbol
.name
= bfd_alloc (abfd
, symlength
+ 1);
275 if (!sym
-> symbol
.name
)
277 bfd_set_error (bfd_error_no_memory
);
282 * Then read in the symbol
285 if (bfd_read ((PTR
) sym
-> symbol
.name
, symlength
, 1, abfd
)
288 sym
-> symbol
.flags
= 0;
289 sym
-> symbol
.value
= 0;
290 sym
-> symbol
.section
= &bfd_und_section
;
293 * Next, start reading in the relocs.
296 nlm_relocs
= ((struct nlm_relent
*)
297 bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
)));
300 bfd_set_error (bfd_error_no_memory
);
303 sym
-> relocs
= nlm_relocs
;
305 while (sym
-> rcnt
< rcount
)
309 if (nlm_sparc_read_reloc (abfd
, sym
, §ion
,
310 &nlm_relocs
-> reloc
)
313 nlm_relocs
-> section
= section
;
321 nlm_sparc_write_import (abfd
, sec
, rel
)
327 asection
*code
, *data
, *bss
, *symsec
;
330 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
331 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
332 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
333 symsec
= (*rel
->sym_ptr_ptr
)->section
;
335 if (symsec
== code
) {
337 } else if (symsec
== data
) {
338 base
= bfd_section_size (abfd
, code
);
339 } else if (symsec
== bss
) {
340 base
= bfd_section_size (abfd
, code
) + bfd_section_size (abfd
, data
);
345 fprintf (stderr
, "%s: <%x, 1>\n\t",
346 __FUNCTION__
, base
+ (*rel
->sym_ptr_ptr
)->value
);
348 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
349 bfd_write ((PTR
)temp
, 4, 1, abfd
);
350 bfd_put_32 (abfd
, 1, temp
);
351 bfd_write ((PTR
)temp
, 4, 1, abfd
);
352 if (nlm_sparc_write_reloc (abfd
, sec
, rel
) == false)
357 /* Write out an external reference. */
360 nlm_sparc_write_external (abfd
, count
, sym
, relocs
)
364 struct reloc_and_sec
*relocs
;
368 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
370 bfd_put_32 (abfd
, count
, temp
);
371 if (bfd_write (temp
, sizeof(temp
), 1, abfd
) != sizeof (temp
))
374 len
= strlen (sym
->name
);
375 if ((bfd_write (&len
, sizeof (bfd_byte
), 1, abfd
) != sizeof(bfd_byte
))
376 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
379 for (i
= 0; i
< count
; i
++)
381 if (nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
,
382 relocs
[i
].rel
) == false)
390 nlm_sparc_write_export (abfd
, sym
, value
)
399 fprintf (stderr
, "%s: <%x, %d, %s>\n",
400 __FUNCTION__
, value
, strlen (sym
->name
), sym
->name
);
402 bfd_put_32 (abfd
, value
, temp
);
403 len
= strlen (sym
->name
);
405 if (bfd_write (temp
, 4, 1, abfd
) != 4
406 || bfd_write (&len
, 1, 1, abfd
) != 1
407 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
413 #undef nlm_swap_fixed_header_in
414 #undef nlm_swap_fixed_header_out
418 static const struct nlm_backend_data nlm32_sparc_backend
=
420 "NetWare SPARC Module \032",
421 sizeof (Nlm32_sparc_External_Fixed_Header
),
422 0, /* optional_prefix_size */
426 0, /* backend_object_p */
427 0, /* write_prefix_func */
428 nlm_sparc_read_reloc
,
429 nlm_sparc_mangle_relocs
,
430 nlm_sparc_read_import
,
431 nlm_sparc_write_import
,
432 0, /* set_public_section */
433 0, /* get_public_offset */
434 nlm_swap_fixed_header_in
,
435 nlm_swap_fixed_header_out
,
436 nlm_sparc_write_external
,
437 nlm_sparc_write_export
440 #define TARGET_BIG_NAME "nlm32-sparc"
441 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
442 #define TARGET_BACKEND_DATA &nlm32_sparc_backend
444 #include "nlm-target.h"