1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 2000, 2001, 2002 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_bread (&tmp_reloc
, (bfd_size_type
) 12, 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_bwrite (&tmp_reloc
, (bfd_size_type
) 12, 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_bread ((PTR
) temp
, (bfd_size_type
) 4, abfd
) != 4)
265 rcount
= bfd_get_32 (abfd
, temp
);
267 /* Next, read in the length of the symbol. */
269 if (bfd_bread ((PTR
) &symlength
, (bfd_size_type
) sizeof (symlength
), abfd
)
270 != sizeof (symlength
))
272 sym
-> symbol
.the_bfd
= abfd
;
273 name
= bfd_alloc (abfd
, (bfd_size_type
) symlength
+ 1);
277 /* Then read in the symbol. */
279 if (bfd_bread (name
, (bfd_size_type
) symlength
, 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
, &nlm_relocs
-> reloc
))
301 nlm_relocs
-> section
= section
;
310 nlm_sparc_write_import (abfd
, sec
, rel
)
316 asection
*code
, *data
, *bss
, *symsec
;
319 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
320 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
321 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
322 symsec
= (*rel
->sym_ptr_ptr
)->section
;
326 else if (symsec
== data
)
327 base
= bfd_section_size (abfd
, code
);
328 else if (symsec
== bss
)
329 base
= bfd_section_size (abfd
, code
) + bfd_section_size (abfd
, data
);
334 fprintf (stderr
, "%s: <%x, 1>\n\t",
335 __FUNCTION__
, base
+ (*rel
->sym_ptr_ptr
)->value
);
337 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
338 if (bfd_bwrite ((PTR
) temp
, (bfd_size_type
) 4, abfd
) != 4)
340 bfd_put_32 (abfd
, (bfd_vma
) 1, temp
);
341 if (bfd_bwrite ((PTR
) temp
, (bfd_size_type
) 4, abfd
) != 4)
343 if (! nlm_sparc_write_reloc (abfd
, sec
, rel
))
348 /* Write out an external reference. */
351 nlm_sparc_write_external (abfd
, count
, sym
, relocs
)
355 struct reloc_and_sec
*relocs
;
359 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
361 bfd_put_32 (abfd
, count
, temp
);
362 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
) != sizeof (temp
))
365 len
= strlen (sym
->name
);
366 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
367 != sizeof (bfd_byte
))
368 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
371 for (i
= 0; i
< count
; i
++)
373 if (! nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
, relocs
[i
].rel
))
381 nlm_sparc_write_export (abfd
, sym
, value
)
390 fprintf (stderr
, "%s: <%x, %d, %s>\n",
391 __FUNCTION__
, value
, strlen (sym
->name
), sym
->name
);
393 bfd_put_32 (abfd
, value
, temp
);
394 len
= strlen (sym
->name
);
396 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4
397 || bfd_bwrite (&len
, (bfd_size_type
) 1, abfd
) != 1
398 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
404 #undef nlm_swap_fixed_header_in
405 #undef nlm_swap_fixed_header_out
409 static const struct nlm_backend_data nlm32_sparc_backend
=
411 "NetWare SPARC Module \032",
412 sizeof (Nlm32_sparc_External_Fixed_Header
),
413 0, /* optional_prefix_size */
417 0, /* backend_object_p */
418 0, /* write_prefix_func */
419 nlm_sparc_read_reloc
,
420 nlm_sparc_mangle_relocs
,
421 nlm_sparc_read_import
,
422 nlm_sparc_write_import
,
423 0, /* set_public_section */
424 0, /* get_public_offset */
425 nlm_swap_fixed_header_in
,
426 nlm_swap_fixed_header_out
,
427 nlm_sparc_write_external
,
428 nlm_sparc_write_export
431 #define TARGET_BIG_NAME "nlm32-sparc"
432 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
433 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
435 #include "nlm-target.h"