/* rescoff.c -- read and write resources in Windows COFF files.
   Copyright (C) 1997-2021 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Cygnus Support.
   Rewritten by Kai Tietz, Onevision.

   This file is part of GNU Binutils.

   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.  */

/* This file contains function that read and write Windows resources
   in COFF files.  */

#include "sysdep.h"
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "windres.h"

#include <assert.h>

/* In order to use the address of a resource data entry, we need to
   get the image base of the file.  Right now we extract it from
   internal BFD information.  FIXME.  */

#include "coff/internal.h"
#include "libcoff.h"

/* Information we extract from the file.  */

struct coff_file_info
{
  /* File name.  */
  const char *filename;
  /* Data read from the file.  */
  const bfd_byte *data;
  /* End of data read from file.  */
  const bfd_byte *data_end;
  /* Address of the resource section minus the image base of the file.  */
  rc_uint_type secaddr;
};

/* A resource directory table in a COFF file.  */

struct __attribute__ ((__packed__)) extern_res_directory
{
  /* Characteristics.  */
  bfd_byte characteristics[4];
  /* Time stamp.  */
  bfd_byte time[4];
  /* Major version number.  */
  bfd_byte major[2];
  /* Minor version number.  */
  bfd_byte minor[2];
  /* Number of named directory entries.  */
  bfd_byte name_count[2];
  /* Number of directory entries with IDs.  */
  bfd_byte id_count[2];
};

/* A resource directory entry in a COFF file.  */

struct extern_res_entry
{
  /* Name or ID.  */
  bfd_byte name[4];
  /* Address of resource entry or subdirectory.  */
  bfd_byte rva[4];
};

/* A resource data entry in a COFF file.  */

struct extern_res_data
{
  /* Address of resource data.  This is apparently a file relative
     address, rather than a section offset.  */
  bfd_byte rva[4];
  /* Size of resource data.  */
  bfd_byte size[4];
  /* Code page.  */
  bfd_byte codepage[4];
  /* Reserved.  */
  bfd_byte reserved[4];
};

/* Local functions.  */

static void overrun (const struct coff_file_info *, const char *);
static rc_res_directory *read_coff_res_dir (windres_bfd *, const bfd_byte *,
					    const struct coff_file_info *,
					    const rc_res_id *, int);
static rc_res_resource *read_coff_data_entry (windres_bfd *, const bfd_byte *,
					      const struct coff_file_info *,
					      const rc_res_id *);

/* Read the resources in a COFF file.  */

rc_res_directory *
read_coff_rsrc (const char *filename, const char *target)
{
  rc_res_directory *ret;
  bfd *abfd;
  windres_bfd wrbfd;
  char **matching;
  asection *sec;
  bfd_size_type size;
  bfd_byte *data;
  struct coff_file_info flaginfo;

  if (filename == NULL)
    fatal (_("filename required for COFF input"));

  abfd = bfd_openr (filename, target);
  if (abfd == NULL)
    bfd_fatal (filename);

  if (! bfd_check_format_matches (abfd, bfd_object, &matching))
    {
      bfd_nonfatal (bfd_get_filename (abfd));
      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
	list_matching_formats (matching);
      xexit (1);
    }

  sec = bfd_get_section_by_name (abfd, ".rsrc");
  if (sec == NULL)
    {
      fatal (_("%s: no resource section"), filename);
    }

  set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);
  size = bfd_section_size (sec);
  /* PR 17512: file: 1b25ba5d
     The call to get_file_size here may be expensive
     but there is no other way to determine if the section size
     is reasonable.  */
  if (size > (bfd_size_type) get_file_size (filename))
    fatal (_("%s: .rsrc section is bigger than the file!"), filename);

  data = (bfd_byte *) res_alloc (size);
  get_windres_bfd_content (&wrbfd, data, 0, size);

  flaginfo.filename = filename;
  flaginfo.data = data;
  flaginfo.data_end = data + size;
  flaginfo.secaddr = (bfd_section_vma (sec)
		      - pe_data (abfd)->pe_opthdr.ImageBase);

  /* Now just read in the top level resource directory.  Note that we
     don't free data, since we create resource entries that point into
     it.  If we ever want to free up the resource information we read,
     this will have to be cleaned up.  */

  ret = read_coff_res_dir (&wrbfd, data, &flaginfo, (const rc_res_id *) NULL, 0);

  bfd_close (abfd);

  return ret;
}

/* Give an error if we are out of bounds.  */

static void
overrun (const struct coff_file_info *flaginfo, const char *msg)
{
  fatal (_("%s: %s: address out of bounds"), flaginfo->filename, msg);
}

/* Read a resource directory.  */

static rc_res_directory *
read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
		   const struct coff_file_info *flaginfo,
		   const rc_res_id *type, int level)
{
  const struct extern_res_directory *erd;
  rc_res_directory *rd;
  int name_count, id_count, i;
  rc_res_entry **pp;
  const struct extern_res_entry *ere;

  /* PR 17512: file: 09d80f53.
     Whilst in theory resources can nest to any level, in practice
     Microsoft only defines 3 levels.  Corrupt files however might
     claim to use more.  */
  if (level > 4)
    overrun (flaginfo, _("Resources nest too deep"));

  if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_directory))
    overrun (flaginfo, _("directory"));

  erd = (const struct extern_res_directory *) data;

  rd = (rc_res_directory *) res_alloc (sizeof (rc_res_directory));
  rd->characteristics = windres_get_32 (wrbfd, erd->characteristics, 4);
  rd->time = windres_get_32 (wrbfd, erd->time, 4);
  rd->major = windres_get_16 (wrbfd, erd->major, 2);
  rd->minor = windres_get_16 (wrbfd, erd->minor, 2);
  rd->entries = NULL;

  name_count = windres_get_16 (wrbfd, erd->name_count, 2);
  id_count = windres_get_16 (wrbfd, erd->id_count, 2);

  pp = &rd->entries;

  /* The resource directory entries immediately follow the directory
     table.  */
  ere = (const struct extern_res_entry *) (erd + 1);

  for (i = 0; i < name_count; i++, ere++)
    {
      rc_uint_type name, rva;
      rc_res_entry *re;
      const bfd_byte *ers;
      int length, j;

      if ((const bfd_byte *) ere >= flaginfo->data_end)
	overrun (flaginfo, _("named directory entry"));

      name = windres_get_32 (wrbfd, ere->name, 4);
      rva = windres_get_32 (wrbfd, ere->rva, 4);

      /* For some reason the high bit in NAME is set.  */
      name &=~ 0x80000000;

      if (name > (rc_uint_type) (flaginfo->data_end - flaginfo->data))
	overrun (flaginfo, _("directory entry name"));

      ers = flaginfo->data + name;

      re = (rc_res_entry *) res_alloc (sizeof *re);
      re->next = NULL;
      re->id.named = 1;
      length = windres_get_16 (wrbfd, ers, 2);
      re->id.u.n.length = length;
      re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar));
      for (j = 0; j < length; j++)
	{
	  /* PR 17512: file: 05dc4a16.  */
	  if (length < 0 || ers >= flaginfo->data_end || ers + j * 2 + 4 >= flaginfo->data_end)
	    overrun (flaginfo, _("resource name"));
	  re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
	}

      if (level == 0)
	type = &re->id;

      if ((rva & 0x80000000) != 0)
	{
	  rva &=~ 0x80000000;
	  if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
	    overrun (flaginfo, _("named subdirectory"));
	  re->subdir = 1;
	  re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
					 level + 1);
	}
      else
	{
	  if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
	    overrun (flaginfo, _("named resource"));
	  re->subdir = 0;
	  re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
	}

      *pp = re;
      pp = &re->next;
    }

  for (i = 0; i < id_count; i++, ere++)
    {
      unsigned long name, rva;
      rc_res_entry *re;

      if ((const bfd_byte *) ere >= flaginfo->data_end)
	overrun (flaginfo, _("ID directory entry"));

      name = windres_get_32 (wrbfd, ere->name, 4);
      rva = windres_get_32 (wrbfd, ere->rva, 4);

      re = (rc_res_entry *) res_alloc (sizeof *re);
      re->next = NULL;
      re->id.named = 0;
      re->id.u.id = name;

      if (level == 0)
	type = &re->id;

      if ((rva & 0x80000000) != 0)
	{
	  rva &=~ 0x80000000;
	  if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
	    overrun (flaginfo, _("ID subdirectory"));
	  re->subdir = 1;
	  re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
					 level + 1);
	}
      else
	{
	  if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
	    overrun (flaginfo, _("ID resource"));
	  re->subdir = 0;
	  re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
	}

      *pp = re;
      pp = &re->next;
    }

  return rd;
}

/* Read a resource data entry.  */

static rc_res_resource *
read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data,
		      const struct coff_file_info *flaginfo,
		      const rc_res_id *type)
{
  const struct extern_res_data *erd;
  rc_res_resource *r;
  rc_uint_type size, rva;
  const bfd_byte *resdata;

  if (type == NULL)
    fatal (_("resource type unknown"));

  if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_data))
    overrun (flaginfo, _("data entry"));

  erd = (const struct extern_res_data *) data;

  size = windres_get_32 (wrbfd, erd->size, 4);
  rva = windres_get_32 (wrbfd, erd->rva, 4);
  if (rva < flaginfo->secaddr
      || rva - flaginfo->secaddr >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
    overrun (flaginfo, _("resource data"));

  resdata = flaginfo->data + (rva - flaginfo->secaddr);

  if (size > (rc_uint_type) (flaginfo->data_end - resdata))
    overrun (flaginfo, _("resource data size"));

  r = bin_to_res (wrbfd, *type, resdata, size);

  memset (&r->res_info, 0, sizeof (rc_res_res_info));
  r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage, 4);
  r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved, 4);

  return r;
}

/* This structure is used to build a list of bindata structures.  */

struct bindata_build
{
  /* The data.  */
  bindata *d;
  /* The last structure we have added to the list.  */
  bindata *last;
  /* The size of the list as a whole.  */
  unsigned long length;
};

struct coff_res_data_build
{
  /* The data.  */
  coff_res_data *d;
  /* The last structure we have added to the list.  */
  coff_res_data *last;
  /* The size of the list as a whole.  */
  unsigned long length;
};

/* This structure keeps track of information as we build the directory
   tree.  */

struct coff_write_info
{
  /* These fields are based on the BFD.  */
  /* The BFD itself.  */
  windres_bfd *wrbfd;
  /* Pointer to section symbol used to build RVA relocs.  */
  asymbol **sympp;

  /* These fields are computed initially, and then not changed.  */
  /* Length of directory tables and entries.  */
  unsigned long dirsize;
  /* Length of directory entry strings.  */
  unsigned long dirstrsize;
  /* Length of resource data entries.  */
  unsigned long dataentsize;

  /* These fields are updated as we add data.  */
  /* Directory tables and entries.  */
  struct bindata_build dirs;
  /* Directory entry strings.  */
  struct bindata_build dirstrs;
  /* Resource data entries.  */
  struct bindata_build dataents;
  /* Actual resource data.  */
  struct coff_res_data_build resources;
  /* Relocations.  */
  arelent **relocs;
  /* Number of relocations.  */
  unsigned int reloc_count;
};

static void coff_bin_sizes (const rc_res_directory *, struct coff_write_info *);
static bfd_byte *coff_alloc (struct bindata_build *, rc_uint_type);
static void coff_to_bin
  (const rc_res_directory *, struct coff_write_info *);
static void coff_res_to_bin
  (const rc_res_resource *, struct coff_write_info *);

/* Write resources to a COFF file.  RESOURCES should already be
   sorted.

   Right now we always create a new file.  Someday we should also
   offer the ability to merge resources into an existing file.  This
   would require doing the basic work of objcopy, just modifying or
   adding the .rsrc section.  */

void
write_coff_file (const char *filename, const char *target,
		 const rc_res_directory *resources)
{
  bfd *abfd;
  asection *sec;
  struct coff_write_info cwi;
  windres_bfd wrbfd;
  bindata *d;
  coff_res_data *rd;
  unsigned long length, offset;

  if (filename == NULL)
    fatal (_("filename required for COFF output"));

  abfd = bfd_openw (filename, target);
  if (abfd == NULL)
    bfd_fatal (filename);

  if (! bfd_set_format (abfd, bfd_object))
    bfd_fatal ("bfd_set_format");

#if defined DLLTOOL_SH
  if (! bfd_set_arch_mach (abfd, bfd_arch_sh, 0))
    bfd_fatal ("bfd_set_arch_mach(sh)");
#elif defined DLLTOOL_MIPS
  if (! bfd_set_arch_mach (abfd, bfd_arch_mips, 0))
    bfd_fatal ("bfd_set_arch_mach(mips)");
#elif defined DLLTOOL_ARM
  if (! bfd_set_arch_mach (abfd, bfd_arch_arm, 0))
    bfd_fatal ("bfd_set_arch_mach(arm)");
#else
  /* FIXME: This is obviously i386 specific.  */
  if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0))
    bfd_fatal ("bfd_set_arch_mach(i386)");
#endif

  if (! bfd_set_file_flags (abfd, HAS_SYMS | HAS_RELOC))
    bfd_fatal ("bfd_set_file_flags");

  sec = bfd_make_section_with_flags (abfd, ".rsrc",
				     (SEC_HAS_CONTENTS | SEC_ALLOC
				      | SEC_LOAD | SEC_DATA));
  if (sec == NULL)
    bfd_fatal ("bfd_make_section");

  if (! bfd_set_symtab (abfd, sec->symbol_ptr_ptr, 1))
    bfd_fatal ("bfd_set_symtab");

  /* Requiring this is probably a bug in BFD.  */
  sec->output_section = sec;

  /* The order of data in the .rsrc section is
       resource directory tables and entries
       resource directory strings
       resource data entries
       actual resource data

     We build these different types of data in different lists.  */

  set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);

  cwi.wrbfd = &wrbfd;
  cwi.sympp = sec->symbol_ptr_ptr;
  cwi.dirsize = 0;
  cwi.dirstrsize = 0;
  cwi.dataentsize = 0;
  cwi.dirs.d = NULL;
  cwi.dirs.last = NULL;
  cwi.dirs.length = 0;
  cwi.dirstrs.d = NULL;
  cwi.dirstrs.last = NULL;
  cwi.dirstrs.length = 0;
  cwi.dataents.d = NULL;
  cwi.dataents.last = NULL;
  cwi.dataents.length = 0;
  cwi.resources.d = NULL;
  cwi.resources.last = NULL;
  cwi.resources.length = 0;
  cwi.relocs = NULL;
  cwi.reloc_count = 0;

  /* Work out the sizes of the resource directory entries, so that we
     know the various offsets we will need.  */
  coff_bin_sizes (resources, &cwi);

  /* Force the directory strings to be 64 bit aligned.  Every other
     structure is 64 bit aligned anyhow.  */
  cwi.dirstrsize = (cwi.dirstrsize + 7) & ~7;

  /* Actually convert the resources to binary.  */
  coff_to_bin (resources, &cwi);

  /* Add another few bytes to the directory strings if needed for
     alignment.  */
  if ((cwi.dirstrs.length & 7) != 0)
    {
      rc_uint_type pad = 8 - (cwi.dirstrs.length & 7);
      bfd_byte *ex;

      ex = coff_alloc (& cwi.dirstrs, pad);
      memset (ex, 0, pad);
    }

  /* Make sure that the data we built came out to the same size as we
     calculated initially.  */
  assert (cwi.dirs.length == cwi.dirsize);
  assert (cwi.dirstrs.length == cwi.dirstrsize);
  assert (cwi.dataents.length == cwi.dataentsize);

  length = (cwi.dirsize
	    + cwi.dirstrsize
	    + cwi.dataentsize
	    + cwi.resources.length);

  if (!bfd_set_section_size (sec, length))
    bfd_fatal ("bfd_set_section_size");

  bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);

  offset = 0;
  for (d = cwi.dirs.d; d != NULL; d = d->next)
    {
      if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
	bfd_fatal ("bfd_set_section_contents");
      offset += d->length;
    }
  for (d = cwi.dirstrs.d; d != NULL; d = d->next)
    {
      set_windres_bfd_content (&wrbfd, d->data, offset, d->length);
      offset += d->length;
    }
  for (d = cwi.dataents.d; d != NULL; d = d->next)
    {
      set_windres_bfd_content (&wrbfd, d->data, offset, d->length);
      offset += d->length;
    }
  for (rd = cwi.resources.d; rd != NULL; rd = rd->next)
    {
      res_to_bin (cwi.wrbfd, (rc_uint_type) offset, rd->res);
      offset += rd->length;
    }

  assert (offset == length);

  if (! bfd_close (abfd))
    bfd_fatal ("bfd_close");

  /* We allocated the relocs array using malloc.  */
  free (cwi.relocs);
}

/* Work out the sizes of the various fixed size resource directory
   entries.  This updates fields in CWI.  */

static void
coff_bin_sizes (const rc_res_directory *resdir,
		struct coff_write_info *cwi)
{
  const rc_res_entry *re;

  cwi->dirsize += sizeof (struct extern_res_directory);

  for (re = resdir->entries; re != NULL; re = re->next)
    {
      cwi->dirsize += sizeof (struct extern_res_entry);

      if (re->id.named)
	cwi->dirstrsize += re->id.u.n.length * 2 + 2;

      if (re->subdir)
	coff_bin_sizes (re->u.dir, cwi);
      else
	cwi->dataentsize += sizeof (struct extern_res_data);
    }
}

/* Allocate data for a particular list.  */

static bfd_byte *
coff_alloc (struct bindata_build *bb, rc_uint_type size)
{
  bindata *d;

  d = (bindata *) reswr_alloc (sizeof (bindata));

  d->next = NULL;
  d->data = (bfd_byte *) reswr_alloc (size);
  d->length = size;

  if (bb->d == NULL)
    bb->d = d;
  else
    bb->last->next = d;
  bb->last = d;
  bb->length += size;

  return d->data;
}

/* Convert the resource directory RESDIR to binary.  */

static void
coff_to_bin (const rc_res_directory *resdir, struct coff_write_info *cwi)
{
  struct extern_res_directory *erd;
  int ci, cn;
  const rc_res_entry *e;
  struct extern_res_entry *ere;

  /* Write out the directory table.  */

  erd = ((struct extern_res_directory *)
	 coff_alloc (&cwi->dirs, sizeof (*erd)));

  windres_put_32 (cwi->wrbfd, erd->characteristics, resdir->characteristics);
  windres_put_32 (cwi->wrbfd, erd->time, resdir->time);
  windres_put_16 (cwi->wrbfd, erd->major, resdir->major);
  windres_put_16 (cwi->wrbfd, erd->minor, resdir->minor);

  ci = 0;
  cn = 0;
  for (e = resdir->entries; e != NULL; e = e->next)
    {
      if (e->id.named)
	++cn;
      else
	++ci;
    }

  windres_put_16 (cwi->wrbfd, erd->name_count, cn);
  windres_put_16 (cwi->wrbfd, erd->id_count, ci);

  /* Write out the data entries.  Note that we allocate space for all
     the entries before writing them out.  That permits a recursive
     call to work correctly when writing out subdirectories.  */

  ere = ((struct extern_res_entry *)
	 coff_alloc (&cwi->dirs, (ci + cn) * sizeof (*ere)));
  for (e = resdir->entries; e != NULL; e = e->next, ere++)
    {
      if (! e->id.named)
	windres_put_32 (cwi->wrbfd, ere->name, e->id.u.id);
      else
	{
	  bfd_byte *str;
	  rc_uint_type i;

	  /* For some reason existing files seem to have the high bit
             set on the address of the name, although that is not
             documented.  */
	  windres_put_32 (cwi->wrbfd, ere->name,
		     0x80000000 | (cwi->dirsize + cwi->dirstrs.length));

	  str = coff_alloc (&cwi->dirstrs, e->id.u.n.length * 2 + 2);
	  windres_put_16 (cwi->wrbfd, str, e->id.u.n.length);
	  for (i = 0; i < e->id.u.n.length; i++)
	    windres_put_16 (cwi->wrbfd, str + (i + 1) * sizeof (unichar), e->id.u.n.name[i]);
	}

      if (e->subdir)
	{
	  windres_put_32 (cwi->wrbfd, ere->rva, 0x80000000 | cwi->dirs.length);
	  coff_to_bin (e->u.dir, cwi);
	}
      else
	{
	  windres_put_32 (cwi->wrbfd, ere->rva,
		     cwi->dirsize + cwi->dirstrsize + cwi->dataents.length);

	  coff_res_to_bin (e->u.res, cwi);
	}
    }
}

/* Convert the resource RES to binary.  */

static void
coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
{
  arelent *r;
  struct extern_res_data *erd;
  coff_res_data *d;

  /* For some reason, although every other address is a section
     offset, the address of the resource data itself is an RVA.  That
     means that we need to generate a relocation for it.  We allocate
     the relocs array using malloc so that we can use realloc.  FIXME:
     This relocation handling is correct for the i386, but probably
     not for any other target.  */

  r = (arelent *) reswr_alloc (sizeof (arelent));
  r->sym_ptr_ptr = cwi->sympp;
  r->address = cwi->dirsize + cwi->dirstrsize + cwi->dataents.length;
  r->addend = 0;
  r->howto = bfd_reloc_type_lookup (WR_BFD (cwi->wrbfd), BFD_RELOC_RVA);
  if (r->howto == NULL)
    bfd_fatal (_("can't get BFD_RELOC_RVA relocation type"));

  cwi->relocs = xrealloc (cwi->relocs,
			  (cwi->reloc_count + 2) * sizeof (arelent *));
  cwi->relocs[cwi->reloc_count] = r;
  cwi->relocs[cwi->reloc_count + 1] = NULL;
  ++cwi->reloc_count;

  erd = (struct extern_res_data *) coff_alloc (&cwi->dataents, sizeof (*erd));

  windres_put_32 (cwi->wrbfd, erd->rva,
	     (cwi->dirsize
	      + cwi->dirstrsize
	      + cwi->dataentsize
	      + cwi->resources.length));
  windres_put_32 (cwi->wrbfd, erd->codepage, res->coff_info.codepage);
  windres_put_32 (cwi->wrbfd, erd->reserved, res->coff_info.reserved);

  d = (coff_res_data *) reswr_alloc (sizeof (coff_res_data));
  d->length = res_to_bin (NULL, (rc_uint_type) 0, res);
  d->res = res;
  d->next = NULL;

  if (cwi->resources.d == NULL)
    cwi->resources.d = d;
  else
    cwi->resources.last->next = d;

  cwi->resources.last = d;
  cwi->resources.length += (d->length + 7) & ~7;

  windres_put_32 (cwi->wrbfd, erd->size, d->length);

  /* Force the next resource to have 64 bit alignment.  */
  d->length = (d->length + 7) & ~7;
}
