1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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 = %u, howto = %p\n",
127 __FUNCTION__
, (unsigned long) rel
->address
,
128 (unsigned long) rel
->addend
, type
, rel
->howto
);
134 /* Write a NetWare sparc reloc. */
137 nlm_sparc_write_reloc (bfd
* abfd
, asection
* sec
, arelent
* rel
)
140 struct nlm32_sparc_reloc_ext tmp_reloc
;
143 reloc_howto_type
*tmp
;
146 index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
149 tmp
= &nlm32_sparc_howto_table
[index
];
151 if (tmp
->rightshift
== rel
->howto
->rightshift
152 && tmp
->size
== rel
->howto
->size
153 && tmp
->bitsize
== rel
->howto
->bitsize
154 && tmp
->pc_relative
== rel
->howto
->pc_relative
155 && tmp
->bitpos
== rel
->howto
->bitpos
156 && tmp
->src_mask
== rel
->howto
->src_mask
157 && tmp
->dst_mask
== rel
->howto
->dst_mask
)
166 /* Netware wants a list of relocs for each address.
171 That should be it. */
173 /* The value we write out is the offset into the appropriate
174 segment. This offset is the section vma, adjusted by the vma of
175 the lowest section in that segment, plus the address of the
177 val
= bfd_get_section_vma (abfd
, sec
) + rel
->address
;
180 fprintf (stderr
, "%s: val = %08lx, addend = %08lx, type = %u\n",
181 __FUNCTION__
, (unsigned long) val
, (unsigned long) rel
->addend
,
184 bfd_put_32 (abfd
, val
, tmp_reloc
.offset
);
185 bfd_put_32 (abfd
, rel
->addend
, tmp_reloc
.addend
);
186 bfd_put_8 (abfd
, (short) (rel
->howto
->type
), tmp_reloc
.type
);
188 if (bfd_bwrite (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
194 /* Mangle relocs for SPARC NetWare. We can just use the standard
198 nlm_sparc_mangle_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
199 asection
*sec ATTRIBUTE_UNUSED
,
200 const void * data ATTRIBUTE_UNUSED
,
201 bfd_vma offset ATTRIBUTE_UNUSED
,
202 bfd_size_type count ATTRIBUTE_UNUSED
)
207 /* Read a NetWare sparc import record. */
210 nlm_sparc_read_import (bfd
*abfd
, nlmNAME (symbol_type
) *sym
)
212 struct nlm_relent
*nlm_relocs
; /* Relocation records for symbol. */
213 bfd_size_type rcount
; /* Number of relocs. */
214 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Temporary 32-bit value. */
215 unsigned char symlength
; /* Length of symbol name. */
218 /* First, read in the number of relocation
219 entries for this symbol. */
220 if (bfd_bread (temp
, (bfd_size_type
) 4, abfd
) != 4)
223 rcount
= bfd_get_32 (abfd
, temp
);
225 /* Next, read in the length of the symbol. */
226 if (bfd_bread (& symlength
, (bfd_size_type
) sizeof (symlength
), abfd
)
227 != sizeof (symlength
))
229 sym
-> symbol
.the_bfd
= abfd
;
230 name
= bfd_alloc (abfd
, (bfd_size_type
) symlength
+ 1);
234 /* Then read in the symbol. */
235 if (bfd_bread (name
, (bfd_size_type
) symlength
, abfd
) != symlength
)
237 name
[symlength
] = '\0';
238 sym
-> symbol
.name
= name
;
239 sym
-> symbol
.flags
= 0;
240 sym
-> symbol
.value
= 0;
241 sym
-> symbol
.section
= bfd_und_section_ptr
;
243 /* Next, start reading in the relocs. */
244 nlm_relocs
= bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
));
247 sym
-> relocs
= nlm_relocs
;
249 while (sym
-> rcnt
< rcount
)
253 if (! nlm_sparc_read_reloc (abfd
, sym
, §ion
, &nlm_relocs
-> reloc
))
255 nlm_relocs
-> section
= section
;
264 nlm_sparc_write_import (bfd
* abfd
, asection
* sec
, arelent
* rel
)
267 asection
*code
, *data
, *bss
, *symsec
;
270 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
271 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
272 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
273 symsec
= (*rel
->sym_ptr_ptr
)->section
;
277 else if (symsec
== data
)
279 else if (symsec
== bss
)
280 base
= code
->size
+ data
->size
;
285 fprintf (stderr
, "%s: <%lx, 1>\n\t",
286 __FUNCTION__
, (unsigned long) (base
+ (*rel
->sym_ptr_ptr
)->value
));
288 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
289 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
291 bfd_put_32 (abfd
, (bfd_vma
) 1, temp
);
292 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
294 if (! nlm_sparc_write_reloc (abfd
, sec
, rel
))
299 /* Write out an external reference. */
302 nlm_sparc_write_external (bfd
*abfd
,
305 struct reloc_and_sec
*relocs
)
309 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
311 bfd_put_32 (abfd
, count
, temp
);
312 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
) != sizeof (temp
))
315 len
= strlen (sym
->name
);
316 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
317 != sizeof (bfd_byte
))
318 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
321 for (i
= 0; i
< count
; i
++)
322 if (! nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
, relocs
[i
].rel
))
329 nlm_sparc_write_export (bfd
* abfd
, asymbol
* sym
, bfd_vma value
)
335 fprintf (stderr
, "%s: <%lx, %u, %s>\n",
336 __FUNCTION__
, (unsigned long) value
, strlen (sym
->name
), sym
->name
);
338 bfd_put_32 (abfd
, value
, temp
);
339 len
= strlen (sym
->name
);
341 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4
342 || bfd_bwrite (&len
, (bfd_size_type
) 1, abfd
) != 1
343 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
349 #undef nlm_swap_fixed_header_in
350 #undef nlm_swap_fixed_header_out
354 static const struct nlm_backend_data nlm32_sparc_backend
=
356 "NetWare SPARC Module \032",
357 sizeof (Nlm32_sparc_External_Fixed_Header
),
358 0, /* Optional_prefix_size. */
362 0, /* Backend_object_p. */
363 0, /* Write_prefix_func. */
364 nlm_sparc_read_reloc
,
365 nlm_sparc_mangle_relocs
,
366 nlm_sparc_read_import
,
367 nlm_sparc_write_import
,
368 0, /* Set_public_section. */
369 0, /* Get_public_offset. */
370 nlm_swap_fixed_header_in
,
371 nlm_swap_fixed_header_out
,
372 nlm_sparc_write_external
,
373 nlm_sparc_write_export
376 #define TARGET_BIG_NAME "nlm32-sparc"
377 #define TARGET_BIG_SYM nlmNAME (sparc_vec)
378 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
380 #include "nlm-target.h"