1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2 Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007, 2009 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 3 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,
20 MA 02110-1301, USA. */
28 #include "nlm/sparc32-ext.h"
29 #define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
36 R_SPARC_8
, R_SPARC_16
, R_SPARC_32
,
37 R_SPARC_DISP8
, R_SPARC_DISP16
, R_SPARC_DISP32
,
38 R_SPARC_WDISP30
, R_SPARC_WDISP22
,
39 R_SPARC_HI22
, R_SPARC_22
,
40 R_SPARC_13
, R_SPARC_LO10
,
41 R_SPARC_GOT10
, R_SPARC_GOT13
, R_SPARC_GOT22
,
42 R_SPARC_PC10
, R_SPARC_PC22
,
45 R_SPARC_GLOB_DAT
, R_SPARC_JMP_SLOT
,
51 static reloc_howto_type nlm32_sparc_howto_table
[] =
53 HOWTO (R_SPARC_NONE
, 0,0, 0,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_NONE", FALSE
,0,0x00000000,TRUE
),
54 HOWTO (R_SPARC_8
, 0,0, 8,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_8", FALSE
,0,0x000000ff,TRUE
),
55 HOWTO (R_SPARC_16
, 0,1,16,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_16", FALSE
,0,0x0000ffff,TRUE
),
56 HOWTO (R_SPARC_32
, 0,2,32,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_32", FALSE
,0,0xffffffff,TRUE
),
57 HOWTO (R_SPARC_DISP8
, 0,0, 8,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP8", FALSE
,0,0x000000ff,TRUE
),
58 HOWTO (R_SPARC_DISP16
, 0,1,16,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP16", FALSE
,0,0x0000ffff,TRUE
),
59 HOWTO (R_SPARC_DISP32
, 0,2,32,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_DISP32", FALSE
,0,0x00ffffff,TRUE
),
60 HOWTO (R_SPARC_WDISP30
, 2,2,30,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_WDISP30", FALSE
,0,0x3fffffff,TRUE
),
61 HOWTO (R_SPARC_WDISP22
, 2,2,22,TRUE
, 0,complain_overflow_signed
, 0,"R_SPARC_WDISP22", FALSE
,0,0x003fffff,TRUE
),
62 HOWTO (R_SPARC_HI22
, 10,2,22,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_HI22", FALSE
,0,0x003fffff,TRUE
),
63 HOWTO (R_SPARC_22
, 0,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_22", FALSE
,0,0x003fffff,TRUE
),
64 HOWTO (R_SPARC_13
, 0,2,13,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_13", FALSE
,0,0x00001fff,TRUE
),
65 HOWTO (R_SPARC_LO10
, 0,2,10,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_LO10", FALSE
,0,0x000003ff,TRUE
),
66 HOWTO (R_SPARC_GOT10
, 0,2,10,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT10", FALSE
,0,0x000003ff,TRUE
),
67 HOWTO (R_SPARC_GOT13
, 0,2,13,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT13", FALSE
,0,0x00001fff,TRUE
),
68 HOWTO (R_SPARC_GOT22
, 10,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_GOT22", FALSE
,0,0x003fffff,TRUE
),
69 HOWTO (R_SPARC_PC10
, 0,2,10,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_PC10", FALSE
,0,0x000003ff,TRUE
),
70 HOWTO (R_SPARC_PC22
, 0,2,22,FALSE
,0,complain_overflow_bitfield
,0,"R_SPARC_PC22", FALSE
,0,0x003fffff,TRUE
),
71 HOWTO (R_SPARC_WPLT30
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_WPLT30", FALSE
,0,0x00000000,TRUE
),
72 HOWTO (R_SPARC_COPY
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_COPY", FALSE
,0,0x00000000,TRUE
),
73 HOWTO (R_SPARC_GLOB_DAT
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_GLOB_DAT",FALSE
,0,0x00000000,TRUE
),
74 HOWTO (R_SPARC_JMP_SLOT
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_JMP_SLOT",FALSE
,0,0x00000000,TRUE
),
75 HOWTO (R_SPARC_RELATIVE
,0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_RELATIVE",FALSE
,0,0x00000000,TRUE
),
76 HOWTO (R_SPARC_UA32
, 0,0,00,FALSE
,0,complain_overflow_dont
, 0,"R_SPARC_UA32", FALSE
,0,0x00000000,TRUE
),
79 /* Read a NetWare sparc reloc. */
81 struct nlm32_sparc_reloc_ext
83 unsigned char offset
[4];
84 unsigned char addend
[4];
85 unsigned char type
[1];
86 unsigned char pad1
[3];
90 nlm_sparc_read_reloc (bfd
*abfd
,
91 nlmNAME (symbol_type
) *sym ATTRIBUTE_UNUSED
,
96 unsigned int howto_index
;
98 struct nlm32_sparc_reloc_ext tmp_reloc
;
99 asection
*code_sec
, *data_sec
;
101 if (bfd_bread (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
104 code_sec
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
105 data_sec
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
109 val
= bfd_get_32 (abfd
, tmp_reloc
.offset
);
110 addend
= bfd_get_32 (abfd
, tmp_reloc
.addend
);
111 type
= bfd_get_8 (abfd
, tmp_reloc
.type
);
114 rel
->addend
= addend
;
117 for (howto_index
= 0;
118 howto_index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
120 if (nlm32_sparc_howto_table
[howto_index
].type
== type
)
122 rel
->howto
= &nlm32_sparc_howto_table
[howto_index
];
127 fprintf (stderr
, "%s: address = %08lx, addend = %08lx, type = %u, howto = %p\n",
128 __FUNCTION__
, (unsigned long) rel
->address
,
129 (unsigned long) rel
->addend
, type
, rel
->howto
);
135 /* Write a NetWare sparc reloc. */
138 nlm_sparc_write_reloc (bfd
* abfd
, asection
* sec
, arelent
* rel
)
141 struct nlm32_sparc_reloc_ext tmp_reloc
;
142 unsigned int howto_index
;
144 reloc_howto_type
*tmp
;
146 for (howto_index
= 0;
147 howto_index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
150 tmp
= &nlm32_sparc_howto_table
[howto_index
];
152 if (tmp
->rightshift
== rel
->howto
->rightshift
153 && tmp
->size
== rel
->howto
->size
154 && tmp
->bitsize
== rel
->howto
->bitsize
155 && tmp
->pc_relative
== rel
->howto
->pc_relative
156 && tmp
->bitpos
== rel
->howto
->bitpos
157 && tmp
->src_mask
== rel
->howto
->src_mask
158 && tmp
->dst_mask
== rel
->howto
->dst_mask
)
167 /* Netware wants a list of relocs for each address.
172 That should be it. */
174 /* The value we write out is the offset into the appropriate
175 segment. This offset is the section vma, adjusted by the vma of
176 the lowest section in that segment, plus the address of the
178 val
= bfd_get_section_vma (abfd
, sec
) + rel
->address
;
181 fprintf (stderr
, "%s: val = %08lx, addend = %08lx, type = %u\n",
182 __FUNCTION__
, (unsigned long) val
, (unsigned long) rel
->addend
,
185 bfd_put_32 (abfd
, val
, tmp_reloc
.offset
);
186 bfd_put_32 (abfd
, rel
->addend
, tmp_reloc
.addend
);
187 bfd_put_8 (abfd
, (short) (rel
->howto
->type
), tmp_reloc
.type
);
189 if (bfd_bwrite (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
195 /* Mangle relocs for SPARC NetWare. We can just use the standard
199 nlm_sparc_mangle_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
200 asection
*sec ATTRIBUTE_UNUSED
,
201 const void * data ATTRIBUTE_UNUSED
,
202 bfd_vma offset ATTRIBUTE_UNUSED
,
203 bfd_size_type count ATTRIBUTE_UNUSED
)
208 /* Read a NetWare sparc import record. */
211 nlm_sparc_read_import (bfd
*abfd
, nlmNAME (symbol_type
) *sym
)
213 struct nlm_relent
*nlm_relocs
; /* Relocation records for symbol. */
214 bfd_size_type rcount
; /* Number of relocs. */
215 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Temporary 32-bit value. */
216 unsigned char symlength
; /* Length of symbol name. */
219 /* First, read in the number of relocation
220 entries for this symbol. */
221 if (bfd_bread (temp
, (bfd_size_type
) 4, abfd
) != 4)
224 rcount
= bfd_get_32 (abfd
, temp
);
226 /* Next, read in the length of the symbol. */
227 if (bfd_bread (& symlength
, (bfd_size_type
) sizeof (symlength
), abfd
)
228 != sizeof (symlength
))
230 sym
-> symbol
.the_bfd
= abfd
;
231 name
= bfd_alloc (abfd
, (bfd_size_type
) symlength
+ 1);
235 /* Then read in the symbol. */
236 if (bfd_bread (name
, (bfd_size_type
) symlength
, abfd
) != symlength
)
238 name
[symlength
] = '\0';
239 sym
-> symbol
.name
= name
;
240 sym
-> symbol
.flags
= 0;
241 sym
-> symbol
.value
= 0;
242 sym
-> symbol
.section
= bfd_und_section_ptr
;
244 /* Next, start reading in the relocs. */
245 nlm_relocs
= bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
));
248 sym
-> relocs
= nlm_relocs
;
250 while (sym
-> rcnt
< rcount
)
254 if (! nlm_sparc_read_reloc (abfd
, sym
, §ion
, &nlm_relocs
-> reloc
))
256 nlm_relocs
-> section
= section
;
265 nlm_sparc_write_import (bfd
* abfd
, asection
* sec
, arelent
* rel
)
268 asection
*code
, *data
, *bss
, *symsec
;
271 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
272 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
273 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
274 symsec
= (*rel
->sym_ptr_ptr
)->section
;
278 else if (symsec
== data
)
280 else if (symsec
== bss
)
281 base
= code
->size
+ data
->size
;
286 fprintf (stderr
, "%s: <%lx, 1>\n\t",
287 __FUNCTION__
, (unsigned long) (base
+ (*rel
->sym_ptr_ptr
)->value
));
289 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
290 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
292 bfd_put_32 (abfd
, (bfd_vma
) 1, temp
);
293 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
295 if (! nlm_sparc_write_reloc (abfd
, sec
, rel
))
300 /* Write out an external reference. */
303 nlm_sparc_write_external (bfd
*abfd
,
306 struct reloc_and_sec
*relocs
)
310 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
312 bfd_put_32 (abfd
, count
, temp
);
313 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
) != sizeof (temp
))
316 len
= strlen (sym
->name
);
317 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
318 != sizeof (bfd_byte
))
319 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
322 for (i
= 0; i
< count
; i
++)
323 if (! nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
, relocs
[i
].rel
))
330 nlm_sparc_write_export (bfd
* abfd
, asymbol
* sym
, bfd_vma value
)
336 fprintf (stderr
, "%s: <%lx, %u, %s>\n",
337 __FUNCTION__
, (unsigned long) value
, strlen (sym
->name
), sym
->name
);
339 bfd_put_32 (abfd
, value
, temp
);
340 len
= strlen (sym
->name
);
342 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4
343 || bfd_bwrite (&len
, (bfd_size_type
) 1, abfd
) != 1
344 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
350 #undef nlm_swap_fixed_header_in
351 #undef nlm_swap_fixed_header_out
355 static const struct nlm_backend_data nlm32_sparc_backend
=
357 "NetWare SPARC Module \032",
358 sizeof (Nlm32_sparc_External_Fixed_Header
),
359 0, /* Optional_prefix_size. */
363 0, /* Backend_object_p. */
364 0, /* Write_prefix_func. */
365 nlm_sparc_read_reloc
,
366 nlm_sparc_mangle_relocs
,
367 nlm_sparc_read_import
,
368 nlm_sparc_write_import
,
369 0, /* Set_public_section. */
370 0, /* Get_public_offset. */
371 nlm_swap_fixed_header_in
,
372 nlm_swap_fixed_header_out
,
373 nlm_sparc_write_external
,
374 nlm_sparc_write_export
377 #define TARGET_BIG_NAME "nlm32-sparc"
378 #define TARGET_BIG_SYM nlmNAME (sparc_vec)
379 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
381 #include "nlm-target.h"