1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
27 #include "nlm/sparc32-ext.h"
28 #define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
35 R_SPARC_8
, R_SPARC_16
, R_SPARC_32
,
36 R_SPARC_DISP8
, R_SPARC_DISP16
, R_SPARC_DISP32
,
37 R_SPARC_WDISP30
, R_SPARC_WDISP22
,
38 R_SPARC_HI22
, R_SPARC_22
,
39 R_SPARC_13
, R_SPARC_LO10
,
40 R_SPARC_GOT10
, R_SPARC_GOT13
, R_SPARC_GOT22
,
41 R_SPARC_PC10
, R_SPARC_PC22
,
44 R_SPARC_GLOB_DAT
, R_SPARC_JMP_SLOT
,
50 static reloc_howto_type nlm32_sparc_howto_table
[] =
52 HOWTO (R_SPARC_NONE
, 0,0, 0,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_NONE", FALSE
,0,0x00000000,TRUE
),
53 HOWTO (R_SPARC_8
, 0,0, 8,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_8", FALSE
,0,0x000000ff,TRUE
),
54 HOWTO (R_SPARC_16
, 0,1,16,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_16", FALSE
,0,0x0000ffff,TRUE
),
55 HOWTO (R_SPARC_32
, 0,2,32,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_32", FALSE
,0,0xffffffff,TRUE
),
56 HOWTO (R_SPARC_DISP8
, 0,0, 8,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP8", FALSE
,0,0x000000ff,TRUE
),
57 HOWTO (R_SPARC_DISP16
, 0,1,16,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP16", FALSE
,0,0x0000ffff,TRUE
),
58 HOWTO (R_SPARC_DISP32
, 0,2,32,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP32", FALSE
,0,0x00ffffff,TRUE
),
59 HOWTO (R_SPARC_WDISP30
, 2,2,30,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_WDISP30", FALSE
,0,0x3fffffff,TRUE
),
60 HOWTO (R_SPARC_WDISP22
, 2,2,22,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_WDISP22", FALSE
,0,0x003fffff,TRUE
),
61 HOWTO (R_SPARC_HI22
, 10,2,22,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_HI22", FALSE
,0,0x003fffff,TRUE
),
62 HOWTO (R_SPARC_22
, 0,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_22", FALSE
,0,0x003fffff,TRUE
),
63 HOWTO (R_SPARC_13
, 0,2,13,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_13", FALSE
,0,0x00001fff,TRUE
),
64 HOWTO (R_SPARC_LO10
, 0,2,10,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_LO10", FALSE
,0,0x000003ff,TRUE
),
65 HOWTO (R_SPARC_GOT10
, 0,2,10,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT10", FALSE
,0,0x000003ff,TRUE
),
66 HOWTO (R_SPARC_GOT13
, 0,2,13,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT13", FALSE
,0,0x00001fff,TRUE
),
67 HOWTO (R_SPARC_GOT22
, 10,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT22", FALSE
,0,0x003fffff,TRUE
),
68 HOWTO (R_SPARC_PC10
, 0,2,10,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_PC10", FALSE
,0,0x000003ff,TRUE
),
69 HOWTO (R_SPARC_PC22
, 0,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_PC22", FALSE
,0,0x003fffff,TRUE
),
70 HOWTO (R_SPARC_WPLT30
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_WPLT30", FALSE
,0,0x00000000,TRUE
),
71 HOWTO (R_SPARC_COPY
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_COPY", FALSE
,0,0x00000000,TRUE
),
72 HOWTO (R_SPARC_GLOB_DAT
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_GLOB_DAT",FALSE
,0,0x00000000,TRUE
),
73 HOWTO (R_SPARC_JMP_SLOT
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_JMP_SLOT",FALSE
,0,0x00000000,TRUE
),
74 HOWTO (R_SPARC_RELATIVE
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_RELATIVE",FALSE
,0,0x00000000,TRUE
),
75 HOWTO (R_SPARC_UA32
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_UA32", FALSE
,0,0x00000000,TRUE
),
78 /* Read a NetWare sparc reloc. */
80 struct nlm32_sparc_reloc_ext
82 unsigned char offset
[4];
83 unsigned char addend
[4];
84 unsigned char type
[1];
85 unsigned char pad1
[3];
89 nlm_sparc_read_reloc (bfd
*abfd
,
90 nlmNAME (symbol_type
) *sym ATTRIBUTE_UNUSED
,
97 struct nlm32_sparc_reloc_ext tmp_reloc
;
98 asection
*code_sec
, *data_sec
;
100 if (bfd_bread (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
103 code_sec
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
104 data_sec
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
108 val
= bfd_get_32 (abfd
, tmp_reloc
.offset
);
109 addend
= bfd_get_32 (abfd
, tmp_reloc
.addend
);
110 type
= bfd_get_8 (abfd
, tmp_reloc
.type
);
113 rel
->addend
= addend
;
117 index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
119 if (nlm32_sparc_howto_table
[index
].type
== type
)
121 rel
->howto
= &nlm32_sparc_howto_table
[index
];
126 fprintf (stderr
, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
127 __FUNCTION__
, rel
->address
, rel
->addend
, type
, rel
->howto
);
133 /* Write a NetWare sparc reloc. */
136 nlm_sparc_write_reloc (bfd
* abfd
, asection
* sec
, arelent
* rel
)
139 struct nlm32_sparc_reloc_ext tmp_reloc
;
142 reloc_howto_type
*tmp
;
145 index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
148 tmp
= &nlm32_sparc_howto_table
[index
];
150 if (tmp
->rightshift
== rel
->howto
->rightshift
151 && tmp
->size
== rel
->howto
->size
152 && tmp
->bitsize
== rel
->howto
->bitsize
153 && tmp
->pc_relative
== rel
->howto
->pc_relative
154 && tmp
->bitpos
== rel
->howto
->bitpos
155 && tmp
->src_mask
== rel
->howto
->src_mask
156 && tmp
->dst_mask
== rel
->howto
->dst_mask
)
165 /* Netware wants a list of relocs for each address.
170 That should be it. */
172 /* The value we write out is the offset into the appropriate
173 segment. This offset is the section vma, adjusted by the vma of
174 the lowest section in that segment, plus the address of the
176 val
= bfd_get_section_vma (abfd
, sec
) + rel
->address
;
179 fprintf (stderr
, "%s: val = %08lx, addend = %08lx, type = %d\n",
180 __FUNCTION__
, val
, rel
->addend
, rel
->howto
->type
);
182 bfd_put_32 (abfd
, val
, tmp_reloc
.offset
);
183 bfd_put_32 (abfd
, rel
->addend
, tmp_reloc
.addend
);
184 bfd_put_8 (abfd
, (short) (rel
->howto
->type
), tmp_reloc
.type
);
186 if (bfd_bwrite (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
192 /* Mangle relocs for SPARC NetWare. We can just use the standard
196 nlm_sparc_mangle_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
197 asection
*sec ATTRIBUTE_UNUSED
,
198 const void * data ATTRIBUTE_UNUSED
,
199 bfd_vma offset ATTRIBUTE_UNUSED
,
200 bfd_size_type count ATTRIBUTE_UNUSED
)
205 /* Read a NetWare sparc import record. */
208 nlm_sparc_read_import (bfd
*abfd
, nlmNAME (symbol_type
) *sym
)
210 struct nlm_relent
*nlm_relocs
; /* Relocation records for symbol. */
211 bfd_size_type rcount
; /* Number of relocs. */
212 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Temporary 32-bit value. */
213 unsigned char symlength
; /* Length of symbol name. */
216 /* First, read in the number of relocation
217 entries for this symbol. */
218 if (bfd_bread (temp
, (bfd_size_type
) 4, abfd
) != 4)
221 rcount
= bfd_get_32 (abfd
, temp
);
223 /* Next, read in the length of the symbol. */
224 if (bfd_bread (& symlength
, (bfd_size_type
) sizeof (symlength
), abfd
)
225 != sizeof (symlength
))
227 sym
-> symbol
.the_bfd
= abfd
;
228 name
= bfd_alloc (abfd
, (bfd_size_type
) symlength
+ 1);
232 /* Then read in the symbol. */
233 if (bfd_bread (name
, (bfd_size_type
) symlength
, abfd
) != symlength
)
235 name
[symlength
] = '\0';
236 sym
-> symbol
.name
= name
;
237 sym
-> symbol
.flags
= 0;
238 sym
-> symbol
.value
= 0;
239 sym
-> symbol
.section
= bfd_und_section_ptr
;
241 /* Next, start reading in the relocs. */
242 nlm_relocs
= bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
));
245 sym
-> relocs
= nlm_relocs
;
247 while (sym
-> rcnt
< rcount
)
251 if (! nlm_sparc_read_reloc (abfd
, sym
, §ion
, &nlm_relocs
-> reloc
))
253 nlm_relocs
-> section
= section
;
262 nlm_sparc_write_import (bfd
* abfd
, asection
* sec
, arelent
* rel
)
265 asection
*code
, *data
, *bss
, *symsec
;
268 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
269 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
270 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
271 symsec
= (*rel
->sym_ptr_ptr
)->section
;
275 else if (symsec
== data
)
277 else if (symsec
== bss
)
278 base
= code
->size
+ data
->size
;
283 fprintf (stderr
, "%s: <%x, 1>\n\t",
284 __FUNCTION__
, base
+ (*rel
->sym_ptr_ptr
)->value
);
286 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
287 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
289 bfd_put_32 (abfd
, (bfd_vma
) 1, temp
);
290 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
292 if (! nlm_sparc_write_reloc (abfd
, sec
, rel
))
297 /* Write out an external reference. */
300 nlm_sparc_write_external (bfd
*abfd
,
303 struct reloc_and_sec
*relocs
)
307 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
309 bfd_put_32 (abfd
, count
, temp
);
310 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
) != sizeof (temp
))
313 len
= strlen (sym
->name
);
314 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
315 != sizeof (bfd_byte
))
316 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
319 for (i
= 0; i
< count
; i
++)
320 if (! nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
, relocs
[i
].rel
))
327 nlm_sparc_write_export (bfd
* abfd
, asymbol
* sym
, bfd_vma value
)
333 fprintf (stderr
, "%s: <%x, %d, %s>\n",
334 __FUNCTION__
, value
, strlen (sym
->name
), sym
->name
);
336 bfd_put_32 (abfd
, value
, temp
);
337 len
= strlen (sym
->name
);
339 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4
340 || bfd_bwrite (&len
, (bfd_size_type
) 1, abfd
) != 1
341 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
347 #undef nlm_swap_fixed_header_in
348 #undef nlm_swap_fixed_header_out
352 static const struct nlm_backend_data nlm32_sparc_backend
=
354 "NetWare SPARC Module \032",
355 sizeof (Nlm32_sparc_External_Fixed_Header
),
356 0, /* Optional_prefix_size. */
360 0, /* Backend_object_p. */
361 0, /* Write_prefix_func. */
362 nlm_sparc_read_reloc
,
363 nlm_sparc_mangle_relocs
,
364 nlm_sparc_read_import
,
365 nlm_sparc_write_import
,
366 0, /* Set_public_section. */
367 0, /* Get_public_offset. */
368 nlm_swap_fixed_header_in
,
369 nlm_swap_fixed_header_out
,
370 nlm_sparc_write_external
,
371 nlm_sparc_write_export
374 #define TARGET_BIG_NAME "nlm32-sparc"
375 #define TARGET_BIG_SYM nlmNAME (sparc_vec)
376 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
378 #include "nlm-target.h"