/* simple-object-coff.c -- routines to manipulate COFF object files.
   Copyright (C) 2010-2022 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 = sobj->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_merge (void *todata, void *fromdata, int *err)
{
  struct simple_object_coff_attributes *to =
    (struct simple_object_coff_attributes *) todata;
  struct simple_object_coff_attributes *from =
    (struct simple_object_coff_attributes *) fromdata;

  if (to->magic != from->magic || to->is_big_endian != from->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_merge,
  simple_object_coff_release_attributes,
  simple_object_coff_start_write,
  simple_object_coff_write_to_file,
  simple_object_coff_release_write,
  NULL
};
