xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/nlm32-sparc.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2*3d8817e4Smiod    Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod    This file is part of BFD, the Binary File Descriptor library.
6*3d8817e4Smiod 
7*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
8*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
9*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
10*3d8817e4Smiod    (at your option) any later version.
11*3d8817e4Smiod 
12*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
13*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3d8817e4Smiod    GNU General Public License for more details.
16*3d8817e4Smiod 
17*3d8817e4Smiod    You should have received a copy of the GNU General Public License
18*3d8817e4Smiod    along with this program; if not, write to the Free Software
19*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20*3d8817e4Smiod 
21*3d8817e4Smiod #include "bfd.h"
22*3d8817e4Smiod #include "sysdep.h"
23*3d8817e4Smiod #include "libbfd.h"
24*3d8817e4Smiod 
25*3d8817e4Smiod #define ARCH_SIZE 32
26*3d8817e4Smiod 
27*3d8817e4Smiod #include "nlm/sparc32-ext.h"
28*3d8817e4Smiod #define Nlm_External_Fixed_Header	Nlm32_sparc_External_Fixed_Header
29*3d8817e4Smiod 
30*3d8817e4Smiod #include "libnlm.h"
31*3d8817e4Smiod 
32*3d8817e4Smiod enum reloc_type
33*3d8817e4Smiod {
34*3d8817e4Smiod   R_SPARC_NONE = 0,
35*3d8817e4Smiod   R_SPARC_8,		R_SPARC_16,		R_SPARC_32,
36*3d8817e4Smiod   R_SPARC_DISP8,	R_SPARC_DISP16,		R_SPARC_DISP32,
37*3d8817e4Smiod   R_SPARC_WDISP30,	R_SPARC_WDISP22,
38*3d8817e4Smiod   R_SPARC_HI22,		R_SPARC_22,
39*3d8817e4Smiod   R_SPARC_13,		R_SPARC_LO10,
40*3d8817e4Smiod   R_SPARC_GOT10,	R_SPARC_GOT13,		R_SPARC_GOT22,
41*3d8817e4Smiod   R_SPARC_PC10,		R_SPARC_PC22,
42*3d8817e4Smiod   R_SPARC_WPLT30,
43*3d8817e4Smiod   R_SPARC_COPY,
44*3d8817e4Smiod   R_SPARC_GLOB_DAT,	R_SPARC_JMP_SLOT,
45*3d8817e4Smiod   R_SPARC_RELATIVE,
46*3d8817e4Smiod   R_SPARC_UA32,
47*3d8817e4Smiod   R_SPARC_max
48*3d8817e4Smiod };
49*3d8817e4Smiod 
50*3d8817e4Smiod static reloc_howto_type nlm32_sparc_howto_table[] =
51*3d8817e4Smiod {
52*3d8817e4Smiod   HOWTO (R_SPARC_NONE,    0,0, 0,FALSE,0,complain_overflow_dont,    0,"R_SPARC_NONE",    FALSE,0,0x00000000,TRUE),
53*3d8817e4Smiod   HOWTO (R_SPARC_8,       0,0, 8,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_8",       FALSE,0,0x000000ff,TRUE),
54*3d8817e4Smiod   HOWTO (R_SPARC_16,      0,1,16,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_16",      FALSE,0,0x0000ffff,TRUE),
55*3d8817e4Smiod   HOWTO (R_SPARC_32,      0,2,32,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_32",      FALSE,0,0xffffffff,TRUE),
56*3d8817e4Smiod   HOWTO (R_SPARC_DISP8,   0,0, 8,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_DISP8",   FALSE,0,0x000000ff,TRUE),
57*3d8817e4Smiod   HOWTO (R_SPARC_DISP16,  0,1,16,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_DISP16",  FALSE,0,0x0000ffff,TRUE),
58*3d8817e4Smiod   HOWTO (R_SPARC_DISP32,  0,2,32,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_DISP32",  FALSE,0,0x00ffffff,TRUE),
59*3d8817e4Smiod   HOWTO (R_SPARC_WDISP30, 2,2,30,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_WDISP30", FALSE,0,0x3fffffff,TRUE),
60*3d8817e4Smiod   HOWTO (R_SPARC_WDISP22, 2,2,22,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_WDISP22", FALSE,0,0x003fffff,TRUE),
61*3d8817e4Smiod   HOWTO (R_SPARC_HI22,   10,2,22,FALSE,0,complain_overflow_dont,    0,"R_SPARC_HI22",    FALSE,0,0x003fffff,TRUE),
62*3d8817e4Smiod   HOWTO (R_SPARC_22,      0,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_22",      FALSE,0,0x003fffff,TRUE),
63*3d8817e4Smiod   HOWTO (R_SPARC_13,      0,2,13,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_13",      FALSE,0,0x00001fff,TRUE),
64*3d8817e4Smiod   HOWTO (R_SPARC_LO10,    0,2,10,FALSE,0,complain_overflow_dont,    0,"R_SPARC_LO10",    FALSE,0,0x000003ff,TRUE),
65*3d8817e4Smiod   HOWTO (R_SPARC_GOT10,   0,2,10,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT10",   FALSE,0,0x000003ff,TRUE),
66*3d8817e4Smiod   HOWTO (R_SPARC_GOT13,   0,2,13,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT13",   FALSE,0,0x00001fff,TRUE),
67*3d8817e4Smiod   HOWTO (R_SPARC_GOT22,  10,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT22",   FALSE,0,0x003fffff,TRUE),
68*3d8817e4Smiod   HOWTO (R_SPARC_PC10,    0,2,10,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_PC10",    FALSE,0,0x000003ff,TRUE),
69*3d8817e4Smiod   HOWTO (R_SPARC_PC22,    0,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_PC22",    FALSE,0,0x003fffff,TRUE),
70*3d8817e4Smiod   HOWTO (R_SPARC_WPLT30,  0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_WPLT30",  FALSE,0,0x00000000,TRUE),
71*3d8817e4Smiod   HOWTO (R_SPARC_COPY,    0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_COPY",    FALSE,0,0x00000000,TRUE),
72*3d8817e4Smiod   HOWTO (R_SPARC_GLOB_DAT,0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_GLOB_DAT",FALSE,0,0x00000000,TRUE),
73*3d8817e4Smiod   HOWTO (R_SPARC_JMP_SLOT,0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_JMP_SLOT",FALSE,0,0x00000000,TRUE),
74*3d8817e4Smiod   HOWTO (R_SPARC_RELATIVE,0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_RELATIVE",FALSE,0,0x00000000,TRUE),
75*3d8817e4Smiod   HOWTO (R_SPARC_UA32,    0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_UA32",    FALSE,0,0x00000000,TRUE),
76*3d8817e4Smiod };
77*3d8817e4Smiod 
78*3d8817e4Smiod /* Read a NetWare sparc reloc.  */
79*3d8817e4Smiod 
80*3d8817e4Smiod struct nlm32_sparc_reloc_ext
81*3d8817e4Smiod {
82*3d8817e4Smiod   unsigned char offset[4];
83*3d8817e4Smiod   unsigned char addend[4];
84*3d8817e4Smiod   unsigned char type[1];
85*3d8817e4Smiod   unsigned char pad1[3];
86*3d8817e4Smiod };
87*3d8817e4Smiod 
88*3d8817e4Smiod static bfd_boolean
nlm_sparc_read_reloc(bfd * abfd,nlmNAME (symbol_type)* sym ATTRIBUTE_UNUSED,asection ** secp,arelent * rel)89*3d8817e4Smiod nlm_sparc_read_reloc (bfd *abfd,
90*3d8817e4Smiod 		      nlmNAME (symbol_type) *sym ATTRIBUTE_UNUSED,
91*3d8817e4Smiod 		      asection **secp,
92*3d8817e4Smiod 		      arelent *rel)
93*3d8817e4Smiod {
94*3d8817e4Smiod   bfd_vma val, addend;
95*3d8817e4Smiod   unsigned int index;
96*3d8817e4Smiod   unsigned int type;
97*3d8817e4Smiod   struct nlm32_sparc_reloc_ext tmp_reloc;
98*3d8817e4Smiod   asection *code_sec, *data_sec;
99*3d8817e4Smiod 
100*3d8817e4Smiod   if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
101*3d8817e4Smiod     return FALSE;
102*3d8817e4Smiod 
103*3d8817e4Smiod   code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
104*3d8817e4Smiod   data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
105*3d8817e4Smiod 
106*3d8817e4Smiod   *secp = code_sec;
107*3d8817e4Smiod 
108*3d8817e4Smiod   val = bfd_get_32 (abfd, tmp_reloc.offset);
109*3d8817e4Smiod   addend = bfd_get_32 (abfd, tmp_reloc.addend);
110*3d8817e4Smiod   type = bfd_get_8 (abfd, tmp_reloc.type);
111*3d8817e4Smiod 
112*3d8817e4Smiod   rel->address = val;
113*3d8817e4Smiod   rel->addend = addend;
114*3d8817e4Smiod   rel->howto = NULL;
115*3d8817e4Smiod 
116*3d8817e4Smiod   for (index = 0;
117*3d8817e4Smiod        index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
118*3d8817e4Smiod        index++)
119*3d8817e4Smiod     if (nlm32_sparc_howto_table[index].type == type)
120*3d8817e4Smiod       {
121*3d8817e4Smiod 	rel->howto = &nlm32_sparc_howto_table[index];
122*3d8817e4Smiod 	break;
123*3d8817e4Smiod       }
124*3d8817e4Smiod 
125*3d8817e4Smiod #ifdef DEBUG
126*3d8817e4Smiod   fprintf (stderr, "%s:  address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
127*3d8817e4Smiod 	   __FUNCTION__, rel->address, rel->addend, type, rel->howto);
128*3d8817e4Smiod #endif
129*3d8817e4Smiod   return TRUE;
130*3d8817e4Smiod 
131*3d8817e4Smiod }
132*3d8817e4Smiod 
133*3d8817e4Smiod /* Write a NetWare sparc reloc.  */
134*3d8817e4Smiod 
135*3d8817e4Smiod static bfd_boolean
nlm_sparc_write_reloc(bfd * abfd,asection * sec,arelent * rel)136*3d8817e4Smiod nlm_sparc_write_reloc (bfd * abfd, asection * sec, arelent * rel)
137*3d8817e4Smiod {
138*3d8817e4Smiod   bfd_vma val;
139*3d8817e4Smiod   struct nlm32_sparc_reloc_ext tmp_reloc;
140*3d8817e4Smiod   unsigned int index;
141*3d8817e4Smiod   int type = -1;
142*3d8817e4Smiod   reloc_howto_type *tmp;
143*3d8817e4Smiod 
144*3d8817e4Smiod   for (index = 0;
145*3d8817e4Smiod        index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
146*3d8817e4Smiod        index++)
147*3d8817e4Smiod     {
148*3d8817e4Smiod       tmp = &nlm32_sparc_howto_table[index];
149*3d8817e4Smiod 
150*3d8817e4Smiod       if (tmp->rightshift == rel->howto->rightshift
151*3d8817e4Smiod 	  && tmp->size == rel->howto->size
152*3d8817e4Smiod 	  && tmp->bitsize == rel->howto->bitsize
153*3d8817e4Smiod 	  && tmp->pc_relative == rel->howto->pc_relative
154*3d8817e4Smiod 	  && tmp->bitpos == rel->howto->bitpos
155*3d8817e4Smiod 	  && tmp->src_mask == rel->howto->src_mask
156*3d8817e4Smiod 	  && tmp->dst_mask == rel->howto->dst_mask)
157*3d8817e4Smiod 	{
158*3d8817e4Smiod 	  type = tmp->type;
159*3d8817e4Smiod 	  break;
160*3d8817e4Smiod 	}
161*3d8817e4Smiod     }
162*3d8817e4Smiod   if (type == -1)
163*3d8817e4Smiod     abort ();
164*3d8817e4Smiod 
165*3d8817e4Smiod   /* Netware wants a list of relocs for each address.
166*3d8817e4Smiod      Format is:
167*3d8817e4Smiod     	long	offset
168*3d8817e4Smiod     	long	addend
169*3d8817e4Smiod     	char	type
170*3d8817e4Smiod      That should be it.  */
171*3d8817e4Smiod 
172*3d8817e4Smiod   /* The value we write out is the offset into the appropriate
173*3d8817e4Smiod      segment.  This offset is the section vma, adjusted by the vma of
174*3d8817e4Smiod      the lowest section in that segment, plus the address of the
175*3d8817e4Smiod      relocation.  */
176*3d8817e4Smiod   val = bfd_get_section_vma (abfd, sec) + rel->address;
177*3d8817e4Smiod 
178*3d8817e4Smiod #ifdef DEBUG
179*3d8817e4Smiod   fprintf (stderr, "%s:  val = %08lx, addend = %08lx, type = %d\n",
180*3d8817e4Smiod 	   __FUNCTION__, val, rel->addend, rel->howto->type);
181*3d8817e4Smiod #endif
182*3d8817e4Smiod   bfd_put_32 (abfd, val, tmp_reloc.offset);
183*3d8817e4Smiod   bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
184*3d8817e4Smiod   bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
185*3d8817e4Smiod 
186*3d8817e4Smiod   if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
187*3d8817e4Smiod     return FALSE;
188*3d8817e4Smiod 
189*3d8817e4Smiod   return TRUE;
190*3d8817e4Smiod }
191*3d8817e4Smiod 
192*3d8817e4Smiod /* Mangle relocs for SPARC NetWare.  We can just use the standard
193*3d8817e4Smiod    SPARC relocs.  */
194*3d8817e4Smiod 
195*3d8817e4Smiod static bfd_boolean
nlm_sparc_mangle_relocs(bfd * abfd ATTRIBUTE_UNUSED,asection * sec ATTRIBUTE_UNUSED,const void * data ATTRIBUTE_UNUSED,bfd_vma offset ATTRIBUTE_UNUSED,bfd_size_type count ATTRIBUTE_UNUSED)196*3d8817e4Smiod nlm_sparc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
197*3d8817e4Smiod 			 asection *sec ATTRIBUTE_UNUSED,
198*3d8817e4Smiod 			 const void * data ATTRIBUTE_UNUSED,
199*3d8817e4Smiod 			 bfd_vma offset ATTRIBUTE_UNUSED,
200*3d8817e4Smiod 			 bfd_size_type count ATTRIBUTE_UNUSED)
201*3d8817e4Smiod {
202*3d8817e4Smiod   return TRUE;
203*3d8817e4Smiod }
204*3d8817e4Smiod 
205*3d8817e4Smiod /* Read a NetWare sparc import record.  */
206*3d8817e4Smiod 
207*3d8817e4Smiod static bfd_boolean
nlm_sparc_read_import(bfd * abfd,nlmNAME (symbol_type)* sym)208*3d8817e4Smiod nlm_sparc_read_import (bfd *abfd, nlmNAME (symbol_type) *sym)
209*3d8817e4Smiod {
210*3d8817e4Smiod   struct nlm_relent *nlm_relocs;	/* Relocation records for symbol.  */
211*3d8817e4Smiod   bfd_size_type rcount;			/* Number of relocs.  */
212*3d8817e4Smiod   bfd_byte temp[NLM_TARGET_LONG_SIZE];	/* Temporary 32-bit value.  */
213*3d8817e4Smiod   unsigned char symlength;		/* Length of symbol name.  */
214*3d8817e4Smiod   char *name;
215*3d8817e4Smiod 
216*3d8817e4Smiod   /* First, read in the number of relocation
217*3d8817e4Smiod      entries for this symbol.  */
218*3d8817e4Smiod   if (bfd_bread (temp, (bfd_size_type) 4, abfd) != 4)
219*3d8817e4Smiod     return FALSE;
220*3d8817e4Smiod 
221*3d8817e4Smiod   rcount = bfd_get_32 (abfd, temp);
222*3d8817e4Smiod 
223*3d8817e4Smiod   /* Next, read in the length of the symbol.  */
224*3d8817e4Smiod   if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
225*3d8817e4Smiod       != sizeof (symlength))
226*3d8817e4Smiod     return FALSE;
227*3d8817e4Smiod   sym -> symbol.the_bfd = abfd;
228*3d8817e4Smiod   name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
229*3d8817e4Smiod   if (name == NULL)
230*3d8817e4Smiod     return FALSE;
231*3d8817e4Smiod 
232*3d8817e4Smiod   /* Then read in the symbol.  */
233*3d8817e4Smiod   if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
234*3d8817e4Smiod     return FALSE;
235*3d8817e4Smiod   name[symlength] = '\0';
236*3d8817e4Smiod   sym -> symbol.name = name;
237*3d8817e4Smiod   sym -> symbol.flags = 0;
238*3d8817e4Smiod   sym -> symbol.value = 0;
239*3d8817e4Smiod   sym -> symbol.section = bfd_und_section_ptr;
240*3d8817e4Smiod 
241*3d8817e4Smiod   /* Next, start reading in the relocs.  */
242*3d8817e4Smiod   nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
243*3d8817e4Smiod   if (!nlm_relocs)
244*3d8817e4Smiod     return FALSE;
245*3d8817e4Smiod   sym -> relocs = nlm_relocs;
246*3d8817e4Smiod   sym -> rcnt = 0;
247*3d8817e4Smiod   while (sym -> rcnt < rcount)
248*3d8817e4Smiod     {
249*3d8817e4Smiod       asection *section;
250*3d8817e4Smiod 
251*3d8817e4Smiod       if (! nlm_sparc_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
252*3d8817e4Smiod 	return FALSE;
253*3d8817e4Smiod       nlm_relocs -> section = section;
254*3d8817e4Smiod       nlm_relocs++;
255*3d8817e4Smiod       sym -> rcnt++;
256*3d8817e4Smiod     }
257*3d8817e4Smiod 
258*3d8817e4Smiod   return TRUE;
259*3d8817e4Smiod }
260*3d8817e4Smiod 
261*3d8817e4Smiod static bfd_boolean
nlm_sparc_write_import(bfd * abfd,asection * sec,arelent * rel)262*3d8817e4Smiod nlm_sparc_write_import (bfd * abfd, asection * sec, arelent * rel)
263*3d8817e4Smiod {
264*3d8817e4Smiod   char temp[4];
265*3d8817e4Smiod   asection *code, *data, *bss, *symsec;
266*3d8817e4Smiod   bfd_vma base;
267*3d8817e4Smiod 
268*3d8817e4Smiod   code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
269*3d8817e4Smiod   data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
270*3d8817e4Smiod   bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
271*3d8817e4Smiod   symsec = (*rel->sym_ptr_ptr)->section;
272*3d8817e4Smiod 
273*3d8817e4Smiod   if (symsec == code)
274*3d8817e4Smiod     base = 0;
275*3d8817e4Smiod   else if (symsec == data)
276*3d8817e4Smiod     base = code->size;
277*3d8817e4Smiod   else if (symsec == bss)
278*3d8817e4Smiod     base = code->size + data->size;
279*3d8817e4Smiod   else
280*3d8817e4Smiod     base = 0;
281*3d8817e4Smiod 
282*3d8817e4Smiod #ifdef DEBUG
283*3d8817e4Smiod   fprintf (stderr, "%s:  <%x, 1>\n\t",
284*3d8817e4Smiod 	   __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
285*3d8817e4Smiod #endif
286*3d8817e4Smiod   bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
287*3d8817e4Smiod   if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
288*3d8817e4Smiod     return FALSE;
289*3d8817e4Smiod   bfd_put_32 (abfd, (bfd_vma) 1, temp);
290*3d8817e4Smiod   if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
291*3d8817e4Smiod     return FALSE;
292*3d8817e4Smiod   if (! nlm_sparc_write_reloc (abfd, sec, rel))
293*3d8817e4Smiod     return FALSE;
294*3d8817e4Smiod   return TRUE;
295*3d8817e4Smiod }
296*3d8817e4Smiod 
297*3d8817e4Smiod /* Write out an external reference.  */
298*3d8817e4Smiod 
299*3d8817e4Smiod static bfd_boolean
nlm_sparc_write_external(bfd * abfd,bfd_size_type count,asymbol * sym,struct reloc_and_sec * relocs)300*3d8817e4Smiod nlm_sparc_write_external (bfd *abfd,
301*3d8817e4Smiod 			  bfd_size_type count,
302*3d8817e4Smiod 			  asymbol *sym,
303*3d8817e4Smiod 			  struct reloc_and_sec *relocs)
304*3d8817e4Smiod {
305*3d8817e4Smiod   unsigned int i;
306*3d8817e4Smiod   bfd_byte len;
307*3d8817e4Smiod   unsigned char temp[NLM_TARGET_LONG_SIZE];
308*3d8817e4Smiod 
309*3d8817e4Smiod   bfd_put_32 (abfd, count, temp);
310*3d8817e4Smiod   if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
311*3d8817e4Smiod     return FALSE;
312*3d8817e4Smiod 
313*3d8817e4Smiod   len = strlen (sym->name);
314*3d8817e4Smiod   if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
315*3d8817e4Smiod        != sizeof (bfd_byte))
316*3d8817e4Smiod       || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
317*3d8817e4Smiod     return FALSE;
318*3d8817e4Smiod 
319*3d8817e4Smiod   for (i = 0; i < count; i++)
320*3d8817e4Smiod     if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
321*3d8817e4Smiod       return FALSE;
322*3d8817e4Smiod 
323*3d8817e4Smiod   return TRUE;
324*3d8817e4Smiod }
325*3d8817e4Smiod 
326*3d8817e4Smiod static bfd_boolean
nlm_sparc_write_export(bfd * abfd,asymbol * sym,bfd_vma value)327*3d8817e4Smiod nlm_sparc_write_export (bfd * abfd, asymbol * sym, bfd_vma value)
328*3d8817e4Smiod {
329*3d8817e4Smiod   bfd_byte len;
330*3d8817e4Smiod   bfd_byte temp[4];
331*3d8817e4Smiod 
332*3d8817e4Smiod #ifdef DEBUG
333*3d8817e4Smiod   fprintf (stderr, "%s: <%x, %d, %s>\n",
334*3d8817e4Smiod 	   __FUNCTION__, value, strlen (sym->name), sym->name);
335*3d8817e4Smiod #endif
336*3d8817e4Smiod   bfd_put_32 (abfd, value, temp);
337*3d8817e4Smiod   len = strlen (sym->name);
338*3d8817e4Smiod 
339*3d8817e4Smiod   if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4
340*3d8817e4Smiod       || bfd_bwrite (&len, (bfd_size_type) 1, abfd) != 1
341*3d8817e4Smiod       || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
342*3d8817e4Smiod     return FALSE;
343*3d8817e4Smiod 
344*3d8817e4Smiod   return TRUE;
345*3d8817e4Smiod }
346*3d8817e4Smiod 
347*3d8817e4Smiod #undef nlm_swap_fixed_header_in
348*3d8817e4Smiod #undef nlm_swap_fixed_header_out
349*3d8817e4Smiod 
350*3d8817e4Smiod #include "nlmswap.h"
351*3d8817e4Smiod 
352*3d8817e4Smiod static const struct nlm_backend_data nlm32_sparc_backend =
353*3d8817e4Smiod {
354*3d8817e4Smiod   "NetWare SPARC Module   \032",
355*3d8817e4Smiod   sizeof (Nlm32_sparc_External_Fixed_Header),
356*3d8817e4Smiod   0,	/* Optional_prefix_size.  */
357*3d8817e4Smiod   bfd_arch_sparc,
358*3d8817e4Smiod   0,
359*3d8817e4Smiod   FALSE,
360*3d8817e4Smiod   0,	/* Backend_object_p.  */
361*3d8817e4Smiod   0,	/* Write_prefix_func.  */
362*3d8817e4Smiod   nlm_sparc_read_reloc,
363*3d8817e4Smiod   nlm_sparc_mangle_relocs,
364*3d8817e4Smiod   nlm_sparc_read_import,
365*3d8817e4Smiod   nlm_sparc_write_import,
366*3d8817e4Smiod   0,	/* Set_public_section.  */
367*3d8817e4Smiod   0,	/* Get_public_offset.  */
368*3d8817e4Smiod   nlm_swap_fixed_header_in,
369*3d8817e4Smiod   nlm_swap_fixed_header_out,
370*3d8817e4Smiod   nlm_sparc_write_external,
371*3d8817e4Smiod   nlm_sparc_write_export
372*3d8817e4Smiod };
373*3d8817e4Smiod 
374*3d8817e4Smiod #define TARGET_BIG_NAME		"nlm32-sparc"
375*3d8817e4Smiod #define TARGET_BIG_SYM		nlmNAME (sparc_vec)
376*3d8817e4Smiod #define TARGET_BACKEND_DATA	& nlm32_sparc_backend
377*3d8817e4Smiod 
378*3d8817e4Smiod #include "nlm-target.h"
379