xref: /openbsd/gnu/usr.bin/binutils/bfd/nlm32-i386.c (revision 007c2a45)
12159047fSniklas /* Support for 32-bit i386 NLM (NetWare Loadable Module)
2*007c2a45Smiod    Copyright 1993, 1994, 2000, 2001, 2002, 2003
3*007c2a45Smiod    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas This file is part of BFD, the Binary File Descriptor library.
62159047fSniklas 
72159047fSniklas This program is free software; you can redistribute it and/or modify
82159047fSniklas it under the terms of the GNU General Public License as published by
92159047fSniklas the Free Software Foundation; either version 2 of the License, or
102159047fSniklas (at your option) any later version.
112159047fSniklas 
122159047fSniklas This program is distributed in the hope that it will be useful,
132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152159047fSniklas GNU General Public License for more details.
162159047fSniklas 
172159047fSniklas You should have received a copy of the GNU General Public License
182159047fSniklas along with this program; if not, write to the Free Software
192159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
202159047fSniklas 
212159047fSniklas #include "bfd.h"
222159047fSniklas #include "sysdep.h"
232159047fSniklas #include "libbfd.h"
242159047fSniklas 
252159047fSniklas #define ARCH_SIZE 32
262159047fSniklas 
272159047fSniklas #include "nlm/i386-ext.h"
282159047fSniklas #define Nlm_External_Fixed_Header	Nlm32_i386_External_Fixed_Header
292159047fSniklas 
302159047fSniklas #include "libnlm.h"
312159047fSniklas 
32c074d1c9Sdrahn static bfd_boolean nlm_i386_read_reloc
332159047fSniklas   PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
34c074d1c9Sdrahn static bfd_boolean nlm_i386_write_import
352159047fSniklas   PARAMS ((bfd *, asection *, arelent *));
36c074d1c9Sdrahn static bfd_boolean nlm_i386_mangle_relocs
37*007c2a45Smiod   PARAMS ((bfd *, asection *, const PTR, bfd_vma, bfd_size_type));
38c074d1c9Sdrahn static bfd_boolean nlm_i386_read_import
392159047fSniklas   PARAMS ((bfd *, nlmNAME(symbol_type) *));
40c074d1c9Sdrahn static bfd_boolean nlm_i386_write_external
412159047fSniklas   PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
422159047fSniklas 
432159047fSniklas /* Adjust the reloc location by an absolute value.  */
442159047fSniklas 
452159047fSniklas static reloc_howto_type nlm_i386_abs_howto =
462159047fSniklas   HOWTO (0,			/* type */
472159047fSniklas 	 0,			/* rightshift */
482159047fSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
492159047fSniklas 	 32,			/* bitsize */
50c074d1c9Sdrahn 	 FALSE,			/* pc_relative */
512159047fSniklas 	 0,			/* bitpos */
522159047fSniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
532159047fSniklas 	 0,			/* special_function */
542159047fSniklas 	 "32",			/* name */
55c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
562159047fSniklas 	 0xffffffff,		/* src_mask */
572159047fSniklas 	 0xffffffff,		/* dst_mask */
58c074d1c9Sdrahn 	 FALSE);		/* pcrel_offset */
592159047fSniklas 
602159047fSniklas /* Adjust the reloc location by a PC relative displacement.  */
612159047fSniklas 
622159047fSniklas static reloc_howto_type nlm_i386_pcrel_howto =
632159047fSniklas   HOWTO (1,			/* type */
642159047fSniklas 	 0,			/* rightshift */
652159047fSniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
662159047fSniklas 	 32,			/* bitsize */
67c074d1c9Sdrahn 	 TRUE,			/* pc_relative */
682159047fSniklas 	 0,			/* bitpos */
692159047fSniklas 	 complain_overflow_signed, /* complain_on_overflow */
702159047fSniklas 	 0,			/* special_function */
712159047fSniklas 	 "DISP32",		/* name */
72c074d1c9Sdrahn 	 TRUE,			/* partial_inplace */
732159047fSniklas 	 0xffffffff,		/* src_mask */
742159047fSniklas 	 0xffffffff,		/* dst_mask */
75c074d1c9Sdrahn 	 TRUE);			/* pcrel_offset */
762159047fSniklas 
772159047fSniklas /* Read a NetWare i386 reloc.  */
782159047fSniklas 
79c074d1c9Sdrahn static bfd_boolean
nlm_i386_read_reloc(abfd,sym,secp,rel)802159047fSniklas nlm_i386_read_reloc (abfd, sym, secp, rel)
812159047fSniklas      bfd *abfd;
822159047fSniklas      nlmNAME(symbol_type) *sym;
832159047fSniklas      asection **secp;
842159047fSniklas      arelent *rel;
852159047fSniklas {
862159047fSniklas   bfd_byte temp[4];
872159047fSniklas   bfd_vma val;
882159047fSniklas   const char *name;
892159047fSniklas 
90c074d1c9Sdrahn   if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
91c074d1c9Sdrahn     return FALSE;
922159047fSniklas 
932159047fSniklas   val = bfd_get_32 (abfd, temp);
942159047fSniklas 
952159047fSniklas   /* The value is an offset into either the code or data segment.
962159047fSniklas      This is the location which needs to be adjusted.
972159047fSniklas 
982159047fSniklas      If this is a relocation fixup rather than an imported symbol (the
992159047fSniklas      sym argument is NULL) then the high bit is 0 if the location
1002159047fSniklas      needs to be adjusted by the address of the data segment, or 1 if
1012159047fSniklas      the location needs to be adjusted by the address of the code
1022159047fSniklas      segment.  If this is an imported symbol, then the high bit is 0
1032159047fSniklas      if the location is 0 if the location should be adjusted by the
1042159047fSniklas      offset to the symbol, or 1 if the location should adjusted by the
1052159047fSniklas      absolute value of the symbol.
1062159047fSniklas 
1072159047fSniklas      The second most significant bit is 0 if the value is an offset
1082159047fSniklas      into the data segment, or 1 if the value is an offset into the
1092159047fSniklas      code segment.
1102159047fSniklas 
1112159047fSniklas      All this translates fairly easily into a BFD reloc.  */
1122159047fSniklas 
1132159047fSniklas   if (sym == NULL)
1142159047fSniklas     {
1152159047fSniklas       if ((val & NLM_HIBIT) == 0)
1162159047fSniklas 	name = NLM_INITIALIZED_DATA_NAME;
1172159047fSniklas       else
1182159047fSniklas 	{
1192159047fSniklas 	  name = NLM_CODE_NAME;
1202159047fSniklas 	  val &=~ NLM_HIBIT;
1212159047fSniklas 	}
1222159047fSniklas       rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
1232159047fSniklas       rel->howto = &nlm_i386_abs_howto;
1242159047fSniklas     }
1252159047fSniklas   else
1262159047fSniklas     {
1272159047fSniklas       /* In this case we do not need to set the sym_ptr_ptr field.  */
1282159047fSniklas       rel->sym_ptr_ptr = NULL;
1292159047fSniklas       if ((val & NLM_HIBIT) == 0)
1302159047fSniklas 	rel->howto = &nlm_i386_pcrel_howto;
1312159047fSniklas       else
1322159047fSniklas 	{
1332159047fSniklas 	  rel->howto = &nlm_i386_abs_howto;
1342159047fSniklas 	  val &=~ NLM_HIBIT;
1352159047fSniklas 	}
1362159047fSniklas     }
1372159047fSniklas 
1382159047fSniklas   if ((val & (NLM_HIBIT >> 1)) == 0)
1392159047fSniklas     *secp = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
1402159047fSniklas   else
1412159047fSniklas     {
1422159047fSniklas       *secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
1432159047fSniklas       val &=~ (NLM_HIBIT >> 1);
1442159047fSniklas     }
1452159047fSniklas 
1462159047fSniklas   rel->address = val;
1472159047fSniklas   rel->addend = 0;
1482159047fSniklas 
149c074d1c9Sdrahn   return TRUE;
1502159047fSniklas }
1512159047fSniklas 
1522159047fSniklas /* Write a NetWare i386 reloc.  */
1532159047fSniklas 
154c074d1c9Sdrahn static bfd_boolean
nlm_i386_write_import(abfd,sec,rel)1552159047fSniklas nlm_i386_write_import (abfd, sec, rel)
1562159047fSniklas      bfd *abfd;
1572159047fSniklas      asection *sec;
1582159047fSniklas      arelent *rel;
1592159047fSniklas {
1602159047fSniklas   asymbol *sym;
1612159047fSniklas   bfd_vma val;
1622159047fSniklas   bfd_byte temp[4];
1632159047fSniklas 
1642159047fSniklas   /* NetWare only supports two kinds of relocs.  We should check
1652159047fSniklas      special_function here, as well, but at the moment coff-i386
1662159047fSniklas      relocs uses a special_function which does not affect what we do
1672159047fSniklas      here.  */
1682159047fSniklas   if (rel->addend != 0
1692159047fSniklas       || rel->howto == NULL
1702159047fSniklas       || rel->howto->rightshift != 0
1712159047fSniklas       || rel->howto->size != 2
1722159047fSniklas       || rel->howto->bitsize != 32
1732159047fSniklas       || rel->howto->bitpos != 0
1742159047fSniklas       || rel->howto->src_mask != 0xffffffff
1752159047fSniklas       || rel->howto->dst_mask != 0xffffffff)
1762159047fSniklas     {
1772159047fSniklas       bfd_set_error (bfd_error_invalid_operation);
178c074d1c9Sdrahn       return FALSE;
1792159047fSniklas     }
1802159047fSniklas 
1812159047fSniklas   sym = *rel->sym_ptr_ptr;
1822159047fSniklas 
1832159047fSniklas   /* The value we write out is the offset into the appropriate
1842159047fSniklas      segment.  This offset is the section vma, adjusted by the vma of
1852159047fSniklas      the lowest section in that segment, plus the address of the
1862159047fSniklas      relocation.  */
1872159047fSniklas   val = bfd_get_section_vma (abfd, sec) + rel->address;
1882159047fSniklas 
1892159047fSniklas   /* The second most significant bit is 0 if the value is an offset
1902159047fSniklas      into the data segment, or 1 if the value is an offset into the
1912159047fSniklas      code segment.  */
1922159047fSniklas   if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
1932159047fSniklas     {
1942159047fSniklas       val -= nlm_get_text_low (abfd);
1952159047fSniklas       val |= NLM_HIBIT >> 1;
1962159047fSniklas     }
1972159047fSniklas   else
1982159047fSniklas     val -= nlm_get_data_low (abfd);
1992159047fSniklas 
2002159047fSniklas   if (! bfd_is_und_section (bfd_get_section (sym)))
2012159047fSniklas     {
2022159047fSniklas       /* NetWare only supports absolute internal relocs.  */
2032159047fSniklas       if (rel->howto->pc_relative)
2042159047fSniklas 	{
2052159047fSniklas 	  bfd_set_error (bfd_error_invalid_operation);
206c074d1c9Sdrahn 	  return FALSE;
2072159047fSniklas 	}
2082159047fSniklas 
2092159047fSniklas       /* The high bit is 1 if the reloc is against the code section, 0
2102159047fSniklas 	 if against the data section.  */
2112159047fSniklas       if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
2122159047fSniklas 	val |= NLM_HIBIT;
2132159047fSniklas     }
2142159047fSniklas   else
2152159047fSniklas     {
2162159047fSniklas       /* The high bit is 1 if this is an absolute reloc, 0 if it is PC
2172159047fSniklas 	 relative.  */
2182159047fSniklas       if (! rel->howto->pc_relative)
2192159047fSniklas 	val |= NLM_HIBIT;
2202159047fSniklas       else
2212159047fSniklas 	{
2222159047fSniklas 	  /* PC relative relocs on NetWare must be pcrel_offset.  */
2232159047fSniklas 	  if (! rel->howto->pcrel_offset)
2242159047fSniklas 	    {
2252159047fSniklas 	      bfd_set_error (bfd_error_invalid_operation);
226c074d1c9Sdrahn 	      return FALSE;
2272159047fSniklas 	    }
2282159047fSniklas 	}
2292159047fSniklas     }
2302159047fSniklas 
2312159047fSniklas   bfd_put_32 (abfd, val, temp);
232c074d1c9Sdrahn   if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
233c074d1c9Sdrahn     return FALSE;
2342159047fSniklas 
235c074d1c9Sdrahn   return TRUE;
2362159047fSniklas }
2372159047fSniklas 
238c074d1c9Sdrahn /* I want to be able to use objcopy to turn an i386 a.out or COFF file
2392159047fSniklas    into a NetWare i386 module.  That means that the relocs from the
2402159047fSniklas    source file have to be mapped into relocs that apply to the target
2412159047fSniklas    file.  This function is called by nlm_set_section_contents to give
2422159047fSniklas    it a chance to rework the relocs.
2432159047fSniklas 
2442159047fSniklas    This is actually a fairly general concept.  However, this is not a
2452159047fSniklas    general implementation.  */
2462159047fSniklas 
247c074d1c9Sdrahn static bfd_boolean
nlm_i386_mangle_relocs(abfd,sec,data,offset,count)2482159047fSniklas nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
2492159047fSniklas      bfd *abfd;
2502159047fSniklas      asection *sec;
251*007c2a45Smiod      const PTR data;
2522159047fSniklas      bfd_vma offset;
2532159047fSniklas      bfd_size_type count;
2542159047fSniklas {
2552159047fSniklas   arelent **rel_ptr_ptr, **rel_end;
2562159047fSniklas 
2572159047fSniklas   rel_ptr_ptr = sec->orelocation;
2582159047fSniklas   rel_end = rel_ptr_ptr + sec->reloc_count;
2592159047fSniklas   for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
2602159047fSniklas     {
2612159047fSniklas       arelent *rel;
2622159047fSniklas       asymbol *sym;
2632159047fSniklas       bfd_vma addend;
2642159047fSniklas 
2652159047fSniklas       rel = *rel_ptr_ptr;
2662159047fSniklas       sym = *rel->sym_ptr_ptr;
2672159047fSniklas 
2682159047fSniklas       /* Note that no serious harm will ensue if we fail to change a
2692159047fSniklas 	 reloc.  We will wind up failing in nlm_i386_write_import.  */
2702159047fSniklas 
2712159047fSniklas       /* Make sure this reloc is within the data we have.  We only 4
2722159047fSniklas 	 byte relocs here, so we insist on having 4 bytes.  */
2732159047fSniklas       if (rel->address < offset
2742159047fSniklas 	  || rel->address + 4 > offset + count)
2752159047fSniklas 	continue;
2762159047fSniklas 
2772159047fSniklas       /* NetWare doesn't support reloc addends, so we get rid of them
2782159047fSniklas 	 here by simply adding them into the object data.  We handle
2792159047fSniklas 	 the symbol value, if any, the same way.  */
2802159047fSniklas       addend = rel->addend + sym->value;
2812159047fSniklas 
2822159047fSniklas       /* The value of a symbol is the offset into the section.  If the
2832159047fSniklas 	 symbol is in the .bss segment, we need to include the size of
2842159047fSniklas 	 the data segment in the offset as well.  Fortunately, we know
2852159047fSniklas 	 that at this point the size of the data section is in the NLM
2862159047fSniklas 	 header.  */
2872159047fSniklas       if (((bfd_get_section_flags (abfd, bfd_get_section (sym))
2882159047fSniklas 	    & SEC_LOAD) == 0)
2892159047fSniklas 	  && ((bfd_get_section_flags (abfd, bfd_get_section (sym))
2902159047fSniklas 	       & SEC_ALLOC) != 0))
2912159047fSniklas 	addend += nlm_fixed_header (abfd)->dataImageSize;
2922159047fSniklas 
2932159047fSniklas       if (addend != 0
2942159047fSniklas 	  && rel->howto != NULL
2952159047fSniklas 	  && rel->howto->rightshift == 0
2962159047fSniklas 	  && rel->howto->size == 2
2972159047fSniklas 	  && rel->howto->bitsize == 32
2982159047fSniklas 	  && rel->howto->bitpos == 0
2992159047fSniklas 	  && rel->howto->src_mask == 0xffffffff
3002159047fSniklas 	  && rel->howto->dst_mask == 0xffffffff)
3012159047fSniklas 	{
3022159047fSniklas 	  bfd_vma val;
3032159047fSniklas 
3042159047fSniklas 	  val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
3052159047fSniklas 	  val += addend;
3062159047fSniklas 	  bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
3072159047fSniklas 	  rel->addend = 0;
3082159047fSniklas 	}
3092159047fSniklas 
3102159047fSniklas       /* NetWare uses a reloc with pcrel_offset set.  We adjust
3112159047fSniklas 	 pc_relative relocs accordingly.  We are going to change the
3122159047fSniklas 	 howto field, so we can only do this if the current one is
3132159047fSniklas 	 compatible.  We should check special_function here, but at
3142159047fSniklas 	 the moment coff-i386 uses a special_function which does not
3152159047fSniklas 	 affect what we are doing here.  */
3162159047fSniklas       if (rel->howto != NULL
3172159047fSniklas 	  && rel->howto->pc_relative
3182159047fSniklas 	  && ! rel->howto->pcrel_offset
3192159047fSniklas 	  && rel->howto->rightshift == 0
3202159047fSniklas 	  && rel->howto->size == 2
3212159047fSniklas 	  && rel->howto->bitsize == 32
3222159047fSniklas 	  && rel->howto->bitpos == 0
3232159047fSniklas 	  && rel->howto->src_mask == 0xffffffff
3242159047fSniklas 	  && rel->howto->dst_mask == 0xffffffff)
3252159047fSniklas 	{
3262159047fSniklas 	  bfd_vma val;
3272159047fSniklas 
3282159047fSniklas 	  /* When pcrel_offset is not set, it means that the negative
3292159047fSniklas 	     of the address of the memory location is stored in the
3302159047fSniklas 	     memory location.  We must add it back in.  */
3312159047fSniklas 	  val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
3322159047fSniklas 	  val += rel->address;
3332159047fSniklas 	  bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
3342159047fSniklas 
3352159047fSniklas 	  rel->howto = &nlm_i386_pcrel_howto;
3362159047fSniklas 	}
3372159047fSniklas     }
3382159047fSniklas 
339c074d1c9Sdrahn   return TRUE;
3402159047fSniklas }
3412159047fSniklas 
3422159047fSniklas /* Read a NetWare i386 import record */
343c074d1c9Sdrahn static bfd_boolean
nlm_i386_read_import(abfd,sym)3442159047fSniklas nlm_i386_read_import (abfd, sym)
3452159047fSniklas      bfd *abfd;
3462159047fSniklas      nlmNAME(symbol_type) *sym;
3472159047fSniklas {
3482159047fSniklas   struct nlm_relent *nlm_relocs;	/* relocation records for symbol */
3492159047fSniklas   bfd_size_type rcount;			/* number of relocs */
3502159047fSniklas   bfd_byte temp[NLM_TARGET_LONG_SIZE];	/* temporary 32-bit value */
3512159047fSniklas   unsigned char symlength;		/* length of symbol name */
3522159047fSniklas   char *name;
3532159047fSniklas 
354c074d1c9Sdrahn   if (bfd_bread ((PTR) &symlength, (bfd_size_type) sizeof (symlength), abfd)
3552159047fSniklas       != sizeof (symlength))
356c074d1c9Sdrahn     return FALSE;
3572159047fSniklas   sym -> symbol.the_bfd = abfd;
358c074d1c9Sdrahn   name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
3592159047fSniklas   if (name == NULL)
360c074d1c9Sdrahn     return FALSE;
361c074d1c9Sdrahn   if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
362c074d1c9Sdrahn     return FALSE;
3632159047fSniklas   name[symlength] = '\0';
3642159047fSniklas   sym -> symbol.name = name;
3652159047fSniklas   sym -> symbol.flags = 0;
3662159047fSniklas   sym -> symbol.value = 0;
3672159047fSniklas   sym -> symbol.section = bfd_und_section_ptr;
368c074d1c9Sdrahn   if (bfd_bread ((PTR) temp, (bfd_size_type) sizeof (temp), abfd)
369c074d1c9Sdrahn       != sizeof (temp))
370c074d1c9Sdrahn     return FALSE;
371c074d1c9Sdrahn   rcount = H_GET_32 (abfd, temp);
3722159047fSniklas   nlm_relocs = ((struct nlm_relent *)
3732159047fSniklas 		bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
3742159047fSniklas   if (!nlm_relocs)
375c074d1c9Sdrahn     return FALSE;
3762159047fSniklas   sym -> relocs = nlm_relocs;
3772159047fSniklas   sym -> rcnt = 0;
3782159047fSniklas   while (sym -> rcnt < rcount)
3792159047fSniklas     {
3802159047fSniklas       asection *section;
3812159047fSniklas 
382c074d1c9Sdrahn       if (! nlm_i386_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
383c074d1c9Sdrahn 	return FALSE;
3842159047fSniklas       nlm_relocs -> section = section;
3852159047fSniklas       nlm_relocs++;
3862159047fSniklas       sym -> rcnt++;
3872159047fSniklas     }
388c074d1c9Sdrahn   return TRUE;
3892159047fSniklas }
3902159047fSniklas 
3912159047fSniklas /* Write out an external reference.  */
3922159047fSniklas 
393c074d1c9Sdrahn static bfd_boolean
nlm_i386_write_external(abfd,count,sym,relocs)3942159047fSniklas nlm_i386_write_external (abfd, count, sym, relocs)
3952159047fSniklas      bfd *abfd;
3962159047fSniklas      bfd_size_type count;
3972159047fSniklas      asymbol *sym;
3982159047fSniklas      struct reloc_and_sec *relocs;
3992159047fSniklas {
4002159047fSniklas   unsigned int i;
4012159047fSniklas   bfd_byte len;
4022159047fSniklas   unsigned char temp[NLM_TARGET_LONG_SIZE];
4032159047fSniklas 
4042159047fSniklas   len = strlen (sym->name);
405c074d1c9Sdrahn   if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
406c074d1c9Sdrahn        != sizeof (bfd_byte))
407c074d1c9Sdrahn       || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
408c074d1c9Sdrahn     return FALSE;
4092159047fSniklas 
4102159047fSniklas   bfd_put_32 (abfd, count, temp);
411c074d1c9Sdrahn   if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
412c074d1c9Sdrahn     return FALSE;
4132159047fSniklas 
4142159047fSniklas   for (i = 0; i < count; i++)
4152159047fSniklas     {
416c074d1c9Sdrahn       if (! nlm_i386_write_import (abfd, relocs[i].sec, relocs[i].rel))
417c074d1c9Sdrahn 	return FALSE;
4182159047fSniklas     }
4192159047fSniklas 
420c074d1c9Sdrahn   return TRUE;
4212159047fSniklas }
4222159047fSniklas 
4232159047fSniklas #include "nlmswap.h"
4242159047fSniklas 
4252159047fSniklas static const struct nlm_backend_data nlm32_i386_backend =
4262159047fSniklas {
4272159047fSniklas   "NetWare Loadable Module\032",
4282159047fSniklas   sizeof (Nlm32_i386_External_Fixed_Header),
4292159047fSniklas   0,	/* optional_prefix_size */
4302159047fSniklas   bfd_arch_i386,
4312159047fSniklas   0,
432c074d1c9Sdrahn   FALSE,
4332159047fSniklas   0,	/* backend_object_p */
4342159047fSniklas   0,	/* write_prefix_func */
4352159047fSniklas   nlm_i386_read_reloc,
4362159047fSniklas   nlm_i386_mangle_relocs,
4372159047fSniklas   nlm_i386_read_import,
4382159047fSniklas   nlm_i386_write_import,
4392159047fSniklas   0,	/* set_public_section */
4402159047fSniklas   0,	/* get_public_offset */
4412159047fSniklas   nlm_swap_fixed_header_in,
4422159047fSniklas   nlm_swap_fixed_header_out,
4432159047fSniklas   nlm_i386_write_external,
4442159047fSniklas   0,	/* write_export */
4452159047fSniklas };
4462159047fSniklas 
4472159047fSniklas #define TARGET_LITTLE_NAME		"nlm32-i386"
4482159047fSniklas #define TARGET_LITTLE_SYM		nlmNAME(i386_vec)
4492159047fSniklas #define TARGET_BACKEND_DATA		&nlm32_i386_backend
4502159047fSniklas 
4512159047fSniklas #include "nlm-target.h"
452