/* simple-object-coff.c -- routines to manipulate COFF object files.
   Copyright 2010 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Google.

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 2, 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, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.  */

#include "config.h"
#include "libiberty.h"
#include "simple-object.h"

#include <errno.h>
#include <stddef.h>

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif

#include "simple-object-common.h"

/* COFF structures and constants.  */

/* COFF file header.  */

struct external_filehdr
{
  unsigned char f_magic[2];	/* magic number			*/
  unsigned char f_nscns[2];	/* number of sections		*/
  unsigned char f_timdat[4];	/* time & date stamp		*/
  unsigned char f_symptr[4];	/* file pointer to symtab	*/
  unsigned char f_nsyms[4];	/* number of symtab entries	*/
  unsigned char f_opthdr[2];	/* sizeof(optional hdr)		*/
  unsigned char f_flags[2];	/* flags			*/
};

/* Bits for filehdr f_flags field.  */

#define F_EXEC			(0x0002)
#define IMAGE_FILE_SYSTEM	(0x1000)
#define IMAGE_FILE_DLL		(0x2000)

/* COFF section header.  */

struct external_scnhdr
{
  unsigned char s_name[8];	/* section name				*/
  unsigned char s_paddr[4];	/* physical address, aliased s_nlib 	*/
  unsigned char s_vaddr[4];	/* virtual address			*/
  unsigned char s_size[4];	/* section size				*/
  unsigned char s_scnptr[4];	/* file ptr to raw data for section 	*/
  unsigned char s_relptr[4];	/* file ptr to relocation		*/
  unsigned char s_lnnoptr[4];	/* file ptr to line numbers		*/
  unsigned char s_nreloc[2];	/* number of relocation entries		*/
  unsigned char s_nlnno[2];	/* number of line number entries	*/
  unsigned char s_flags[4];	/* flags				*/
};

/* The length of the s_name field in struct external_scnhdr.  */

#define SCNNMLEN (8)

/* Bits for scnhdr s_flags field.  This includes some bits defined
   only for PE.  This may need to be moved into coff_magic.  */

#define STYP_DATA			(1 << 6)
#define IMAGE_SCN_MEM_DISCARDABLE	(1 << 25)
#define IMAGE_SCN_MEM_SHARED		(1 << 28)
#define IMAGE_SCN_MEM_READ		(1 << 30)

#define IMAGE_SCN_ALIGN_POWER_BIT_POS	     20
#define IMAGE_SCN_ALIGN_POWER_CONST(val)     \
  (((val) + 1) << IMAGE_SCN_ALIGN_POWER_BIT_POS)

/* COFF symbol table entry.  */

#define E_SYMNMLEN	8	/* # characters in a symbol name	*/

struct external_syment
{
  union
  {
    unsigned char e_name[E_SYMNMLEN];

    struct
    {
      unsigned char e_zeroes[4];
      unsigned char e_offset[4];
    } e;
  } e;

  unsigned char e_value[4];
  unsigned char e_scnum[2];
  unsigned char e_type[2];
  unsigned char e_sclass[1];
  unsigned char e_numaux[1];
};

/* Length allowed for filename in aux sym format 4.  */

#define E_FILNMLEN	18

/* Omits x_sym and other unused variants.  */

union external_auxent
{
  /* Aux sym format 4: file.  */
  union
  {
    char x_fname[E_FILNMLEN];
    struct
    {
      unsigned char x_zeroes[4];
      unsigned char x_offset[4];
    } x_n;
  } x_file;
  /* Aux sym format 5: section.  */
  struct
  {
    unsigned char x_scnlen[4];		/* section length		*/
    unsigned char x_nreloc[2];		/* # relocation entries		*/
    unsigned char x_nlinno[2];		/* # line numbers		*/
    unsigned char x_checksum[4];	/* section COMDAT checksum	*/
    unsigned char x_associated[2];	/* COMDAT assoc section index	*/
    unsigned char x_comdat[1];		/* COMDAT selection number	*/
  } x_scn;
};

/* Symbol-related constants.  */

#define IMAGE_SYM_DEBUG		(-2)
#define IMAGE_SYM_TYPE_NULL	(0)
#define IMAGE_SYM_DTYPE_NULL	(0)
#define IMAGE_SYM_CLASS_STATIC	(3)
#define IMAGE_SYM_CLASS_FILE	(103)

#define IMAGE_SYM_TYPE \
  ((IMAGE_SYM_DTYPE_NULL << 4) | IMAGE_SYM_TYPE_NULL)

/* Private data for an simple_object_read.  */

struct simple_object_coff_read
{
  /* Magic number.  */
  unsigned short magic;
  /* Whether the file is big-endian.  */
  unsigned char is_big_endian;
  /* Number of sections.  */
  unsigned short nscns;
  /* File offset of symbol table.  */
  off_t symptr;
  /* Number of symbol table entries.  */
  unsigned int nsyms;
  /* Flags.  */
  unsigned short flags;
  /* Offset of section headers in file.  */
  off_t scnhdr_offset;
};

/* Private data for an simple_object_attributes.  */

struct simple_object_coff_attributes
{
  /* Magic number.  */
  unsigned short magic;
  /* Whether the file is big-endian.  */
  unsigned char is_big_endian;
  /* Flags.  */
  unsigned short flags;
};

/* There is no magic number which indicates a COFF file as opposed to
   any other sort of file.  Instead, each COFF file starts with a
   two-byte magic number which also indicates the type of the target.
   This struct holds a magic number as well as characteristics of that
   COFF format.  */

struct coff_magic_struct
{
  /* Magic number.  */
  unsigned short magic;
  /* Whether this magic number is for a big-endian file.  */
  unsigned char is_big_endian;
  /* Flag bits, in the f_flags fields, which indicates that this file
     is not a relocatable object file.  There is no flag which
     specifically indicates a relocatable object file, it is only
     implied by the absence of these flags.  */
  unsigned short non_object_flags;
};

/* This is a list of the COFF magic numbers which we recognize, namely
   the ones used on Windows.  More can be added as needed.  */

static const struct coff_magic_struct coff_magic[] =
{
  /* i386.  */
  { 0x14c, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL },
  /* x86_64.  */
  { 0x8664, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL }
};

/* See if we have a COFF file.  */

static void *
simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
			  int descriptor, off_t offset,
			  const char *segment_name ATTRIBUTE_UNUSED,
			  const char **errmsg, int *err)
{
  size_t c;
  unsigned short magic_big;
  unsigned short magic_little;
  unsigned short magic;
  size_t i;
  int is_big_endian;
  unsigned short (*fetch_16) (const unsigned char *);
  unsigned int (*fetch_32) (const unsigned char *);
  unsigned char hdrbuf[sizeof (struct external_filehdr)];
  unsigned short flags;
  struct simple_object_coff_read *ocr;

  c = sizeof (coff_magic) / sizeof (coff_magic[0]);
  magic_big = simple_object_fetch_big_16 (header);
  magic_little = simple_object_fetch_little_16 (header);
  for (i = 0; i < c; ++i)
    {
      if (coff_magic[i].is_big_endian
	  ? coff_magic[i].magic == magic_big
	  : coff_magic[i].magic == magic_little)
	break;
    }
  if (i >= c)
    {
      *errmsg = NULL;
      *err = 0;
      return NULL;
    }
  is_big_endian = coff_magic[i].is_big_endian;

  magic = is_big_endian ? magic_big : magic_little;
  fetch_16 = (is_big_endian
	      ? simple_object_fetch_big_16
	      : simple_object_fetch_little_16);
  fetch_32 = (is_big_endian
	      ? simple_object_fetch_big_32
	      : simple_object_fetch_little_32);

  if (!simple_object_internal_read (descriptor, offset, hdrbuf, sizeof hdrbuf,
				    errmsg, err))
    return NULL;

  flags = fetch_16 (hdrbuf + offsetof (struct external_filehdr, f_flags));
  if ((flags & coff_magic[i].non_object_flags) != 0)
    {
      *errmsg = "not relocatable object file";
      *err = 0;
      return NULL;
    }

  ocr = XNEW (struct simple_object_coff_read);
  ocr->magic = magic;
  ocr->is_big_endian = is_big_endian;
  ocr->nscns = fetch_16 (hdrbuf + offsetof (struct external_filehdr, f_nscns));
  ocr->symptr = fetch_32 (hdrbuf
			  + offsetof (struct external_filehdr, f_symptr));
  ocr->nsyms = fetch_32 (hdrbuf + offsetof (struct external_filehdr, f_nsyms));
  ocr->flags = flags;
  ocr->scnhdr_offset = (sizeof (struct external_filehdr)
			+ fetch_16 (hdrbuf + offsetof (struct external_filehdr,
						       f_opthdr)));

  return (void *) ocr;
}

/* Read the string table in a COFF file.  */

static char *
simple_object_coff_read_strtab (simple_object_read *sobj, size_t *strtab_size,
				const char **errmsg, int *err)
{
  struct simple_object_coff_read *ocr =
    (struct simple_object_coff_read *) sobj->data;
  off_t strtab_offset;
  unsigned char strsizebuf[4];
  size_t strsize;
  char *strtab;

  strtab_offset = ocr->symptr + ocr->nsyms * sizeof (struct external_syment);
  if (!simple_object_internal_read (sobj->descriptor, strtab_offset,
				    strsizebuf, 4, errmsg, err))
    return NULL;
  strsize = (ocr->is_big_endian
	     ? simple_object_fetch_big_32 (strsizebuf)
	     : simple_object_fetch_little_32 (strsizebuf));
  strtab = XNEWVEC (char, strsize);
  if (!simple_object_internal_read (sobj->descriptor, strtab_offset,
				    (unsigned char *) strtab, strsize, errmsg,
				    err))
    {
      XDELETEVEC (strtab);
      return NULL;
    }
  *strtab_size = strsize;
  return strtab;
}

/* Find all sections in a COFF file.  */

static const char *
simple_object_coff_find_sections (simple_object_read *sobj,
				  int (*pfn) (void *, const char *,
					      off_t offset, off_t length),
				  void *data,
				  int *err)
{
  struct simple_object_coff_read *ocr =
    (struct simple_object_coff_read *) sobj->data;
  size_t scnhdr_size;
  unsigned char *scnbuf;
  const char *errmsg;
  unsigned int (*fetch_32) (const unsigned char *);
  unsigned int nscns;
  char *strtab;
  size_t strtab_size;
  unsigned int i;

  scnhdr_size = sizeof (struct external_scnhdr);
  scnbuf = XNEWVEC (unsigned char, scnhdr_size * ocr->nscns);
  if (!simple_object_internal_read (sobj->descriptor,
				    sobj->offset + ocr->scnhdr_offset,
				    scnbuf, scnhdr_size * ocr->nscns, &errmsg,
				    err))
    {
      XDELETEVEC (scnbuf);
      return errmsg;
    }

  fetch_32 = (ocr->is_big_endian
	      ? simple_object_fetch_big_32
	      : simple_object_fetch_little_32);

  nscns = ocr->nscns;
  strtab = NULL;
  strtab_size = 0;
  for (i = 0; i < nscns; ++i)
    {
      unsigned char *scnhdr;
      unsigned char *scnname;
      char namebuf[SCNNMLEN + 1];
      char *name;
      off_t scnptr;
      unsigned int size;

      scnhdr = scnbuf + i * scnhdr_size;
      scnname = scnhdr + offsetof (struct external_scnhdr, s_name);
      memcpy (namebuf, scnname, SCNNMLEN);
      namebuf[SCNNMLEN] = '\0';
      name = &namebuf[0];
      if (namebuf[0] == '/')
	{
	  size_t strindex;
	  char *end;

	  strindex = strtol (namebuf + 1, &end, 10);
	  if (*end == '\0')
	    {
	      /* The real section name is found in the string
		 table.  */
	      if (strtab == NULL)
		{
		  strtab = simple_object_coff_read_strtab (sobj,
							   &strtab_size,
							   &errmsg, err);
		  if (strtab == NULL)
		    {
		      XDELETEVEC (scnbuf);
		      return errmsg;
		    }
		}

	      if (strindex < 4 || strindex >= strtab_size)
		{
		  XDELETEVEC (strtab);
		  XDELETEVEC (scnbuf);
		  *err = 0;
		  return "section string index out of range";
		}

	      name = strtab + strindex;
	    }
	}

      scnptr = fetch_32 (scnhdr + offsetof (struct external_scnhdr, s_scnptr));
      size = fetch_32 (scnhdr + offsetof (struct external_scnhdr, s_size));

      if (!(*pfn) (data, name, scnptr, size))
	break;
    }

  if (strtab != NULL)
    XDELETEVEC (strtab);
  XDELETEVEC (scnbuf);

  return NULL;
}

/* Fetch the attributes for an simple_object_read.  */

static void *
simple_object_coff_fetch_attributes (simple_object_read *sobj,
				     const char **errmsg ATTRIBUTE_UNUSED,
				     int *err ATTRIBUTE_UNUSED)
{
  struct simple_object_coff_read *ocr =
    (struct simple_object_coff_read *) sobj->data;
  struct simple_object_coff_attributes *ret;

  ret = XNEW (struct simple_object_coff_attributes);
  ret->magic = ocr->magic;
  ret->is_big_endian = ocr->is_big_endian;
  ret->flags = ocr->flags;
  return ret;
}

/* Release the private data for an simple_object_read.  */

static void
simple_object_coff_release_read (void *data)
{
  XDELETE (data);
}

/* Compare two attributes structures.  */

static const char *
simple_object_coff_attributes_compare (void *data1, void *data2, int *err)
{
  struct simple_object_coff_attributes *attrs1 =
    (struct simple_object_coff_attributes *) data1;
  struct simple_object_coff_attributes *attrs2 =
    (struct simple_object_coff_attributes *) data2;

  if (attrs1->magic != attrs2->magic
      || attrs1->is_big_endian != attrs2->is_big_endian)
    {
      *err = 0;
      return "COFF object format mismatch";
    }
  return NULL;
}

/* Release the private data for an attributes structure.  */

static void
simple_object_coff_release_attributes (void *data)
{
  XDELETE (data);
}

/* Prepare to write out a file.  */

static void *
simple_object_coff_start_write (void *attributes_data,
				const char **errmsg ATTRIBUTE_UNUSED,
				int *err ATTRIBUTE_UNUSED)
{
  struct simple_object_coff_attributes *attrs =
    (struct simple_object_coff_attributes *) attributes_data;
  struct simple_object_coff_attributes *ret;

  /* We're just going to record the attributes, but we need to make a
     copy because the user may delete them.  */
  ret = XNEW (struct simple_object_coff_attributes);
  *ret = *attrs;
  return ret;
}

/* Write out a COFF filehdr.  */

static int
simple_object_coff_write_filehdr (simple_object_write *sobj, int descriptor,
				  unsigned int nscns, size_t symtab_offset,
				  unsigned int nsyms, const char **errmsg,
				  int *err)
{
  struct simple_object_coff_attributes *attrs =
    (struct simple_object_coff_attributes *) sobj->data;
  unsigned char hdrbuf[sizeof (struct external_filehdr)];
  unsigned char *hdr;
  void (*set_16) (unsigned char *, unsigned short);
  void (*set_32) (unsigned char *, unsigned int);

  hdr = &hdrbuf[0];

  set_16 = (attrs->is_big_endian
	    ? simple_object_set_big_16
	    : simple_object_set_little_16);
  set_32 = (attrs->is_big_endian
	    ? simple_object_set_big_32
	    : simple_object_set_little_32);

  memset (hdr, 0, sizeof (struct external_filehdr));

  set_16 (hdr + offsetof (struct external_filehdr, f_magic), attrs->magic);
  set_16 (hdr + offsetof (struct external_filehdr, f_nscns), nscns);
  /* f_timdat left as zero.  */
  set_32 (hdr + offsetof (struct external_filehdr, f_symptr), symtab_offset);
  set_32 (hdr + offsetof (struct external_filehdr, f_nsyms), nsyms);
  /* f_opthdr left as zero.  */
  set_16 (hdr + offsetof (struct external_filehdr, f_flags), attrs->flags);

  return simple_object_internal_write (descriptor, 0, hdrbuf,
				       sizeof (struct external_filehdr),
				       errmsg, err);
}

/* Write out a COFF section header.  */

static int
simple_object_coff_write_scnhdr (simple_object_write *sobj, int descriptor,
				 const char *name, size_t *name_offset,
				 off_t scnhdr_offset, size_t scnsize,
				 off_t offset, unsigned int align,
				 const char **errmsg, int *err)
{
  struct simple_object_coff_attributes *attrs =
    (struct simple_object_coff_attributes *) sobj->data;
  void (*set_32) (unsigned char *, unsigned int);
  unsigned char hdrbuf[sizeof (struct external_scnhdr)];
  unsigned char *hdr;
  size_t namelen;
  unsigned int flags;

  set_32 = (attrs->is_big_endian
	    ? simple_object_set_big_32
	    : simple_object_set_little_32);

  memset (hdrbuf, 0, sizeof hdrbuf);
  hdr = &hdrbuf[0];

  namelen = strlen (name);
  if (namelen <= SCNNMLEN)
    strncpy ((char *) hdr + offsetof (struct external_scnhdr, s_name), name,
	     SCNNMLEN);
  else
    {
      snprintf ((char *) hdr + offsetof (struct external_scnhdr, s_name),
		SCNNMLEN, "/%lu", (unsigned long) *name_offset);
      *name_offset += namelen + 1;
    }

  /* s_paddr left as zero.  */
  /* s_vaddr left as zero.  */
  set_32 (hdr + offsetof (struct external_scnhdr, s_size), scnsize);
  set_32 (hdr + offsetof (struct external_scnhdr, s_scnptr), offset);
  /* s_relptr left as zero.  */
  /* s_lnnoptr left as zero.  */
  /* s_nreloc left as zero.  */
  /* s_nlnno left as zero.  */
  flags = (STYP_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_SHARED
	   | IMAGE_SCN_MEM_READ);
  /* PE can represent alignment up to 13.  */
  if (align > 13)
    align = 13;
  flags |= IMAGE_SCN_ALIGN_POWER_CONST(align);
  set_32 (hdr + offsetof (struct external_scnhdr, s_flags), flags);

  return simple_object_internal_write (descriptor, scnhdr_offset, hdrbuf,
				       sizeof (struct external_scnhdr),
				       errmsg, err);
}

/* Write out a complete COFF file.  */

static const char *
simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
				  int *err)
{
  struct simple_object_coff_attributes *attrs =
    (struct simple_object_coff_attributes *) sobj->data;
  unsigned int nscns, secnum;
  simple_object_write_section *section;
  off_t scnhdr_offset;
  size_t symtab_offset;
  off_t secsym_offset;
  unsigned int nsyms;
  size_t offset;
  size_t name_offset;
  const char *errmsg;
  unsigned char strsizebuf[4];
  /* The interface doesn't give us access to the name of the input file
     yet.  We want to use its basename for the FILE symbol.  This is
     what 'gas' uses when told to assemble from stdin.  */
  const char *source_filename = "fake";
  size_t sflen;
  union
  {
    struct external_syment sym;
    union external_auxent aux;
  } syms[2];
  void (*set_16) (unsigned char *, unsigned short);
  void (*set_32) (unsigned char *, unsigned int);

  set_16 = (attrs->is_big_endian
	    ? simple_object_set_big_16
	    : simple_object_set_little_16);
  set_32 = (attrs->is_big_endian
	    ? simple_object_set_big_32
	    : simple_object_set_little_32);

  nscns = 0;
  for (section = sobj->sections; section != NULL; section = section->next)
    ++nscns;

  scnhdr_offset = sizeof (struct external_filehdr);
  offset = scnhdr_offset + nscns * sizeof (struct external_scnhdr);
  name_offset = 4;
  for (section = sobj->sections; section != NULL; section = section->next)
    {
      size_t mask;
      size_t new_offset;
      size_t scnsize;
      struct simple_object_write_section_buffer *buffer;

      mask = (1U << section->align) - 1;
      new_offset = offset & mask;
      new_offset &= ~ mask;
      while (new_offset > offset)
	{
	  unsigned char zeroes[16];
	  size_t write;

	  memset (zeroes, 0, sizeof zeroes);
	  write = new_offset - offset;
	  if (write > sizeof zeroes)
	    write = sizeof zeroes;
	  if (!simple_object_internal_write (descriptor, offset, zeroes, write,
					     &errmsg, err))
	    return errmsg;
	}

      scnsize = 0;
      for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
	{
	  if (!simple_object_internal_write (descriptor, offset + scnsize,
					     ((const unsigned char *)
					      buffer->buffer),
					     buffer->size, &errmsg, err))
	    return errmsg;
	  scnsize += buffer->size;
	}

      if (!simple_object_coff_write_scnhdr (sobj, descriptor, section->name,
					    &name_offset, scnhdr_offset,
					    scnsize, offset, section->align,
					    &errmsg, err))
	return errmsg;

      scnhdr_offset += sizeof (struct external_scnhdr);
      offset += scnsize;
    }

  /* Symbol table is always half-word aligned.  */
  offset += (offset & 1);
  /* There is a file symbol and a section symbol per section,
     and each of these has a single auxiliary symbol following.  */
  nsyms = 2 * (nscns + 1);
  symtab_offset = offset;
  /* Advance across space reserved for symbol table to locate
     start of string table.  */
  offset += nsyms * sizeof (struct external_syment);

  /* Write out file symbol.  */
  memset (&syms[0], 0, sizeof (syms));
  strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
  set_16 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
  set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
  syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
  syms[0].sym.e_numaux[0] = 1;
  /* The name need not be nul-terminated if it fits into the x_fname field
     directly, but must be if it has to be placed into the string table.  */
  sflen = strlen (source_filename);
  if (sflen <= E_FILNMLEN)
    memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
  else
    {
      set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
      if (!simple_object_internal_write (descriptor, offset + name_offset,
					 ((const unsigned char *)
					  source_filename),
					 sflen + 1, &errmsg, err))
	return errmsg;
      name_offset += strlen (source_filename) + 1;
    }
  if (!simple_object_internal_write (descriptor, symtab_offset,
				     (const unsigned char *) &syms[0],
				     sizeof (syms), &errmsg, err))
    return errmsg;

  /* Write the string table length, followed by the strings and section
     symbols in step with each other.  */
  set_32 (strsizebuf, name_offset);
  if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
				     &errmsg, err))
    return errmsg;

  name_offset = 4;
  secsym_offset = symtab_offset + sizeof (syms);
  memset (&syms[0], 0, sizeof (syms));
  set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
  syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
  syms[0].sym.e_numaux[0] = 1;
  secnum = 1;

  for (section = sobj->sections; section != NULL; section = section->next)
    {
      size_t namelen;
      size_t scnsize;
      struct simple_object_write_section_buffer *buffer;

      namelen = strlen (section->name);
      set_16 (&syms[0].sym.e_scnum[0], secnum++);
      scnsize = 0;
      for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
	scnsize += buffer->size;
      set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
      if (namelen > SCNNMLEN)
	{
	  set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
	  set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
	  if (!simple_object_internal_write (descriptor, offset + name_offset,
					     ((const unsigned char *)
					      section->name),
					     namelen + 1, &errmsg, err))
	    return errmsg;
	  name_offset += namelen + 1;
	}
      else
	{
	  memcpy (&syms[0].sym.e.e_name[0], section->name,
		  strlen (section->name));
	  memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
		  E_SYMNMLEN - strlen (section->name));
	}

      if (!simple_object_internal_write (descriptor, secsym_offset,
					 (const unsigned char *) &syms[0],
					 sizeof (syms), &errmsg, err))
	return errmsg;
      secsym_offset += sizeof (syms);
    }

  if (!simple_object_coff_write_filehdr (sobj, descriptor, nscns,
					 symtab_offset, nsyms, &errmsg, err))
    return errmsg;

  return NULL;
}

/* Release the private data for an simple_object_write structure.  */

static void
simple_object_coff_release_write (void *data)
{
  XDELETE (data);
}

/* The COFF functions.  */

const struct simple_object_functions simple_object_coff_functions =
{
  simple_object_coff_match,
  simple_object_coff_find_sections,
  simple_object_coff_fetch_attributes,
  simple_object_coff_release_read,
  simple_object_coff_attributes_compare,
  simple_object_coff_release_attributes,
  simple_object_coff_start_write,
  simple_object_coff_write_to_file,
  simple_object_coff_release_write
};
