/* NLM (NetWare Loadable Module) executable support for BFD.
   Copyright (C) 1993-2016 Free Software Foundation, Inc.

   Written by Fred Fish @ Cygnus Support, using ELF support as the
   template.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "libnlm.h"

/* The functions in this file do not use the names they appear to use.
   This file is actually compiled multiple times, once for each size
   of NLM target we are using.  At each size we use a different name,
   constructed by the macro nlmNAME.  For example, the function which
   is named nlm_symbol_type below is actually named nlm32_symbol_type
   in the final executable.  */

#define Nlm_External_Fixed_Header	NlmNAME (External_Fixed_Header)
#define Nlm_External_Version_Header	NlmNAME (External_Version_Header)
#define Nlm_External_Copyright_Header	NlmNAME (External_Copyright_Header)
#define Nlm_External_Extended_Header	NlmNAME (External_Extended_Header)
#define Nlm_External_Custom_Header	NlmNAME (External_Custom_Header)
#define Nlm_External_Cygnus_Ext_Header	NlmNAME (External_Cygnus_Ext_Header)

#define nlm_symbol_type			nlmNAME (symbol_type)
#define nlm_get_symtab_upper_bound	nlmNAME (get_symtab_upper_bound)
#define nlm_canonicalize_symtab		nlmNAME (canonicalize_symtab)
#define nlm_make_empty_symbol		nlmNAME (make_empty_symbol)
#define nlm_print_symbol		nlmNAME (print_symbol)
#define nlm_get_symbol_info		nlmNAME (get_symbol_info)
#define nlm_get_reloc_upper_bound	nlmNAME (get_reloc_upper_bound)
#define nlm_canonicalize_reloc		nlmNAME (canonicalize_reloc)
#define nlm_object_p			nlmNAME (object_p)
#define nlm_set_section_contents	nlmNAME (set_section_contents)
#define nlm_write_object_contents	nlmNAME (write_object_contents)

#define nlm_swap_fixed_header_in(abfd,src,dst) \
  (nlm_swap_fixed_header_in_func (abfd)) (abfd, src, dst)
#define nlm_swap_fixed_header_out(abfd,src,dst) \
  (nlm_swap_fixed_header_out_func (abfd)) (abfd, src, dst)

/* Should perhaps use put_offset, put_word, etc.  For now, the two versions
   can be handled by explicitly specifying 32 bits or "the long type".  */
#if ARCH_SIZE == 64
#define put_word	H_PUT_64
#define get_word	H_GET_64
#endif
#if ARCH_SIZE == 32
#define put_word	H_PUT_32
#define get_word	H_GET_32
#endif

/* Read and swap in the variable length header.  All the fields must
   exist in the NLM, and must exist in the order they are read here.  */

static bfd_boolean
nlm_swap_variable_header_in (bfd *abfd)
{
  unsigned char temp[NLM_TARGET_LONG_SIZE];
  bfd_size_type amt;

  /* Read the description length and text members.  */
  amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
  if (bfd_bread ((void *) &nlm_variable_header (abfd)->descriptionLength,
		amt, abfd) != amt)
    return FALSE;
  amt = nlm_variable_header (abfd)->descriptionLength + 1;
  if (bfd_bread ((void *) nlm_variable_header (abfd)->descriptionText,
		amt, abfd) != amt)
    return FALSE;

  /* Read and convert the stackSize field.  */
  amt = sizeof (temp);
  if (bfd_bread ((void *) temp, amt, abfd) != amt)
    return FALSE;
  nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);

  /* Read and convert the reserved field.  */
  amt = sizeof (temp);
  if (bfd_bread ((void *) temp, amt, abfd) != amt)
    return FALSE;
  nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);

  /* Read the oldThreadName field.  This field is a fixed length string.  */
  amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
  if (bfd_bread ((void *) nlm_variable_header (abfd)->oldThreadName,
		amt, abfd) != amt)
    return FALSE;

  /* Read the screen name length and text members.  */
  amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
  if (bfd_bread ((void *) & nlm_variable_header (abfd)->screenNameLength,
		amt, abfd) != amt)
    return FALSE;
  amt = nlm_variable_header (abfd)->screenNameLength + 1;
  if (bfd_bread ((void *) nlm_variable_header (abfd)->screenName,
		amt, abfd) != amt)
    return FALSE;

  /* Read the thread name length and text members.  */
  amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
  if (bfd_bread ((void *) & nlm_variable_header (abfd)->threadNameLength,
		amt, abfd) != amt)
    return FALSE;
  amt = nlm_variable_header (abfd)->threadNameLength + 1;
  if (bfd_bread ((void *) nlm_variable_header (abfd)->threadName,
		amt, abfd) != amt)
    return FALSE;
  return TRUE;
}

/* Add a section to the bfd.  */

static bfd_boolean
add_bfd_section (bfd *abfd,
		 char *name,
		 file_ptr offset,
		 bfd_size_type size,
		 flagword flags)
{
  asection *newsect;

  newsect = bfd_make_section_with_flags (abfd, name, flags);
  if (newsect == NULL)
    return FALSE;

  newsect->vma = 0;		/* NLM's are relocatable.  */
  newsect->size = size;
  newsect->filepos = offset;
  newsect->alignment_power = bfd_log2 ((bfd_vma) 0);	/* FIXME */

  return TRUE;
}

/* Read and swap in the contents of all the auxiliary headers.  Because of
   the braindead design, we have to do strcmps on strings of indeterminate
   length to figure out what each auxiliary header is.  Even worse, we have
   no way of knowing how many auxiliary headers there are or where the end
   of the auxiliary headers are, except by finding something that doesn't
   look like a known auxiliary header.  This means that the first new type
   of auxiliary header added will break all existing tools that don't
   recognize it.  */

static bfd_boolean
nlm_swap_auxiliary_headers_in (bfd *abfd)
{
  char tempstr[16];
  file_ptr position;
  bfd_size_type amt;

  for (;;)
    {
      position = bfd_tell (abfd);
      amt = sizeof (tempstr);
      if (bfd_bread ((void *) tempstr, amt, abfd) != amt)
	return FALSE;
      if (bfd_seek (abfd, position, SEEK_SET) != 0)
	return FALSE;
      if (CONST_STRNEQ (tempstr, "VeRsIoN#"))
	{
	  Nlm_External_Version_Header thdr;

	  amt = sizeof (thdr);
	  if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
	    return FALSE;
	  memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
		  sizeof (thdr.stamp));
	  nlm_version_header (abfd)->majorVersion =
	    get_word (abfd, (bfd_byte *) thdr.majorVersion);
	  nlm_version_header (abfd)->minorVersion =
	    get_word (abfd, (bfd_byte *) thdr.minorVersion);
	  nlm_version_header (abfd)->revision =
	    get_word (abfd, (bfd_byte *) thdr.revision);
	  nlm_version_header (abfd)->year =
	    get_word (abfd, (bfd_byte *) thdr.year);
	  nlm_version_header (abfd)->month =
	    get_word (abfd, (bfd_byte *) thdr.month);
	  nlm_version_header (abfd)->day =
	    get_word (abfd, (bfd_byte *) thdr.day);
	}
      else if (CONST_STRNEQ (tempstr, "MeSsAgEs"))
	{
	  Nlm_External_Extended_Header thdr;

	  amt = sizeof (thdr);
	  if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
	    return FALSE;
	  memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
		  sizeof (thdr.stamp));
	  nlm_extended_header (abfd)->languageID =
	    get_word (abfd, (bfd_byte *) thdr.languageID);
	  nlm_extended_header (abfd)->messageFileOffset =
	    get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
	  nlm_extended_header (abfd)->messageFileLength =
	    get_word (abfd, (bfd_byte *) thdr.messageFileLength);
	  nlm_extended_header (abfd)->messageCount =
	    get_word (abfd, (bfd_byte *) thdr.messageCount);
	  nlm_extended_header (abfd)->helpFileOffset =
	    get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
	  nlm_extended_header (abfd)->helpFileLength =
	    get_word (abfd, (bfd_byte *) thdr.helpFileLength);
	  nlm_extended_header (abfd)->RPCDataOffset =
	    get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
	  nlm_extended_header (abfd)->RPCDataLength =
	    get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
	  nlm_extended_header (abfd)->sharedCodeOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
	  nlm_extended_header (abfd)->sharedCodeLength =
	    get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
	  nlm_extended_header (abfd)->sharedDataOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
	  nlm_extended_header (abfd)->sharedDataLength =
	    get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
	  nlm_extended_header (abfd)->sharedRelocationFixupOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
	  nlm_extended_header (abfd)->sharedRelocationFixupCount =
	    get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
	  nlm_extended_header (abfd)->sharedExternalReferenceOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
	  nlm_extended_header (abfd)->sharedExternalReferenceCount =
	    get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
	  nlm_extended_header (abfd)->sharedPublicsOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
	  nlm_extended_header (abfd)->sharedPublicsCount =
	    get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
	  nlm_extended_header (abfd)->sharedDebugRecordOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
	  nlm_extended_header (abfd)->sharedDebugRecordCount =
	    get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
	  nlm_extended_header (abfd)->SharedInitializationOffset =
	    get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
	  nlm_extended_header (abfd)->SharedExitProcedureOffset =
	    get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
	  nlm_extended_header (abfd)->productID =
	    get_word (abfd, (bfd_byte *) thdr.productID);
	  nlm_extended_header (abfd)->reserved0 =
	    get_word (abfd, (bfd_byte *) thdr.reserved0);
	  nlm_extended_header (abfd)->reserved1 =
	    get_word (abfd, (bfd_byte *) thdr.reserved1);
	  nlm_extended_header (abfd)->reserved2 =
	    get_word (abfd, (bfd_byte *) thdr.reserved2);
	  nlm_extended_header (abfd)->reserved3 =
	    get_word (abfd, (bfd_byte *) thdr.reserved3);
	  nlm_extended_header (abfd)->reserved4 =
	    get_word (abfd, (bfd_byte *) thdr.reserved4);
	  nlm_extended_header (abfd)->reserved5 =
	    get_word (abfd, (bfd_byte *) thdr.reserved5);
	}
      else if (CONST_STRNEQ (tempstr, "CoPyRiGhT="))
	{
	  amt = sizeof (nlm_copyright_header (abfd)->stamp);
	  if (bfd_bread ((void *) nlm_copyright_header (abfd)->stamp,
			amt, abfd) != amt)
	    return FALSE;
	  if (bfd_bread ((void *) &(nlm_copyright_header (abfd)
				->copyrightMessageLength),
			(bfd_size_type) 1, abfd) != 1)
	    return FALSE;
	  /* The copyright message is a variable length string.  */
	  amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
	  if (bfd_bread ((void *) nlm_copyright_header (abfd)->copyrightMessage,
			amt, abfd) != amt)
	    return FALSE;
	}
      else if (CONST_STRNEQ (tempstr, "CuStHeAd"))
	{
	  Nlm_External_Custom_Header thdr;
	  bfd_size_type hdrLength;
	  file_ptr dataOffset;
	  bfd_size_type dataLength;
	  char dataStamp[8];
	  void * hdr;

	  /* Read the stamp ("CuStHeAd").  */
	  amt = sizeof (thdr.stamp);
	  if (bfd_bread ((void *) thdr.stamp, amt, abfd) != amt)
	    return FALSE;
	  /* Read the length of this custom header.  */
	  amt = sizeof (thdr.length);
	  if (bfd_bread ((void *) thdr.length, amt, abfd) != amt)
	    return FALSE;
	  hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
	  /* Read further fields if we have them.  */
	  if (hdrLength < NLM_TARGET_LONG_SIZE)
	    dataOffset = 0;
	  else
	    {
	      amt = sizeof (thdr.dataOffset);
	      if (bfd_bread ((void *) thdr.dataOffset, amt, abfd) != amt)
		return FALSE;
	      dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
	    }
	  if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
	    dataLength = 0;
	  else
	    {
	      amt = sizeof (thdr.dataLength);
	      if (bfd_bread ((void *) thdr.dataLength, amt, abfd) != amt)
		return FALSE;
	      dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
	    }
	  if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
	    memset (dataStamp, 0, sizeof (dataStamp));
	  else
	    {
	      amt = sizeof (dataStamp);
	      if (bfd_bread ((void *) dataStamp, amt, abfd) != amt)
		return FALSE;
	    }

	  /* Read the rest of the header, if any.  */
	  if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
	    {
	      hdr = NULL;
	      hdrLength = 0;
	    }
	  else
	    {
	      hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
	      hdr = bfd_alloc (abfd, hdrLength);
	      if (hdr == NULL)
		return FALSE;
	      if (bfd_bread (hdr, hdrLength, abfd) != hdrLength)
		return FALSE;
	    }

	  /* If we have found a Cygnus header, process it.  Otherwise,
	     just save the associated data without trying to interpret
	     it.  */
	  if (CONST_STRNEQ (dataStamp, "CyGnUsEx"))
	    {
	      file_ptr pos;
	      bfd_byte *contents;
	      bfd_byte *p, *pend;

	      BFD_ASSERT (hdrLength == 0 && hdr == NULL);

	      pos = bfd_tell (abfd);
	      if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
		return FALSE;
	      contents = bfd_alloc (abfd, dataLength);
	      if (contents == NULL)
		return FALSE;
	      if (bfd_bread (contents, dataLength, abfd) != dataLength)
		return FALSE;
	      if (bfd_seek (abfd, pos, SEEK_SET) != 0)
		return FALSE;

	      LITMEMCPY (nlm_cygnus_ext_header (abfd), "CyGnUsEx");
	      nlm_cygnus_ext_header (abfd)->offset = dataOffset;
	      nlm_cygnus_ext_header (abfd)->length = dataLength;

	      /* This data this header points to provides a list of
		 the sections which were in the original object file
		 which was converted to become an NLM.  We locate
		 those sections and add them to the BFD.  Note that
		 this is likely to create a second .text, .data and
		 .bss section; retrieving the sections by name will
		 get the actual NLM sections, which is what we want to
		 happen.  The sections from the original file, which
		 may be subsets of the NLM section, can only be found
		 using bfd_map_over_sections.  */
	      p = contents;
	      pend = p + dataLength;
	      while (p < pend)
		{
		  char *name;
		  size_t l;
		  file_ptr filepos;
		  bfd_size_type size;
		  asection *newsec;

		  /* The format of this information is
		     null terminated section name
		     zeroes to adjust to 4 byte boundary
		     4 byte section data file pointer
		     4 byte section size.  */

		  name = (char *) p;
		  l = strlen (name) + 1;
		  l = (l + 3) &~ (size_t) 3;
		  p += l;
		  filepos = H_GET_32 (abfd, p);
		  p += 4;
		  size = H_GET_32 (abfd, p);
		  p += 4;

		  newsec = bfd_make_section_anyway (abfd, name);
		  if (newsec == NULL)
		    return FALSE;
		  newsec->size = size;
		  if (filepos != 0)
		    {
		      newsec->filepos = filepos;
		      newsec->flags |= SEC_HAS_CONTENTS;
		    }
		}
	    }
	  else
	    {
	      memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
		      sizeof (thdr.stamp));
	      nlm_custom_header (abfd)->hdrLength = hdrLength;
	      nlm_custom_header (abfd)->dataOffset = dataOffset;
	      nlm_custom_header (abfd)->dataLength = dataLength;
	      memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
		      sizeof (dataStamp));
	      nlm_custom_header (abfd)->hdr = hdr;
	    }
	}
      else
	break;
    }
  return TRUE;
}

const bfd_target *
nlm_object_p (bfd *abfd)
{
  struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
  bfd_boolean (*backend_object_p) (bfd *);
  void * x_fxdhdr = NULL;
  Nlm_Internal_Fixed_Header *i_fxdhdrp;
  struct nlm_obj_tdata *new_tdata = NULL;
  const char *signature;
  enum bfd_architecture arch;
  bfd_size_type amt;

  /* Some NLM formats have a prefix before the standard NLM fixed
     header.  */
  backend_object_p = nlm_backend_object_p_func (abfd);
  if (backend_object_p)
    {
      if (!(*backend_object_p) (abfd))
	goto got_wrong_format_error;
    }

  /* Read in the fixed length portion of the NLM header in external format.  */
  amt = nlm_fixed_header_size (abfd);
  x_fxdhdr = bfd_malloc (amt);
  if (x_fxdhdr == NULL)
    goto got_no_match;

  if (bfd_bread ((void *) x_fxdhdr, amt, abfd) != amt)
    {
      if (bfd_get_error () != bfd_error_system_call)
	goto got_wrong_format_error;
      else
	goto got_no_match;
    }

  /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
     the tdata pointer in the bfd.  */
  amt = sizeof (struct nlm_obj_tdata);
  new_tdata = bfd_zalloc (abfd, amt);
  if (new_tdata == NULL)
    goto got_no_match;

  nlm_tdata (abfd) = new_tdata;

  i_fxdhdrp = nlm_fixed_header (abfd);
  nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
  free (x_fxdhdr);
  x_fxdhdr = NULL;

  /* Check to see if we have an NLM file for this backend by matching
     the NLM signature.  */
  signature = nlm_signature (abfd);
  if (signature != NULL
      && *signature != '\0'
      && strncmp ((char *) i_fxdhdrp->signature, signature,
		  NLM_SIGNATURE_SIZE) != 0)
    goto got_wrong_format_error;

  /* There's no supported way to discover the endianness of an NLM, so test for
     a sane version number after doing byte swapping appropriate for this
     XVEC.  (Hack alert!)  */
  if (i_fxdhdrp->version > 0xFFFF)
    goto got_wrong_format_error;

  /* There's no supported way to check for 32 bit versus 64 bit addresses,
     so ignore this distinction for now.  (FIXME) */
  /* Swap in the rest of the required header.  */
  if (!nlm_swap_variable_header_in (abfd))
    {
      if (bfd_get_error () != bfd_error_system_call)
	goto got_wrong_format_error;
      else
	goto got_no_match;
    }

  /* Add the sections supplied by all NLM's, and then read in the
     auxiliary headers.  Reading the auxiliary headers may create
     additional sections described in the cygnus_ext header.
     From this point on we assume that we have an NLM, and do not
     treat errors as indicating the wrong format.  */
  if (!add_bfd_section (abfd, NLM_CODE_NAME,
			i_fxdhdrp->codeImageOffset,
			i_fxdhdrp->codeImageSize,
			(SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
			 | SEC_RELOC))
      || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
			   i_fxdhdrp->dataImageOffset,
			   i_fxdhdrp->dataImageSize,
			   (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
			    | SEC_RELOC))
      || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
			   (file_ptr) 0,
			   i_fxdhdrp->uninitializedDataSize,
			   SEC_ALLOC))
    goto got_no_match;

  if (!nlm_swap_auxiliary_headers_in (abfd))
    goto got_no_match;

  if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
      || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
    abfd->flags |= HAS_RELOC;
  if (nlm_fixed_header (abfd)->numberOfPublics != 0
      || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
      || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
    abfd->flags |= HAS_SYMS;

  arch = nlm_architecture (abfd);
  if (arch != bfd_arch_unknown)
    bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);

  abfd->flags |= EXEC_P;
  bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;

  return abfd->xvec;

got_wrong_format_error:
  bfd_set_error (bfd_error_wrong_format);
got_no_match:
  nlm_tdata (abfd) = preserved_tdata;
  if (new_tdata != NULL)
    bfd_release (abfd, new_tdata);
  if (x_fxdhdr != NULL)
    free (x_fxdhdr);

  return NULL;
}

/* Swap and write out the variable length header.  All the fields must
   exist in the NLM, and must exist in this order.  */

static bfd_boolean
nlm_swap_variable_header_out (bfd *abfd)
{
  bfd_byte temp[NLM_TARGET_LONG_SIZE];
  bfd_size_type amt;

  /* Write the description length and text members.  */
  amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
  if (bfd_bwrite (& nlm_variable_header (abfd)->descriptionLength, amt,
		  abfd) != amt)
    return FALSE;
  amt = nlm_variable_header (abfd)->descriptionLength + 1;
  if (bfd_bwrite ((void *) nlm_variable_header (abfd)->descriptionText, amt,
		  abfd) != amt)
    return FALSE;

  /* Convert and write the stackSize field.  */
  put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, temp);
  amt = sizeof (temp);
  if (bfd_bwrite (temp, amt, abfd) != amt)
    return FALSE;

  /* Convert and write the reserved field.  */
  put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, temp);
  amt = sizeof (temp);
  if (bfd_bwrite (temp, amt, abfd) != amt)
    return FALSE;

  /* Write the oldThreadName field.  This field is a fixed length string.  */
  amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
  if (bfd_bwrite (nlm_variable_header (abfd)->oldThreadName, amt,
		  abfd) != amt)
    return FALSE;

  /* Write the screen name length and text members.  */
  amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
  if (bfd_bwrite (& nlm_variable_header (abfd)->screenNameLength, amt,
		 abfd) != amt)
    return FALSE;
  amt = nlm_variable_header (abfd)->screenNameLength + 1;
  if (bfd_bwrite (nlm_variable_header (abfd)->screenName, amt, abfd) != amt)
    return FALSE;

  /* Write the thread name length and text members.  */
  amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
  if (bfd_bwrite (& nlm_variable_header (abfd)->threadNameLength, amt,
		 abfd) != amt)
    return FALSE;
  amt = nlm_variable_header (abfd)->threadNameLength + 1;
  if (bfd_bwrite (nlm_variable_header (abfd)->threadName, amt, abfd) != amt)
    return FALSE;
  return TRUE;
}

/* Return whether there is a non-zero byte in a memory block.  */

static bfd_boolean
find_nonzero (void * buf, size_t size)
{
  char *p = (char *) buf;

  while (size-- != 0)
    if (*p++ != 0)
      return TRUE;
  return FALSE;
}

/* Swap out the contents of the auxiliary headers.  We create those
   auxiliary headers which have been set non-zero.  We do not require
   the caller to set up the stamp fields.  */

static bfd_boolean
nlm_swap_auxiliary_headers_out (bfd *abfd)
{
  bfd_size_type amt;

  /* Write out the version header if there is one.  */
  if (find_nonzero (nlm_version_header (abfd),
		    sizeof (Nlm_Internal_Version_Header)))
    {
      Nlm_External_Version_Header thdr;

      LITMEMCPY (thdr.stamp, "VeRsIoN#");
      put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
		(bfd_byte *) thdr.majorVersion);
      put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
		(bfd_byte *) thdr.minorVersion);
      put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
		(bfd_byte *) thdr.revision);
      put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
		(bfd_byte *) thdr.year);
      put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
		(bfd_byte *) thdr.month);
      put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
		(bfd_byte *) thdr.day);
      if (bfd_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
	  != sizeof (thdr))
	return FALSE;
    }

  /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
     tag in order to make the NW4.x and NW5.x loaders happy.  */

  /* Write out the copyright header if there is one.  */
  if (find_nonzero (nlm_copyright_header (abfd),
		    sizeof (Nlm_Internal_Copyright_Header)))
    {
      Nlm_External_Copyright_Header thdr;

      LITMEMCPY (thdr.stamp, "CoPyRiGhT=");
      amt = sizeof (thdr.stamp);
      if (bfd_bwrite ((void *) thdr.stamp, amt, abfd) != amt)
	return FALSE;
      thdr.copyrightMessageLength[0] =
	nlm_copyright_header (abfd)->copyrightMessageLength;
      amt = 1;
      if (bfd_bwrite ((void *) thdr.copyrightMessageLength, amt, abfd) != amt)
	return FALSE;
      /* The copyright message is a variable length string.  */
      amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
      if (bfd_bwrite ((void *) nlm_copyright_header (abfd)->copyrightMessage,
		     amt, abfd) != amt)
	return FALSE;
    }

  /* Write out the extended header if there is one.  */
  if (find_nonzero (nlm_extended_header (abfd),
		    sizeof (Nlm_Internal_Extended_Header)))
    {
      Nlm_External_Extended_Header thdr;

      LITMEMCPY (thdr.stamp, "MeSsAgEs");
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->languageID,
		(bfd_byte *) thdr.languageID);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
		(bfd_byte *) thdr.messageFileOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->messageFileLength,
		(bfd_byte *) thdr.messageFileLength);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->messageCount,
		(bfd_byte *) thdr.messageCount);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
		(bfd_byte *) thdr.helpFileOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->helpFileLength,
		(bfd_byte *) thdr.helpFileLength);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
		(bfd_byte *) thdr.RPCDataOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
		(bfd_byte *) thdr.RPCDataLength);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
		(bfd_byte *) thdr.sharedCodeOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
		(bfd_byte *) thdr.sharedCodeLength);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
		(bfd_byte *) thdr.sharedDataOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
		(bfd_byte *) thdr.sharedDataLength);
      put_word (abfd,
	  (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
		(bfd_byte *) thdr.sharedRelocationFixupOffset);
      put_word (abfd,
	   (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
		(bfd_byte *) thdr.sharedRelocationFixupCount);
      put_word (abfd,
	(bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
		(bfd_byte *) thdr.sharedExternalReferenceOffset);
      put_word (abfd,
	 (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
		(bfd_byte *) thdr.sharedExternalReferenceCount);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
		(bfd_byte *) thdr.sharedPublicsOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
		(bfd_byte *) thdr.sharedPublicsCount);
      put_word (abfd,
	      (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
		(bfd_byte *) thdr.sharedDebugRecordOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
		(bfd_byte *) thdr.sharedDebugRecordCount);
      put_word (abfd,
	   (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
		(bfd_byte *) thdr.sharedInitializationOffset);
      put_word (abfd,
	    (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
		(bfd_byte *) thdr.SharedExitProcedureOffset);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->productID,
		(bfd_byte *) thdr.productID);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->reserved0,
		(bfd_byte *) thdr.reserved0);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->reserved1,
		(bfd_byte *) thdr.reserved1);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->reserved2,
		(bfd_byte *) thdr.reserved2);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->reserved3,
		(bfd_byte *) thdr.reserved3);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->reserved4,
		(bfd_byte *) thdr.reserved4);
      put_word (abfd,
		(bfd_vma) nlm_extended_header (abfd)->reserved5,
		(bfd_byte *) thdr.reserved5);
      if (bfd_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
	  != sizeof (thdr))
	return FALSE;
    }

  /* Write out the custom header if there is one.   */
  if (find_nonzero (nlm_custom_header (abfd),
		    sizeof (Nlm_Internal_Custom_Header)))
    {
      Nlm_External_Custom_Header thdr;
      bfd_boolean ds;
      bfd_size_type hdrLength;

      ds = find_nonzero (nlm_custom_header (abfd)->dataStamp,
			 sizeof (nlm_custom_header (abfd)->dataStamp));
      LITMEMCPY (thdr.stamp, "CuStHeAd");
      hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
		   + nlm_custom_header (abfd)->hdrLength);
      put_word (abfd, hdrLength, thdr.length);
      put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
		thdr.dataOffset);
      put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
		thdr.dataLength);
      if (! ds)
	{
	  BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
	  amt = sizeof (thdr) - sizeof (thdr.dataStamp);
	  if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
	    return FALSE;
	}
      else
	{
	  memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
		  sizeof (thdr.dataStamp));
	  amt = sizeof (thdr);
	  if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
	    return FALSE;
	  amt = nlm_custom_header (abfd)->hdrLength;
	  if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
	    return FALSE;
	}
    }

  /* Write out the Cygnus debugging header if there is one.  */
  if (find_nonzero (nlm_cygnus_ext_header (abfd),
		    sizeof (Nlm_Internal_Cygnus_Ext_Header)))
    {
      Nlm_External_Custom_Header thdr;

      LITMEMCPY (thdr.stamp, "CuStHeAd");
      put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
		(bfd_byte *) thdr.length);
      put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
		(bfd_byte *) thdr.dataOffset);
      put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
		(bfd_byte *) thdr.dataLength);
      LITMEMCPY (thdr.dataStamp, "CyGnUsEx");
      amt = sizeof (thdr);
      if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
	return FALSE;
    }

  return TRUE;
}

/* We read the NLM's public symbols and use it to generate a bfd symbol
   table (hey, it's better than nothing) on a one-for-one basis.  Thus
   use the number of public symbols as the number of bfd symbols we will
   have once we actually get around to reading them in.

   Return the number of bytes required to hold the symtab vector, based on
   the count plus 1, since we will NULL terminate the vector allocated based
   on this size.  */

long
nlm_get_symtab_upper_bound (bfd *abfd)
{
  Nlm_Internal_Fixed_Header *i_fxdhdrp;	/* Nlm file header, internal form.  */
  long symcount;
  long symtab_size = 0;

  i_fxdhdrp = nlm_fixed_header (abfd);
  symcount = (i_fxdhdrp->numberOfPublics
	      + i_fxdhdrp->numberOfDebugRecords
	      + i_fxdhdrp->numberOfExternalReferences);
  symtab_size = (symcount + 1) * (sizeof (asymbol));
  return symtab_size;
}

/* Slurp in nlm symbol table.

   In the external (in-file) form, NLM export records are variable length,
   with the following form:

	1 byte		length of the symbol name (N)
	N bytes		the symbol name
	4 bytes		the symbol offset from start of it's section

   We also read in the debugging symbols and import records.  Import
   records are treated as undefined symbols.  As we read the import
   records we also read in the associated reloc information, which is
   attached to the symbol.

   The bfd symbols are copied to SYMvoid *S.

   When we return, the bfd symcount is either zero or contains the correct
   number of symbols.  */

static bfd_boolean
nlm_slurp_symbol_table (bfd *abfd)
{
  Nlm_Internal_Fixed_Header *i_fxdhdrp;	/* Nlm file header, internal form.  */
  bfd_size_type totsymcount;	/* Number of NLM symbols.  */
  bfd_size_type symcount;	/* Counter of NLM symbols.  */
  nlm_symbol_type *sym;		/* Pointer to current bfd symbol.  */
  unsigned char symlength;	/* Symbol length read into here.  */
  unsigned char symtype;	/* Type of debugging symbol.  */
  bfd_byte temp[NLM_TARGET_LONG_SIZE];	/* Symbol offsets read into here.  */
  bfd_boolean (*read_import_func) (bfd *, nlm_symbol_type *);
  bfd_boolean (*set_public_section_func) (bfd *, nlm_symbol_type *);
  bfd_size_type amt;

  if (nlm_get_symbols (abfd) != NULL)
    return TRUE;

  /* Read each raw NLM symbol, using the information to create a canonical bfd
     symbol table entry.

     Note that we allocate the initial bfd canonical symbol buffer based on a
     one-to-one mapping of the NLM symbols to canonical symbols.  We actually
     use all the NLM symbols, so there will be no space left over at the end.
     When we have all the symbols, we build the caller's pointer vector.  */

  abfd->symcount = 0;
  i_fxdhdrp = nlm_fixed_header (abfd);
  totsymcount = (i_fxdhdrp->numberOfPublics
		 + i_fxdhdrp->numberOfDebugRecords
		 + i_fxdhdrp->numberOfExternalReferences);
  if (totsymcount == 0)
    return TRUE;

  if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0)
    return FALSE;

  amt = totsymcount * sizeof (nlm_symbol_type);
  sym = bfd_zalloc (abfd, amt);
  if (!sym)
    return FALSE;
  nlm_set_symbols (abfd, sym);

  /* We use the bfd's symcount directly as the control count, so that early
     termination of the loop leaves the symcount correct for the symbols that
     were read.  */

  set_public_section_func = nlm_set_public_section_func (abfd);
  symcount = i_fxdhdrp->numberOfPublics;
  while (abfd->symcount < symcount)
    {
      amt = sizeof (symlength);
      if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
	return FALSE;
      amt = symlength;
      sym->symbol.the_bfd = abfd;
      sym->symbol.name = bfd_alloc (abfd, amt + 1);
      if (!sym->symbol.name)
	return FALSE;
      if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
	return FALSE;
      /* Cast away const.  */
      ((char *) (sym->symbol.name))[symlength] = '\0';
      amt = sizeof (temp);
      if (bfd_bread ((void *) temp, amt, abfd) != amt)
	return FALSE;
      sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
      sym->symbol.value = get_word (abfd, temp);
      if (set_public_section_func)
	{
	  /* Most backends can use the code below, but unfortunately
	     some use a different scheme.  */
	  if (! (*set_public_section_func) (abfd, sym))
	    return FALSE;
	}
      else
	{
	  if (sym->symbol.value & NLM_HIBIT)
	    {
	      sym->symbol.value &= ~NLM_HIBIT;
	      sym->symbol.flags |= BSF_FUNCTION;
	      sym->symbol.section =
		bfd_get_section_by_name (abfd, NLM_CODE_NAME);
	    }
	  else
	    sym->symbol.section =
	      bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
	}
      sym->rcnt = 0;
      abfd->symcount++;
      sym++;
    }

  /* Read the debugging records.  */

  if (i_fxdhdrp->numberOfDebugRecords > 0)
    {
      if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0)
	return FALSE;

      symcount += i_fxdhdrp->numberOfDebugRecords;
      while (abfd->symcount < symcount)
	{
	  amt = sizeof (symtype);
	  if (bfd_bread ((void *) &symtype, amt, abfd) != amt)
	    return FALSE;
	  amt = sizeof (temp);
	  if (bfd_bread ((void *) temp, amt, abfd) != amt)
	    return FALSE;
	  amt = sizeof (symlength);
	  if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
	    return FALSE;
	  amt = symlength;
	  sym->symbol.the_bfd = abfd;
	  sym->symbol.name = bfd_alloc (abfd, amt + 1);
	  if (!sym->symbol.name)
	    return FALSE;
	  if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
	    return FALSE;
	  /* Cast away const.  */
	  ((char *) (sym->symbol.name))[symlength] = '\0';
	  sym->symbol.flags = BSF_LOCAL;
	  sym->symbol.value = get_word (abfd, temp);

	  if (symtype == 0)
	    sym->symbol.section =
	      bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
	  else if (symtype == 1)
	    {
	      sym->symbol.flags |= BSF_FUNCTION;
	      sym->symbol.section =
		bfd_get_section_by_name (abfd, NLM_CODE_NAME);
	    }
	  else
	    sym->symbol.section = bfd_abs_section_ptr;

	  sym->rcnt = 0;
	  abfd->symcount++;
	  sym++;
	}
    }

  /* Read in the import records.  We can only do this if we know how
     to read relocs for this target.  */
  read_import_func = nlm_read_import_func (abfd);
  if (read_import_func != NULL)
    {
      if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0)
	return FALSE;

      symcount += i_fxdhdrp->numberOfExternalReferences;
      while (abfd->symcount < symcount)
	{
	  if (! (*read_import_func) (abfd, sym))
	    return FALSE;
	  sym++;
	  abfd->symcount++;
	}
    }

  return TRUE;
}

/* Note that bfd_get_symcount is guaranteed to be zero if slurping the
   symbol table fails.  */

long
nlm_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
  nlm_symbol_type *symbase;
  bfd_size_type counter = 0;

  if (! nlm_slurp_symbol_table (abfd))
    return -1;
  symbase = nlm_get_symbols (abfd);
  while (counter < bfd_get_symcount (abfd))
    {
      *alocation++ = &symbase->symbol;
      symbase++;
      counter++;
    }
  *alocation = NULL;
  return bfd_get_symcount (abfd);
}

/* Make an NLM symbol.  There is nothing special to do here.  */

asymbol *
nlm_make_empty_symbol (bfd *abfd)
{
  bfd_size_type amt = sizeof (nlm_symbol_type);
  nlm_symbol_type *new = bfd_zalloc (abfd, amt);

  if (new == NULL)
    return NULL;
  new->symbol.the_bfd = abfd;
  return & new->symbol;
}

/* Get symbol information.  */

void
nlm_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
		     asymbol *symbol,
		     symbol_info *ret)
{
  bfd_symbol_info (symbol, ret);
}

/* Print symbol information.  */

void
nlm_print_symbol (bfd *abfd,
		  void * afile,
		  asymbol *symbol,
		  bfd_print_symbol_type how)
{
  FILE *file = (FILE *) afile;

  switch (how)
    {
    case bfd_print_symbol_name:
    case bfd_print_symbol_more:
      if (symbol->name)
	fprintf (file, "%s", symbol->name);
      break;
    case bfd_print_symbol_all:
      bfd_print_symbol_vandf (abfd, (void *) file, symbol);
      fprintf (file, " %-5s", symbol->section->name);
      if (symbol->name)
	fprintf (file, " %s", symbol->name);
      break;
    }
}

/* Get the relocs for an NLM file.  There are two types of relocs.
   Imports are relocs against symbols defined in other NLM files.  We
   treat these as relocs against global symbols.  Relocation fixups
   are internal relocs.

   The actual format used to store the relocs is machine specific.  */

/* Read in the relocation fixup information.  This is stored in
   nlm_relocation_fixups, an array of arelent structures, and
   nlm_relocation_fixup_secs, an array of section pointers.  The
   section pointers are needed because the relocs are not sorted by
   section.  */

static bfd_boolean
nlm_slurp_reloc_fixups (bfd *abfd)
{
  bfd_boolean (*read_func) (bfd *, nlm_symbol_type *, asection **, arelent *);
  bfd_size_type count, amt;
  arelent *rels;
  asection **secs;

  if (nlm_relocation_fixups (abfd) != NULL)
    return TRUE;
  read_func = nlm_read_reloc_func (abfd);
  if (read_func == NULL)
    return TRUE;

  if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
		SEEK_SET) != 0)
    return FALSE;

  count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
  amt = count * sizeof (arelent);
  rels = bfd_alloc (abfd, amt);
  amt = count * sizeof (asection *);
  secs = bfd_alloc (abfd, amt);
  if ((rels == NULL || secs == NULL) && count != 0)
    return FALSE;
  nlm_relocation_fixups (abfd) = rels;
  nlm_relocation_fixup_secs (abfd) = secs;

  /* We have to read piece by piece, because we don't know how large
     the machine specific reloc information is.  */
  while (count-- != 0)
    {
      if (! (*read_func) (abfd, NULL, secs, rels))
	{
	  nlm_relocation_fixups (abfd) = NULL;
	  nlm_relocation_fixup_secs (abfd) = NULL;
	  return FALSE;
	}
      ++secs;
      ++rels;
    }

  return TRUE;
}

/* Get the number of relocs.  This really just returns an upper bound,
   since it does not attempt to distinguish them based on the section.
   That will be handled when they are actually read.  */

long
nlm_get_reloc_upper_bound (bfd *abfd, asection *sec)
{
  nlm_symbol_type *syms;
  bfd_size_type count;
  unsigned int ret;

  /* If we don't know how to read relocs, just return 0.  */
  if (nlm_read_reloc_func (abfd) == NULL)
    return -1;
  /* Make sure we have either the code or the data section.  */
  if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
    return 0;

  syms = nlm_get_symbols (abfd);
  if (syms == NULL)
    {
      if (! nlm_slurp_symbol_table (abfd))
	return -1;
      syms = nlm_get_symbols (abfd);
    }

  ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;

  count = bfd_get_symcount (abfd);
  while (count-- != 0)
    {
      ret += syms->rcnt;
      ++syms;
    }

  return (ret + 1) * sizeof (arelent *);
}

/* Get the relocs themselves.  */

long
nlm_canonicalize_reloc (bfd *abfd,
			asection *sec,
			arelent **relptr,
			asymbol **symbols)
{
  arelent *rels;
  asection **secs;
  bfd_size_type count, i;
  long ret;

  /* Get the relocation fixups.  */
  rels = nlm_relocation_fixups (abfd);
  if (rels == NULL)
    {
      if (! nlm_slurp_reloc_fixups (abfd))
	return -1;
      rels = nlm_relocation_fixups (abfd);
    }
  secs = nlm_relocation_fixup_secs (abfd);

  ret = 0;
  count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
  for (i = 0; i < count; i++, rels++, secs++)
    {
      if (*secs == sec)
	{
	  *relptr++ = rels;
	  ++ret;
	}
    }

  /* Get the import symbols.  */
  count = bfd_get_symcount (abfd);
  for (i = 0; i < count; i++, symbols++)
    {
      asymbol *sym;

      sym = *symbols;
      if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
	{
	  nlm_symbol_type *nlm_sym;
	  bfd_size_type j;

	  nlm_sym = (nlm_symbol_type *) sym;
	  for (j = 0; j < nlm_sym->rcnt; j++)
	    {
	      if (nlm_sym->relocs[j].section == sec)
		{
		  *relptr = &nlm_sym->relocs[j].reloc;
		  (*relptr)->sym_ptr_ptr = symbols;
		  ++relptr;
		  ++ret;
		}
	    }
	}
    }

  *relptr = NULL;

  return ret;
}

/* Compute the section file positions for an NLM file.  All variable
   length data in the file headers must be set before this function is
   called.  If the variable length data is changed later, the
   resulting object file will be incorrect.  Unfortunately, there is
   no way to check this.

   This routine also sets the Size and Offset fields in the fixed
   header.

   It also looks over the symbols and moves any common symbols into
   the .bss section; NLM has no way to represent a common symbol.
   This approach means that either the symbols must already have been
   set at this point, or there must be no common symbols.  We need to
   move the symbols at this point so that mangle_relocs can see the
   final values.  */

static bfd_boolean
nlm_compute_section_file_positions (bfd *abfd)
{
  file_ptr sofar;
  asection *sec;
  bfd_vma text, data, bss;
  bfd_vma text_low, data_low;
  unsigned int text_align, data_align, other_align;
  file_ptr text_ptr, data_ptr, other_ptr;
  asection *bss_sec;
  asymbol **sym_ptr_ptr;

  if (abfd->output_has_begun)
    return TRUE;

  /* Make sure we have a section to hold uninitialized data.  */
  bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
  if (bss_sec == NULL)
    {
      if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
			    (file_ptr) 0, (bfd_size_type) 0,
			    SEC_ALLOC))
	return FALSE;
      bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
    }

  abfd->output_has_begun = TRUE;

  /* The fixed header.  */
  sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);

  /* The variable header.  */
  sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
	    + nlm_variable_header (abfd)->descriptionLength + 1
	    + NLM_TARGET_LONG_SIZE	/* stackSize */
	    + NLM_TARGET_LONG_SIZE	/* reserved */
	    + sizeof (nlm_variable_header (abfd)->oldThreadName)
	    + sizeof (nlm_variable_header (abfd)->screenNameLength)
	    + nlm_variable_header (abfd)->screenNameLength + 1
	    + sizeof (nlm_variable_header (abfd)->threadNameLength)
	    + nlm_variable_header (abfd)->threadNameLength + 1);

  /* The auxiliary headers.  */
  if (find_nonzero (nlm_version_header (abfd),
		    sizeof (Nlm_Internal_Version_Header)))
    sofar += sizeof (Nlm_External_Version_Header);
  if (find_nonzero (nlm_extended_header (abfd),
		    sizeof (Nlm_Internal_Extended_Header)))
    sofar += sizeof (Nlm_External_Extended_Header);
  if (find_nonzero (nlm_copyright_header (abfd),
		    sizeof (Nlm_Internal_Copyright_Header)))
    sofar += (sizeof (Nlm_External_Copyright_Header)
	      + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
  if (find_nonzero (nlm_custom_header (abfd),
		    sizeof (Nlm_Internal_Custom_Header)))
    sofar += (sizeof (Nlm_External_Custom_Header)
	      + nlm_custom_header (abfd)->hdrLength);
  if (find_nonzero (nlm_cygnus_ext_header (abfd),
		    sizeof (Nlm_Internal_Cygnus_Ext_Header)))
    sofar += sizeof (Nlm_External_Custom_Header);

  /* Compute the section file positions in two passes.  First get the
     sizes of the text and data sections, and then set the file
     positions.  This code aligns the sections in the file using the
     same alignment restrictions that apply to the sections in memory;
     this may not be necessary.  */
  text = 0;
  text_low = (bfd_vma) - 1;
  text_align = 0;
  data = 0;
  data_low = (bfd_vma) - 1;
  data_align = 0;
  bss = 0;
  other_align = 0;
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
    {
      flagword f;

      sec->size = BFD_ALIGN (sec->size, 1 << sec->alignment_power);

      f = bfd_get_section_flags (abfd, sec);
      if (f & SEC_CODE)
	{
	  text += sec->size;
	  if (bfd_get_section_vma (abfd, sec) < text_low)
	    text_low = bfd_get_section_vma (abfd, sec);
	  if (sec->alignment_power > text_align)
	    text_align = sec->alignment_power;
	}
      else if (f & SEC_DATA)
	{
	  data += sec->size;
	  if (bfd_get_section_vma (abfd, sec) < data_low)
	    data_low = bfd_get_section_vma (abfd, sec);
	  if (sec->alignment_power > data_align)
	    data_align = sec->alignment_power;
	}
      else if (f & SEC_HAS_CONTENTS)
	{
	  if (sec->alignment_power > other_align)
	    other_align = sec->alignment_power;
	}
      else if (f & SEC_ALLOC)
	bss += sec->size;
    }

  nlm_set_text_low (abfd, text_low);
  nlm_set_data_low (abfd, data_low);

  if (nlm_no_uninitialized_data (abfd))
    {
      /* This NetWare format does not use uninitialized data.  We must
	 increase the size of the data section.  We will never wind up
	 writing those file locations, so they will remain zero.  */
      data += bss;
      bss = 0;
    }

  text_ptr = BFD_ALIGN (sofar, 1 << text_align);
  data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
  other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);

  /* Fill in some fields in the header for which we now have the
     information.  */
  nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
  nlm_fixed_header (abfd)->codeImageSize = text;
  nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
  nlm_fixed_header (abfd)->dataImageSize = data;
  nlm_fixed_header (abfd)->uninitializedDataSize = bss;

  for (sec = abfd->sections; sec != NULL; sec = sec->next)
    {
      flagword f;

      f = bfd_get_section_flags (abfd, sec);

      if (f & SEC_CODE)
	{
	  sec->filepos = text_ptr;
	  text_ptr += sec->size;
	}
      else if (f & SEC_DATA)
	{
	  sec->filepos = data_ptr;
	  data_ptr += sec->size;
	}
      else if (f & SEC_HAS_CONTENTS)
	{
	  sec->filepos = other_ptr;
	  other_ptr += sec->size;
	}
    }

  nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;

  /* Move all common symbols into the .bss section.  */

  sym_ptr_ptr = bfd_get_outsymbols (abfd);
  if (sym_ptr_ptr != NULL)
    {
      asymbol **sym_end;
      bfd_vma add;

      sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
      add = 0;
      for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
	{
	  asymbol *sym;
	  bfd_vma size;

	  sym = *sym_ptr_ptr;

	  if (!bfd_is_com_section (bfd_get_section (sym)))
	    continue;

	  /* Put the common symbol in the .bss section, and increase
	     the size of the .bss section by the size of the common
	     symbol (which is the old value of the symbol).  */
	  sym->section = bss_sec;
	  size = sym->value;
	  sym->value = bss_sec->size + add;
	  add += size;
	  add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
	}
      if (add != 0)
	{
	  if (nlm_no_uninitialized_data (abfd))
	    {
	      /* We could handle this case, but so far it hasn't been
		 necessary.  */
	      abort ();
	    }
	  nlm_fixed_header (abfd)->uninitializedDataSize += add;
	  bss_sec->size += add;
	}
    }

  return TRUE;
}

/* Set the contents of a section.  To do this we need to know where
   the section is going to be located in the output file.  That means
   that the sizes of all the sections must be set, and all the
   variable size header information must be known.  */

bfd_boolean
nlm_set_section_contents (bfd *abfd,
			  asection *section,
			  const void * location,
			  file_ptr offset,
			  bfd_size_type count)
{
  if (! abfd->output_has_begun
      && ! nlm_compute_section_file_positions (abfd))
    return FALSE;

  if (count == 0)
    return TRUE;

  /* i386 NetWare has a very restricted set of relocs.  In order for
     objcopy to work, the NLM i386 backend needs a chance to rework
     the section contents so that its set of relocs will work.  If all
     the relocs are already acceptable, this will not do anything.  */
  if (section->reloc_count != 0)
    {
      bfd_boolean (*mangle_relocs_func)
	(bfd *, asection *, const void *, bfd_vma, bfd_size_type);

      mangle_relocs_func = nlm_mangle_relocs_func (abfd);
      if (mangle_relocs_func != NULL)
	{
	  if (!(*mangle_relocs_func) (abfd, section, location,
				      (bfd_vma) offset, count))
	    return FALSE;
	}
    }

  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
      || bfd_bwrite (location, count, abfd) != count)
    return FALSE;

  return TRUE;
}

/* We need to sort a list of relocs associated with sections when we
   write out the external relocs.  */

static int
nlm_external_reloc_compare (const void *p1, const void *p2)
{
  const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
  const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
  int cmp;

  cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
		(*r2->rel->sym_ptr_ptr)->name);
  if (cmp != 0)
    return cmp;

  /* We sort by address within symbol to make the sort more stable and
     increase the chances that different hosts will generate bit for
     bit equivalent results.  */
  return (int) (r1->rel->address - r2->rel->address);
}

/* Write out an NLM file.  We write out the information in this order:
     fixed header
     variable header
     auxiliary headers
     code sections
     data sections
     other sections (custom data, messages, help, shared NLM, RPC,
     		     module dependencies)
     relocation fixups
     external references (imports)
     public symbols (exports)
     debugging records
   This is similar to the order used by the NetWare tools; the
   difference is that NetWare puts the sections other than code, data
   and custom data at the end of the NLM.  It is convenient for us to
   know where the sections are going to be before worrying about the
   size of the other information.

   By the time this function is called, all the section data should
   have been output using set_section_contents.  Note that custom
   data, the message file, the help file, the shared NLM file, the RPC
   data, and the module dependencies are all considered to be
   sections; the caller is responsible for filling in the offset and
   length fields in the NLM headers.  The relocation fixups and
   imports are both obtained from the list of relocs attached to each
   section.  The exports and debugging records are obtained from the
   list of outsymbols.  */

bfd_boolean
nlm_write_object_contents (bfd *abfd)
{
  asection *sec;
  bfd_boolean (*write_import_func) (bfd *, asection *, arelent *);
  bfd_size_type external_reloc_count, internal_reloc_count, i, c;
  struct reloc_and_sec *external_relocs;
  asymbol **sym_ptr_ptr;
  file_ptr last;
  bfd_boolean (*write_prefix_func) (bfd *);
  unsigned char *fixed_header = NULL;
  file_ptr pos;
  bfd_size_type amt;

  fixed_header = bfd_malloc (nlm_fixed_header_size (abfd));
  if (fixed_header == NULL)
    goto error_return;

  if (! abfd->output_has_begun
      && ! nlm_compute_section_file_positions (abfd))
    goto error_return;

  /* Write out the variable length headers.  */
  pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
    goto error_return;
  if (! nlm_swap_variable_header_out (abfd)
      || ! nlm_swap_auxiliary_headers_out (abfd))
    {
      bfd_set_error (bfd_error_system_call);
      goto error_return;
    }

  /* A weak check on whether the section file positions were
     reasonable.  */
  if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
    {
      bfd_set_error (bfd_error_invalid_operation);
      goto error_return;
    }

  /* Advance to the relocs.  */
  if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
		SEEK_SET) != 0)
    goto error_return;

  /* The format of the relocation entries is dependent upon the
     particular target.  We use an external routine to write the reloc
     out.  */
  write_import_func = nlm_write_import_func (abfd);

  /* Write out the internal relocation fixups.  While we're looping
     over the relocs, we also count the external relocs, which is
     needed when they are written out below.  */
  internal_reloc_count = 0;
  external_reloc_count = 0;
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
    {
      arelent **rel_ptr_ptr, **rel_end;

      if (sec->reloc_count == 0)
	continue;

      /* We can only represent relocs within a code or data
	 section.  We ignore them for a debugging section.  */
      if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
	continue;

      /* We need to know how to write out imports */
      if (write_import_func == NULL)
	{
	  bfd_set_error (bfd_error_invalid_operation);
	  goto error_return;
	}

      rel_ptr_ptr = sec->orelocation;
      rel_end = rel_ptr_ptr + sec->reloc_count;
      for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
	{
	  arelent *rel;
	  asymbol *sym;

	  rel = *rel_ptr_ptr;
	  sym = *rel->sym_ptr_ptr;

	  if (! bfd_is_und_section (bfd_get_section (sym)))
	    {
	      ++internal_reloc_count;
	      if (! (*write_import_func) (abfd, sec, rel))
		goto error_return;
	    }
	  else
	    ++external_reloc_count;
	}
    }
  nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;

  /* Write out the imports (relocs against external symbols).  These
     are output as a symbol name followed by all the relocs for that
     symbol, so we must first gather together all the relocs against
     external symbols and sort them.  */
  amt = external_reloc_count * sizeof (struct reloc_and_sec);
  external_relocs = bfd_alloc (abfd, amt);
  if (external_relocs == NULL)
    goto error_return;
  i = 0;
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
    {
      arelent **rel_ptr_ptr, **rel_end;

      if (sec->reloc_count == 0)
	continue;

      rel_ptr_ptr = sec->orelocation;
      rel_end = rel_ptr_ptr + sec->reloc_count;
      for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
	{
	  arelent *rel;
	  asymbol *sym;

	  rel = *rel_ptr_ptr;
	  sym = *rel->sym_ptr_ptr;

	  if (! bfd_is_und_section (bfd_get_section (sym)))
	    continue;

	  external_relocs[i].rel = rel;
	  external_relocs[i].sec = sec;
	  ++i;
	}
    }

  BFD_ASSERT (i == external_reloc_count);

  /* Sort the external relocs by name.  */
  qsort (external_relocs, (size_t) external_reloc_count,
	 sizeof (struct reloc_and_sec), nlm_external_reloc_compare);

  /* Write out the external relocs.  */
  nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
  c = 0;
  i = 0;
  while (i < external_reloc_count)
    {
      arelent *rel;
      asymbol *sym;
      bfd_size_type j, cnt;

      ++c;

      rel = external_relocs[i].rel;
      sym = *rel->sym_ptr_ptr;

      cnt = 0;
      for (j = i;
	   (j < external_reloc_count
	    && *external_relocs[j].rel->sym_ptr_ptr == sym);
	   j++)
	++cnt;

      if (! (*nlm_write_external_func (abfd)) (abfd, cnt, sym,
					       &external_relocs[i]))
	goto error_return;

      i += cnt;
    }

  nlm_fixed_header (abfd)->numberOfExternalReferences = c;

  /* Write out the public symbols (exports).  */
  sym_ptr_ptr = bfd_get_outsymbols (abfd);
  if (sym_ptr_ptr != NULL)
    {
      bfd_vma (*get_public_offset_func) (bfd *, asymbol *);
      bfd_boolean (*write_export_func) (bfd *, asymbol *, bfd_vma);

      asymbol **sym_end;

      nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
      get_public_offset_func = nlm_get_public_offset_func (abfd);
      write_export_func = nlm_write_export_func (abfd);
      c = 0;
      sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
      for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
	{
	  asymbol *sym;
	  bfd_byte len;
	  bfd_vma offset;
	  bfd_byte temp[NLM_TARGET_LONG_SIZE];

	  sym = *sym_ptr_ptr;

	  if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
	      || bfd_is_und_section (bfd_get_section (sym)))
	    continue;

	  ++c;

	  if (get_public_offset_func)
	    {
	      /* Most backends can use the code below, but
		 unfortunately some use a different scheme.  */
	      offset = (*get_public_offset_func) (abfd, sym);
	    }
	  else
	    {
	      offset = bfd_asymbol_value (sym);
	      sec = sym->section;
	      if (sec->flags & SEC_CODE)
		{
		  offset -= nlm_get_text_low (abfd);
		  offset |= NLM_HIBIT;
		}
	      else if (sec->flags & (SEC_DATA | SEC_ALLOC))
		{
		  /* SEC_ALLOC is for the .bss section.  */
		  offset -= nlm_get_data_low (abfd);
		}
	      else
		{
		  /* We can't handle an exported symbol that is not in
		     the code or data segment.  */
		  bfd_set_error (bfd_error_invalid_operation);
		  goto error_return;
		}
	    }

	  if (write_export_func)
	    {
	      if (! (*write_export_func) (abfd, sym, offset))
		goto error_return;
	    }
	  else
	    {
	      len = strlen (sym->name);
	      if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
		   != sizeof (bfd_byte))
		  || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
		goto error_return;

	      put_word (abfd, offset, temp);
	      if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
		  != sizeof (temp))
		goto error_return;
	    }
	}
      nlm_fixed_header (abfd)->numberOfPublics = c;

      /* Write out the debugging records.  The NLM conversion program
	 wants to be able to inhibit this, so as a special hack if
	 debugInfoOffset is set to -1 we don't write any debugging
	 information.  This can not be handled by fiddling with the
	 symbol table, because exported symbols appear in both the
	 exported symbol list and the debugging information.  */
      if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
	{
	  nlm_fixed_header (abfd)->debugInfoOffset = 0;
	  nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
	}
      else
	{
	  nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
	  c = 0;
	  sym_ptr_ptr = bfd_get_outsymbols (abfd);
	  sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
	  for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
	    {
	      asymbol *sym;
	      bfd_byte type, len;
	      bfd_vma offset;
	      bfd_byte temp[NLM_TARGET_LONG_SIZE];

	      sym = *sym_ptr_ptr;

	      /* The NLM notion of a debugging symbol is actually what
		 BFD calls a local or global symbol.  What BFD calls a
		 debugging symbol NLM does not understand at all.  */
	      if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
		  || (sym->flags & BSF_DEBUGGING) != 0
		  || bfd_is_und_section (bfd_get_section (sym)))
		continue;

	      ++c;

	      offset = bfd_asymbol_value (sym);
	      sec = sym->section;
	      if (sec->flags & SEC_CODE)
		{
		  offset -= nlm_get_text_low (abfd);
		  type = 1;
		}
	      else if (sec->flags & (SEC_DATA | SEC_ALLOC))
		{
		  /* SEC_ALLOC is for the .bss section.  */
		  offset -= nlm_get_data_low (abfd);
		  type = 0;
		}
	      else
		type = 2;

	      /* The type is 0 for data, 1 for code, 2 for absolute.  */
	      if (bfd_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
		  != sizeof (bfd_byte))
		goto error_return;

	      put_word (abfd, offset, temp);
	      if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
		  != sizeof (temp))
		goto error_return;

	      len = strlen (sym->name);
	      if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
		   != sizeof (bfd_byte))
		  || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
		goto error_return;
	    }
	  nlm_fixed_header (abfd)->numberOfDebugRecords = c;
	}
    }

  /* NLMLINK fills in offset values even if there is no data, so we do
     the same.  */
  last = bfd_tell (abfd);
  if (nlm_fixed_header (abfd)->codeImageOffset == 0)
    nlm_fixed_header (abfd)->codeImageOffset = last;
  if (nlm_fixed_header (abfd)->dataImageOffset == 0)
    nlm_fixed_header (abfd)->dataImageOffset = last;
  if (nlm_fixed_header (abfd)->customDataOffset == 0)
    nlm_fixed_header (abfd)->customDataOffset = last;
  if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
    nlm_fixed_header (abfd)->moduleDependencyOffset = last;
  if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
    nlm_fixed_header (abfd)->relocationFixupOffset = last;
  if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
    nlm_fixed_header (abfd)->externalReferencesOffset = last;
  if (nlm_fixed_header (abfd)->publicsOffset == 0)
    nlm_fixed_header (abfd)->publicsOffset = last;
  if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
    nlm_fixed_header (abfd)->debugInfoOffset = last;

  /* At this point everything has been written out except the fixed
     header.  */
  memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
	  NLM_SIGNATURE_SIZE);
  nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
  nlm_fixed_header (abfd)->codeStartOffset =
    (bfd_get_start_address (abfd)
     - nlm_get_text_low (abfd));

  /* We have no convenient way for the caller to pass in the exit
     procedure or the check unload procedure, so the caller must set
     the values in the header to the values of the symbols.  */
  nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
  if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
    nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
      nlm_get_text_low (abfd);

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto error_return;

  write_prefix_func = nlm_write_prefix_func (abfd);
  if (write_prefix_func)
    {
      if (! (*write_prefix_func) (abfd))
	goto error_return;
    }

  BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
	      == nlm_optional_prefix_size (abfd));

  nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
  if (bfd_bwrite (fixed_header, nlm_fixed_header_size (abfd), abfd)
      != nlm_fixed_header_size (abfd))
    goto error_return;

  if (fixed_header != NULL)
    free (fixed_header);
  return TRUE;

error_return:
  if (fixed_header != NULL)
    free (fixed_header);
  return FALSE;
}
