/* resbin.c -- manipulate the Windows binary resource format.
   Copyright (C) 1997-2024 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 functions to convert between the binary resource
   format and the internal structures that we want to use.  The same
   binary resource format is used in both res and COFF files.  */

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

/* Local functions.  */

static void toosmall (const char *);

static unichar *get_unicode (windres_bfd *, const bfd_byte *, rc_uint_type, rc_uint_type *);
static int get_resid (windres_bfd *, rc_res_id *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_generic (windres_bfd *, enum rc_res_type,
					    const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_cursor (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_menu (windres_bfd *,const bfd_byte *, rc_uint_type);
static rc_menuitem *bin_to_res_menuitems (windres_bfd *, const bfd_byte *, rc_uint_type,
					  rc_uint_type *);
static rc_menuitem *bin_to_res_menuexitems (windres_bfd *, const bfd_byte *, rc_uint_type,
					    rc_uint_type *);
static rc_res_resource *bin_to_res_dialog (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_string (windres_bfd *,const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_fontdir (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_accelerators (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_rcdata (windres_bfd *, const bfd_byte *, rc_uint_type, int);
static rc_res_resource *bin_to_res_group_cursor (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_group_icon (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_version (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_userdata (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *);
static void get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
				unichar **, rc_uint_type *, rc_uint_type *, rc_uint_type *,
				rc_uint_type *);

/* Given a resource type ID, a pointer to data, a length, return a
   rc_res_resource structure which represents that resource.  The caller
   is responsible for initializing the res_info and coff_info fields
   of the returned structure.  */

rc_res_resource *
bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
	    rc_uint_type length)
{
  if (type.named)
    return bin_to_res_userdata (wrbfd, data, length);
  else
    {
      switch (type.u.id)
	{
	default:
	  return bin_to_res_userdata (wrbfd, data, length);
	case RT_CURSOR:
	  return bin_to_res_cursor (wrbfd, data, length);
	case RT_BITMAP:
	  return bin_to_res_generic (wrbfd, RES_TYPE_BITMAP, data, length);
	case RT_ICON:
	  return bin_to_res_generic (wrbfd, RES_TYPE_ICON, data, length);
	case RT_MENU:
	  return bin_to_res_menu (wrbfd, data, length);
	case RT_DIALOG:
	  return bin_to_res_dialog (wrbfd, data, length);
	case RT_STRING:
	  return bin_to_res_string (wrbfd, data, length);
	case RT_FONTDIR:
	  return bin_to_res_fontdir (wrbfd, data, length);
	case RT_FONT:
	  return bin_to_res_generic (wrbfd, RES_TYPE_FONT, data, length);
	case RT_ACCELERATOR:
	  return bin_to_res_accelerators (wrbfd, data, length);
	case RT_RCDATA:
	  return bin_to_res_rcdata (wrbfd, data, length, RES_TYPE_RCDATA);
	case RT_MESSAGETABLE:
	  return bin_to_res_generic (wrbfd, RES_TYPE_MESSAGETABLE, data, length);
	case RT_GROUP_CURSOR:
	  return bin_to_res_group_cursor (wrbfd, data, length);
	case RT_GROUP_ICON:
	  return bin_to_res_group_icon (wrbfd, data, length);
	case RT_VERSION:
	  return bin_to_res_version (wrbfd, data, length);
	case RT_TOOLBAR:
	  return  bin_to_res_toolbar (wrbfd, data);

	}
    }
}

/* Give an error if the binary data is too small.  */

static void
toosmall (const char *msg)
{
  fatal (_("%s: not enough binary data"), msg);
}

/* Swap in a NULL terminated unicode string.  */

static unichar *
get_unicode (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
	     rc_uint_type *retlen)
{
  rc_uint_type c, i;
  unichar *ret;

  c = 0;
  while (1)
    {
      if (length < c * 2 + 2)
	toosmall (_("null terminated unicode string"));
      if (windres_get_16 (wrbfd, data + c * 2, 2) == 0)
	break;
      ++c;
    }

  ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));

  for (i = 0; i < c; i++)
    ret[i] = windres_get_16 (wrbfd, data + i * 2, 2);
  ret[i] = 0;

  if (retlen != NULL)
    *retlen = c;

  return ret;
}

/* Get a resource identifier.  This returns the number of bytes used.  */

static int
get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data,
	   rc_uint_type length)
{
  rc_uint_type first;

  if (length < 2)
    toosmall (_("resource ID"));

  first = windres_get_16 (wrbfd, data, 2);
  if (first == 0xffff)
    {
      if (length < 4)
	toosmall (_("resource ID"));
      id->named = 0;
      id->u.id = windres_get_16 (wrbfd, data + 2, 2);
      return 4;
    }
  else
    {
      id->named = 1;
      id->u.n.name = get_unicode (wrbfd, data, length, &id->u.n.length);
      return id->u.n.length * 2 + 2;
    }
}

/* Convert a resource which just stores uninterpreted data from
   binary.  */

rc_res_resource *
bin_to_res_generic (windres_bfd *wrbfd ATTRIBUTE_UNUSED, enum rc_res_type type,
		    const bfd_byte *data, rc_uint_type length)
{
  rc_res_resource *r;

  r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
  r->type = type;
  r->u.data.data = data;
  r->u.data.length = length;

  return r;
}

/* Convert a cursor resource from binary.  */

rc_res_resource *
bin_to_res_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_cursor *c;
  rc_res_resource *r;

  if (length < 4)
    toosmall (_("cursor"));

  c = (rc_cursor *) res_alloc (sizeof (rc_cursor));
  c->xhotspot = windres_get_16 (wrbfd, data, 2);
  c->yhotspot = windres_get_16 (wrbfd, data + 2, 2);
  c->length = length - 4;
  c->data = data + 4;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_CURSOR;
  r->u.cursor = c;

  return r;
}

/* Convert a menu resource from binary.  */

rc_res_resource *
bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_res_resource *r;
  rc_menu *m;
  rc_uint_type version, got;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_MENU;

  m = (rc_menu *) res_alloc (sizeof (rc_menu));
  r->u.menu = m;

  if (length < 2)
    toosmall (_("menu header"));

  version = windres_get_16 (wrbfd, data, 2);

  if (version == 0)
    {
      if (length < 4)
	toosmall (_("menu header"));
      m->help = 0;
      m->items = bin_to_res_menuitems (wrbfd, data + 4, length - 4, &got);
    }
  else if (version == 1)
    {
      rc_uint_type offset;

      if (length < 8)
	toosmall (_("menuex header"));
      m->help = windres_get_32 (wrbfd, data + 4, 4);
      offset = windres_get_16 (wrbfd, data + 2, 2);
      if (offset + 4 >= length)
	toosmall (_("menuex offset"));
      m->items = bin_to_res_menuexitems (wrbfd, data + 4 + offset,
					 length - (4 + offset), &got);
    }
  else
    fatal (_("unsupported menu version %d"), (int) version);

  return r;
}

/* Convert menu items from binary.  */

static rc_menuitem *
bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
		      rc_uint_type *got)
{
  rc_menuitem *first, **pp;

  first = NULL;
  pp = &first;

  *got = 0;

  while (length > 0)
    {
      rc_uint_type flags, slen, itemlen;
      rc_uint_type stroff;
      rc_menuitem *mi;

      if (length < 4)
	toosmall (_("menuitem header"));

      mi = (rc_menuitem *) res_alloc (sizeof *mi);
      mi->state = 0;
      mi->help = 0;

      flags = windres_get_16 (wrbfd, data, 2);
      mi->type = flags &~ (MENUITEM_POPUP | MENUITEM_ENDMENU);

      if ((flags & MENUITEM_POPUP) == 0)
	stroff = 4;
      else
	stroff = 2;

      if (length < stroff + 2)
	toosmall (_("menuitem header"));

      if (windres_get_16 (wrbfd, data + stroff, 2) == 0)
	{
	  slen = 0;
	  mi->text = NULL;
	}
      else
	mi->text = get_unicode (wrbfd, data + stroff, length - stroff, &slen);

      itemlen = stroff + slen * 2 + 2;

      if ((flags & MENUITEM_POPUP) == 0)
	{
	  mi->popup = NULL;
	  mi->id = windres_get_16 (wrbfd, data + 2, 2);
	}
      else
	{
	  rc_uint_type subread;

	  mi->id = 0;
	  mi->popup = bin_to_res_menuitems (wrbfd, data + itemlen, length - itemlen,
	  				    &subread);
	  itemlen += subread;
	}

      mi->next = NULL;
      *pp = mi;
      pp = &mi->next;

      data += itemlen;
      length -= itemlen;
      *got += itemlen;

      if ((flags & MENUITEM_ENDMENU) != 0)
	return first;
    }

  return first;
}

/* Convert menuex items from binary.  */

static rc_menuitem *
bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
			rc_uint_type *got)
{
  rc_menuitem *first, **pp;

  first = NULL;
  pp = &first;

  *got = 0;

  while (length > 0)
    {
      rc_uint_type flags, slen;
      rc_uint_type itemlen;
      rc_menuitem *mi;

      if (length < 16)
	toosmall (_("menuitem header"));

      mi = (rc_menuitem *) res_alloc (sizeof (rc_menuitem));
      mi->type = windres_get_32 (wrbfd, data, 4);
      mi->state = windres_get_32 (wrbfd, data + 4, 4);
      mi->id = windres_get_32 (wrbfd, data + 8, 4);

      flags = windres_get_16 (wrbfd, data + 12, 2);

      if (windres_get_16 (wrbfd, data + 14, 2) == 0)
	{
	  slen = 0;
	  mi->text = NULL;
	}
      else
	mi->text = get_unicode (wrbfd, data + 14, length - 14, &slen);

      itemlen = 14 + slen * 2 + 2;
      itemlen = (itemlen + 3) &~ 3;

      if ((flags & 1) == 0)
	{
	  mi->popup = NULL;
	  mi->help = 0;
	}
      else
	{
	  rc_uint_type subread;

	  if (length < itemlen + 4)
	    toosmall (_("menuitem"));
	  mi->help = windres_get_32 (wrbfd, data + itemlen, 4);
	  itemlen += 4;

	  mi->popup = bin_to_res_menuexitems (wrbfd, data + itemlen,
					      length - itemlen, &subread);
	  itemlen += subread;
	}

      mi->next = NULL;
      *pp = mi;
      pp = &mi->next;

      data += itemlen;
      length -= itemlen;
      *got += itemlen;

      if ((flags & 0x80) != 0)
	return first;
    }

  return first;
}

/* Convert a dialog resource from binary.  */

static rc_res_resource *
bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_uint_type signature;
  rc_dialog *d;
  rc_uint_type c, sublen, i;
  rc_uint_type off;
  rc_dialog_control **pp;
  rc_res_resource *r;

  if (length < 18)
    toosmall (_("dialog header"));

  d = (rc_dialog *) res_alloc (sizeof (rc_dialog));

  signature = windres_get_16 (wrbfd, data + 2, 2);
  if (signature != 0xffff)
    {
      d->ex = NULL;
      d->style = windres_get_32 (wrbfd, data, 4);
      d->exstyle = windres_get_32 (wrbfd, data + 4, 4);
      off = 8;
    }
  else
    {
      int version;

      version = windres_get_16 (wrbfd, data, 2);
      if (version != 1)
	fatal (_("unexpected DIALOGEX version %d"), version);

      d->ex = (rc_dialog_ex *) res_alloc (sizeof (rc_dialog_ex));
      d->ex->help = windres_get_32 (wrbfd, data + 4, 4);
      d->exstyle = windres_get_32 (wrbfd, data + 8, 4);
      d->style = windres_get_32 (wrbfd, data + 12, 4);
      off = 16;
    }

  if (length < off + 10)
    toosmall (_("dialog header"));

  c = windres_get_16 (wrbfd, data + off, 2);
  d->x = windres_get_16 (wrbfd, data + off + 2, 2);
  d->y = windres_get_16 (wrbfd, data + off + 4, 2);
  d->width = windres_get_16 (wrbfd, data + off + 6, 2);
  d->height = windres_get_16 (wrbfd, data + off + 8, 2);

  off += 10;

  sublen = get_resid (wrbfd, &d->menu, data + off, length - off);
  off += sublen;

  sublen = get_resid (wrbfd, &d->class, data + off, length - off);
  off += sublen;

  d->caption = get_unicode (wrbfd, data + off, length - off, &sublen);
  off += sublen * 2 + 2;
  if (sublen == 0)
    d->caption = NULL;

  if ((d->style & DS_SETFONT) == 0)
    {
      d->pointsize = 0;
      d->font = NULL;
      if (d->ex != NULL)
	{
	  d->ex->weight = 0;
	  d->ex->italic = 0;
	  d->ex->charset = 1; /* Default charset.  */
	}
    }
  else
    {
      if (length < off + 2)
	toosmall (_("dialog font point size"));

      d->pointsize = windres_get_16 (wrbfd, data + off, 2);
      off += 2;

      if (d->ex != NULL)
	{
	  if (length < off + 4)
	    toosmall (_("dialogex font information"));
	  d->ex->weight = windres_get_16 (wrbfd, data + off, 2);
	  d->ex->italic = windres_get_8 (wrbfd, data + off + 2, 1);
	  d->ex->charset = windres_get_8 (wrbfd, data + off + 3, 1);
	  off += 4;
	}

      d->font = get_unicode (wrbfd, data + off, length - off, &sublen);
      off += sublen * 2 + 2;
    }

  d->controls = NULL;
  pp = &d->controls;

  for (i = 0; i < c; i++)
    {
      rc_dialog_control *dc;
      int datalen;

      off = (off + 3) &~ 3;

      dc = (rc_dialog_control *) res_alloc (sizeof (rc_dialog_control));

      if (d->ex == NULL)
	{
	  if (length < off + 8)
	    toosmall (_("dialog control"));

	  dc->style = windres_get_32 (wrbfd, data + off, 4);
	  dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
	  dc->help = 0;
	  off += 8;
	}
      else
	{
	  if (length < off + 12)
	    toosmall (_("dialogex control"));
	  dc->help = windres_get_32 (wrbfd, data + off, 4);
	  dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
	  dc->style = windres_get_32 (wrbfd, data + off + 8, 4);
	  off += 12;
	}

      if (length < off + (d->ex != NULL ? 2 : 0) + 10)
	toosmall (_("dialog control"));

      dc->x = windres_get_16 (wrbfd, data + off, 2);
      dc->y = windres_get_16 (wrbfd, data + off + 2, 2);
      dc->width = windres_get_16 (wrbfd, data + off + 4, 2);
      dc->height = windres_get_16 (wrbfd, data + off + 6, 2);

      if (d->ex != NULL)
	dc->id = windres_get_32 (wrbfd, data + off + 8, 4);
      else
	dc->id = windres_get_16 (wrbfd, data + off + 8, 2);

      off += 10 + (d->ex != NULL ? 2 : 0);

      sublen = get_resid (wrbfd, &dc->class, data + off, length - off);
      off += sublen;

      sublen = get_resid (wrbfd, &dc->text, data + off, length - off);
      off += sublen;

      if (length < off + 2)
	toosmall (_("dialog control end"));

      datalen = windres_get_16 (wrbfd, data + off, 2);
      off += 2;

      if (datalen == 0)
	dc->data = NULL;
      else
	{
	  if (length < off + datalen)
	    toosmall (_("dialog control data"));

	  dc->data = ((rc_rcdata_item *)
		      res_alloc (sizeof (rc_rcdata_item)));
	  dc->data->next = NULL;
	  dc->data->type = RCDATA_BUFFER;
	  dc->data->u.buffer.length = datalen;
	  dc->data->u.buffer.data = data + off;

	  off += datalen;
	}

      dc->next = NULL;
      *pp = dc;
      pp = &dc->next;
    }

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_DIALOG;
  r->u.dialog = d;

  return r;
}

/* Convert a stringtable resource from binary.  */

static rc_res_resource *
bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_stringtable *st;
  int i;
  rc_res_resource *r;

  st = (rc_stringtable *) res_alloc (sizeof (rc_stringtable));

  for (i = 0; i < 16; i++)
    {
      unsigned int slen;

      if (length < 2)
	toosmall (_("stringtable string length"));
      slen = windres_get_16 (wrbfd, data, 2);
      st->strings[i].length = slen;

      if (slen > 0)
	{
	  unichar *s;
	  unsigned int j;

	  if (length < 2 + 2 * slen)
	    toosmall (_("stringtable string"));

	  s = (unichar *) res_alloc (slen * sizeof (unichar));
	  st->strings[i].string = s;

	  for (j = 0; j < slen; j++)
	    s[j] = windres_get_16 (wrbfd, data + 2 + j * 2, 2);
	}

      data += 2 + 2 * slen;
      length -= 2 + 2 * slen;
    }

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_STRINGTABLE;
  r->u.stringtable = st;

  return r;
}

/* Convert a fontdir resource from binary.  */

static rc_res_resource *
bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_uint_type c, i;
  rc_fontdir *first, **pp;
  rc_res_resource *r;

  if (length < 2)
    toosmall (_("fontdir header"));

  c = windres_get_16 (wrbfd, data, 2);

  first = NULL;
  pp = &first;

  for (i = 0; i < c; i++)
    {
      const struct bin_fontdir_item *bfi;
      rc_fontdir *fd;
      unsigned int off;

      if (length < 56)
	toosmall (_("fontdir"));

      bfi = (const struct bin_fontdir_item *) data;
      fd = (rc_fontdir *) res_alloc (sizeof *fd);
      fd->index = windres_get_16 (wrbfd, bfi->index, 2);

      /* To work out the length of the fontdir data, we must get the
         length of the device name and face name strings, even though
         we don't store them in the rc_fontdir.  The
         documentation says that these are NULL terminated char
         strings, not Unicode strings.  */

      off = 56;

      while (off < length && data[off] != '\0')
	++off;
      if (off >= length)
	toosmall (_("fontdir device name"));
      ++off;

      while (off < length && data[off] != '\0')
	++off;
      if (off >= length)
	toosmall (_("fontdir face name"));
      ++off;

      fd->length = off;
      fd->data = data;

      fd->next = NULL;
      *pp = fd;
      pp = &fd->next;

      /* The documentation does not indicate that any rounding is
         required.  */

      data += off;
      length -= off;
    }

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_FONTDIR;
  r->u.fontdir = first;

  return r;
}

/* Convert an accelerators resource from binary.  */

static rc_res_resource *
bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_accelerator *first, **pp;
  rc_res_resource *r;

  first = NULL;
  pp = &first;

  while (1)
    {
      rc_accelerator *a;

      if (length < 8)
	toosmall (_("accelerator"));

      a = (rc_accelerator *) res_alloc (sizeof (rc_accelerator));

      a->flags = windres_get_16 (wrbfd, data, 2);
      a->key = windres_get_16 (wrbfd, data + 2, 2);
      a->id = windres_get_16 (wrbfd, data + 4, 2);

      a->next = NULL;
      *pp = a;
      pp = &a->next;

      if ((a->flags & ACC_LAST) != 0)
	break;

      data += 8;
      length -= 8;
    }

  r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
  r->type = RES_TYPE_ACCELERATOR;
  r->u.acc = first;

  return r;
}

/* Convert an rcdata resource from binary.  */

static rc_res_resource *
bin_to_res_rcdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
		   rc_uint_type length, int rctyp)
{
  rc_rcdata_item *ri;
  rc_res_resource *r;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));

  ri->next = NULL;
  ri->type = RCDATA_BUFFER;
  ri->u.buffer.length = length;
  ri->u.buffer.data = data;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = rctyp;
  r->u.rcdata = ri;

  return r;
}

/* Convert a group cursor resource from binary.  */

static rc_res_resource *
bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  int type, c, i;
  rc_group_cursor *first, **pp;
  rc_res_resource *r;

  if (length < 6)
    toosmall (_("group cursor header"));

  type = windres_get_16 (wrbfd, data + 2, 2);
  if (type != 2)
    fatal (_("unexpected group cursor type %d"), type);

  c = windres_get_16 (wrbfd, data + 4, 2);

  data += 6;
  length -= 6;

  first = NULL;
  pp = &first;

  for (i = 0; i < c; i++)
    {
      rc_group_cursor *gc;

      if (length < 14)
	toosmall (_("group cursor"));

      gc = (rc_group_cursor *) res_alloc (sizeof *gc);

      gc->width = windres_get_16 (wrbfd, data, 2);
      gc->height = windres_get_16 (wrbfd, data + 2, 2);
      gc->planes = windres_get_16 (wrbfd, data + 4, 2);
      gc->bits = windres_get_16 (wrbfd, data + 6, 2);
      gc->bytes = windres_get_32 (wrbfd, data + 8, 4);
      gc->index = windres_get_16 (wrbfd, data + 12, 2);

      gc->next = NULL;
      *pp = gc;
      pp = &gc->next;

      data += 14;
      length -= 14;
    }

  r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
  r->type = RES_TYPE_GROUP_CURSOR;
  r->u.group_cursor = first;

  return r;
}

/* Convert a group icon resource from binary.  */

static rc_res_resource *
bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  int type, c, i;
  rc_group_icon *first, **pp;
  rc_res_resource *r;

  if (length < 6)
    toosmall (_("group icon header"));

  type = windres_get_16 (wrbfd, data + 2, 2);
  if (type != 1)
    fatal (_("unexpected group icon type %d"), type);

  c = windres_get_16 (wrbfd, data + 4, 2);

  data += 6;
  length -= 6;

  first = NULL;
  pp = &first;

  for (i = 0; i < c; i++)
    {
      rc_group_icon *gi;

      if (length < 14)
	toosmall (_("group icon"));

      gi = (rc_group_icon *) res_alloc (sizeof (rc_group_icon));

      gi->width = windres_get_8 (wrbfd, data, 1);
      gi->height = windres_get_8 (wrbfd, data + 1, 1);
      gi->colors = windres_get_8 (wrbfd, data + 2, 1);
      gi->planes = windres_get_16 (wrbfd, data + 4, 2);
      gi->bits = windres_get_16 (wrbfd, data + 6, 2);
      gi->bytes = windres_get_32 (wrbfd, data + 8, 4);
      gi->index = windres_get_16 (wrbfd, data + 12, 2);

      gi->next = NULL;
      *pp = gi;
      pp = &gi->next;

      data += 14;
      length -= 14;
    }

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_GROUP_ICON;
  r->u.group_icon = first;

  return r;
}

/* Extract data from a version header.  If KEY is not NULL, then the
   key must be KEY; otherwise, the key is returned in *PKEY.  This
   sets *LEN to the total length, *VALLEN to the value length, *TYPE
   to the type, and *OFF to the offset to the children.  */

static void
get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
		    const char *key, unichar **pkey,
		    rc_uint_type *len, rc_uint_type *vallen, rc_uint_type *type,
		    rc_uint_type *off)
{
  if (length < 8)
    toosmall (key);

  *len = (windres_get_16 (wrbfd, data, 2) + 3) & ~3;
  *vallen = windres_get_16 (wrbfd, data + 2, 2);
  *type = windres_get_16 (wrbfd, data + 4, 2);

  *off = 6;

  length -= 6;
  data += 6;

  if (key == NULL)
    {
      rc_uint_type sublen;

      *pkey = get_unicode (wrbfd, data, length, &sublen);
      *off += (sublen + 1) * sizeof (unichar);
    }
  else
    {
      while (1)
	{
	  if (length < 2)
	    toosmall (key);
	  if (windres_get_16 (wrbfd, data, 2) != (bfd_byte) *key)
	    fatal (_("unexpected version string"));

	  *off += 2;
	  length -= 2;
	  data += 2;

	  if (*key == '\0')
	    break;

	  ++key;
	}
    }

  *off = (*off + 3) &~ 3;
}

/* Convert a version resource from binary.  */

static rc_res_resource *
bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_uint_type verlen, vallen, type, off;
  rc_fixed_versioninfo *fi;
  rc_ver_info *first, **pp;
  rc_versioninfo *v;
  rc_res_resource *r;

  get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
		      (unichar **) NULL, &verlen, &vallen, &type, &off);

  /* PR 17512: The verlen field does not include padding length.  */
  if (verlen > length)
    fatal (_("version length %lu greater than resource length %lu"),
	   (unsigned long) verlen, (unsigned long) length);

  if (type != 0)
    fatal (_("unexpected version type %d"), (int) type);

  /* PR 27686: Ignore any padding bytes after the end of the version structure.  */
  length = verlen;

  data += off;
  length -= off;

  if (vallen == 0)
    fi = NULL;
  else
    {
      unsigned long signature, fiv;

      if (vallen != 52)
	fatal (_("unexpected fixed version information length %ld"), (long) vallen);

      if (length < 52)
	toosmall (_("fixed version info"));

      signature = windres_get_32 (wrbfd, data, 4);
      if (signature != 0xfeef04bd)
	fatal (_("unexpected fixed version signature %lu"), signature);

      fiv = windres_get_32 (wrbfd, data + 4, 4);
      if (fiv != 0 && fiv != 0x10000)
	fatal (_("unexpected fixed version info version %lu"), fiv);

      fi = (rc_fixed_versioninfo *) res_alloc (sizeof (rc_fixed_versioninfo));

      fi->file_version_ms = windres_get_32 (wrbfd, data + 8, 4);
      fi->file_version_ls = windres_get_32 (wrbfd, data + 12, 4);
      fi->product_version_ms = windres_get_32 (wrbfd, data + 16, 4);
      fi->product_version_ls = windres_get_32 (wrbfd, data + 20, 4);
      fi->file_flags_mask = windres_get_32 (wrbfd, data + 24, 4);
      fi->file_flags = windres_get_32 (wrbfd, data + 28, 4);
      fi->file_os = windres_get_32 (wrbfd, data + 32, 4);
      fi->file_type = windres_get_32 (wrbfd, data + 36, 4);
      fi->file_subtype = windres_get_32 (wrbfd, data + 40, 4);
      fi->file_date_ms = windres_get_32 (wrbfd, data + 44, 4);
      fi->file_date_ls = windres_get_32 (wrbfd, data + 48, 4);

      data += 52;
      length -= 52;
    }

  first = NULL;
  pp = &first;

  while (length > 0)
    {
      rc_ver_info *vi;
      int ch;

      if (length < 8)
	toosmall (_("version var info"));

      vi = (rc_ver_info *) res_alloc (sizeof (rc_ver_info));

      ch = windres_get_16 (wrbfd, data + 6, 2);

      if (ch == 'S')
	{
	  rc_ver_stringtable **ppvst;

	  vi->type = VERINFO_STRING;

	  get_version_header (wrbfd, data, length, "StringFileInfo",
			      (unichar **) NULL, &verlen, &vallen, &type,
			      &off);

	  if (vallen != 0)
	    fatal (_("unexpected stringfileinfo value length %ld"), (long) vallen);

	  data += off;
	  length -= off;

	  verlen -= off;

	  vi->u.string.stringtables = NULL;
	  ppvst = &vi->u.string.stringtables;

	  while (verlen > 0)
	    {
	      rc_ver_stringtable *vst;
	      rc_uint_type stverlen;
	      rc_ver_stringinfo **ppvs;

	      if (length < 8)
		toosmall (_("version stringtable"));

	      vst = (rc_ver_stringtable *) res_alloc (sizeof (rc_ver_stringtable));

	      get_version_header (wrbfd, data, length, (const char *) NULL,
				  &vst->language, &stverlen, &vallen, &type, &off);

	      if (vallen != 0)
		fatal (_("unexpected version stringtable value length %ld"), (long) vallen);

	      data += off;
	      length -= off;
	      verlen -= off;

	  stverlen -= off;

	  vst->strings = NULL;
	  ppvs = &vst->strings;

	  while (stverlen > 0)
	    {
	      rc_ver_stringinfo *vs;
	      rc_uint_type sverlen, vslen, valoff;

	      if (length < 8)
		toosmall (_("version string"));

	      vs = (rc_ver_stringinfo *) res_alloc (sizeof (rc_ver_stringinfo));

	      get_version_header (wrbfd, data, length, (const char *) NULL,
				  &vs->key, &sverlen, &vallen, &type, &off);

	      data += off;
	      length -= off;

	      vs->value = get_unicode (wrbfd, data, length, &vslen);
	      valoff = vslen * 2 + 2;
	      valoff = (valoff + 3) & ~3;

	      if (off + valoff != sverlen)
		fatal (_("unexpected version string length %ld != %ld + %ld"),
		       (long) sverlen, (long) off, (long) valoff);

	      data += valoff;
	      length -= valoff;

	      if (stverlen < sverlen)
		fatal (_("unexpected version string length %ld < %ld"),
		       (long) verlen, (long) sverlen);
	      stverlen -= sverlen;
	      verlen -= sverlen;

	      vs->next = NULL;
	      *ppvs = vs;
	      ppvs = &vs->next;
	    }

	  vst->next = NULL;
	  *ppvst = vst;
	  ppvst = &vst->next;
	    }
	}
      else if (ch == 'V')
	{
	  rc_ver_varinfo **ppvv;

	  vi->type = VERINFO_VAR;

	  get_version_header (wrbfd, data, length, "VarFileInfo",
			      (unichar **) NULL, &verlen, &vallen, &type,
			      &off);

	  if (vallen != 0)
	    fatal (_("unexpected varfileinfo value length %ld"), (long) vallen);

	  data += off;
	  length -= off;

	  get_version_header (wrbfd, data, length, (const char *) NULL,
			      &vi->u.var.key, &verlen, &vallen, &type, &off);

	  data += off;
	  length -= off;

	  vi->u.var.var = NULL;
	  ppvv = &vi->u.var.var;

	  while (vallen > 0)
	    {
	      rc_ver_varinfo *vv;

	      if (length < 4)
		toosmall (_("version varfileinfo"));

	      vv = (rc_ver_varinfo *) res_alloc (sizeof (rc_ver_varinfo));

	      vv->language = windres_get_16 (wrbfd, data, 2);
	      vv->charset = windres_get_16 (wrbfd, data + 2, 2);

	      vv->next = NULL;
	      *ppvv = vv;
	      ppvv = &vv->next;

	      data += 4;
	      length -= 4;

	      if (vallen < 4)
		fatal (_("unexpected version value length %ld"), (long) vallen);

	      vallen -= 4;
	    }
	}
      else if (ch == 0)
	{
	  if (length == 8)
	    /* Padding - skip.  */
	    break;
	  fatal (_("nul bytes found in version string"));
	}
      else
	fatal (_("unexpected version string character: %x"), ch);

      vi->next = NULL;
      *pp = vi;
      pp = &vi->next;
    }

  v = (rc_versioninfo *) res_alloc (sizeof (rc_versioninfo));
  v->fixed = fi;
  v->var = first;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_VERSIONINFO;
  r->u.versioninfo = v;

  return r;
}

/* Convert an arbitrary user defined resource from binary.  */

static rc_res_resource *
bin_to_res_userdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
		     rc_uint_type length)
{
  rc_rcdata_item *ri;
  rc_res_resource *r;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));

  ri->next = NULL;
  ri->type = RCDATA_BUFFER;
  ri->u.buffer.length = length;
  ri->u.buffer.data = data;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_USERDATA;
  r->u.rcdata = ri;

  return r;
}

static rc_res_resource *
bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
{
  rc_toolbar *ri;
  rc_res_resource *r;
  rc_uint_type i;

  ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
  ri->button_width = windres_get_32 (wrbfd, data, 4);
  ri->button_height = windres_get_32 (wrbfd, data + 4, 4);
  ri->nitems = windres_get_32 (wrbfd, data + 8, 4);
  ri->items = NULL;

  data += 12;
  for (i=0 ; i < ri->nitems; i++)
  {
    rc_toolbar_item *it;
    it = (rc_toolbar_item *) res_alloc (sizeof (rc_toolbar_item));
    it->id.named = 0;
    it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
    it->prev = it->next = NULL;
    data += 4;
    if(ri->items) {
      rc_toolbar_item *ii = ri->items;
      while (ii->next != NULL)
	ii = ii->next;
      it->prev = ii;
      ii->next = it;
    }
    else
      ri->items = it;
  }
  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_TOOLBAR;
  r->u.toolbar = ri;
  return r;
}


/* Local functions used to convert resources to binary format.  */

static rc_uint_type resid_to_bin (windres_bfd *, rc_uint_type, rc_res_id);
static rc_uint_type unicode_to_bin (windres_bfd *, rc_uint_type, const unichar *);
static rc_uint_type res_to_bin_accelerator (windres_bfd *, rc_uint_type, const rc_accelerator *);
static rc_uint_type res_to_bin_cursor (windres_bfd *, rc_uint_type, const rc_cursor *);
static rc_uint_type res_to_bin_group_cursor (windres_bfd *, rc_uint_type, const rc_group_cursor *);
static rc_uint_type res_to_bin_dialog (windres_bfd *, rc_uint_type, const rc_dialog *);
static rc_uint_type res_to_bin_fontdir (windres_bfd *, rc_uint_type, const rc_fontdir *);
static rc_uint_type res_to_bin_group_icon (windres_bfd *, rc_uint_type, const rc_group_icon *);
static rc_uint_type res_to_bin_menu (windres_bfd *, rc_uint_type, const rc_menu *);
static rc_uint_type res_to_bin_menuitems (windres_bfd *, rc_uint_type, const rc_menuitem *);
static rc_uint_type res_to_bin_menuexitems (windres_bfd *, rc_uint_type, const rc_menuitem *);
static rc_uint_type res_to_bin_rcdata (windres_bfd *, rc_uint_type, const rc_rcdata_item *);
static rc_uint_type res_to_bin_stringtable (windres_bfd *, rc_uint_type, const rc_stringtable *);
static rc_uint_type string_to_unicode_bin (windres_bfd *, rc_uint_type, const char *);
static rc_uint_type res_to_bin_toolbar (windres_bfd *, rc_uint_type, rc_toolbar *tb);
static rc_uint_type res_to_bin_versioninfo (windres_bfd *, rc_uint_type, const rc_versioninfo *);
static rc_uint_type res_to_bin_generic (windres_bfd *, rc_uint_type, rc_uint_type,
					const bfd_byte *);

/* Convert a resource to binary.  */

rc_uint_type
res_to_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res)
{
  switch (res->type)
    {
    case RES_TYPE_BITMAP:
    case RES_TYPE_FONT:
    case RES_TYPE_ICON:
    case RES_TYPE_MESSAGETABLE:
      return res_to_bin_generic (wrbfd, off, res->u.data.length, res->u.data.data);
    case RES_TYPE_ACCELERATOR:
      return res_to_bin_accelerator (wrbfd, off, res->u.acc);
    case RES_TYPE_CURSOR:
      return res_to_bin_cursor (wrbfd, off, res->u.cursor);
    case RES_TYPE_GROUP_CURSOR:
      return res_to_bin_group_cursor (wrbfd, off, res->u.group_cursor);
    case RES_TYPE_DIALOG:
      return res_to_bin_dialog (wrbfd, off, res->u.dialog);
    case RES_TYPE_FONTDIR:
      return res_to_bin_fontdir (wrbfd, off, res->u.fontdir);
    case RES_TYPE_GROUP_ICON:
      return res_to_bin_group_icon (wrbfd, off, res->u.group_icon);
    case RES_TYPE_MENU:
      return res_to_bin_menu (wrbfd, off, res->u.menu);
    case RES_TYPE_STRINGTABLE:
      return res_to_bin_stringtable (wrbfd, off, res->u.stringtable);
    case RES_TYPE_VERSIONINFO:
      return res_to_bin_versioninfo (wrbfd, off, res->u.versioninfo);
    case RES_TYPE_TOOLBAR:
      return res_to_bin_toolbar (wrbfd, off, res->u.toolbar);
    case RES_TYPE_USERDATA:
    case RES_TYPE_RCDATA:
    default:
      return res_to_bin_rcdata (wrbfd, off, res->u.rcdata);
    }
}

/* Convert a resource ID to binary.  This always returns exactly one
   bindata structure.  */

static rc_uint_type
resid_to_bin (windres_bfd *wrbfd, rc_uint_type off, rc_res_id id)
{
  if (! id.named)
    {
      if (wrbfd)
	{
	  struct bin_res_id bri;

	  windres_put_16 (wrbfd, bri.sig, 0xffff);
	  windres_put_16 (wrbfd, bri.id, id.u.id);
	  set_windres_bfd_content (wrbfd, &bri, off, BIN_RES_ID);
	}
      off += BIN_RES_ID;
    }
  else
    {
      rc_uint_type len = (id.u.n.name ? unichar_len (id.u.n.name) : 0);
      if (wrbfd)
	{
	  bfd_byte *d = (bfd_byte *) reswr_alloc ((len + 1) * sizeof (unichar));
	  rc_uint_type i;
	  for (i = 0; i < len; i++)
	    windres_put_16 (wrbfd, d + (i * sizeof (unichar)), id.u.n.name[i]);
	  windres_put_16 (wrbfd, d + (len * sizeof (unichar)), 0);
	  set_windres_bfd_content (wrbfd, d, off, (len + 1) * sizeof (unichar));
    }
      off += (rc_uint_type) ((len + 1) * sizeof (unichar));
    }
  return off;
}

/* Convert a null terminated unicode string to binary.  This always
   returns exactly one bindata structure.  */

static rc_uint_type
unicode_to_bin (windres_bfd *wrbfd, rc_uint_type off, const unichar *str)
{
  rc_uint_type len = 0;

  if (str != NULL)
    len = unichar_len (str);

  if (wrbfd)
    {
      bfd_byte *d;
      rc_uint_type i;
      d = (bfd_byte *) reswr_alloc ( (len + 1) * sizeof (unichar));
      for (i = 0; i < len; i++)
	windres_put_16 (wrbfd, d + (i * sizeof (unichar)), str[i]);
      windres_put_16 (wrbfd, d + (len * sizeof (unichar)), 0);
      set_windres_bfd_content (wrbfd, d, off, (len + 1) * sizeof (unichar));
    }
  off += (rc_uint_type) ((len + 1) * sizeof (unichar));

  return off;
}

/* Convert an accelerator resource to binary.  */

static rc_uint_type
res_to_bin_accelerator (windres_bfd *wrbfd, rc_uint_type off,
			const rc_accelerator *accelerators)
{
  const rc_accelerator *a;

  for (a = accelerators; a != NULL; a = a->next)
    {
      if (wrbfd)
	{
	  struct bin_accelerator ba;

	  windres_put_16 (wrbfd, ba.flags, a->flags | (a->next != NULL ? 0 : ACC_LAST));
	  windres_put_16 (wrbfd, ba.key, a->key);
	  windres_put_16 (wrbfd, ba.id, a->id);
	  windres_put_16 (wrbfd, ba.pad, 0);
	  set_windres_bfd_content (wrbfd, &ba, off, BIN_ACCELERATOR_SIZE);
    }
      off += BIN_ACCELERATOR_SIZE;
    }
  return off;
}

/* Convert a cursor resource to binary.  */

static rc_uint_type
res_to_bin_cursor (windres_bfd *wrbfd, rc_uint_type off, const rc_cursor *c)
{
  if (wrbfd)
    {
      struct bin_cursor bc;

      windres_put_16 (wrbfd, bc.xhotspot, c->xhotspot);
      windres_put_16 (wrbfd, bc.yhotspot, c->yhotspot);
      set_windres_bfd_content (wrbfd, &bc, off, BIN_CURSOR_SIZE);
      if (c->length)
	set_windres_bfd_content (wrbfd, c->data, off + BIN_CURSOR_SIZE, c->length);
    }
  off = (off + BIN_CURSOR_SIZE + (rc_uint_type) c->length);
  return off;
}

/* Convert a group cursor resource to binary.  */

static rc_uint_type
res_to_bin_group_cursor (windres_bfd *wrbfd, rc_uint_type off,
			 const rc_group_cursor *group_cursors)
{
  int c = 0;
  const rc_group_cursor *gc;
  struct bin_group_cursor bgc;
  struct bin_group_cursor_item bgci;
  rc_uint_type start = off;

  off += BIN_GROUP_CURSOR_SIZE;

  for (c = 0, gc = group_cursors; gc != NULL; gc = gc->next, c++)
    {
      if (wrbfd)
	{
	  windres_put_16 (wrbfd, bgci.width, gc->width);
	  windres_put_16 (wrbfd, bgci.height, gc->height);
	  windres_put_16 (wrbfd, bgci.planes, gc->planes);
	  windres_put_16 (wrbfd, bgci.bits, gc->bits);
	  windres_put_32 (wrbfd, bgci.bytes, gc->bytes);
	  windres_put_16 (wrbfd, bgci.index, gc->index);
	  set_windres_bfd_content (wrbfd, &bgci, off, BIN_GROUP_CURSOR_ITEM_SIZE);
    }

      off += BIN_GROUP_CURSOR_ITEM_SIZE;
    }
  if (wrbfd)
    {
      windres_put_16 (wrbfd, bgc.sig1, 0);
      windres_put_16 (wrbfd, bgc.sig2, 2);
      windres_put_16 (wrbfd, bgc.nitems, c);
      set_windres_bfd_content (wrbfd, &bgc, start, BIN_GROUP_CURSOR_SIZE);
    }
  return off;
}

/* Convert a dialog resource to binary.  */

static rc_uint_type
res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog)
{
  rc_uint_type off_delta;
  rc_uint_type start, marker;
  int dialogex;
  int c;
  rc_dialog_control *dc;
  struct bin_dialogex bdx;
  struct bin_dialog bd;

  off_delta = off;
  start = off;
  dialogex = extended_dialog (dialog);

  if (wrbfd)
    {
  if (! dialogex)
    {
	  windres_put_32 (wrbfd, bd.style, dialog->style);
	  windres_put_32 (wrbfd, bd.exstyle, dialog->exstyle);
	  windres_put_16 (wrbfd, bd.x, dialog->x);
	  windres_put_16 (wrbfd, bd.y, dialog->y);
	  windres_put_16 (wrbfd, bd.width, dialog->width);
	  windres_put_16 (wrbfd, bd.height, dialog->height);
    }
  else
    {
	  windres_put_16 (wrbfd, bdx.sig1, 1);
	  windres_put_16 (wrbfd, bdx.sig2, 0xffff);
	  windres_put_32 (wrbfd, bdx.help, (dialog->ex ? dialog->ex->help : 0));
	  windres_put_32 (wrbfd, bdx.exstyle, dialog->exstyle);
	  windres_put_32 (wrbfd, bdx.style, dialog->style);
	  windres_put_16 (wrbfd, bdx.x, dialog->x);
	  windres_put_16 (wrbfd, bdx.y, dialog->y);
	  windres_put_16 (wrbfd, bdx.width, dialog->width);
	  windres_put_16 (wrbfd, bdx.height, dialog->height);
	}
    }

  off += (dialogex != 0 ? BIN_DIALOGEX_SIZE : BIN_DIALOG_SIZE);

  off = resid_to_bin (wrbfd, off, dialog->menu);
  off = resid_to_bin (wrbfd, off, dialog->class);
  off = unicode_to_bin (wrbfd, off, dialog->caption);

  if ((dialog->style & DS_SETFONT) != 0)
    {
      if (wrbfd)
	{
	  if (! dialogex)
	    {
	      struct bin_dialogfont bdf;
	      windres_put_16 (wrbfd, bdf.pointsize, dialog->pointsize);
	      set_windres_bfd_content (wrbfd, &bdf, off, BIN_DIALOGFONT_SIZE);
	    }
	  else
	    {
	      struct bin_dialogexfont bdxf;
	      windres_put_16 (wrbfd, bdxf.pointsize, dialog->pointsize);
	      windres_put_16 (wrbfd, bdxf.weight, (dialog->ex == NULL ? 0 : dialog->ex->weight));
	      windres_put_8 (wrbfd, bdxf.italic, (dialog->ex == NULL ? 0 : dialog->ex->italic));
	      windres_put_8 (wrbfd, bdxf.charset, (dialog->ex == NULL ? 1 : dialog->ex->charset));
	      set_windres_bfd_content (wrbfd, &bdxf, off, BIN_DIALOGEXFONT_SIZE);
	    }
	}
      off += (dialogex ? BIN_DIALOGEXFONT_SIZE : BIN_DIALOGFONT_SIZE);
      off = unicode_to_bin (wrbfd, off, dialog->font);
    }
  for (c = 0, dc = dialog->controls; dc != NULL; dc = dc->next, c++)
    {
      bfd_byte dc_rclen[2];

      off += (4 - ((off - off_delta) & 3)) & 3;
      if (wrbfd)
	{
      if (! dialogex)
	{
	      struct bin_dialog_control bdc;

	      windres_put_32 (wrbfd, bdc.style, dc->style);
	      windres_put_32 (wrbfd, bdc.exstyle, dc->exstyle);
	      windres_put_16 (wrbfd, bdc.x, dc->x);
	      windres_put_16 (wrbfd, bdc.y, dc->y);
	      windres_put_16 (wrbfd, bdc.width, dc->width);
	      windres_put_16 (wrbfd, bdc.height, dc->height);
	      windres_put_16 (wrbfd, bdc.id, dc->id);
	      set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOG_CONTROL_SIZE);
	}
      else
	{
	      struct bin_dialogex_control bdc;

	      windres_put_32 (wrbfd, bdc.help, dc->help);
	      windres_put_32 (wrbfd, bdc.exstyle, dc->exstyle);
	      windres_put_32 (wrbfd, bdc.style, dc->style);
	      windres_put_16 (wrbfd, bdc.x, dc->x);
	      windres_put_16 (wrbfd, bdc.y, dc->y);
	      windres_put_16 (wrbfd, bdc.width, dc->width);
	      windres_put_16 (wrbfd, bdc.height, dc->height);
	      windres_put_32 (wrbfd, bdc.id, dc->id);
	      set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOGEX_CONTROL_SIZE);
	    }
	}
      off += (dialogex != 0 ? BIN_DIALOGEX_CONTROL_SIZE : BIN_DIALOG_CONTROL_SIZE);

      off = resid_to_bin (wrbfd, off, dc->class);
      off = resid_to_bin (wrbfd, off, dc->text);

      marker = off; /* Save two bytes for size of optional data.  */
      off += 2;

      if (dc->data == NULL)
        {
	  if (wrbfd)
	    windres_put_16 (wrbfd, dc_rclen, 0);
	}
      else
	{
	  rc_uint_type saved_off = off;
	  rc_uint_type old_off;

	  old_off = off;
	  off = res_to_bin_rcdata (wrbfd, off, dc->data);
	  if ((off - old_off) == 0)
	    old_off = off = saved_off;
	  if (wrbfd)
	    windres_put_16 (wrbfd, dc_rclen, off - old_off);
	}
      if (wrbfd)
	set_windres_bfd_content (wrbfd, dc_rclen, marker, 2);
    }

  if (wrbfd)
    {
      windres_put_16 (wrbfd, (dialogex != 0 ? bdx.off : bd.off), c);
      if (! dialogex)
	set_windres_bfd_content (wrbfd, &bd, start, BIN_DIALOG_SIZE);
      else
	set_windres_bfd_content (wrbfd, &bdx, start, BIN_DIALOGEX_SIZE);
    }

  return off;
}

/* Convert a fontdir resource to binary.  */
static rc_uint_type
res_to_bin_fontdir (windres_bfd *wrbfd, rc_uint_type off, const rc_fontdir *fontdirs)
{
  rc_uint_type start;
  int c;
  const rc_fontdir *fd;

  start = off;
  off += 2;

  for (c = 0, fd = fontdirs; fd != NULL; fd = fd->next, c++)
    {
      if (wrbfd)
	{
	  bfd_byte d[2];
	  windres_put_16 (wrbfd, d, fd->index);
	  set_windres_bfd_content (wrbfd, d, off, 2);
	  if (fd->length)
	    set_windres_bfd_content (wrbfd, fd->data, off + 2, fd->length);
	}
      off += (rc_uint_type) fd->length + 2;
    }

  if (wrbfd)
    {
      bfd_byte d[2];
      windres_put_16 (wrbfd, d, c);
      set_windres_bfd_content (wrbfd, d, start, 2);
    }
  return off;
}

/* Convert a group icon resource to binary.  */

static rc_uint_type
res_to_bin_group_icon (windres_bfd *wrbfd, rc_uint_type off, const rc_group_icon *group_icons)
{
  rc_uint_type start;
  struct bin_group_icon bgi;
  int c;
  const rc_group_icon *gi;

  start = off;
  off += BIN_GROUP_ICON_SIZE;

  for (c = 0, gi = group_icons; gi != NULL; gi = gi->next, c++)
    {
      struct bin_group_icon_item bgii;

      if (wrbfd)
	{
	  windres_put_8 (wrbfd, bgii.width, gi->width);
	  windres_put_8 (wrbfd, bgii.height, gi->height);
	  windres_put_8 (wrbfd, bgii.colors, gi->colors);
	  windres_put_8 (wrbfd, bgii.pad, 0);
	  windres_put_16 (wrbfd, bgii.planes, gi->planes);
	  windres_put_16 (wrbfd, bgii.bits, gi->bits);
	  windres_put_32 (wrbfd, bgii.bytes, gi->bytes);
	  windres_put_16 (wrbfd, bgii.index, gi->index);
	  set_windres_bfd_content (wrbfd, &bgii, off, BIN_GROUP_ICON_ITEM_SIZE);
	}
      off += BIN_GROUP_ICON_ITEM_SIZE;
    }

  if (wrbfd)
    {
      windres_put_16 (wrbfd, bgi.sig1, 0);
      windres_put_16 (wrbfd, bgi.sig2, 1);
      windres_put_16 (wrbfd, bgi.count, c);
      set_windres_bfd_content (wrbfd, &bgi, start, BIN_GROUP_ICON_SIZE);
    }
  return off;
}

/* Convert a menu resource to binary.  */

static rc_uint_type
res_to_bin_menu (windres_bfd *wrbfd, rc_uint_type off, const rc_menu *menu)
{
  int menuex;

  menuex = extended_menu (menu);

  if (wrbfd)
    {
  if (! menuex)
    {
	  struct bin_menu bm;
	  windres_put_16 (wrbfd, bm.sig1, 0);
	  windres_put_16 (wrbfd, bm.sig2, 0);
	  set_windres_bfd_content (wrbfd, &bm, off, BIN_MENU_SIZE);
    }
  else
    {
	  struct bin_menuex bm;
	  windres_put_16 (wrbfd, bm.sig1, 1);
	  windres_put_16 (wrbfd, bm.sig2, 4);
	  windres_put_32 (wrbfd, bm.help, menu->help);
	  set_windres_bfd_content (wrbfd, &bm, off, BIN_MENUEX_SIZE);
    }
    }
  off += (menuex != 0 ? BIN_MENUEX_SIZE : BIN_MENU_SIZE);
  if (! menuex)
    {
      off = res_to_bin_menuitems (wrbfd, off, menu->items);
    }
  else
    {
      off = res_to_bin_menuexitems (wrbfd, off, menu->items);
    }
  return off;
}

/* Convert menu items to binary.  */

static rc_uint_type
res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *items)
{
  const rc_menuitem *mi;

  for (mi = items; mi != NULL; mi = mi->next)
    {
      struct bin_menuitem bmi;
      int flags;

      flags = mi->type;
      if (mi->next == NULL)
	flags |= MENUITEM_ENDMENU;
      if (mi->popup != NULL)
	flags |= MENUITEM_POPUP;

      if (wrbfd)
	{
	  windres_put_16 (wrbfd, bmi.flags, flags);
      if (mi->popup == NULL)
	    windres_put_16 (wrbfd, bmi.id, mi->id);
	  set_windres_bfd_content (wrbfd, &bmi, off,
				   mi->popup == NULL ? BIN_MENUITEM_SIZE
				   		     : BIN_MENUITEM_POPUP_SIZE);
	}
      off += (mi->popup == NULL ? BIN_MENUITEM_SIZE : BIN_MENUITEM_POPUP_SIZE);

      off = unicode_to_bin (wrbfd, off, mi->text);

      if (mi->popup != NULL)
	{
	  off = res_to_bin_menuitems (wrbfd, off, mi->popup);
	}
    }
  return off;
}

/* Convert menuex items to binary.  */

static rc_uint_type
res_to_bin_menuexitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *items)
{
  rc_uint_type off_delta = off;
  const rc_menuitem *mi;

  for (mi = items; mi != NULL; mi = mi->next)
    {
      struct bin_menuitemex bmi;
      int flags;

      off += (4 - ((off - off_delta) & 3)) & 3;

      flags = 0;
      if (mi->next == NULL)
	flags |= 0x80;
      if (mi->popup != NULL)
	flags |= 1;

      if (wrbfd)
	{
	  windres_put_32 (wrbfd, bmi.type, mi->type);
	  windres_put_32 (wrbfd, bmi.state, mi->state);
	  windres_put_32 (wrbfd, bmi.id, mi->id);
	  windres_put_16 (wrbfd, bmi.flags, flags);
	  set_windres_bfd_content (wrbfd, &bmi, off, BIN_MENUITEMEX_SIZE);
	}
      off += BIN_MENUITEMEX_SIZE;

      off = unicode_to_bin (wrbfd, off, mi->text);

      if (mi->popup != NULL)
	{
	  bfd_byte help[4];

	  off += (4 - ((off - off_delta) & 3)) & 3;

	  if (wrbfd)
	    {
	      windres_put_32 (wrbfd, help, mi->help);
	      set_windres_bfd_content (wrbfd, help, off, 4);
	    }
	  off += 4;
	  off = res_to_bin_menuexitems (wrbfd, off, mi->popup);
	}
    }
  return off;
}

/* Convert an rcdata resource to binary.  This is also used to convert
   other information which happens to be stored in rc_rcdata_item lists
   to binary.  */

static rc_uint_type
res_to_bin_rcdata (windres_bfd *wrbfd, rc_uint_type off, const rc_rcdata_item *items)
{
  const rc_rcdata_item *ri;

  for (ri = items; ri != NULL; ri = ri->next)
    {
      rc_uint_type len;
      switch (ri->type)
	{
	default:
	  abort ();
	case RCDATA_WORD:
	  len = 2;
	  break;
	case RCDATA_DWORD:
	  len = 4;
	  break;
	case RCDATA_STRING:
	  len = ri->u.string.length;
	  break;
	case RCDATA_WSTRING:
	  len = ri->u.wstring.length * sizeof (unichar);
	  break;
	case RCDATA_BUFFER:
	  len = ri->u.buffer.length;
	  break;
	}
      if (wrbfd)
	{
	  bfd_byte h[4];
	  bfd_byte *hp = &h[0];
	  switch (ri->type)
	    {
	    case RCDATA_WORD:
	      windres_put_16 (wrbfd, hp, ri->u.word);
	      break;
	    case RCDATA_DWORD:
	      windres_put_32 (wrbfd, hp, ri->u.dword);
	      break;
	    case RCDATA_STRING:
	      hp = (bfd_byte *) ri->u.string.s;
	  break;
	case RCDATA_WSTRING:
	  {
		rc_uint_type i;

		hp = (bfd_byte *) reswr_alloc (len);
	    for (i = 0; i < ri->u.wstring.length; i++)
		  windres_put_16 (wrbfd, hp + i * sizeof (unichar), ri->u.wstring.w[i]);
	  }
	      break;
	case RCDATA_BUFFER:
	      hp = (bfd_byte *) ri->u.buffer.data;
	  break;
	}
	  set_windres_bfd_content (wrbfd, hp, off, len);
    }
      off += len;
    }
  return off;
}

/* Convert a stringtable resource to binary.  */

static rc_uint_type
res_to_bin_stringtable (windres_bfd *wrbfd, rc_uint_type off,
			const rc_stringtable *st)
{
  int i;

  for (i = 0; i < 16; i++)
    {
      rc_uint_type slen, length;
      unichar *s;

      slen = (rc_uint_type) st->strings[i].length;
      if (slen == 0xffffffff) slen = 0;
      s = st->strings[i].string;

      length = 2 + slen * 2;
      if (wrbfd)
	{
	  bfd_byte *hp;
	  rc_uint_type j;

	  hp = (bfd_byte *) reswr_alloc (length);
	  windres_put_16 (wrbfd, hp, slen);

      for (j = 0; j < slen; j++)
	    windres_put_16 (wrbfd, hp + 2 + j * 2, s[j]);
	  set_windres_bfd_content (wrbfd, hp, off, length);
    }
      off += length;
    }
  return off;
}

/* Convert an ASCII string to a unicode binary string.  This always
   returns exactly one bindata structure.  */

static rc_uint_type
string_to_unicode_bin (windres_bfd *wrbfd, rc_uint_type off, const char *s)
{
  rc_uint_type len;

  len = (rc_uint_type) strlen (s);

  if (wrbfd)
    {
      rc_uint_type i;
      bfd_byte *hp;

      hp = (bfd_byte *) reswr_alloc ((len + 1) * sizeof (unichar));

      for (i = 0; i < len; i++)
	windres_put_16 (wrbfd, hp + i * 2, s[i]);
      windres_put_16 (wrbfd, hp + i * 2, 0);
      set_windres_bfd_content (wrbfd, hp, off, (len + 1) * sizeof (unichar));
    }
  off += (rc_uint_type) ((len + 1) * sizeof (unichar));
  return off;
}

static rc_uint_type
res_to_bin_toolbar (windres_bfd *wrbfd, rc_uint_type off, rc_toolbar *tb)
{
  if (wrbfd)
    {
      struct bin_toolbar bt;
      windres_put_32 (wrbfd, bt.button_width, tb->button_width);
      windres_put_32 (wrbfd, bt.button_height, tb->button_height);
      windres_put_32 (wrbfd, bt.nitems, tb->nitems);
      set_windres_bfd_content (wrbfd, &bt, off, BIN_TOOLBAR_SIZE);
      if (tb->nitems > 0)
	{
	  rc_toolbar_item *it;
	  bfd_byte *ids;
	  rc_uint_type i = 0;

	  ids = (bfd_byte *) reswr_alloc (tb->nitems * 4);
	  it=tb->items;
	  while(it != NULL)
	    {
	      windres_put_32 (wrbfd, ids + i, it->id.u.id);
	      i += 4;
	      it = it->next;
	    }
	  set_windres_bfd_content (wrbfd, ids, off + BIN_TOOLBAR_SIZE, i);
 	}
    }
  off += BIN_TOOLBAR_SIZE + tb->nitems * 4;

  return off;
}

/* Convert a versioninfo resource to binary.  */

static rc_uint_type
res_to_bin_versioninfo (windres_bfd *wrbfd, rc_uint_type off,
			const rc_versioninfo *versioninfo)
{
  rc_uint_type off_delta = off;
  rc_uint_type start;
  struct bin_versioninfo bvi;
  rc_ver_info *vi;

  start = off;
  off += BIN_VERSIONINFO_SIZE;
  off = string_to_unicode_bin (wrbfd, off, "VS_VERSION_INFO");
  off += (4 - ((off - off_delta) & 3)) & 3;

  if (versioninfo->fixed != NULL)
    {
      if (wrbfd)
	{
	  struct bin_fixed_versioninfo bfv;
	  const rc_fixed_versioninfo *fi;

      fi = versioninfo->fixed;
	  windres_put_32 (wrbfd, bfv.sig1, 0xfeef04bd);
	  windres_put_32 (wrbfd, bfv.sig2, 0x10000);
	  windres_put_32 (wrbfd, bfv.file_version, fi->file_version_ms);
	  windres_put_32 (wrbfd, bfv.file_version_ls, fi->file_version_ls);
	  windres_put_32 (wrbfd, bfv.product_version_ms, fi->product_version_ms);
	  windres_put_32 (wrbfd, bfv.product_version_ls, fi->product_version_ls);
	  windres_put_32 (wrbfd, bfv.file_flags_mask, fi->file_flags_mask);
	  windres_put_32 (wrbfd, bfv.file_flags, fi->file_flags);
	  windres_put_32 (wrbfd, bfv.file_os, fi->file_os);
	  windres_put_32 (wrbfd, bfv.file_type, fi->file_type);
	  windres_put_32 (wrbfd, bfv.file_subtype, fi->file_subtype);
	  windres_put_32 (wrbfd, bfv.file_date_ms, fi->file_date_ms);
	  windres_put_32 (wrbfd, bfv.file_date_ls, fi->file_date_ls);
	  set_windres_bfd_content (wrbfd, &bfv, off, BIN_FIXED_VERSIONINFO_SIZE);
	}
      off += BIN_FIXED_VERSIONINFO_SIZE;
    }

  for (vi = versioninfo->var; vi != NULL; vi = vi->next)
    {
      struct bin_ver_info bv;
      rc_uint_type bv_off;

      off += (4 - ((off - off_delta) & 3)) & 3;

      bv_off = off;

      off += BIN_VER_INFO_SIZE;

      switch (vi->type)
	{
	default:
	  abort ();
	case VERINFO_STRING:
	  {
	    const rc_ver_stringtable *vst;

	    off = string_to_unicode_bin (wrbfd, off, "StringFileInfo");

	    if (!vi->u.string.stringtables)
	      off += (4 - ((off - off_delta) & 3)) & 3;

	    for (vst = vi->u.string.stringtables; vst != NULL; vst = vst->next)
	      {
		struct bin_ver_info bvst;
		rc_uint_type vst_off;
		const rc_ver_stringinfo *vs;

		off += (4 - ((off - off_delta) & 3)) & 3;

		vst_off = off;
		off += BIN_VER_INFO_SIZE;

		off = unicode_to_bin (wrbfd, off, vst->language);

		for (vs = vst->strings; vs != NULL; vs = vs->next)
		  {
		    struct bin_ver_info bvs;
		    rc_uint_type vs_off, str_off;

		    off += (4 - ((off - off_delta) & 3)) & 3;

		    vs_off = off;
		    off += BIN_VER_INFO_SIZE;

		    off = unicode_to_bin (wrbfd, off, vs->key);

		    off += (4 - ((off - off_delta) & 3)) & 3;

		    str_off = off;
		    off = unicode_to_bin (wrbfd, off, vs->value);

		    if (wrbfd)
		      {
			windres_put_16 (wrbfd, bvs.size, off - vs_off);
			windres_put_16 (wrbfd, bvs.sig1, (off - str_off) / 2);
			windres_put_16 (wrbfd, bvs.sig2, 1);
			set_windres_bfd_content (wrbfd, &bvs, vs_off,
						 BIN_VER_INFO_SIZE);
		      }
		  }

		if (wrbfd)
		  {
		    windres_put_16 (wrbfd, bvst.size, off - vst_off);
		    windres_put_16 (wrbfd, bvst.sig1, 0);
		    windres_put_16 (wrbfd, bvst.sig2, 1);
		    set_windres_bfd_content (wrbfd, &bvst, vst_off,
					     BIN_VER_INFO_SIZE);
		  }
	      }
	    break;
	  }

	case VERINFO_VAR:
	  {
	    rc_uint_type vvd_off, vvvd_off;
	    struct bin_ver_info bvvd;
	    const rc_ver_varinfo *vv;

	    off = string_to_unicode_bin (wrbfd, off, "VarFileInfo");

	    off += (4 - ((off - off_delta) & 3)) & 3;

	    vvd_off = off;
	    off += BIN_VER_INFO_SIZE;

	    off = unicode_to_bin (wrbfd, off, vi->u.var.key);

	    off += (4 - ((off - off_delta) & 3)) & 3;

	    vvvd_off = off;

	    for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
	      {
		if (wrbfd)
		  {
		    bfd_byte vvsd[4];

		    windres_put_16 (wrbfd, &vvsd[0], vv->language);
		    windres_put_16 (wrbfd, &vvsd[2], vv->charset);
		    set_windres_bfd_content (wrbfd, vvsd, off, 4);
		  }
		off += 4;
	      }
	    if (wrbfd)
	    {
		windres_put_16 (wrbfd, bvvd.size, off - vvd_off);
		windres_put_16 (wrbfd, bvvd.sig1, off - vvvd_off);
		windres_put_16 (wrbfd, bvvd.sig2, 0);
		set_windres_bfd_content (wrbfd, &bvvd, vvd_off,
					 BIN_VER_INFO_SIZE);
	    }

	    break;
	  }
	}

      if (wrbfd)
	{
	  windres_put_16 (wrbfd, bv.size, off - bv_off);
	  windres_put_16 (wrbfd, bv.sig1, 0);
	  windres_put_16 (wrbfd, bv.sig2, 1);
	  set_windres_bfd_content (wrbfd, &bv, bv_off,
	  			   BIN_VER_INFO_SIZE);
	}
    }

  if (wrbfd)
    {
      windres_put_16 (wrbfd, bvi.size, off - start);
      windres_put_16 (wrbfd, bvi.fixed_size,
		      versioninfo->fixed == NULL ? 0
		      				 : BIN_FIXED_VERSIONINFO_SIZE);
      windres_put_16 (wrbfd, bvi.sig2, 0);
      set_windres_bfd_content (wrbfd, &bvi, start, BIN_VER_INFO_SIZE);
    }
  return off;
}

/* Convert a generic resource to binary.  */

static rc_uint_type
res_to_bin_generic (windres_bfd *wrbfd, rc_uint_type off, rc_uint_type length,
		    const bfd_byte *data)
{
  if (wrbfd && length != 0)
    set_windres_bfd_content (wrbfd, data, off, length);
  return off + (rc_uint_type) length;
}
