diff options
author | Nick Clifton <nickc@redhat.com> | 2007-05-23 08:48:29 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2007-05-23 08:48:29 +0000 |
commit | 4a594fce16683232bbb2e239d3e3ebcfcde16d1a (patch) | |
tree | 9c141b63ef3b88f6c02f4f7c6262be435ee49c3c /binutils/resres.c | |
parent | 950c3b7d2c4101097d82395abaede0ae167a933d (diff) | |
download | gdb-4a594fce16683232bbb2e239d3e3ebcfcde16d1a.zip gdb-4a594fce16683232bbb2e239d3e3ebcfcde16d1a.tar.gz gdb-4a594fce16683232bbb2e239d3e3ebcfcde16d1a.tar.bz2 |
Updated windres tool
Diffstat (limited to 'binutils/resres.c')
-rw-r--r-- | binutils/resres.c | 540 |
1 files changed, 305 insertions, 235 deletions
diff --git a/binutils/resres.c b/binutils/resres.c index b5677d2..8b75bcf 100644 --- a/binutils/resres.c +++ b/binutils/resres.c @@ -1,6 +1,8 @@ /* resres.c: read_res_file and write_res_file implementation for windres. - Copyright 1998, 1999, 2001, 2002, 2007 Free Software Foundation, Inc. + Copyright 1998, 1999, 2001, 2002, 2007 + Free Software Foundation, Inc. Written by Anders Norlander <anorland@hem2.passagen.se>. + Rewritten by Kai Tietz, Onevision. This file is part of GNU Binutils. @@ -25,161 +27,186 @@ #include "sysdep.h" #include "bfd.h" -#include "libiberty.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 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 *); -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_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 *); -void - res_append_resource - PARAMS ((struct res_directory **, struct res_resource *, - int, const struct res_id *, int)); +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 void res_add_resource (rc_res_resource *, const rc_res_id *, + const rc_res_id *, rc_uint_type, int); -static struct res_directory *resources = NULL; +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 */ -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; - 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_endianess (&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 -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}; - long fpos; filename = fn; - fres = fopen (filename, "wb"); - if (fres == NULL) - fatal ("can't open `%s' for output: %s", filename, strerror (errno)); - - /* Write 32 bit resource signature */ - write_res_data (sign, sizeof (sign), 1); - - /* write resources */ + abfd = windres_open_as_binary (filename, 0); + sec = bfd_make_section (abfd, ".data"); + if (sec == NULL) + bfd_fatal ("bfd_make_section"); + if (! bfd_set_section_flags (abfd, sec, + (SEC_HAS_CONTENTS | SEC_ALLOC + | SEC_LOAD | SEC_DATA))) + bfd_fatal ("bfd_set_section_flags"); + /* Requiring this is probably a bug in BFD. */ + sec->output_section = sec; + + set_windres_bfd (&wrbfd, abfd, sec, + (target_is_bigendian ? WR_KIND_BFD_BIN_B + : WR_KIND_BFD_BIN_L)); 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 (abfd, 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).", (long) sec_length, + (long) sec_length_wrote); + + bfd_close (abfd); + return; } /* 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; - struct res_resource *r; + rc_res_resource *r; + struct bin_res_info l; - res_align_file (); + off[0] = (off[0] + 3) & ~3; /* Read header */ - if (fread (&reshdr, sizeof (reshdr), 1, fres) != 1) + if ((off[0] + 8) > omax) return 0; + read_res_data_hdr (wrbfd, off, omax, &reshdr); /* read resource type */ - read_res_id (&type); + read_res_id (wrbfd, off, omax, &type); /* 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_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 */ - read_res_data (buff, reshdr.data_size, 1); + read_res_data (wrbfd, off, omax, buff, reshdr.data_size); /* 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); @@ -188,15 +215,12 @@ read_resource_entry (void) } /* 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) { @@ -219,7 +243,7 @@ write_res_directory (rd, type, name, language, level) 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 + if (! re->id.named && re->id.u.id != (unsigned long) *language && (re->id.u.id & 0xffff) == re->id.u.id) { @@ -232,7 +256,8 @@ write_res_directory (rd, type, name, language, level) } 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) @@ -242,25 +267,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. */ - 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); - 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 ATTRIBUTE_UNUSED; +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; @@ -328,6 +353,10 @@ write_res_resource (type, name, res, language) case RES_TYPE_VERSIONINFO: rt = RT_VERSION; break; + + case RES_TYPE_TOOLBAR: + rt = RT_TOOLBAR; + break; } if (rt != 0 @@ -340,35 +369,29 @@ write_res_resource (type, name, res, language) 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 */ -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; + rc_uint_type noff; + rc_uint_type datasize = 0; - bin_rep = res_to_bin (res, 0); - for (data = bin_rep; data != NULL; data = data->next) - datasize += data->length; + noff = res_to_bin ((windres_bfd *) NULL, off, res); + datasize = noff - off; - write_res_header (datasize, type, name, resinfo); - - 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_id_size (id) - const struct res_id *id; + const rc_res_id *id; { if (id->named) return sizeof (unichar) * (id->u.n.length + 1); @@ -377,108 +400,142 @@ get_id_size (id) } /* 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.header_size = (reshdr.header_size + 3) & ~3; - res_align_file (); - write_res_data (&reshdr, sizeof (reshdr), 1); - write_res_id (type); - write_res_id (name); + off = (off + 3) & ~3; + + off = write_res_data_hdr (wrbfd, off, &reshdr); + off = write_res_id (wrbfd, off, type); + off = write_res_id (wrbfd, off, name); - res_align_file (); + off = (off + 3) & ~3; - write_res_info (resinfo); - res_align_file (); + 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 -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 ((size_t) fwrite (data, size, count, fres) != (size_t) count) - fatal ("%s: could not write to file", 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_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) != (size_t) count) - fatal ("%s: unexpected end of file", 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 */ -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) { - 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 { - 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 */ -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 */ -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; - 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 */ { - read_res_data (&ord, sizeof (ord), 1); + read_res_data (wrbfd, off, omax, bid.id, BIN_RES_ID - 2); id->named = 0; - id->u.id = ord; + id->u.id = windres_get_16 (wrbfd, bid.id, 2); } 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; @@ -487,39 +544,57 @@ read_res_id (id) /* 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; + bfd_byte d[2]; 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 { - 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; - if (c != 0) - l++; } while (c != 0); - *len = l; + *len = l - 1; return s; } -/* align file on DWORD boundary */ -static void -res_align_file (void) +static int +probe_binary (windres_bfd *wrbfd, rc_uint_type omax) { - int pos = ftell (fres); - int skip = ((pos + 3) & ~3) - pos; - if (fseek (fres, skip, 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); + if ((off + reshdr.data_size + reshdr.header_size) > omax) + return 0; + return 1; } /* Check if file is a win32 binary resource file, if so @@ -527,16 +602,19 @@ res_align_file (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; - /* 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; @@ -548,15 +626,11 @@ skip_err: } /* 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; @@ -569,21 +643,17 @@ res_add_resource (r, type, id, language, dupok) 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 **resources, 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++) { - struct res_entry **pp; + rc_res_entry **pp; if (*resources == NULL) { @@ -594,8 +664,8 @@ res_append_resource (resources, resource, cids, ids, dupok) if (timeval == 0) timeval = time (NULL); - *resources = ((struct res_directory *) - res_alloc (sizeof **resources)); + *resources = ((rc_res_directory *) + res_alloc (sizeof (rc_res_directory))); (*resources)->characteristics = 0; (*resources)->time = timeval; (*resources)->major = 0; @@ -611,7 +681,7 @@ res_append_resource (resources, resource, cids, ids, dupok) 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) @@ -630,7 +700,7 @@ res_append_resource (resources, resource, cids, ids, dupok) if ((i + 1) < cids) { - if (!re->subdir) + if (! re->subdir) { fprintf (stderr, "%s: ", program_name); res_ids_print (stderr, i, ids); |