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) {
134 bfd_error
= system_call_error
;
138 code_sec
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
139 data_sec
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
143 val
= bfd_get_32 (abfd
, tmp_reloc
.offset
);
144 addend
= bfd_get_32 (abfd
, tmp_reloc
.addend
);
145 type
= bfd_get_8 (abfd
, tmp_reloc
.type
);
148 rel
->addend
= addend
;
152 index
< sizeof(nlm32_sparc_howto_table
) / sizeof(reloc_howto_type
);
154 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
;
183 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.
210 /* The value we write out is the offset into the appropriate
211 segment. This offset is the section vma, adjusted by the vma of
212 the lowest section in that segment, plus the address of the
215 val
= bfd_get_section_vma (abfd
, (*rel
->sym_ptr_ptr
)->section
) + rel
->address
;
217 val
= bfd_get_section_vma (abfd
, sec
) + rel
->address
;
221 fprintf (stderr
, "%s: val = %08lx, addend = %08lx, type = %d\n",
222 __FUNCTION__
, val
, rel
->addend
, rel
->howto
->type
);
224 bfd_put_32 (abfd
, val
, tmp_reloc
.offset
);
225 bfd_put_32 (abfd
, rel
->addend
, tmp_reloc
.addend
);
226 bfd_put_8 (abfd
, (short)(rel
->howto
->type
), tmp_reloc
.type
);
228 if (bfd_write (&tmp_reloc
, 12, 1, abfd
) != 12)
236 /* Mangle relocs for SPARC NetWare. We can just use the standard
240 nlm_sparc_mangle_relocs (abfd
, sec
, data
, offset
, count
)
250 /* Read a NetWare sparc import record */
252 nlm_sparc_read_import (abfd
, sym
)
254 nlmNAME(symbol_type
) *sym
;
256 struct nlm_relent
*nlm_relocs
; /* relocation records for symbol */
257 bfd_size_type rcount
; /* number of relocs */
258 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* temporary 32-bit value */
259 unsigned char symlength
; /* length of symbol name */
262 * First, read in the number of relocation
263 * entries for this symbol
265 if (bfd_read ((PTR
) temp
, 4, 1, abfd
)
268 bfd_error
= system_call_error
;
272 rcount
= bfd_get_32 (abfd
, temp
);
275 * Next, read in the length of the symbol
278 if (bfd_read ((PTR
) &symlength
, sizeof (symlength
), 1, abfd
)
279 != sizeof (symlength
))
281 bfd_error
= system_call_error
;
284 sym
-> symbol
.the_bfd
= abfd
;
285 sym
-> symbol
.name
= bfd_alloc (abfd
, symlength
+ 1);
286 if (!sym
-> symbol
.name
)
288 bfd_error
= no_memory
;
293 * Then read in the symbol
296 if (bfd_read ((PTR
) sym
-> symbol
.name
, symlength
, 1, abfd
)
299 bfd_error
= system_call_error
;
302 sym
-> symbol
.flags
= 0;
303 sym
-> symbol
.value
= 0;
304 sym
-> symbol
.section
= &bfd_und_section
;
307 * Next, start reading in the relocs.
310 nlm_relocs
= ((struct nlm_relent
*)
311 bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
)));
314 bfd_error
= no_memory
;
317 sym
-> relocs
= nlm_relocs
;
319 while (sym
-> rcnt
< rcount
)
323 if (nlm_sparc_read_reloc (abfd
, sym
, §ion
,
324 &nlm_relocs
-> reloc
)
327 nlm_relocs
-> section
= section
;
335 nlm_sparc_write_import (abfd
, sec
, rel
)
341 asection
*code
, *data
, *bss
, *symsec
;
344 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
345 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
346 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
347 symsec
= (*rel
->sym_ptr_ptr
)->section
;
349 if (symsec
== code
) {
351 } else if (symsec
== data
) {
352 base
= bfd_section_size (abfd
, code
);
353 } else if (symsec
== bss
) {
354 base
= bfd_section_size (abfd
, code
) + bfd_section_size (abfd
, data
);
359 fprintf (stderr
, "%s: <%x, 1>\n\t",
360 __FUNCTION__
, base
+ (*rel
->sym_ptr_ptr
)->value
);
362 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
363 bfd_write ((PTR
)temp
, 4, 1, abfd
);
364 bfd_put_32 (abfd
, 1, temp
);
365 bfd_write ((PTR
)temp
, 4, 1, abfd
);
366 if (nlm_sparc_write_reloc (abfd
, sec
, rel
) == false)
371 /* Write out an external reference. */
374 nlm_sparc_write_external (abfd
, count
, sym
, relocs
)
378 struct reloc_and_sec
*relocs
;
382 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
384 bfd_put_32 (abfd
, count
, temp
);
385 if (bfd_write (temp
, sizeof(temp
), 1, abfd
) != sizeof (temp
))
387 bfd_error
= system_call_error
;
391 len
= strlen (sym
->name
);
392 if ((bfd_write (&len
, sizeof (bfd_byte
), 1, abfd
) != sizeof(bfd_byte
))
393 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
395 bfd_error
= system_call_error
;
399 for (i
= 0; i
< count
; i
++)
401 if (nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
,
402 relocs
[i
].rel
) == false)
410 nlm_sparc_write_export (abfd
, sym
, value
)
419 fprintf (stderr
, "%s: <%x, %d, %s>\n",
420 __FUNCTION__
, value
, strlen (sym
->name
), sym
->name
);
422 bfd_put_32 (abfd
, value
, temp
);
423 len
= strlen (sym
->name
);
425 if (bfd_write (temp
, 4, 1, abfd
) != 4
426 || bfd_write (&len
, 1, 1, abfd
) != 1
427 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
429 bfd_error
= system_call_error
;
436 #undef nlm_swap_fixed_header_in
437 #undef nlm_swap_fixed_header_out
441 static const struct nlm_backend_data nlm32_sparc_backend
=
443 "NetWare SPARC Module \032",
444 sizeof (Nlm32_sparc_External_Fixed_Header
),
445 0, /* optional_prefix_size */
449 0, /* backend_object_p */
450 0, /* write_prefix_func */
451 nlm_sparc_read_reloc
,
452 nlm_sparc_mangle_relocs
,
453 nlm_sparc_read_import
,
454 nlm_sparc_write_import
,
455 0, /* set_public_section */
456 0, /* get_public_offset */
457 nlm_swap_fixed_header_in
,
458 nlm_swap_fixed_header_out
,
459 nlm_sparc_write_external
,
460 nlm_sparc_write_export
463 #define TARGET_BIG_NAME "nlm32-sparc"
464 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
465 #define TARGET_BACKEND_DATA &nlm32_sparc_backend
467 #include "nlm-target.h"