Add "info connections" command, "info inferiors" connection number/string
[deliverable/binutils-gdb.git] / binutils / resres.c
index 39264f445a22749999ffaa1ed29bdfc5edb1ba21..115c983756326f88eee2813978d2f71def1f4300 100644 (file)
@@ -1,13 +1,13 @@
 /* resres.c: read_res_file and write_res_file implementation for windres.
 /* resres.c: read_res_file and write_res_file implementation for windres.
-
-   Copyright 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998-2020 Free Software Foundation, Inc.
    Written by Anders Norlander <anorland@hem2.passagen.se>.
    Written by Anders Norlander <anorland@hem2.passagen.se>.
+   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
 
    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 2 of the License, or
+   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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    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., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* FIXME: This file does not work correctly in a cross configuration.
+   It assumes that it can use fread and fwrite to read and write
+   integers.  It does no swapping.  */
 
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "bucomm.h"
 #include "libiberty.h"
 #include "windres.h"
 
 #include <assert.h>
 #include "bfd.h"
 #include "bucomm.h"
 #include "libiberty.h"
 #include "windres.h"
 
 #include <assert.h>
-#include <time.h>
-
-struct res_hdr
-  {
-    unsigned long data_size;
-    unsigned long header_size;
-  };
-
-static void write_res_directory
-  PARAMS ((const struct res_directory *,
-          const struct res_id *, const struct res_id *,
-          int *, int));
-static void write_res_resource
-  PARAMS ((const struct res_id *, const struct res_id *,
-          const struct res_resource *, int *));
-static void write_res_bin
-  PARAMS ((const struct res_resource *, const struct res_id *,
-          const struct res_id *, const struct res_res_info *));
-
-static void write_res_id PARAMS ((const struct res_id *));
-static void write_res_info PARAMS ((const struct res_res_info *));
-static void write_res_data PARAMS ((const void *, size_t, int));
-static void write_res_header
-  PARAMS ((unsigned long, const struct res_id *, const struct res_id *,
-          const struct res_res_info *));
-
-static int read_resource_entry PARAMS ((void));
-static void read_res_data PARAMS ((void *, size_t, int));
-static void read_res_id PARAMS ((struct res_id *));
-static unichar *read_unistring PARAMS ((int *));
-static void skip_null_resource PARAMS ((void));
-
-static unsigned long get_id_size PARAMS ((const struct res_id *));
-static void res_align_file PARAMS ((void));
 
 
-static void
-  res_add_resource
-  PARAMS ((struct res_resource *, const struct res_id *,
-          const struct res_id *, int, int));
+static rc_uint_type write_res_directory (windres_bfd *, rc_uint_type,
+                                        const rc_res_directory *, const rc_res_id *,
+                                        const rc_res_id *, rc_uint_type *, int);
+static rc_uint_type write_res_resource (windres_bfd *, rc_uint_type,const rc_res_id *,
+                                       const rc_res_id *, const rc_res_resource *,
+                                       rc_uint_type *);
+static rc_uint_type write_res_bin (windres_bfd *, rc_uint_type, const rc_res_resource *,
+                                  const rc_res_id *, const rc_res_id *,
+                                  const rc_res_res_info *);
 
 
-void
-  res_append_resource
-  PARAMS ((struct res_directory **, struct res_resource *,
-          int, const struct res_id *, int));
+static rc_uint_type write_res_id (windres_bfd *, rc_uint_type, const rc_res_id *);
+static rc_uint_type write_res_info (windres_bfd *, rc_uint_type, const rc_res_res_info *);
+static rc_uint_type write_res_data_hdr (windres_bfd *, rc_uint_type, res_hdr *);
+
+static rc_uint_type write_res_header (windres_bfd *, rc_uint_type, rc_uint_type,
+                                     const rc_res_id *, const rc_res_id *,
+                                     const rc_res_res_info *);
+
+static int read_resource_entry (windres_bfd *, rc_uint_type *, rc_uint_type);
+static void read_res_data (windres_bfd *, rc_uint_type *, rc_uint_type, void *,
+                          rc_uint_type);
+static void read_res_data_hdr (windres_bfd *, rc_uint_type *, rc_uint_type, res_hdr *);
+static void read_res_id (windres_bfd *, rc_uint_type *, rc_uint_type, rc_res_id *);
+static unichar *read_unistring (windres_bfd *, rc_uint_type *, rc_uint_type, rc_uint_type *);
+static void skip_null_resource (windres_bfd *, rc_uint_type *, rc_uint_type);
+static int probe_binary (windres_bfd *wrbfd, rc_uint_type);
+
+static unsigned long get_id_size (const rc_res_id *);
 
 
-static struct res_directory *resources = NULL;
+static void res_add_resource (rc_res_resource *, const rc_res_id *,
+                             const rc_res_id *, rc_uint_type, int);
+
+static void res_append_resource (rc_res_directory **, rc_res_resource *,
+                                int, const rc_res_id *, int);
+
+static rc_res_directory *resources = NULL;
 
 
-static FILE *fres;
 static const char *filename;
 
 extern char *program_name;
 
 /* Read resource file */
 static const char *filename;
 
 extern char *program_name;
 
 /* Read resource file */
-struct res_directory *
-read_res_file (fn)
-     const char *fn;
+rc_res_directory *
+read_res_file (const char *fn)
 {
 {
+  rc_uint_type off, flen;
+  windres_bfd wrbfd;
+  bfd *abfd;
+  asection *sec;
   filename = fn;
   filename = fn;
-  fres = fopen (filename, "rb");
-  if (fres == NULL)
-    fatal ("can't open `%s' for output: %s", filename, strerror (errno));
 
 
-  skip_null_resource ();
+  flen = (rc_uint_type) get_file_size (filename);
+  if (! flen)
+    fatal ("can't open '%s' for input.", filename);
+  abfd = windres_open_as_binary (filename, 1);
+  sec = bfd_get_section_by_name (abfd, ".data");
+  if (sec == NULL)
+    bfd_fatal ("bfd_get_section_by_name");
+  set_windres_bfd (&wrbfd, abfd, sec,
+                  (target_is_bigendian ? WR_KIND_BFD_BIN_B
+                                       : WR_KIND_BFD_BIN_L));
+  off = 0;
+
+  if (! probe_binary (&wrbfd, flen))
+    set_windres_bfd_endianness (&wrbfd, ! target_is_bigendian);
+
+  skip_null_resource (&wrbfd, &off, flen);
 
 
-  while (read_resource_entry ())
+  while (read_resource_entry (&wrbfd, &off, flen))
     ;
 
     ;
 
-  fclose (fres);
+  bfd_close (abfd);
 
   return resources;
 }
 
 /* Write resource file */
 void
 
   return resources;
 }
 
 /* Write resource file */
 void
-write_res_file (fn, resdir)
-     const char *fn;
-     const struct res_directory *resdir;
+write_res_file (const char *fn,const rc_res_directory *resdir)
 {
 {
-  int language;
-  static const unsigned char sign[] =
+  asection *sec;
+  rc_uint_type language;
+  bfd *abfd;
+  windres_bfd wrbfd;
+  unsigned long sec_length = 0,sec_length_wrote;
+  static const bfd_byte sign[] =
   {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
    0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
    0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-  long fpos;
 
   filename = fn;
 
 
   filename = fn;
 
-  fres = fopen (filename, "wb");
-  if (fres == NULL)
-    fatal ("can't open `%s' for output: %s", filename, strerror (errno));
+  abfd = windres_open_as_binary (filename, 0);
+  sec = bfd_make_section_with_flags (abfd, ".data",
+                                    (SEC_HAS_CONTENTS | SEC_ALLOC
+                                     | SEC_LOAD | SEC_DATA));
+  if (sec == NULL)
+    bfd_fatal ("bfd_make_section");
+  /* Requiring this is probably a bug in BFD.  */
+  sec->output_section = sec;
 
 
-  /* Write 32 bit resource signature */
-  write_res_data (sign, sizeof (sign), 1);
-
-  /* write resources */
+  set_windres_bfd (&wrbfd, abfd, sec,
+                  (target_is_bigendian ? WR_KIND_BFD_BIN_B
+                                       : WR_KIND_BFD_BIN_L));
 
   language = -1;
 
   language = -1;
-  write_res_directory (resdir, (const struct res_id *) NULL,
-                      (const struct res_id *) NULL, &language, 1);
-
-  /* end file on DWORD boundary */
-  fpos = ftell (fres);
-  if (fpos % 4)
-    write_res_data (sign, fpos % 4, 1);
-
-  fclose (fres);
+  sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
+                                   (const rc_res_id *) NULL,
+                                   (const rc_res_id *) NULL, &language, 1);
+  if (!bfd_set_section_size (sec, (sec_length + 3) & ~3))
+    bfd_fatal ("bfd_set_section_size");
+  if ((sec_length & 3) != 0)
+    set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3));
+  set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign));
+  language = -1;
+  sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir,
+                                         (const rc_res_id *) NULL,
+                                         (const rc_res_id *) NULL,
+                                         &language, 1);
+  if (sec_length != sec_length_wrote)
+    fatal ("res write failed with different sizes (%lu/%lu).",
+          (unsigned long) sec_length, (unsigned long) sec_length_wrote);
+
+  bfd_close (abfd);
+  return;
 }
 
 /* Read a resource entry, returns 0 when all resources are read */
 static int
 }
 
 /* Read a resource entry, returns 0 when all resources are read */
 static int
-read_resource_entry (void)
+read_resource_entry (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax)
 {
 {
-  struct res_id type;
-  struct res_id name;
-  struct res_res_info resinfo;
-  struct res_hdr reshdr;
-  long version;
+  rc_res_id type;
+  rc_res_id name;
+  rc_res_res_info resinfo;
+  res_hdr reshdr;
   void *buff;
 
   void *buff;
 
-  struct res_resource *r;
+  rc_res_resource *r;
+  struct bin_res_info l;
 
 
-  res_align_file ();
+  off[0] = (off[0] + 3) & ~3;
 
   /* Read header */
 
   /* Read header */
-  if (fread (&reshdr, sizeof (reshdr), 1, fres) != 1)
+  if ((off[0] + 8) > omax)
     return 0;
     return 0;
+  read_res_data_hdr (wrbfd, off, omax, &reshdr);
 
   /* read resource type */
 
   /* read resource type */
-  read_res_id (&type);
+  read_res_id (wrbfd, off, omax, &type);
   /* read resource id */
   /* read resource id */
-  read_res_id (&name);
+  read_res_id (wrbfd, off, omax, &name);
 
 
-  res_align_file ();
+  off[0] = (off[0] + 3) & ~3;
 
   /* Read additional resource header */
 
   /* Read additional resource header */
-  read_res_data (&resinfo.version, sizeof (resinfo.version), 1);
-  read_res_data (&resinfo.memflags, sizeof (resinfo.memflags), 1);
-  read_res_data (&resinfo.language, sizeof (resinfo.language), 1);
-  read_res_data (&version, sizeof (version), 1);
-  read_res_data (&resinfo.characteristics, sizeof (resinfo.characteristics), 1);
+  read_res_data (wrbfd, off, omax, &l, BIN_RES_INFO_SIZE);
+  resinfo.version = windres_get_32 (wrbfd, l.version, 4);
+  resinfo.memflags = windres_get_16 (wrbfd, l.memflags, 2);
+  resinfo.language = windres_get_16 (wrbfd, l.language, 2);
+  /* resinfo.version2 = windres_get_32 (wrbfd, l.version2, 4); */
+  resinfo.characteristics = windres_get_32 (wrbfd, l.characteristics, 4);
 
 
-  res_align_file ();
+  off[0] = (off[0] + 3) & ~3;
 
   /* Allocate buffer for data */
   buff = res_alloc (reshdr.data_size);
   /* Read data */
 
   /* Allocate buffer for data */
   buff = res_alloc (reshdr.data_size);
   /* Read data */
-  read_res_data (buff, reshdr.data_size, 1);
+  read_res_data (wrbfd, off, omax, buff, reshdr.data_size);
   /* Convert binary data to resource */
   /* Convert binary data to resource */
-  r = bin_to_res (type, buff, reshdr.data_size, 0);
+  r = bin_to_res (wrbfd, type, buff, reshdr.data_size);
   r->res_info = resinfo;
   /* Add resource to resource directory */
   res_add_resource (r, &type, &name, resinfo.language, 0);
   r->res_info = resinfo;
   /* Add resource to resource directory */
   res_add_resource (r, &type, &name, resinfo.language, 0);
@@ -184,15 +211,12 @@ read_resource_entry (void)
 }
 
 /* write resource directory to binary resource file */
 }
 
 /* write resource directory to binary resource file */
-static void
-write_res_directory (rd, type, name, language, level)
-     const struct res_directory *rd;
-     const struct res_id *type;
-     const struct res_id *name;
-     int *language;
-     int level;
+static rc_uint_type
+write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_directory *rd,
+                    const rc_res_id *type, const rc_res_id *name, rc_uint_type *language,
+                    int level)
 {
 {
-  const struct res_entry *re;
+  const rc_res_entry *re;
 
   for (re = rd->entries; re != NULL; re = re->next)
     {
 
   for (re = rd->entries; re != NULL; re = re->next)
     {
@@ -208,15 +232,15 @@ write_res_directory (rd, type, name, language, level)
 
        case 2:
          /* If we're at level 2, the key of this resource is the name
 
        case 2:
          /* If we're at level 2, the key of this resource is the name
-            we are going to use in the rc printout. */
+            we are going to use in the rc printout.  */
          name = &re->id;
          break;
 
        case 3:
          /* If we're at level 3, then this key represents a language.
             Use it to update the current language.  */
          name = &re->id;
          break;
 
        case 3:
          /* If we're at level 3, then this key represents a language.
             Use it to update the current language.  */
-         if (!re->id.named
-             && re->id.u.id != *language
+         if (! re->id.named
+             && re->id.u.id != (unsigned long) *language
              && (re->id.u.id & 0xffff) == re->id.u.id)
            {
              *language = re->id.u.id;
              && (re->id.u.id & 0xffff) == re->id.u.id)
            {
              *language = re->id.u.id;
@@ -228,7 +252,8 @@ write_res_directory (rd, type, name, language, level)
        }
 
       if (re->subdir)
        }
 
       if (re->subdir)
-       write_res_directory (re->u.dir, type, name, language, level + 1);
+       off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
+                                  level + 1);
       else
        {
          if (level == 3)
       else
        {
          if (level == 3)
@@ -238,25 +263,25 @@ write_res_directory (rd, type, name, language, level)
                 2, and represents the name to use.  We probably just
                 set LANGUAGE, and it will probably match what the
                 resource itself records if anything.  */
                 2, and represents the name to use.  We probably just
                 set LANGUAGE, and it will probably match what the
                 resource itself records if anything.  */
-             write_res_resource (type, name, re->u.res, language);
+             off = write_res_resource (wrbfd, off, type, name, re->u.res,
+                                       language);
            }
          else
            {
              fprintf (stderr, "// Resource at unexpected level %d\n", level);
            }
          else
            {
              fprintf (stderr, "// Resource at unexpected level %d\n", level);
-             write_res_resource (type, (struct res_id *) NULL, re->u.res,
-                                 language);
+             off = write_res_resource (wrbfd, off, type, (rc_res_id *) NULL,
+                                       re->u.res, language);
            }
        }
     }
 
            }
        }
     }
 
+  return off;
 }
 
 }
 
-static void
-write_res_resource (type, name, res, language)
-     const struct res_id *type;
-     const struct res_id *name;
-     const struct res_resource *res;
-     int *language;
+static rc_uint_type
+write_res_resource (windres_bfd *wrbfd, rc_uint_type off, const rc_res_id *type,
+                   const rc_res_id *name, const rc_res_resource *res,
+                   rc_uint_type *language ATTRIBUTE_UNUSED)
 {
   int rt;
 
 {
   int rt;
 
@@ -324,11 +349,15 @@ write_res_resource (type, name, res, language)
     case RES_TYPE_VERSIONINFO:
       rt = RT_VERSION;
       break;
     case RES_TYPE_VERSIONINFO:
       rt = RT_VERSION;
       break;
+
+    case RES_TYPE_TOOLBAR:
+      rt = RT_TOOLBAR;
+      break;
     }
 
   if (rt != 0
       && type != NULL
     }
 
   if (rt != 0
       && type != NULL
-      && (type->named || type->u.id != rt))
+      && (type->named || type->u.id != (unsigned long) rt))
     {
       fprintf (stderr, "// Unexpected resource type mismatch: ");
       res_id_print (stderr, *type, 1);
     {
       fprintf (stderr, "// Unexpected resource type mismatch: ");
       res_id_print (stderr, *type, 1);
@@ -336,35 +365,28 @@ write_res_resource (type, name, res, language)
       abort ();
     }
 
       abort ();
     }
 
-  write_res_bin (res, type, name, &res->res_info);
-  return;
+  return write_res_bin (wrbfd, off, res, type, name, &res->res_info);
 }
 
 /* Write a resource in binary resource format */
 }
 
 /* Write a resource in binary resource format */
-static void
-write_res_bin (res, type, name, resinfo)
-     const struct res_resource *res;
-     const struct res_id *type;
-     const struct res_id *name;
-     const struct res_res_info *resinfo;
+static rc_uint_type
+write_res_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res,
+              const rc_res_id *type, const rc_res_id *name,
+              const rc_res_res_info *resinfo)
 {
 {
-  unsigned long datasize = 0;
-  const struct bindata *bin_rep, *data;
-
-  bin_rep = res_to_bin (res, 0);
-  for (data = bin_rep; data != NULL; data = data->next)
-    datasize += data->length;
+  rc_uint_type noff;
+  rc_uint_type datasize = 0;
 
 
-  write_res_header (datasize, type, name, resinfo);
+  noff = res_to_bin ((windres_bfd *) NULL, off, res);
+  datasize = noff - off;
 
 
-  for (data = bin_rep; data != NULL; data = data->next)
-    write_res_data (data->data, data->length, 1);
+  off = write_res_header (wrbfd, off, datasize, type, name, resinfo);
+  return res_to_bin (wrbfd, off, res);
 }
 
 /* Get number of bytes needed to store an id in binary format */
 static unsigned long
 }
 
 /* Get number of bytes needed to store an id in binary format */
 static unsigned long
-get_id_size (id)
-     const struct res_id *id;
+get_id_size (const rc_res_id *id)
 {
   if (id->named)
     return sizeof (unichar) * (id->u.n.length + 1);
 {
   if (id->named)
     return sizeof (unichar) * (id->u.n.length + 1);
@@ -373,106 +395,142 @@ get_id_size (id)
 }
 
 /* Write a resource header */
 }
 
 /* Write a resource header */
-static void
-write_res_header (datasize, type, name, resinfo)
-     unsigned long datasize;
-     const struct res_id *type;
-     const struct res_id *name;
-     const struct res_res_info *resinfo;
+static rc_uint_type
+write_res_header (windres_bfd *wrbfd, rc_uint_type off, rc_uint_type datasize,
+                 const rc_res_id *type, const rc_res_id *name,
+                 const rc_res_res_info *resinfo)
 {
 {
-  struct res_hdr reshdr;
+  res_hdr reshdr;
   reshdr.data_size = datasize;
   reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);
 
   reshdr.data_size = datasize;
   reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);
 
-  res_align_file ();
-  write_res_data (&reshdr, sizeof (reshdr), 1);
-  write_res_id (type);
-  write_res_id (name);
+  reshdr.header_size = (reshdr.header_size + 3) & ~3;
 
 
-  res_align_file ();
+  off = (off + 3) & ~3;
 
 
-  write_res_info (resinfo);
-  res_align_file ();
+  off = write_res_data_hdr (wrbfd, off, &reshdr);
+  off = write_res_id (wrbfd, off, type);
+  off = write_res_id (wrbfd, off, name);
+
+  off = (off + 3) & ~3;
+
+  off = write_res_info (wrbfd, off, resinfo);
+  off = (off + 3) & ~3;
+  return off;
 }
 
 }
 
+static rc_uint_type
+write_res_data_hdr (windres_bfd *wrbfd, rc_uint_type off, res_hdr *hdr)
+{
+  if (wrbfd)
+    {
+      struct bin_res_hdr brh;
+      windres_put_32 (wrbfd, brh.data_size, hdr->data_size);
+      windres_put_32 (wrbfd, brh.header_size, hdr->header_size);
+      set_windres_bfd_content (wrbfd, &brh, off, BIN_RES_HDR_SIZE);
+    }
+  return off + BIN_RES_HDR_SIZE;
+}
 
 
-/* Write data to file, abort on failure */
 static void
 static void
-write_res_data (data, size, count)
-     const void *data;
-     size_t size;
-     int count;
+read_res_data_hdr (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax,
+                  res_hdr *reshdr)
 {
 {
-  if (fwrite (data, size, count, fres) != count)
-    fatal ("%s: %s: could not write to file", program_name, filename);
+  struct bin_res_hdr brh;
+
+  if ((off[0] + BIN_RES_HDR_SIZE) > omax)
+    fatal ("%s: unexpected end of file %ld/%ld", filename,(long) off[0], (long) omax);
+
+  get_windres_bfd_content (wrbfd, &brh, off[0], BIN_RES_HDR_SIZE);
+  reshdr->data_size = windres_get_32 (wrbfd, brh.data_size, 4);
+  reshdr->header_size = windres_get_32 (wrbfd, brh.header_size, 4);
+  off[0] += BIN_RES_HDR_SIZE;
 }
 
 /* Read data from file, abort on failure */
 static void
 }
 
 /* Read data from file, abort on failure */
 static void
-read_res_data (data, size, count)
-     void *data;
-     size_t size;
-     int count;
+read_res_data (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, void *data,
+              rc_uint_type size)
 {
 {
-  if (fread (data, size, count, fres) != count)
-    fatal ("%s: %s: unexpected end of file", program_name, filename);
+  if ((off[0] + size) > omax)
+    fatal ("%s: unexpected end of file %ld/%ld %ld", filename,(long) off[0],
+          (long) omax, (long) size);
+  get_windres_bfd_content (wrbfd, data, off[0], size);
+  off[0] += size;
 }
 
 /* Write a resource id */
 }
 
 /* Write a resource id */
-static void
-write_res_id (id)
-     const struct res_id *id;
+static rc_uint_type
+write_res_id (windres_bfd *wrbfd, rc_uint_type off, const rc_res_id *id)
 {
   if (id->named)
     {
 {
   if (id->named)
     {
-      unsigned long len = id->u.n.length;
-      unichar null_term = 0;
-      write_res_data (id->u.n.name, len * sizeof (unichar), 1);
-      write_res_data (&null_term, sizeof (null_term), 1);
+      rc_uint_type len = (((bfd_signed_vma) id->u.n.length < 0 ? 0 : id->u.n.length) + 1);
+      if (wrbfd)
+       {
+         rc_uint_type i;
+         bfd_byte *d = (bfd_byte *) xmalloc (len * sizeof (unichar));
+         for (i = 0; i < (len - 1); i++)
+           windres_put_16 (wrbfd, d + (i * sizeof (unichar)), id->u.n.name[i]);
+         windres_put_16 (wrbfd, d + (i * sizeof (unichar)), 0);
+         set_windres_bfd_content (wrbfd, d, off, (len * sizeof (unichar)));
+       }
+      off += (len * sizeof (unichar));
     }
   else
     {
     }
   else
     {
-      unsigned short i = 0xFFFF;
-      write_res_data (&i, sizeof (i), 1);
-      i = id->u.id;
-      write_res_data (&i, sizeof (i), 1);
+      if (wrbfd)
+       {
+         struct bin_res_id bid;
+         windres_put_16 (wrbfd, bid.sig, 0xffff);
+         windres_put_16 (wrbfd, bid.id, id->u.id);
+         set_windres_bfd_content (wrbfd, &bid, off, BIN_RES_ID);
+       }
+      off += BIN_RES_ID;
     }
     }
+  return off;
 }
 
 /* Write resource info */
 }
 
 /* Write resource info */
-static void
-write_res_info (info)
-     const struct res_res_info *info;
+static rc_uint_type
+write_res_info (windres_bfd *wrbfd, rc_uint_type off, const rc_res_res_info *info)
 {
 {
-  write_res_data (&info->version, sizeof (info->version), 1);
-  write_res_data (&info->memflags, sizeof (info->memflags), 1);
-  write_res_data (&info->language, sizeof (info->language), 1);
-  write_res_data (&info->version, sizeof (info->version), 1);
-  write_res_data (&info->characteristics, sizeof (info->characteristics), 1);
+  if (wrbfd)
+    {
+      struct bin_res_info l;
+
+      windres_put_32 (wrbfd, l.version, info->version);
+      windres_put_16 (wrbfd, l.memflags, info->memflags);
+      windres_put_16 (wrbfd, l.language, info->language);
+      windres_put_32 (wrbfd, l.version2, info->version);
+      windres_put_32 (wrbfd, l.characteristics, info->characteristics);
+      set_windres_bfd_content (wrbfd, &l, off, BIN_RES_INFO_SIZE);
+    }
+  return off + BIN_RES_INFO_SIZE;
 }
 
 /* read a resource identifier */
 }
 
 /* read a resource identifier */
-void 
-read_res_id (id)
-     struct res_id *id;
+static void
+read_res_id (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, rc_res_id *id)
 {
 {
+  struct bin_res_id bid;
   unsigned short ord;
   unichar *id_s = NULL;
   unsigned short ord;
   unichar *id_s = NULL;
-  int len;
+  rc_uint_type len;
 
 
-  read_res_data (&ord, sizeof (ord), 1);
+  read_res_data (wrbfd, off, omax, &bid, BIN_RES_ID - 2);
+  ord = (unsigned short) windres_get_16 (wrbfd, bid.sig, 2);
   if (ord == 0xFFFF)           /* an ordinal id */
     {
   if (ord == 0xFFFF)           /* an ordinal id */
     {
-      read_res_data (&ord, sizeof (ord), 1);
+      read_res_data (wrbfd, off, omax, bid.id, BIN_RES_ID - 2);
       id->named = 0;
       id->named = 0;
-      id->u.id = ord;
+      id->u.id = windres_get_16 (wrbfd, bid.id, 2);
     }
   else
     /* named id */
     {
     }
   else
     /* named id */
     {
-      if (fseek (fres, -sizeof (ord), SEEK_CUR) != 0)
-       fatal ("%s: %s: could not seek in file", program_name, filename);
-      id_s = read_unistring (&len);
+      off[0] -= 2;
+      id_s = read_unistring (wrbfd, off, omax, &len);
       id->named = 1;
       id->u.n.length = len;
       id->u.n.name = id_s;
       id->named = 1;
       id->u.n.length = len;
       id->u.n.name = id_s;
@@ -481,37 +539,62 @@ read_res_id (id)
 
 /* Read a null terminated UNICODE string */
 static unichar *
 
 /* Read a null terminated UNICODE string */
 static unichar *
-read_unistring (len)
-     int *len;
+read_unistring (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax,
+               rc_uint_type *len)
 {
   unichar *s;
 {
   unichar *s;
+  bfd_byte d[2];
   unichar c;
   unichar *p;
   unichar c;
   unichar *p;
-  int l;
+  rc_uint_type l;
+  rc_uint_type soff = off[0];
 
 
-  *len = 0;
-  l = 0;
+  do
+    {
+      read_res_data (wrbfd, &soff, omax, d, sizeof (unichar));
+      c = windres_get_16 (wrbfd, d, 2);
+    }
+  while (c != 0);
+  l = ((soff - off[0]) / sizeof (unichar));
 
 
-  /* there are hardly any names longer than 256 characters */
-  p = s = (unichar *) xmalloc (sizeof (unichar) * 256);
+  /* there are hardly any names longer than 256 characters, but anyway. */
+  p = s = (unichar *) xmalloc (sizeof (unichar) * l);
   do
     {
   do
     {
-      read_res_data (&c, sizeof (c), 1);
+      read_res_data (wrbfd, off, omax, d, sizeof (unichar));
+      c = windres_get_16 (wrbfd, d, 2);
       *p++ = c;
       *p++ = c;
-      if (c != 0)
-       l++;
     }
   while (c != 0);
     }
   while (c != 0);
-  *len = l;
+  *len = l - 1;
   return s;
 }
 
   return s;
 }
 
-/* align file on DWORD boundary */
-static void
-res_align_file (void)
+static int
+probe_binary (windres_bfd *wrbfd, rc_uint_type omax)
 {
 {
-  if (fseek (fres, ftell (fres) % 4, SEEK_CUR) != 0)
-    fatal ("%s: %s: unable to align file", program_name, filename);
+  rc_uint_type off;
+  res_hdr reshdr;
+
+  off = 0;
+  read_res_data_hdr (wrbfd, &off, omax, &reshdr);
+  if (reshdr.data_size != 0)
+    return 1;
+  if ((reshdr.header_size != 0x20 && ! target_is_bigendian)
+      || (reshdr.header_size != 0x20000000 && target_is_bigendian))
+    return 1;
+
+  /* Subtract size of HeaderSize. DataSize has to be zero. */
+  off += 0x20 - BIN_RES_HDR_SIZE;
+  if ((off + BIN_RES_HDR_SIZE) >= omax)
+    return 1;
+  read_res_data_hdr (wrbfd, &off, omax, &reshdr);
+  /* off is advanced by BIN_RES_HDR_SIZE in read_res_data_hdr()
+     which is part of reshdr.header_size. We shouldn't take it
+     into account twice.  */
+  if ((off - BIN_RES_HDR_SIZE + reshdr.data_size + reshdr.header_size) > omax)
+    return 0;
+  return 1;
 }
 
 /* Check if file is a win32 binary resource file, if so
 }
 
 /* Check if file is a win32 binary resource file, if so
@@ -519,16 +602,19 @@ res_align_file (void)
    error.
  */
 static void
    error.
  */
 static void
-skip_null_resource (void)
+skip_null_resource (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax)
 {
 {
-  struct res_hdr reshdr =
-  {0, 0};
-  read_res_data (&reshdr, sizeof (reshdr), 1);
-  if ((reshdr.data_size != 0) || (reshdr.header_size != 0x20))
+  res_hdr reshdr;
+  read_res_data_hdr (wrbfd, off, omax, &reshdr);
+  if (reshdr.data_size != 0)
+    goto skip_err;
+  if ((reshdr.header_size != 0x20 && ! target_is_bigendian)
+    || (reshdr.header_size != 0x20000000 && target_is_bigendian))
     goto skip_err;
 
     goto skip_err;
 
-  /* Subtract size of HeaderSize and DataSize */
-  if (fseek (fres, reshdr.header_size - 8, SEEK_CUR) != 0)
+  /* Subtract size of HeaderSize. DataSize has to be zero. */
+  off[0] += 0x20 - BIN_RES_HDR_SIZE;
+  if (off[0] >= omax)
     goto skip_err;
 
   return;
     goto skip_err;
 
   return;
@@ -540,15 +626,11 @@ skip_err:
 }
 
 /* Add a resource to resource directory */
 }
 
 /* Add a resource to resource directory */
-void
-res_add_resource (r, type, id, language, dupok)
-     struct res_resource *r;
-     const struct res_id *type;
-     const struct res_id *id;
-     int language;
-     int dupok;
+static void
+res_add_resource (rc_res_resource *r, const rc_res_id *type, const rc_res_id *id,
+                 rc_uint_type language, int dupok)
 {
 {
-  struct res_id a[3];
+  rc_res_id a[3];
 
   a[0] = *type;
   a[1] = *id;
 
   a[0] = *type;
   a[1] = *id;
@@ -561,41 +643,33 @@ res_add_resource (r, type, id, language, dupok)
    This is just copied from define_resource
    and modified to add an existing resource.
  */
    This is just copied from define_resource
    and modified to add an existing resource.
  */
-void
-res_append_resource (resources, resource, cids, ids, dupok)
-     struct res_directory **resources;
-     struct res_resource *resource;
-     int cids;
-     const struct res_id *ids;
-     int dupok;
+static void
+res_append_resource (rc_res_directory **res_dirs, rc_res_resource *resource,
+                    int cids, const rc_res_id *ids, int dupok)
 {
 {
-  struct res_entry *re = NULL;
+  rc_res_entry *re = NULL;
   int i;
 
   assert (cids > 0);
   for (i = 0; i < cids; i++)
     {
   int i;
 
   assert (cids > 0);
   for (i = 0; i < cids; i++)
     {
-      struct res_entry **pp;
+      rc_res_entry **pp;
 
 
-      if (*resources == NULL)
+      if (*res_dirs == NULL)
        {
        {
-         static unsigned long timeval;
-
-         /* Use the same timestamp for every resource created in a
-            single run.  */
-         if (timeval == 0)
-           timeval = time (NULL);
-
-         *resources = ((struct res_directory *)
-                       res_alloc (sizeof **resources));
-         (*resources)->characteristics = 0;
-         (*resources)->time = timeval;
-         (*resources)->major = 0;
-         (*resources)->minor = 0;
-         (*resources)->entries = NULL;
+         *res_dirs = ((rc_res_directory *)
+                       res_alloc (sizeof (rc_res_directory)));
+
+         (*res_dirs)->characteristics = 0;
+         /* Using a real timestamp only serves to create non-deterministic
+            results.  Use zero instead.  */
+         (*res_dirs)->time = 0;
+         (*res_dirs)->major = 0;
+         (*res_dirs)->minor = 0;
+         (*res_dirs)->entries = NULL;
        }
 
        }
 
-      for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
+      for (pp = &(*res_dirs)->entries; *pp != NULL; pp = &(*pp)->next)
        if (res_id_cmp ((*pp)->id, ids[i]) == 0)
          break;
 
        if (res_id_cmp ((*pp)->id, ids[i]) == 0)
          break;
 
@@ -603,7 +677,7 @@ res_append_resource (resources, resource, cids, ids, dupok)
        re = *pp;
       else
        {
        re = *pp;
       else
        {
-         re = (struct res_entry *) res_alloc (sizeof *re);
+         re = (rc_res_entry *) res_alloc (sizeof (rc_res_entry));
          re->next = NULL;
          re->id = ids[i];
          if ((i + 1) < cids)
          re->next = NULL;
          re->id = ids[i];
          if ((i + 1) < cids)
@@ -622,7 +696,7 @@ res_append_resource (resources, resource, cids, ids, dupok)
 
       if ((i + 1) < cids)
        {
 
       if ((i + 1) < cids)
        {
-         if (!re->subdir)
+         if (! re->subdir)
            {
              fprintf (stderr, "%s: ", program_name);
              res_ids_print (stderr, i, ids);
            {
              fprintf (stderr, "%s: ", program_name);
              res_ids_print (stderr, i, ids);
@@ -630,7 +704,7 @@ res_append_resource (resources, resource, cids, ids, dupok)
              xexit (1);
            }
 
              xexit (1);
            }
 
-         resources = &re->u.dir;
+         res_dirs = &re->u.dir;
        }
     }
 
        }
     }
 
This page took 0.032435 seconds and 4 git commands to generate.