1*3d8817e4Smiod /* Support for 32-bit i386 NLM (NetWare Loadable Module)
2*3d8817e4Smiod Copyright 1993, 1994, 2000, 2001, 2002, 2003, 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/i386-ext.h"
28*3d8817e4Smiod #define Nlm_External_Fixed_Header Nlm32_i386_External_Fixed_Header
29*3d8817e4Smiod
30*3d8817e4Smiod #include "libnlm.h"
31*3d8817e4Smiod
32*3d8817e4Smiod /* Adjust the reloc location by an absolute value. */
33*3d8817e4Smiod
34*3d8817e4Smiod static reloc_howto_type nlm_i386_abs_howto =
35*3d8817e4Smiod HOWTO (0, /* Type. */
36*3d8817e4Smiod 0, /* Rightshift. */
37*3d8817e4Smiod 2, /* Size (0 = byte, 1 = short, 2 = long). */
38*3d8817e4Smiod 32, /* Bitsize. */
39*3d8817e4Smiod FALSE, /* PC relative. */
40*3d8817e4Smiod 0, /* Bitpos. */
41*3d8817e4Smiod complain_overflow_bitfield, /* Complain_on_overflow. */
42*3d8817e4Smiod 0, /* Special_function. */
43*3d8817e4Smiod "32", /* Name. */
44*3d8817e4Smiod TRUE, /* Partial_inplace. */
45*3d8817e4Smiod 0xffffffff, /* Source mask. */
46*3d8817e4Smiod 0xffffffff, /* Dest mask. */
47*3d8817e4Smiod FALSE); /* PR rel_offset. */
48*3d8817e4Smiod
49*3d8817e4Smiod /* Adjust the reloc location by a PC relative displacement. */
50*3d8817e4Smiod
51*3d8817e4Smiod static reloc_howto_type nlm_i386_pcrel_howto =
52*3d8817e4Smiod HOWTO (1, /* Type. */
53*3d8817e4Smiod 0, /* Rightshift. */
54*3d8817e4Smiod 2, /* Size (0 = byte, 1 = short, 2 = long). */
55*3d8817e4Smiod 32, /* Bitsize. */
56*3d8817e4Smiod TRUE, /* PC relative. */
57*3d8817e4Smiod 0, /* Bitpos. */
58*3d8817e4Smiod complain_overflow_signed, /* Complain_on_overflow. */
59*3d8817e4Smiod 0, /* Special_function. */
60*3d8817e4Smiod "DISP32", /* Name. */
61*3d8817e4Smiod TRUE, /* Partial_inplace. */
62*3d8817e4Smiod 0xffffffff, /* Source mask. */
63*3d8817e4Smiod 0xffffffff, /* Dest mask. */
64*3d8817e4Smiod TRUE); /* PR rel_offset. */
65*3d8817e4Smiod
66*3d8817e4Smiod /* Read a NetWare i386 reloc. */
67*3d8817e4Smiod
68*3d8817e4Smiod static bfd_boolean
nlm_i386_read_reloc(bfd * abfd,nlmNAME (symbol_type)* sym,asection ** secp,arelent * rel)69*3d8817e4Smiod nlm_i386_read_reloc (bfd *abfd,
70*3d8817e4Smiod nlmNAME (symbol_type) *sym,
71*3d8817e4Smiod asection **secp,
72*3d8817e4Smiod arelent *rel)
73*3d8817e4Smiod {
74*3d8817e4Smiod bfd_byte temp[4];
75*3d8817e4Smiod bfd_vma val;
76*3d8817e4Smiod const char *name;
77*3d8817e4Smiod
78*3d8817e4Smiod if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
79*3d8817e4Smiod return FALSE;
80*3d8817e4Smiod
81*3d8817e4Smiod val = bfd_get_32 (abfd, temp);
82*3d8817e4Smiod
83*3d8817e4Smiod /* The value is an offset into either the code or data segment.
84*3d8817e4Smiod This is the location which needs to be adjusted.
85*3d8817e4Smiod
86*3d8817e4Smiod If this is a relocation fixup rather than an imported symbol (the
87*3d8817e4Smiod sym argument is NULL) then the high bit is 0 if the location
88*3d8817e4Smiod needs to be adjusted by the address of the data segment, or 1 if
89*3d8817e4Smiod the location needs to be adjusted by the address of the code
90*3d8817e4Smiod segment. If this is an imported symbol, then the high bit is 0
91*3d8817e4Smiod if the location is 0 if the location should be adjusted by the
92*3d8817e4Smiod offset to the symbol, or 1 if the location should adjusted by the
93*3d8817e4Smiod absolute value of the symbol.
94*3d8817e4Smiod
95*3d8817e4Smiod The second most significant bit is 0 if the value is an offset
96*3d8817e4Smiod into the data segment, or 1 if the value is an offset into the
97*3d8817e4Smiod code segment.
98*3d8817e4Smiod
99*3d8817e4Smiod All this translates fairly easily into a BFD reloc. */
100*3d8817e4Smiod
101*3d8817e4Smiod if (sym == NULL)
102*3d8817e4Smiod {
103*3d8817e4Smiod if ((val & NLM_HIBIT) == 0)
104*3d8817e4Smiod name = NLM_INITIALIZED_DATA_NAME;
105*3d8817e4Smiod else
106*3d8817e4Smiod {
107*3d8817e4Smiod name = NLM_CODE_NAME;
108*3d8817e4Smiod val &=~ NLM_HIBIT;
109*3d8817e4Smiod }
110*3d8817e4Smiod rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
111*3d8817e4Smiod rel->howto = &nlm_i386_abs_howto;
112*3d8817e4Smiod }
113*3d8817e4Smiod else
114*3d8817e4Smiod {
115*3d8817e4Smiod /* In this case we do not need to set the sym_ptr_ptr field. */
116*3d8817e4Smiod rel->sym_ptr_ptr = NULL;
117*3d8817e4Smiod if ((val & NLM_HIBIT) == 0)
118*3d8817e4Smiod rel->howto = &nlm_i386_pcrel_howto;
119*3d8817e4Smiod else
120*3d8817e4Smiod {
121*3d8817e4Smiod rel->howto = &nlm_i386_abs_howto;
122*3d8817e4Smiod val &=~ NLM_HIBIT;
123*3d8817e4Smiod }
124*3d8817e4Smiod }
125*3d8817e4Smiod
126*3d8817e4Smiod if ((val & (NLM_HIBIT >> 1)) == 0)
127*3d8817e4Smiod *secp = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
128*3d8817e4Smiod else
129*3d8817e4Smiod {
130*3d8817e4Smiod *secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
131*3d8817e4Smiod val &=~ (NLM_HIBIT >> 1);
132*3d8817e4Smiod }
133*3d8817e4Smiod
134*3d8817e4Smiod rel->address = val;
135*3d8817e4Smiod rel->addend = 0;
136*3d8817e4Smiod
137*3d8817e4Smiod return TRUE;
138*3d8817e4Smiod }
139*3d8817e4Smiod
140*3d8817e4Smiod /* Write a NetWare i386 reloc. */
141*3d8817e4Smiod
142*3d8817e4Smiod static bfd_boolean
nlm_i386_write_import(bfd * abfd,asection * sec,arelent * rel)143*3d8817e4Smiod nlm_i386_write_import (bfd * abfd, asection * sec, arelent * rel)
144*3d8817e4Smiod {
145*3d8817e4Smiod asymbol *sym;
146*3d8817e4Smiod bfd_vma val;
147*3d8817e4Smiod bfd_byte temp[4];
148*3d8817e4Smiod
149*3d8817e4Smiod /* NetWare only supports two kinds of relocs. We should check
150*3d8817e4Smiod special_function here, as well, but at the moment coff-i386
151*3d8817e4Smiod relocs uses a special_function which does not affect what we do
152*3d8817e4Smiod here. */
153*3d8817e4Smiod if (rel->addend != 0
154*3d8817e4Smiod || rel->howto == NULL
155*3d8817e4Smiod || rel->howto->rightshift != 0
156*3d8817e4Smiod || rel->howto->size != 2
157*3d8817e4Smiod || rel->howto->bitsize != 32
158*3d8817e4Smiod || rel->howto->bitpos != 0
159*3d8817e4Smiod || rel->howto->src_mask != 0xffffffff
160*3d8817e4Smiod || rel->howto->dst_mask != 0xffffffff)
161*3d8817e4Smiod {
162*3d8817e4Smiod bfd_set_error (bfd_error_invalid_operation);
163*3d8817e4Smiod return FALSE;
164*3d8817e4Smiod }
165*3d8817e4Smiod
166*3d8817e4Smiod sym = *rel->sym_ptr_ptr;
167*3d8817e4Smiod
168*3d8817e4Smiod /* The value we write out is the offset into the appropriate
169*3d8817e4Smiod segment. This offset is the section vma, adjusted by the vma of
170*3d8817e4Smiod the lowest section in that segment, plus the address of the
171*3d8817e4Smiod relocation. */
172*3d8817e4Smiod val = bfd_get_section_vma (abfd, sec) + rel->address;
173*3d8817e4Smiod
174*3d8817e4Smiod /* The second most significant bit is 0 if the value is an offset
175*3d8817e4Smiod into the data segment, or 1 if the value is an offset into the
176*3d8817e4Smiod code segment. */
177*3d8817e4Smiod if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
178*3d8817e4Smiod {
179*3d8817e4Smiod val -= nlm_get_text_low (abfd);
180*3d8817e4Smiod val |= NLM_HIBIT >> 1;
181*3d8817e4Smiod }
182*3d8817e4Smiod else
183*3d8817e4Smiod val -= nlm_get_data_low (abfd);
184*3d8817e4Smiod
185*3d8817e4Smiod if (! bfd_is_und_section (bfd_get_section (sym)))
186*3d8817e4Smiod {
187*3d8817e4Smiod /* NetWare only supports absolute internal relocs. */
188*3d8817e4Smiod if (rel->howto->pc_relative)
189*3d8817e4Smiod {
190*3d8817e4Smiod bfd_set_error (bfd_error_invalid_operation);
191*3d8817e4Smiod return FALSE;
192*3d8817e4Smiod }
193*3d8817e4Smiod
194*3d8817e4Smiod /* The high bit is 1 if the reloc is against the code section, 0
195*3d8817e4Smiod if against the data section. */
196*3d8817e4Smiod if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
197*3d8817e4Smiod val |= NLM_HIBIT;
198*3d8817e4Smiod }
199*3d8817e4Smiod else
200*3d8817e4Smiod {
201*3d8817e4Smiod /* The high bit is 1 if this is an absolute reloc, 0 if it is PC
202*3d8817e4Smiod relative. */
203*3d8817e4Smiod if (! rel->howto->pc_relative)
204*3d8817e4Smiod val |= NLM_HIBIT;
205*3d8817e4Smiod else
206*3d8817e4Smiod {
207*3d8817e4Smiod /* PC relative relocs on NetWare must be pcrel_offset. */
208*3d8817e4Smiod if (! rel->howto->pcrel_offset)
209*3d8817e4Smiod {
210*3d8817e4Smiod bfd_set_error (bfd_error_invalid_operation);
211*3d8817e4Smiod return FALSE;
212*3d8817e4Smiod }
213*3d8817e4Smiod }
214*3d8817e4Smiod }
215*3d8817e4Smiod
216*3d8817e4Smiod bfd_put_32 (abfd, val, temp);
217*3d8817e4Smiod if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
218*3d8817e4Smiod return FALSE;
219*3d8817e4Smiod
220*3d8817e4Smiod return TRUE;
221*3d8817e4Smiod }
222*3d8817e4Smiod
223*3d8817e4Smiod /* I want to be able to use objcopy to turn an i386 a.out or COFF file
224*3d8817e4Smiod into a NetWare i386 module. That means that the relocs from the
225*3d8817e4Smiod source file have to be mapped into relocs that apply to the target
226*3d8817e4Smiod file. This function is called by nlm_set_section_contents to give
227*3d8817e4Smiod it a chance to rework the relocs.
228*3d8817e4Smiod
229*3d8817e4Smiod This is actually a fairly general concept. However, this is not a
230*3d8817e4Smiod general implementation. */
231*3d8817e4Smiod
232*3d8817e4Smiod static bfd_boolean
nlm_i386_mangle_relocs(bfd * abfd,asection * sec,const PTR data,bfd_vma offset,bfd_size_type count)233*3d8817e4Smiod nlm_i386_mangle_relocs (bfd *abfd,
234*3d8817e4Smiod asection *sec,
235*3d8817e4Smiod const PTR data,
236*3d8817e4Smiod bfd_vma offset,
237*3d8817e4Smiod bfd_size_type count)
238*3d8817e4Smiod {
239*3d8817e4Smiod arelent **rel_ptr_ptr, **rel_end;
240*3d8817e4Smiod
241*3d8817e4Smiod rel_ptr_ptr = sec->orelocation;
242*3d8817e4Smiod rel_end = rel_ptr_ptr + sec->reloc_count;
243*3d8817e4Smiod for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
244*3d8817e4Smiod {
245*3d8817e4Smiod arelent *rel;
246*3d8817e4Smiod asymbol *sym;
247*3d8817e4Smiod bfd_vma addend;
248*3d8817e4Smiod
249*3d8817e4Smiod rel = *rel_ptr_ptr;
250*3d8817e4Smiod sym = *rel->sym_ptr_ptr;
251*3d8817e4Smiod
252*3d8817e4Smiod /* Note that no serious harm will ensue if we fail to change a
253*3d8817e4Smiod reloc. We will wind up failing in nlm_i386_write_import. */
254*3d8817e4Smiod
255*3d8817e4Smiod /* Make sure this reloc is within the data we have. We only 4
256*3d8817e4Smiod byte relocs here, so we insist on having 4 bytes. */
257*3d8817e4Smiod if (rel->address < offset
258*3d8817e4Smiod || rel->address + 4 > offset + count)
259*3d8817e4Smiod continue;
260*3d8817e4Smiod
261*3d8817e4Smiod /* NetWare doesn't support reloc addends, so we get rid of them
262*3d8817e4Smiod here by simply adding them into the object data. We handle
263*3d8817e4Smiod the symbol value, if any, the same way. */
264*3d8817e4Smiod addend = rel->addend + sym->value;
265*3d8817e4Smiod
266*3d8817e4Smiod /* The value of a symbol is the offset into the section. If the
267*3d8817e4Smiod symbol is in the .bss segment, we need to include the size of
268*3d8817e4Smiod the data segment in the offset as well. Fortunately, we know
269*3d8817e4Smiod that at this point the size of the data section is in the NLM
270*3d8817e4Smiod header. */
271*3d8817e4Smiod if (((bfd_get_section_flags (abfd, bfd_get_section (sym))
272*3d8817e4Smiod & SEC_LOAD) == 0)
273*3d8817e4Smiod && ((bfd_get_section_flags (abfd, bfd_get_section (sym))
274*3d8817e4Smiod & SEC_ALLOC) != 0))
275*3d8817e4Smiod addend += nlm_fixed_header (abfd)->dataImageSize;
276*3d8817e4Smiod
277*3d8817e4Smiod if (addend != 0
278*3d8817e4Smiod && rel->howto != NULL
279*3d8817e4Smiod && rel->howto->rightshift == 0
280*3d8817e4Smiod && rel->howto->size == 2
281*3d8817e4Smiod && rel->howto->bitsize == 32
282*3d8817e4Smiod && rel->howto->bitpos == 0
283*3d8817e4Smiod && rel->howto->src_mask == 0xffffffff
284*3d8817e4Smiod && rel->howto->dst_mask == 0xffffffff)
285*3d8817e4Smiod {
286*3d8817e4Smiod bfd_vma val;
287*3d8817e4Smiod
288*3d8817e4Smiod val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
289*3d8817e4Smiod val += addend;
290*3d8817e4Smiod bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
291*3d8817e4Smiod rel->addend = 0;
292*3d8817e4Smiod }
293*3d8817e4Smiod
294*3d8817e4Smiod /* NetWare uses a reloc with pcrel_offset set. We adjust
295*3d8817e4Smiod pc_relative relocs accordingly. We are going to change the
296*3d8817e4Smiod howto field, so we can only do this if the current one is
297*3d8817e4Smiod compatible. We should check special_function here, but at
298*3d8817e4Smiod the moment coff-i386 uses a special_function which does not
299*3d8817e4Smiod affect what we are doing here. */
300*3d8817e4Smiod if (rel->howto != NULL
301*3d8817e4Smiod && rel->howto->pc_relative
302*3d8817e4Smiod && ! rel->howto->pcrel_offset
303*3d8817e4Smiod && rel->howto->rightshift == 0
304*3d8817e4Smiod && rel->howto->size == 2
305*3d8817e4Smiod && rel->howto->bitsize == 32
306*3d8817e4Smiod && rel->howto->bitpos == 0
307*3d8817e4Smiod && rel->howto->src_mask == 0xffffffff
308*3d8817e4Smiod && rel->howto->dst_mask == 0xffffffff)
309*3d8817e4Smiod {
310*3d8817e4Smiod bfd_vma val;
311*3d8817e4Smiod
312*3d8817e4Smiod /* When pcrel_offset is not set, it means that the negative
313*3d8817e4Smiod of the address of the memory location is stored in the
314*3d8817e4Smiod memory location. We must add it back in. */
315*3d8817e4Smiod val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
316*3d8817e4Smiod val += rel->address;
317*3d8817e4Smiod bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
318*3d8817e4Smiod
319*3d8817e4Smiod rel->howto = &nlm_i386_pcrel_howto;
320*3d8817e4Smiod }
321*3d8817e4Smiod }
322*3d8817e4Smiod
323*3d8817e4Smiod return TRUE;
324*3d8817e4Smiod }
325*3d8817e4Smiod
326*3d8817e4Smiod /* Read a NetWare i386 import record. */
327*3d8817e4Smiod
328*3d8817e4Smiod static bfd_boolean
nlm_i386_read_import(bfd * abfd,nlmNAME (symbol_type)* sym)329*3d8817e4Smiod nlm_i386_read_import (bfd * abfd, nlmNAME (symbol_type) * sym)
330*3d8817e4Smiod {
331*3d8817e4Smiod struct nlm_relent *nlm_relocs; /* Relocation records for symbol. */
332*3d8817e4Smiod bfd_size_type rcount; /* Number of relocs. */
333*3d8817e4Smiod bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Temporary 32-bit value. */
334*3d8817e4Smiod unsigned char symlength; /* Length of symbol name. */
335*3d8817e4Smiod char *name;
336*3d8817e4Smiod
337*3d8817e4Smiod if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
338*3d8817e4Smiod != sizeof (symlength))
339*3d8817e4Smiod return FALSE;
340*3d8817e4Smiod sym -> symbol.the_bfd = abfd;
341*3d8817e4Smiod name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
342*3d8817e4Smiod if (name == NULL)
343*3d8817e4Smiod return FALSE;
344*3d8817e4Smiod if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
345*3d8817e4Smiod return FALSE;
346*3d8817e4Smiod name[symlength] = '\0';
347*3d8817e4Smiod sym -> symbol.name = name;
348*3d8817e4Smiod sym -> symbol.flags = 0;
349*3d8817e4Smiod sym -> symbol.value = 0;
350*3d8817e4Smiod sym -> symbol.section = bfd_und_section_ptr;
351*3d8817e4Smiod if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
352*3d8817e4Smiod return FALSE;
353*3d8817e4Smiod rcount = H_GET_32 (abfd, temp);
354*3d8817e4Smiod nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
355*3d8817e4Smiod if (!nlm_relocs)
356*3d8817e4Smiod return FALSE;
357*3d8817e4Smiod sym -> relocs = nlm_relocs;
358*3d8817e4Smiod sym -> rcnt = 0;
359*3d8817e4Smiod while (sym -> rcnt < rcount)
360*3d8817e4Smiod {
361*3d8817e4Smiod asection *section;
362*3d8817e4Smiod
363*3d8817e4Smiod if (! nlm_i386_read_reloc (abfd, sym, §ion, &nlm_relocs -> reloc))
364*3d8817e4Smiod return FALSE;
365*3d8817e4Smiod nlm_relocs -> section = section;
366*3d8817e4Smiod nlm_relocs++;
367*3d8817e4Smiod sym -> rcnt++;
368*3d8817e4Smiod }
369*3d8817e4Smiod return TRUE;
370*3d8817e4Smiod }
371*3d8817e4Smiod
372*3d8817e4Smiod /* Write out an external reference. */
373*3d8817e4Smiod
374*3d8817e4Smiod static bfd_boolean
nlm_i386_write_external(bfd * abfd,bfd_size_type count,asymbol * sym,struct reloc_and_sec * relocs)375*3d8817e4Smiod nlm_i386_write_external (bfd *abfd,
376*3d8817e4Smiod bfd_size_type count,
377*3d8817e4Smiod asymbol *sym,
378*3d8817e4Smiod struct reloc_and_sec *relocs)
379*3d8817e4Smiod {
380*3d8817e4Smiod unsigned int i;
381*3d8817e4Smiod bfd_byte len;
382*3d8817e4Smiod unsigned char temp[NLM_TARGET_LONG_SIZE];
383*3d8817e4Smiod
384*3d8817e4Smiod len = strlen (sym->name);
385*3d8817e4Smiod if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
386*3d8817e4Smiod != sizeof (bfd_byte))
387*3d8817e4Smiod || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
388*3d8817e4Smiod return FALSE;
389*3d8817e4Smiod
390*3d8817e4Smiod bfd_put_32 (abfd, count, temp);
391*3d8817e4Smiod if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
392*3d8817e4Smiod return FALSE;
393*3d8817e4Smiod
394*3d8817e4Smiod for (i = 0; i < count; i++)
395*3d8817e4Smiod if (! nlm_i386_write_import (abfd, relocs[i].sec, relocs[i].rel))
396*3d8817e4Smiod return FALSE;
397*3d8817e4Smiod
398*3d8817e4Smiod return TRUE;
399*3d8817e4Smiod }
400*3d8817e4Smiod
401*3d8817e4Smiod #include "nlmswap.h"
402*3d8817e4Smiod
403*3d8817e4Smiod static const struct nlm_backend_data nlm32_i386_backend =
404*3d8817e4Smiod {
405*3d8817e4Smiod "NetWare Loadable Module\032",
406*3d8817e4Smiod sizeof (Nlm32_i386_External_Fixed_Header),
407*3d8817e4Smiod 0, /* Optional_prefix_size. */
408*3d8817e4Smiod bfd_arch_i386,
409*3d8817e4Smiod 0,
410*3d8817e4Smiod FALSE,
411*3d8817e4Smiod 0, /* Backend_object_p. */
412*3d8817e4Smiod 0, /* Write_prefix_func. */
413*3d8817e4Smiod nlm_i386_read_reloc,
414*3d8817e4Smiod nlm_i386_mangle_relocs,
415*3d8817e4Smiod nlm_i386_read_import,
416*3d8817e4Smiod nlm_i386_write_import,
417*3d8817e4Smiod 0, /* Set_public_section. */
418*3d8817e4Smiod 0, /* Set_public_offset. */
419*3d8817e4Smiod nlm_swap_fixed_header_in,
420*3d8817e4Smiod nlm_swap_fixed_header_out,
421*3d8817e4Smiod nlm_i386_write_external,
422*3d8817e4Smiod 0, /* Write_export. */
423*3d8817e4Smiod };
424*3d8817e4Smiod
425*3d8817e4Smiod #define TARGET_LITTLE_NAME "nlm32-i386"
426*3d8817e4Smiod #define TARGET_LITTLE_SYM nlmNAME (i386_vec)
427*3d8817e4Smiod #define TARGET_BACKEND_DATA & nlm32_i386_backend
428*3d8817e4Smiod
429*3d8817e4Smiod #include "nlm-target.h"
430