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, 2010 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
;
101 if (bfd_bread (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
104 code_sec
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
107 val
= bfd_get_32 (abfd
, tmp_reloc
.offset
);
108 addend
= bfd_get_32 (abfd
, tmp_reloc
.addend
);
109 type
= bfd_get_8 (abfd
, tmp_reloc
.type
);
112 rel
->addend
= addend
;
115 for (howto_index
= 0;
116 howto_index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
118 if (nlm32_sparc_howto_table
[howto_index
].type
== type
)
120 rel
->howto
= &nlm32_sparc_howto_table
[howto_index
];
125 fprintf (stderr
, "%s: address = %08lx, addend = %08lx, type = %u, howto = %p\n",
126 __FUNCTION__
, (unsigned long) rel
->address
,
127 (unsigned long) 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
;
140 unsigned int howto_index
;
142 reloc_howto_type
*tmp
;
144 for (howto_index
= 0;
145 howto_index
< sizeof (nlm32_sparc_howto_table
) / sizeof (reloc_howto_type
);
148 tmp
= &nlm32_sparc_howto_table
[howto_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 = %u\n",
180 __FUNCTION__
, (unsigned long) val
, (unsigned long) rel
->addend
,
183 bfd_put_32 (abfd
, val
, tmp_reloc
.offset
);
184 bfd_put_32 (abfd
, rel
->addend
, tmp_reloc
.addend
);
185 bfd_put_8 (abfd
, (short) (rel
->howto
->type
), tmp_reloc
.type
);
187 if (bfd_bwrite (&tmp_reloc
, (bfd_size_type
) 12, abfd
) != 12)
193 /* Mangle relocs for SPARC NetWare. We can just use the standard
197 nlm_sparc_mangle_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
198 asection
*sec ATTRIBUTE_UNUSED
,
199 const void * data ATTRIBUTE_UNUSED
,
200 bfd_vma offset ATTRIBUTE_UNUSED
,
201 bfd_size_type count ATTRIBUTE_UNUSED
)
206 /* Read a NetWare sparc import record. */
209 nlm_sparc_read_import (bfd
*abfd
, nlmNAME (symbol_type
) *sym
)
211 struct nlm_relent
*nlm_relocs
; /* Relocation records for symbol. */
212 bfd_size_type rcount
; /* Number of relocs. */
213 bfd_byte temp
[NLM_TARGET_LONG_SIZE
]; /* Temporary 32-bit value. */
214 unsigned char symlength
; /* Length of symbol name. */
217 /* First, read in the number of relocation
218 entries for this symbol. */
219 if (bfd_bread (temp
, (bfd_size_type
) 4, abfd
) != 4)
222 rcount
= bfd_get_32 (abfd
, temp
);
224 /* Next, read in the length of the symbol. */
225 if (bfd_bread (& symlength
, (bfd_size_type
) sizeof (symlength
), abfd
)
226 != sizeof (symlength
))
228 sym
-> symbol
.the_bfd
= abfd
;
229 name
= bfd_alloc (abfd
, (bfd_size_type
) symlength
+ 1);
233 /* Then read in the symbol. */
234 if (bfd_bread (name
, (bfd_size_type
) symlength
, abfd
) != symlength
)
236 name
[symlength
] = '\0';
237 sym
-> symbol
.name
= name
;
238 sym
-> symbol
.flags
= 0;
239 sym
-> symbol
.value
= 0;
240 sym
-> symbol
.section
= bfd_und_section_ptr
;
242 /* Next, start reading in the relocs. */
243 nlm_relocs
= bfd_alloc (abfd
, rcount
* sizeof (struct nlm_relent
));
246 sym
-> relocs
= nlm_relocs
;
248 while (sym
-> rcnt
< rcount
)
252 if (! nlm_sparc_read_reloc (abfd
, sym
, §ion
, &nlm_relocs
-> reloc
))
254 nlm_relocs
-> section
= section
;
263 nlm_sparc_write_import (bfd
* abfd
, asection
* sec
, arelent
* rel
)
266 asection
*code
, *data
, *bss
, *symsec
;
269 code
= bfd_get_section_by_name (abfd
, NLM_CODE_NAME
);
270 data
= bfd_get_section_by_name (abfd
, NLM_INITIALIZED_DATA_NAME
);
271 bss
= bfd_get_section_by_name (abfd
, NLM_UNINITIALIZED_DATA_NAME
);
272 symsec
= (*rel
->sym_ptr_ptr
)->section
;
276 else if (symsec
== data
)
278 else if (symsec
== bss
)
279 base
= code
->size
+ data
->size
;
284 fprintf (stderr
, "%s: <%lx, 1>\n\t",
285 __FUNCTION__
, (unsigned long) (base
+ (*rel
->sym_ptr_ptr
)->value
));
287 bfd_put_32 (abfd
, base
+ (*rel
->sym_ptr_ptr
)->value
, temp
);
288 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
290 bfd_put_32 (abfd
, (bfd_vma
) 1, temp
);
291 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4)
293 if (! nlm_sparc_write_reloc (abfd
, sec
, rel
))
298 /* Write out an external reference. */
301 nlm_sparc_write_external (bfd
*abfd
,
304 struct reloc_and_sec
*relocs
)
308 unsigned char temp
[NLM_TARGET_LONG_SIZE
];
310 bfd_put_32 (abfd
, count
, temp
);
311 if (bfd_bwrite (temp
, (bfd_size_type
) sizeof (temp
), abfd
) != sizeof (temp
))
314 len
= strlen (sym
->name
);
315 if ((bfd_bwrite (&len
, (bfd_size_type
) sizeof (bfd_byte
), abfd
)
316 != sizeof (bfd_byte
))
317 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
320 for (i
= 0; i
< count
; i
++)
321 if (! nlm_sparc_write_reloc (abfd
, relocs
[i
].sec
, relocs
[i
].rel
))
328 nlm_sparc_write_export (bfd
* abfd
, asymbol
* sym
, bfd_vma value
)
334 fprintf (stderr
, "%s: <%lx, %u, %s>\n",
335 __FUNCTION__
, (unsigned long) value
, strlen (sym
->name
), sym
->name
);
337 bfd_put_32 (abfd
, value
, temp
);
338 len
= strlen (sym
->name
);
340 if (bfd_bwrite (temp
, (bfd_size_type
) 4, abfd
) != 4
341 || bfd_bwrite (&len
, (bfd_size_type
) 1, abfd
) != 1
342 || bfd_bwrite (sym
->name
, (bfd_size_type
) len
, abfd
) != len
)
348 #undef nlm_swap_fixed_header_in
349 #undef nlm_swap_fixed_header_out
353 static const struct nlm_backend_data nlm32_sparc_backend
=
355 "NetWare SPARC Module \032",
356 sizeof (Nlm32_sparc_External_Fixed_Header
),
357 0, /* Optional_prefix_size. */
361 0, /* Backend_object_p. */
362 0, /* Write_prefix_func. */
363 nlm_sparc_read_reloc
,
364 nlm_sparc_mangle_relocs
,
365 nlm_sparc_read_import
,
366 nlm_sparc_write_import
,
367 0, /* Set_public_section. */
368 0, /* Get_public_offset. */
369 nlm_swap_fixed_header_in
,
370 nlm_swap_fixed_header_out
,
371 nlm_sparc_write_external
,
372 nlm_sparc_write_export
375 #define TARGET_BIG_NAME "nlm32-sparc"
376 #define TARGET_BIG_SYM nlmNAME (sparc_vec)
377 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
379 #include "nlm-target.h"