1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #include "nlm/sparc32-ext.h"
28 #define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
32 static bfd_boolean nlm_sparc_read_reloc
33 PARAMS ((bfd
*, nlmNAME(symbol_type
) *, asection
**, arelent
*));
34 static bfd_boolean nlm_sparc_write_reloc
35 PARAMS ((bfd
*, asection
*, arelent
*));
36 static bfd_boolean nlm_sparc_mangle_relocs
37 PARAMS ((bfd
*, asection
*, const PTR
, bfd_vma
, bfd_size_type
));
38 static bfd_boolean nlm_sparc_read_import
39 PARAMS ((bfd
*, nlmNAME(symbol_type
) *));
40 static bfd_boolean nlm_sparc_write_import
41 PARAMS ((bfd
*, asection
*, arelent
*));
42 static bfd_boolean nlm_sparc_write_external
43 PARAMS ((bfd
*, bfd_size_type
, asymbol
*, struct reloc_and_sec
*));
44 static bfd_boolean nlm_sparc_write_export
45 PARAMS ((bfd
*, asymbol
*, bfd_vma
));
50 R_SPARC_8
, R_SPARC_16
, R_SPARC_32
,
51 R_SPARC_DISP8
, R_SPARC_DISP16
, R_SPARC_DISP32
,
52 R_SPARC_WDISP30
, R_SPARC_WDISP22
,
53 R_SPARC_HI22
, R_SPARC_22
,
54 R_SPARC_13
, R_SPARC_LO10
,
55 R_SPARC_GOT10
, R_SPARC_GOT13
, R_SPARC_GOT22
,
56 R_SPARC_PC10
, R_SPARC_PC22
,
59 R_SPARC_GLOB_DAT
, R_SPARC_JMP_SLOT
,
66 static const char *const reloc_type_names
[] =
69 "R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
70 "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
71 "R_SPARC_WDISP30", "R_SPARC_WDISP22",
72 "R_SPARC_HI22", "R_SPARC_22",
73 "R_SPARC_13", "R_SPARC_LO10",
74 "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
75 "R_SPARC_PC10", "R_SPARC_PC22",
78 "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
84 static reloc_howto_type nlm32_sparc_howto_table
[] =
86 HOWTO (R_SPARC_NONE
, 0,0, 0,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_NONE", FALSE
,0,0x00000000,TRUE
),
87 HOWTO (R_SPARC_8
, 0,0, 8,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_8", FALSE
,0,0x000000ff,TRUE
),
88 HOWTO (R_SPARC_16
, 0,1,16,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_16", FALSE
,0,0x0000ffff,TRUE
),
89 HOWTO (R_SPARC_32
, 0,2,32,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_32", FALSE
,0,0xffffffff,TRUE
),
90 HOWTO (R_SPARC_DISP8
, 0,0, 8,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP8", FALSE
,0,0x000000ff,TRUE
),
91 HOWTO (R_SPARC_DISP16
, 0,1,16,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP16", FALSE
,0,0x0000ffff,TRUE
),
92 HOWTO (R_SPARC_DISP32
, 0,2,32,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP32", FALSE
,0,0x00ffffff,TRUE
),
93 HOWTO (R_SPARC_WDISP30
, 2,2,30,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_WDISP30", FALSE
,0,0x3fffffff,TRUE
),
94 HOWTO (R_SPARC_WDISP22
, 2,2,22,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_WDISP22", FALSE
,0,0x003fffff,TRUE
),
95 HOWTO (R_SPARC_HI22
, 10,2,22,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_HI22", FALSE
,0,0x003fffff,TRUE
),
96 HOWTO (R_SPARC_22
, 0,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_22", FALSE
,0,0x003fffff,TRUE
),
97 HOWTO (R_SPARC_13
, 0,2,13,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_13", FALSE
,0,0x00001fff,TRUE
),
98 HOWTO (R_SPARC_LO10
, 0,2,10,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_LO10", FALSE
,0,0x000003ff,TRUE
),
99 HOWTO (R_SPARC_GOT10
, 0,2,10,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT10", FALSE
,0,0x000003ff,TRUE
),
100 HOWTO (R_SPARC_GOT13
, 0,2,13,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT13", FALSE
,0,0x00001fff,TRUE
),
101 HOWTO (R_SPARC_GOT22
, 10,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT22", FALSE
,0,0x003fffff,TRUE
),
102 HOWTO (R_SPARC_PC10
, 0,2,10,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_PC10", FALSE
,0,0x000003ff,TRUE
),
103 HOWTO (R_SPARC_PC22
, 0,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_PC22", FALSE
,0,0x003fffff,TRUE
),
104 HOWTO (R_SPARC_WPLT30
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_WPLT30", FALSE
,0,0x00000000,TRUE
),
105 HOWTO (R_SPARC_COPY
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_COPY", FALSE
,0,0x00000000,TRUE
),
106 HOWTO (R_SPARC_GLOB_DAT
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_GLOB_DAT",FALSE
,0,0x00000000,TRUE
),
107 HOWTO (R_SPARC_JMP_SLOT
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_JMP_SLOT",FALSE
,0,0x00000000,TRUE
),
108 HOWTO (R_SPARC_RELATIVE
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_RELATIVE",FALSE
,0,0x00000000,TRUE
),
109 HOWTO (R_SPARC_UA32
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_UA32", FALSE
,0,0x00000000,TRUE
),
112 /* Read a NetWare sparc reloc. */
114 struct nlm32_sparc_reloc_ext
116 unsigned char offset
[4];
117 unsigned char addend
[4];
118 unsigned char type
[1];
119 unsigned char pad1
[3];
123 nlm_sparc_read_reloc (abfd
, sym
, secp
, rel
)
125 nlmNAME(symbol_type
) *sym ATTRIBUTE_UNUSED
;
132 struct nlm32_sparc_reloc_ext tmp_reloc
;
133 asection
*code_sec
, *data_sec
;
135 if (bfd_bread (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
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
)
156 rel
->howto
= &nlm32_sparc_howto_table
[index
];
161 fprintf (stderr
, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
162 __FUNCTION__
, rel
->address
, rel
->addend
, type
, rel
->howto
);
168 /* Write a NetWare sparc reloc. */
171 nlm_sparc_write_reloc (abfd
, sec
, rel
)
177 struct nlm32_sparc_reloc_ext tmp_reloc
;
180 reloc_howto_type
*tmp
;
183 index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
186 tmp
= &nlm32_sparc_howto_table
[index
];
188 if (tmp
->rightshift
== rel
->howto
->rightshift
189 && tmp
->size
== rel
->howto
->size
190 && tmp
->bitsize
== rel
->howto
->bitsize
191 && tmp
->pc_relative
== rel
->howto
->pc_relative
192 && tmp
->bitpos
== rel
->howto
->bitpos
193 && tmp
->src_mask
== rel
->howto
->src_mask
194 && tmp
->dst_mask
== rel
->howto
->dst_mask
)
203 /* Netware wants a list of relocs for each address.
208 That should be it. */
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_bwrite (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
234 /* Mangle relocs for SPARC NetWare. We can just use the standard
238 nlm_sparc_mangle_relocs (abfd
, sec
, data
, offset
, count
)
239 bfd
*abfd ATTRIBUTE_UNUSED
;
240 asection
*sec ATTRIBUTE_UNUSED
;
241 const PTR data ATTRIBUTE_UNUSED
;
242 bfd_vma offset ATTRIBUTE_UNUSED
;
243 bfd_size_type count ATTRIBUTE_UNUSED
;
248 /* Read a NetWare sparc import record. */
251 nlm_sparc_read_import (abfd
, sym
)
253 nlmNAME(symbol_type
) *sym
;
255 struct nlm_relent
*nlm_relocs
; /* Relocation records for symbol. */
256 bfd_size_type rcount
; /* Number of relocs. */
257 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Temporary 32-bit value. */
258 unsigned char symlength
; /* Length of symbol name. */
261 /* First, read in the number of relocation
262 entries for this symbol. */
263 if (bfd_bread ((PTR
) temp
, (bfd_size_type
) 4, abfd
) != 4)
266 rcount
= bfd_get_32 (abfd
, temp
);
268 /* Next, read in the length of the symbol. */
270 if (bfd_bread ((PTR
) &symlength
, (bfd_size_type
) sizeof (symlength
), abfd
)
271 != sizeof (symlength
))
273 sym
-> symbol
.the_bfd
= abfd
;
274 name
= bfd_alloc (abfd
, (bfd_size_type
) symlength
+ 1);
278 /* Then read in the symbol. */
280 if (bfd_bread (name
, (bfd_size_type
) symlength
, abfd
) != symlength
)
282 name
[symlength
] = '\0';
283 sym
-> symbol
.name
= name
;
284 sym
-> symbol
.flags
= 0;
285 sym
-> symbol
.value
= 0;
286 sym
-> symbol
.section
= bfd_und_section_ptr
;
288 /* Next, start reading in the relocs. */
290 nlm_relocs
= ((struct nlm_relent
*)
291 bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
)));
294 sym
-> relocs
= nlm_relocs
;
296 while (sym
-> rcnt
< rcount
)
300 if (! nlm_sparc_read_reloc (abfd
, sym
, §ion
, &nlm_relocs
-> reloc
))
302 nlm_relocs
-> section
= section
;
311 nlm_sparc_write_import (abfd
, sec
, rel
)
317 asection
*code
, *data
, *bss
, *symsec
;
320 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
321 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
322 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
323 symsec
= (*rel
->sym_ptr_ptr
)->section
;
327 else if (symsec
== data
)
329 else if (symsec
== bss
)
330 base
= code
->size
+ data
->size
;
335 fprintf (stderr
, "%s: <%x, 1>\n\t",
336 __FUNCTION__
, base
+ (*rel
->sym_ptr_ptr
)->value
);
338 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
339 if (bfd_bwrite ((PTR
) temp
, (bfd_size_type
) 4, abfd
) != 4)
341 bfd_put_32 (abfd
, (bfd_vma
) 1, temp
);
342 if (bfd_bwrite ((PTR
) temp
, (bfd_size_type
) 4, abfd
) != 4)
344 if (! nlm_sparc_write_reloc (abfd
, sec
, rel
))
349 /* Write out an external reference. */
352 nlm_sparc_write_external (abfd
, count
, sym
, relocs
)
356 struct reloc_and_sec
*relocs
;
360 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
362 bfd_put_32 (abfd
, count
, temp
);
363 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
) != sizeof (temp
))
366 len
= strlen (sym
->name
);
367 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
368 != sizeof (bfd_byte
))
369 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
372 for (i
= 0; i
< count
; i
++)
374 if (! nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
, relocs
[i
].rel
))
382 nlm_sparc_write_export (abfd
, sym
, value
)
391 fprintf (stderr
, "%s: <%x, %d, %s>\n",
392 __FUNCTION__
, value
, strlen (sym
->name
), sym
->name
);
394 bfd_put_32 (abfd
, value
, temp
);
395 len
= strlen (sym
->name
);
397 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4
398 || bfd_bwrite (&len
, (bfd_size_type
) 1, abfd
) != 1
399 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
405 #undef nlm_swap_fixed_header_in
406 #undef nlm_swap_fixed_header_out
410 static const struct nlm_backend_data nlm32_sparc_backend
=
412 "NetWare SPARC Module \032",
413 sizeof (Nlm32_sparc_External_Fixed_Header
),
414 0, /* optional_prefix_size */
418 0, /* backend_object_p */
419 0, /* write_prefix_func */
420 nlm_sparc_read_reloc
,
421 nlm_sparc_mangle_relocs
,
422 nlm_sparc_read_import
,
423 nlm_sparc_write_import
,
424 0, /* set_public_section */
425 0, /* get_public_offset */
426 nlm_swap_fixed_header_in
,
427 nlm_swap_fixed_header_out
,
428 nlm_sparc_write_external
,
429 nlm_sparc_write_export
432 #define TARGET_BIG_NAME "nlm32-sparc"
433 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
434 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
436 #include "nlm-target.h"