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
= {0};
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);
288 * Then read in the symbol
291 if (bfd_read ((PTR
) sym
-> symbol
.name
, symlength
, 1, abfd
)
294 bfd_error
= system_call_error
;
297 sym
-> symbol
.flags
= 0;
298 sym
-> symbol
.value
= 0;
299 sym
-> symbol
.section
= &bfd_und_section
;
302 * Next, start reading in the relocs.
305 nlm_relocs
= ((struct nlm_relent
*)
306 bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
)));
307 sym
-> relocs
= nlm_relocs
;
309 while (sym
-> rcnt
< rcount
)
313 if (nlm_sparc_read_reloc (abfd
, sym
, §ion
,
314 &nlm_relocs
-> reloc
)
317 nlm_relocs
-> section
= section
;
325 nlm_sparc_write_import (abfd
, sec
, rel
)
331 asection
*code
, *data
, *bss
, *symsec
;
334 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
335 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
336 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
337 symsec
= (*rel
->sym_ptr_ptr
)->section
;
339 if (symsec
== code
) {
341 } else if (symsec
== data
) {
342 base
= bfd_section_size (abfd
, code
);
343 } else if (symsec
== bss
) {
344 base
= bfd_section_size (abfd
, code
) + bfd_section_size (abfd
, data
);
349 fprintf (stderr
, "%s: <%x, 1>\n\t",
350 __FUNCTION__
, base
+ (*rel
->sym_ptr_ptr
)->value
);
352 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
353 bfd_write ((PTR
)temp
, 4, 1, abfd
);
354 bfd_put_32 (abfd
, 1, temp
);
355 bfd_write ((PTR
)temp
, 4, 1, abfd
);
356 if (nlm_sparc_write_reloc (abfd
, sec
, rel
) == false)
361 /* Write out an external reference. */
364 nlm_sparc_write_external (abfd
, count
, sym
, relocs
)
368 struct reloc_and_sec
*relocs
;
372 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
374 bfd_put_32 (abfd
, count
, temp
);
375 if (bfd_write (temp
, sizeof(temp
), 1, abfd
) != sizeof (temp
))
377 bfd_error
= system_call_error
;
381 len
= strlen (sym
->name
);
382 if ((bfd_write (&len
, sizeof (bfd_byte
), 1, abfd
) != sizeof(bfd_byte
))
383 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
385 bfd_error
= system_call_error
;
389 for (i
= 0; i
< count
; i
++)
391 if (nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
,
392 relocs
[i
].rel
) == false)
400 nlm_sparc_write_export (abfd
, sym
, value
)
409 fprintf (stderr
, "%s: <%x, %d, %s>\n",
410 __FUNCTION__
, value
, strlen (sym
->name
), sym
->name
);
412 bfd_put_32 (abfd
, value
, temp
);
413 len
= strlen (sym
->name
);
415 if (bfd_write (temp
, 4, 1, abfd
) != 4
416 || bfd_write (&len
, 1, 1, abfd
) != 1
417 || bfd_write (sym
->name
, len
, 1, abfd
) != len
)
419 bfd_error
= system_call_error
;
426 #undef nlm_swap_fixed_header_in
427 #undef nlm_swap_fixed_header_out
431 static const struct nlm_backend_data nlm32_sparc_backend
=
433 "NetWare SPARC Module \032",
434 sizeof (Nlm32_sparc_External_Fixed_Header
),
435 0, /* optional_prefix_size */
439 0, /* backend_object_p */
440 0, /* write_prefix_func */
441 nlm_sparc_read_reloc
,
442 nlm_sparc_mangle_relocs
,
443 nlm_sparc_read_import
,
444 nlm_sparc_write_import
,
445 0, /* set_public_section */
446 0, /* get_public_offset */
447 nlm_swap_fixed_header_in
,
448 nlm_swap_fixed_header_out
,
449 nlm_sparc_write_external
,
450 nlm_sparc_write_export
453 #define TARGET_BIG_NAME "nlm32-sparc"
454 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
455 #define TARGET_BACKEND_DATA &nlm32_sparc_backend
457 #include "nlm-target.h"