aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'binutils')
-rw-r--r--binutils/Makefile.am10
-rw-r--r--binutils/Makefile.in28
-rw-r--r--binutils/ar.c21
-rw-r--r--binutils/doc/binutils.texi11
-rw-r--r--binutils/is-ranlib.c5
-rw-r--r--binutils/is-strip.c6
-rw-r--r--binutils/nm.c29
-rw-r--r--binutils/not-ranlib.c5
-rw-r--r--binutils/not-strip.c6
-rw-r--r--binutils/objcopy.c56
-rw-r--r--binutils/resbin.c439
-rw-r--r--binutils/rescoff.c216
-rw-r--r--binutils/resrc.c9
-rw-r--r--binutils/resres.c42
-rw-r--r--binutils/testsuite/binutils-all/nm-coff-1.s26
-rw-r--r--binutils/testsuite/binutils-all/nm-coff-sdef-1.s26
-rw-r--r--binutils/testsuite/binutils-all/nm.exp6
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp1
-rw-r--r--binutils/testsuite/binutils-all/section-alignment.d9
-rw-r--r--binutils/testsuite/binutils-all/set-section-alignment.d4
-rw-r--r--binutils/windres.c30
-rw-r--r--binutils/windres.h6
22 files changed, 706 insertions, 285 deletions
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index 20c711a..1528302 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -255,7 +255,7 @@ LDADD = $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
size_SOURCES = size.c $(BULIBS)
-objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+objcopy_SOURCES = not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
strings_SOURCES = strings.c $(BULIBS)
@@ -265,7 +265,7 @@ readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
-strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+strip_new_SOURCES = is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
@@ -287,13 +287,13 @@ endif
cxxfilt_SOURCES = cxxfilt.c $(BULIBS)
-ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \
+ar_SOURCES = arparse.y arlex.l not-ranlib.c arsup.c rename.c binemul.c \
emul_$(EMULATION).c $(BULIBS)
EXTRA_ar_SOURCES = $(CFILES)
ar_LDADD = $(BFDLIB) $(LIBIBERTY) $(LEXLIB) $(LIBINTL)
-ranlib_SOURCES = ar.c is-ranlib.c arparse.y arlex.l arsup.c rename.c \
- binemul.c emul_$(EMULATION).c $(BULIBS)
+ranlib_SOURCES = arparse.y arlex.l is-ranlib.c arsup.c rename.c binemul.c \
+ emul_$(EMULATION).c $(BULIBS)
ranlib_LDADD = $(BFDLIB) $(LIBIBERTY) $(LEXLIB) $(LIBINTL)
addr2line_SOURCES = addr2line.c $(BULIBS)
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index 8029bc2..549b5a3 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -208,9 +208,9 @@ AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
-am_ar_OBJECTS = arparse.$(OBJEXT) arlex.$(OBJEXT) ar.$(OBJEXT) \
- not-ranlib.$(OBJEXT) arsup.$(OBJEXT) rename.$(OBJEXT) \
- binemul.$(OBJEXT) emul_$(EMULATION).$(OBJEXT) $(am__objects_1)
+am_ar_OBJECTS = arparse.$(OBJEXT) arlex.$(OBJEXT) not-ranlib.$(OBJEXT) \
+ arsup.$(OBJEXT) rename.$(OBJEXT) binemul.$(OBJEXT) \
+ emul_$(EMULATION).$(OBJEXT) $(am__objects_1)
ar_OBJECTS = $(am_ar_OBJECTS)
bfdtest1_SOURCES = bfdtest1.c
bfdtest1_OBJECTS = bfdtest1.$(OBJEXT)
@@ -240,8 +240,8 @@ nm_new_LDADD = $(LDADD)
am__objects_3 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \
rdcoff.$(OBJEXT)
am__objects_4 = $(am__objects_3) wrstabs.$(OBJEXT)
-am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \
- rename.$(OBJEXT) $(am__objects_4) $(am__objects_1)
+am_objcopy_OBJECTS = not-strip.$(OBJEXT) rename.$(OBJEXT) \
+ $(am__objects_4) $(am__objects_1)
objcopy_OBJECTS = $(am_objcopy_OBJECTS)
objcopy_LDADD = $(LDADD)
am_objdump_OBJECTS = objdump.$(OBJEXT) dwarf.$(OBJEXT) prdbg.$(OBJEXT) \
@@ -249,8 +249,8 @@ am_objdump_OBJECTS = objdump.$(OBJEXT) dwarf.$(OBJEXT) prdbg.$(OBJEXT) \
$(am__objects_2)
objdump_OBJECTS = $(am_objdump_OBJECTS)
@ENABLE_LIBCTF_TRUE@am__DEPENDENCIES_2 = ../libctf/libctf.la
-am_ranlib_OBJECTS = ar.$(OBJEXT) is-ranlib.$(OBJEXT) arparse.$(OBJEXT) \
- arlex.$(OBJEXT) arsup.$(OBJEXT) rename.$(OBJEXT) \
+am_ranlib_OBJECTS = arparse.$(OBJEXT) arlex.$(OBJEXT) \
+ is-ranlib.$(OBJEXT) arsup.$(OBJEXT) rename.$(OBJEXT) \
binemul.$(OBJEXT) emul_$(EMULATION).$(OBJEXT) $(am__objects_1)
ranlib_OBJECTS = $(am_ranlib_OBJECTS)
am_readelf_OBJECTS = readelf.$(OBJEXT) version.$(OBJEXT) \
@@ -268,8 +268,8 @@ srconv_LDADD = $(LDADD)
am_strings_OBJECTS = strings.$(OBJEXT) $(am__objects_1)
strings_OBJECTS = $(am_strings_OBJECTS)
strings_LDADD = $(LDADD)
-am_strip_new_OBJECTS = objcopy.$(OBJEXT) is-strip.$(OBJEXT) \
- rename.$(OBJEXT) $(am__objects_4) $(am__objects_1)
+am_strip_new_OBJECTS = is-strip.$(OBJEXT) rename.$(OBJEXT) \
+ $(am__objects_4) $(am__objects_1)
strip_new_OBJECTS = $(am_strip_new_OBJECTS)
strip_new_LDADD = $(LDADD)
am_sysdump_OBJECTS = sysdump.$(OBJEXT) $(am__objects_1)
@@ -793,25 +793,25 @@ bfdtest1_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
bfdtest2_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
LDADD = $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
size_SOURCES = size.c $(BULIBS)
-objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+objcopy_SOURCES = not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
strings_SOURCES = strings.c $(BULIBS)
readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) $(LIBSFRAME)
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
-strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+strip_new_SOURCES = is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
EXTRA_objdump_SOURCES = od-elf32_avr.c od-macho.c od-xcoff.c od-pe.c
objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS) $(LIBSFRAME)
cxxfilt_SOURCES = cxxfilt.c $(BULIBS)
-ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \
+ar_SOURCES = arparse.y arlex.l not-ranlib.c arsup.c rename.c binemul.c \
emul_$(EMULATION).c $(BULIBS)
EXTRA_ar_SOURCES = $(CFILES)
ar_LDADD = $(BFDLIB) $(LIBIBERTY) $(LEXLIB) $(LIBINTL)
-ranlib_SOURCES = ar.c is-ranlib.c arparse.y arlex.l arsup.c rename.c \
- binemul.c emul_$(EMULATION).c $(BULIBS)
+ranlib_SOURCES = arparse.y arlex.l is-ranlib.c arsup.c rename.c binemul.c \
+ emul_$(EMULATION).c $(BULIBS)
ranlib_LDADD = $(BFDLIB) $(LIBIBERTY) $(LEXLIB) $(LIBINTL)
addr2line_SOURCES = addr2line.c $(BULIBS)
diff --git a/binutils/ar.c b/binutils/ar.c
index 40cad57..de41c9e 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -67,7 +67,9 @@ static int mri_mode;
/* This flag distinguishes between ar and ranlib:
1 means this is 'ranlib'; 0 means this is 'ar'.
-1 means if we should use argv[0] to decide. */
+#ifndef is_ranlib
extern int is_ranlib;
+#endif
/* Nonzero means don't warn about creating the archive file if necessary. */
int silent_create = 0;
@@ -735,16 +737,23 @@ main (int argc, char **argv)
expandargv (&argc, &argv);
+#ifndef is_ranlib
if (is_ranlib < 0)
{
- const char *temp = lbasename (program_name);
+ size_t l = strlen (program_name);
- if (strlen (temp) >= 6
- && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
- is_ranlib = 1;
- else
- is_ranlib = 0;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* Drop the .exe suffix, if any. */
+ if (l > 4 && FILENAME_CMP (program_name + l - 4, ".exe") == 0)
+ {
+ l -= 4;
+ program_name[l] = '\0';
+ }
+#endif
+ is_ranlib = (l >= 6 &&
+ FILENAME_CMP (program_name + l - 6, "ranlib") == 0);
}
+#endif
if (bfd_init () != BFD_INIT_MAGIC)
fatal (_("fatal error: libbfd ABI mismatch"));
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 5bf5d80..c74526e 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2146,9 +2146,6 @@ Sets the section alignment field in the PE header - if one is present
in the binary. Sections in memory will always begin at addresses
which are a multiple of this number. Defaults to 0x1000.
-Note - this option will also set the alignment field in each section's
-flags.
-
Note - if a section's LMA or VMA addresses are no longer aligned, and
those addresses have not been set via the @option{--set-section-lma} or
@option{--set-section-vma} options, and the file has been fully
@@ -2704,6 +2701,14 @@ but the result again may not be as you expect.
For RISC-V, the following options are supported:
@table @code
+@item max
+Disassemble without checking architecture string. This is a best effort mode, so
+for overlapping ISA extensions the first match (possibly incorrect in a given
+context) will be used to decode the instruction. It's useful, if the ELF file
+doesn't expose ISA string, preventing automatic ISA subset deduction, and the
+default fallback ISA string (@code{rv64gc}) doesn't cover all instructions in
+the binary.
+
@item numeric
Print numeric register names, rather than ABI names (e.g., print @code{x2}
instead of @code{sp}).
diff --git a/binutils/is-ranlib.c b/binutils/is-ranlib.c
index 4a04adb..47296eb 100644
--- a/binutils/is-ranlib.c
+++ b/binutils/is-ranlib.c
@@ -17,6 +17,5 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-/* Linked with ar.o to flag that this program is 'ranlib' (not 'ar'). */
-
-int is_ranlib = 1;
+#define is_ranlib 1
+#include "ar.c"
diff --git a/binutils/is-strip.c b/binutils/is-strip.c
index 26aeaf0..4ac1035 100644
--- a/binutils/is-strip.c
+++ b/binutils/is-strip.c
@@ -17,7 +17,5 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-/* Linked with objcopy.o to flag that this program is 'strip' (not
- 'objcopy'). */
-
-int is_strip = 1;
+#define is_strip 1
+#include "objcopy.c"
diff --git a/binutils/nm.c b/binutils/nm.c
index 4e86057..7ef5d61 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -79,7 +79,15 @@ struct extended_symbol_info
#define SYM_STAB_DESC(sym) (sym->sinfo->stab_desc)
#define SYM_STAB_OTHER(sym) (sym->sinfo->stab_other)
#define SYM_SIZE(sym) \
- (sym->elfinfo ? sym->elfinfo->internal_elf_sym.st_size: sym->ssize)
+ (sym->elfinfo \
+ && sym->elfinfo->internal_elf_sym.st_size \
+ ? sym->elfinfo->internal_elf_sym.st_size \
+ : sym->coffinfo \
+ && ISFCN (sym->coffinfo->native->u.syment.n_type) \
+ && sym->coffinfo->native->u.syment.n_numaux \
+ && sym->coffinfo->native[1].u.auxent.x_sym.x_misc.x_fsize \
+ ? sym->coffinfo->native[1].u.auxent.x_sym.x_misc.x_fsize \
+ : sym->ssize)
/* The output formatting functions. */
static void print_object_filename_bsd (const char *);
@@ -1036,9 +1044,9 @@ size_forward2 (const void *P_x, const void *P_y)
return sorters[0][reverse_sort] (x->minisym, y->minisym);
}
-/* Sort the symbols by size. ELF provides a size but for other formats
- we have to make a guess by assuming that the difference between the
- address of a symbol and the address of the next higher symbol is the
+/* Sort the symbols by size. ELF and COFF may provide a size but for other
+ formats we have to make a guess by assuming that the difference between
+ the address of a symbol and the address of the next higher symbol is the
size. */
static long
@@ -1081,6 +1089,8 @@ sort_symbols_by_size (bfd *abfd, bool is_dynamic, void *minisyms,
asection *sec;
bfd_vma sz;
asymbol *temp;
+ const elf_symbol_type *elfsym;
+ const coff_symbol_type *coffsym;
if (from + size < fromend)
{
@@ -1100,8 +1110,15 @@ sort_symbols_by_size (bfd *abfd, bool is_dynamic, void *minisyms,
we can't rely on that information for the symbol size. Ditto for
bfd/section.c:global_syms like *ABS*. */
if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
- && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- sz = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ && (elfsym = elf_symbol_from (sym)) != NULL
+ && elfsym->internal_elf_sym.st_size != 0)
+ sz = elfsym->internal_elf_sym.st_size;
+ else if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
+ && (coffsym = coff_symbol_from (sym)) != NULL
+ && ISFCN (coffsym->native->u.syment.n_type)
+ && coffsym->native->u.syment.n_numaux != 0
+ && coffsym->native[1].u.auxent.x_sym.x_misc.x_fsize != 0)
+ sz = coffsym->native[1].u.auxent.x_sym.x_misc.x_fsize;
else if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
&& bfd_is_com_section (sec))
sz = sym->value;
diff --git a/binutils/not-ranlib.c b/binutils/not-ranlib.c
index 5fc0d6a..17da296 100644
--- a/binutils/not-ranlib.c
+++ b/binutils/not-ranlib.c
@@ -17,6 +17,5 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-/* Linked with ar.o to flag that this program is 'ar' (not 'ranlib'). */
-
-int is_ranlib = 0;
+#define is_ranlib 0
+#include "ar.c"
diff --git a/binutils/not-strip.c b/binutils/not-strip.c
index 5c72848..9e39da4 100644
--- a/binutils/not-strip.c
+++ b/binutils/not-strip.c
@@ -17,7 +17,5 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-/* Linked with objcopy.o to flag that this program is 'objcopy' (not
- 'strip'). */
-
-int is_strip = 0;
+#define is_strip 0
+#include "objcopy.c"
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 572f22c..31933e1 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -533,7 +533,9 @@ extern char *program_name;
/* This flag distinguishes between strip and objcopy:
1 means this is 'strip'; 0 means this is 'objcopy'.
-1 means if we should use argv[0] to decide. */
+#ifndef is_strip
extern int is_strip;
+#endif
/* The maximum length of an S record. This variable is defined in srec.c
and can be modified by the --srec-len parameter. */
@@ -4112,29 +4114,6 @@ power_of_two (bfd_vma val)
return result;
}
-static unsigned int
-image_scn_align (unsigned int alignment)
-{
- switch (alignment)
- {
- case 8192: return IMAGE_SCN_ALIGN_8192BYTES;
- case 4096: return IMAGE_SCN_ALIGN_4096BYTES;
- case 2048: return IMAGE_SCN_ALIGN_2048BYTES;
- case 1024: return IMAGE_SCN_ALIGN_1024BYTES;
- case 512: return IMAGE_SCN_ALIGN_512BYTES;
- case 256: return IMAGE_SCN_ALIGN_256BYTES;
- case 128: return IMAGE_SCN_ALIGN_128BYTES;
- case 64: return IMAGE_SCN_ALIGN_64BYTES;
- case 32: return IMAGE_SCN_ALIGN_32BYTES;
- case 16: return IMAGE_SCN_ALIGN_16BYTES;
- case 8: return IMAGE_SCN_ALIGN_8BYTES;
- case 4: return IMAGE_SCN_ALIGN_4BYTES;
- case 2: return IMAGE_SCN_ALIGN_2BYTES;
- case 1: return IMAGE_SCN_ALIGN_1BYTES;
- default: return 0;
- }
-}
-
/* Create a section in OBFD with the same
name and attributes as ISECTION in IBFD. */
@@ -4300,24 +4279,9 @@ setup_section (bfd *ibfd, sec_ptr isection, bfd *obfd)
if (p != NULL)
alignment = p->alignment;
else if (pe_section_alignment != (bfd_vma) -1
- && bfd_get_flavour (ibfd) == bfd_target_coff_flavour
- && bfd_get_flavour (obfd) == bfd_target_coff_flavour)
- {
- alignment = power_of_two (pe_section_alignment);
-
- if (coff_section_data (ibfd, isection))
- {
- struct pei_section_tdata * pei_data = pei_section_data (ibfd, isection);
-
- if (pei_data != NULL)
- {
- /* Set the alignment flag of the input section, which will
- be copied to the output section later on. */
- pei_data->pe_flags &= ~IMAGE_SCN_ALIGN_POWER_BIT_MASK;
- pei_data->pe_flags |= image_scn_align (pe_section_alignment);
- }
- }
- }
+ && bfd_get_flavour (obfd) == bfd_target_coff_flavour
+ && bfd_pei_p (obfd))
+ alignment = power_of_two (pe_section_alignment);
else
alignment = bfd_section_alignment (isection);
@@ -5979,6 +5943,11 @@ copy_main (int argc, char *argv[])
case OPTION_FILE_ALIGNMENT:
pe_file_alignment = parse_vma (optarg, "--file-alignment");
+ if (power_of_two (pe_file_alignment) == -1)
+ {
+ non_fatal (_("--file-alignment argument is not a power of two: %s - ignoring"), optarg);
+ pe_file_alignment = (bfd_vma) -1;
+ }
break;
case OPTION_HEAP:
@@ -6222,9 +6191,11 @@ main (int argc, char *argv[])
fatal (_("fatal error: libbfd ABI mismatch"));
set_default_bfd_target ();
+#ifndef is_strip
if (is_strip < 0)
{
- int i = strlen (program_name);
+ size_t i = strlen (program_name);
+
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
/* Drop the .exe suffix, if any. */
if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
@@ -6235,6 +6206,7 @@ main (int argc, char *argv[])
#endif
is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
}
+#endif /* is_strip */
create_symbol_htabs ();
xatexit (delete_symbol_htabs);
diff --git a/binutils/resbin.c b/binutils/resbin.c
index 388b016..1698e14 100644
--- a/binutils/resbin.c
+++ b/binutils/resbin.c
@@ -54,8 +54,8 @@ static rc_res_resource *bin_to_res_group_cursor (windres_bfd *, const bfd_byte *
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 *,
+static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *, rc_uint_type);
+static bool 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 *);
@@ -105,7 +105,7 @@ bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
case RT_VERSION:
return bin_to_res_version (wrbfd, data, length);
case RT_TOOLBAR:
- return bin_to_res_toolbar (wrbfd, data);
+ return bin_to_res_toolbar (wrbfd, data, length);
}
}
@@ -116,7 +116,7 @@ bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
static void
toosmall (const char *msg)
{
- fatal (_("%s: not enough binary data"), msg);
+ non_fatal (_("%s: not enough binary data"), msg);
}
/* Swap in a NULL terminated unicode string. */
@@ -132,7 +132,10 @@ get_unicode (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
while (1)
{
if (length < c * 2 + 2)
- toosmall (_("null terminated unicode string"));
+ {
+ toosmall (_("null terminated unicode string"));
+ return NULL;
+ }
if (windres_get_16 (wrbfd, data + c * 2, 2) == 0)
break;
++c;
@@ -159,13 +162,19 @@ get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data,
rc_uint_type first;
if (length < 2)
- toosmall (_("resource ID"));
+ {
+ toosmall (_("resource ID"));
+ return -1;
+ }
first = windres_get_16 (wrbfd, data, 2);
if (first == 0xffff)
{
if (length < 4)
- toosmall (_("resource ID"));
+ {
+ toosmall (_("resource ID"));
+ return -1;
+ }
id->named = 0;
id->u.id = windres_get_16 (wrbfd, data + 2, 2);
return 4;
@@ -174,6 +183,8 @@ get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data,
{
id->named = 1;
id->u.n.name = get_unicode (wrbfd, data, length, &id->u.n.length);
+ if (id->u.n.name == NULL)
+ return -1;
return id->u.n.length * 2 + 2;
}
}
@@ -204,7 +215,10 @@ bin_to_res_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
rc_res_resource *r;
if (length < 4)
- toosmall (_("cursor"));
+ {
+ toosmall (_("cursor"));
+ return NULL;
+ }
c = (rc_cursor *) res_alloc (sizeof (rc_cursor));
c->xhotspot = windres_get_16 (wrbfd, data, 2);
@@ -235,32 +249,51 @@ bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
r->u.menu = m;
if (length < 2)
- toosmall (_("menu header"));
+ {
+ toosmall (_("menu header"));
+ return NULL;
+ }
version = windres_get_16 (wrbfd, data, 2);
if (version == 0)
{
if (length < 4)
- toosmall (_("menu header"));
+ {
+ toosmall (_("menu header"));
+ return NULL;
+ }
m->help = 0;
m->items = bin_to_res_menuitems (wrbfd, data + 4, length - 4, &got);
+ if (m->items == NULL)
+ return NULL;
}
else if (version == 1)
{
rc_uint_type offset;
if (length < 8)
- toosmall (_("menuex header"));
+ {
+ toosmall (_("menuex header"));
+ return NULL;
+ }
m->help = windres_get_32 (wrbfd, data + 4, 4);
offset = windres_get_16 (wrbfd, data + 2, 2);
if (offset + 4 >= length)
- toosmall (_("menuex offset"));
+ {
+ toosmall (_("menuex offset"));
+ return NULL;
+ }
m->items = bin_to_res_menuexitems (wrbfd, data + 4 + offset,
length - (4 + offset), &got);
+ if (m->items == NULL)
+ return NULL;
}
else
- fatal (_("unsupported menu version %d"), (int) version);
+ {
+ non_fatal (_("unsupported menu version %d"), (int) version);
+ return NULL;
+ }
return r;
}
@@ -285,7 +318,10 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
rc_menuitem *mi;
if (length < 4)
- toosmall (_("menuitem header"));
+ {
+ toosmall (_("menuitem header"));
+ return NULL;
+ }
mi = (rc_menuitem *) res_alloc (sizeof *mi);
mi->state = 0;
@@ -300,7 +336,10 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
stroff = 2;
if (length < stroff + 2)
- toosmall (_("menuitem header"));
+ {
+ toosmall (_("menuitem header"));
+ return NULL;
+ }
if (windres_get_16 (wrbfd, data + stroff, 2) == 0)
{
@@ -308,7 +347,11 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
mi->text = NULL;
}
else
- mi->text = get_unicode (wrbfd, data + stroff, length - stroff, &slen);
+ {
+ mi->text = get_unicode (wrbfd, data + stroff, length - stroff, &slen);
+ if (mi->text == NULL)
+ return NULL;
+ }
itemlen = stroff + slen * 2 + 2;
@@ -324,6 +367,8 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
mi->id = 0;
mi->popup = bin_to_res_menuitems (wrbfd, data + itemlen, length - itemlen,
&subread);
+ if (mi->popup == NULL)
+ return NULL;
itemlen += subread;
}
@@ -362,7 +407,10 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type l
rc_menuitem *mi;
if (length < 16)
- toosmall (_("menuitem header"));
+ {
+ toosmall (_("menuitem header"));
+ return NULL;
+ }
mi = (rc_menuitem *) res_alloc (sizeof (rc_menuitem));
mi->type = windres_get_32 (wrbfd, data, 4);
@@ -377,7 +425,11 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type l
mi->text = NULL;
}
else
- mi->text = get_unicode (wrbfd, data + 14, length - 14, &slen);
+ {
+ mi->text = get_unicode (wrbfd, data + 14, length - 14, &slen);
+ if (mi->text == NULL)
+ return NULL;
+ }
itemlen = 14 + slen * 2 + 2;
itemlen = (itemlen + 3) &~ 3;
@@ -392,12 +444,17 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type l
rc_uint_type subread;
if (length < itemlen + 4)
- toosmall (_("menuitem"));
+ {
+ toosmall (_("menuitem"));
+ return NULL;
+ }
mi->help = windres_get_32 (wrbfd, data + itemlen, 4);
itemlen += 4;
mi->popup = bin_to_res_menuexitems (wrbfd, data + itemlen,
length - itemlen, &subread);
+ if (mi->popup == NULL)
+ return NULL;
itemlen += subread;
}
@@ -424,12 +481,16 @@ 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;
+ int ilen;
rc_uint_type off;
rc_dialog_control **pp;
rc_res_resource *r;
if (length < 18)
- toosmall (_("dialog header"));
+ {
+ toosmall (_("dialog header"));
+ return NULL;
+ }
d = (rc_dialog *) res_alloc (sizeof (rc_dialog));
@@ -447,7 +508,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
version = windres_get_16 (wrbfd, data, 2);
if (version != 1)
- fatal (_("unexpected DIALOGEX version %d"), version);
+ {
+ non_fatal (_("unexpected DIALOGEX version %d"), version);
+ return NULL;
+ }
d->ex = (rc_dialog_ex *) res_alloc (sizeof (rc_dialog_ex));
d->ex->help = windres_get_32 (wrbfd, data + 4, 4);
@@ -457,7 +521,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
}
if (length < off + 10)
- toosmall (_("dialog header"));
+ {
+ toosmall (_("dialog header"));
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data + off, 2);
d->x = windres_get_16 (wrbfd, data + off + 2, 2);
@@ -467,13 +534,19 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
off += 10;
- sublen = get_resid (wrbfd, &d->menu, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &d->menu, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
- sublen = get_resid (wrbfd, &d->class, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &d->class, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
d->caption = get_unicode (wrbfd, data + off, length - off, &sublen);
+ if (d->caption == NULL)
+ return NULL;
off += sublen * 2 + 2;
if (sublen == 0)
d->caption = NULL;
@@ -492,7 +565,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
else
{
if (length < off + 2)
- toosmall (_("dialog font point size"));
+ {
+ toosmall (_("dialog font point size"));
+ return NULL;
+ }
d->pointsize = windres_get_16 (wrbfd, data + off, 2);
off += 2;
@@ -500,7 +576,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
if (d->ex != NULL)
{
if (length < off + 4)
- toosmall (_("dialogex font information"));
+ {
+ toosmall (_("dialogex font information"));
+ return NULL;
+ }
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);
@@ -508,6 +587,8 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
}
d->font = get_unicode (wrbfd, data + off, length - off, &sublen);
+ if (d->font == NULL)
+ return NULL;
off += sublen * 2 + 2;
}
@@ -526,7 +607,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
if (d->ex == NULL)
{
if (length < off + 8)
- toosmall (_("dialog control"));
+ {
+ toosmall (_("dialog control"));
+ return NULL;
+ }
dc->style = windres_get_32 (wrbfd, data + off, 4);
dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
@@ -536,7 +620,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
else
{
if (length < off + 12)
- toosmall (_("dialogex control"));
+ {
+ toosmall (_("dialogex control"));
+ return NULL;
+ }
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);
@@ -544,7 +631,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
}
if (length < off + (d->ex != NULL ? 2 : 0) + 10)
- toosmall (_("dialog control"));
+ {
+ toosmall (_("dialog control"));
+ return NULL;
+ }
dc->x = windres_get_16 (wrbfd, data + off, 2);
dc->y = windres_get_16 (wrbfd, data + off + 2, 2);
@@ -558,14 +648,21 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
off += 10 + (d->ex != NULL ? 2 : 0);
- sublen = get_resid (wrbfd, &dc->class, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &dc->class, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
- sublen = get_resid (wrbfd, &dc->text, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &dc->text, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
if (length < off + 2)
- toosmall (_("dialog control end"));
+ {
+ toosmall (_("dialog control end"));
+ return NULL;
+ }
datalen = windres_get_16 (wrbfd, data + off, 2);
off += 2;
@@ -575,7 +672,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
else
{
if (length < off + datalen)
- toosmall (_("dialog control data"));
+ {
+ toosmall (_("dialog control data"));
+ return NULL;
+ }
dc->data = ((rc_rcdata_item *)
res_alloc (sizeof (rc_rcdata_item)));
@@ -615,7 +715,10 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
unsigned int slen;
if (length < 2)
- toosmall (_("stringtable string length"));
+ {
+ toosmall (_("stringtable string length"));
+ return NULL;
+ }
slen = windres_get_16 (wrbfd, data, 2);
st->strings[i].length = slen;
@@ -625,7 +728,10 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
unsigned int j;
if (length < 2 + 2 * slen)
- toosmall (_("stringtable string"));
+ {
+ toosmall (_("stringtable string"));
+ return NULL;
+ }
s = (unichar *) res_alloc (slen * sizeof (unichar));
st->strings[i].string = s;
@@ -655,7 +761,10 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_res_resource *r;
if (length < 2)
- toosmall (_("fontdir header"));
+ {
+ toosmall (_("fontdir header"));
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data, 2);
@@ -669,7 +778,10 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
unsigned int off;
if (length < 56)
- toosmall (_("fontdir"));
+ {
+ toosmall (_("fontdir"));
+ return NULL;
+ }
bfi = (const struct bin_fontdir_item *) data;
fd = (rc_fontdir *) res_alloc (sizeof *fd);
@@ -686,13 +798,19 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
while (off < length && data[off] != '\0')
++off;
if (off >= length)
- toosmall (_("fontdir device name"));
+ {
+ toosmall (_("fontdir device name"));
+ return NULL;
+ }
++off;
while (off < length && data[off] != '\0')
++off;
if (off >= length)
- toosmall (_("fontdir face name"));
+ {
+ toosmall (_("fontdir face name"));
+ return NULL;
+ }
++off;
fd->length = off;
@@ -732,7 +850,10 @@ bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
rc_accelerator *a;
if (length < 8)
- toosmall (_("accelerator"));
+ {
+ toosmall (_("accelerator"));
+ return NULL;
+ }
a = (rc_accelerator *) res_alloc (sizeof (rc_accelerator));
@@ -791,11 +912,17 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
rc_res_resource *r;
if (length < 6)
- toosmall (_("group cursor header"));
+ {
+ toosmall (_("group cursor header"));
+ return NULL;
+ }
type = windres_get_16 (wrbfd, data + 2, 2);
if (type != 2)
- fatal (_("unexpected group cursor type %d"), type);
+ {
+ non_fatal (_("unexpected group cursor type %d"), type);
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data + 4, 2);
@@ -810,7 +937,10 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
rc_group_cursor *gc;
if (length < 14)
- toosmall (_("group cursor"));
+ {
+ toosmall (_("group cursor"));
+ return NULL;
+ }
gc = (rc_group_cursor *) res_alloc (sizeof *gc);
@@ -846,11 +976,17 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
rc_res_resource *r;
if (length < 6)
- toosmall (_("group icon header"));
+ {
+ toosmall (_("group icon header"));
+ return NULL;
+ }
type = windres_get_16 (wrbfd, data + 2, 2);
if (type != 1)
- fatal (_("unexpected group icon type %d"), type);
+ {
+ non_fatal (_("unexpected group icon type %d"), type);
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data + 4, 2);
@@ -865,7 +1001,10 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
rc_group_icon *gi;
if (length < 14)
- toosmall (_("group icon"));
+ {
+ toosmall (_("group icon"));
+ return NULL;
+ }
gi = (rc_group_icon *) res_alloc (sizeof (rc_group_icon));
@@ -897,14 +1036,17 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
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
+static bool
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);
+ {
+ toosmall (key);
+ return false;
+ }
*len = (windres_get_16 (wrbfd, data, 2) + 3) & ~3;
*vallen = windres_get_16 (wrbfd, data + 2, 2);
@@ -920,6 +1062,8 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_uint_type sublen;
*pkey = get_unicode (wrbfd, data, length, &sublen);
+ if (*pkey == NULL)
+ return false;
*off += (sublen + 1) * sizeof (unichar);
}
else
@@ -927,9 +1071,15 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
while (1)
{
if (length < 2)
- toosmall (key);
+ {
+ toosmall (key);
+ return false;
+ }
if (windres_get_16 (wrbfd, data, 2) != (bfd_byte) *key)
- fatal (_("unexpected version string"));
+ {
+ non_fatal (_("unexpected version string"));
+ return false;
+ }
*off += 2;
length -= 2;
@@ -943,6 +1093,7 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
}
*off = (*off + 3) &~ 3;
+ return true;
}
/* Convert a version resource from binary. */
@@ -956,16 +1107,23 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_versioninfo *v;
rc_res_resource *r;
- get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
- (unichar **) NULL, &verlen, &vallen, &type, &off);
+ if (!get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
+ (unichar **) NULL, &verlen, &vallen, &type, &off))
+ return NULL;
/* 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);
+ {
+ non_fatal (_("version length %lu greater than resource length %lu"),
+ (unsigned long) verlen, (unsigned long) length);
+ return NULL;
+ }
if (type != 0)
- fatal (_("unexpected version type %d"), (int) type);
+ {
+ non_fatal (_("unexpected version type %d"), (int) type);
+ return NULL;
+ }
/* PR 27686: Ignore any padding bytes after the end of the version structure. */
length = verlen;
@@ -980,18 +1138,31 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
unsigned long signature, fiv;
if (vallen != 52)
- fatal (_("unexpected fixed version information length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected fixed version information length %ld"),
+ (long) vallen);
+ return NULL;
+ }
if (length < 52)
- toosmall (_("fixed version info"));
+ {
+ toosmall (_("fixed version info"));
+ return NULL;
+ }
signature = windres_get_32 (wrbfd, data, 4);
if (signature != 0xfeef04bd)
- fatal (_("unexpected fixed version signature %lu"), signature);
+ {
+ non_fatal (_("unexpected fixed version signature %lu"), signature);
+ return NULL;
+ }
fiv = windres_get_32 (wrbfd, data + 4, 4);
if (fiv != 0 && fiv != 0x10000)
- fatal (_("unexpected fixed version info version %lu"), fiv);
+ {
+ non_fatal (_("unexpected fixed version info version %lu"), fiv);
+ return NULL;
+ }
fi = (rc_fixed_versioninfo *) res_alloc (sizeof (rc_fixed_versioninfo));
@@ -1020,7 +1191,10 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
int ch;
if (length < 8)
- toosmall (_("version var info"));
+ {
+ toosmall (_("version var info"));
+ return NULL;
+ }
vi = (rc_ver_info *) res_alloc (sizeof (rc_ver_info));
@@ -1032,12 +1206,17 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
vi->type = VERINFO_STRING;
- get_version_header (wrbfd, data, length, "StringFileInfo",
- (unichar **) NULL, &verlen, &vallen, &type,
- &off);
+ if (!get_version_header (wrbfd, data, length, "StringFileInfo",
+ (unichar **) NULL, &verlen, &vallen, &type,
+ &off))
+ return NULL;
if (vallen != 0)
- fatal (_("unexpected stringfileinfo value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected stringfileinfo value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
data += off;
length -= off;
@@ -1054,15 +1233,24 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_ver_stringinfo **ppvs;
if (length < 8)
- toosmall (_("version stringtable"));
+ {
+ toosmall (_("version stringtable"));
+ return NULL;
+ }
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 (!get_version_header (wrbfd, data, length, (const char *) NULL,
+ &vst->language, &stverlen, &vallen,
+ &type, &off))
+ return NULL;
if (vallen != 0)
- fatal (_("unexpected version stringtable value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected version stringtable value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
data += off;
length -= off;
@@ -1079,30 +1267,42 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_uint_type sverlen, vslen, valoff;
if (length < 8)
- toosmall (_("version string"));
+ {
+ toosmall (_("version string"));
+ return NULL;
+ }
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);
+ if (!get_version_header (wrbfd, data, length, (const char *) NULL,
+ &vs->key, &sverlen, &vallen, &type, &off))
+ return NULL;
data += off;
length -= off;
vs->value = get_unicode (wrbfd, data, length, &vslen);
+ if (vs->value == NULL)
+ return NULL;
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);
+ {
+ non_fatal (_("unexpected version string length %ld != %ld + %ld"),
+ (long) sverlen, (long) off, (long) valoff);
+ return NULL;
+ }
data += valoff;
length -= valoff;
if (stverlen < sverlen)
- fatal (_("unexpected version string length %ld < %ld"),
- (long) verlen, (long) sverlen);
+ {
+ non_fatal (_("unexpected version string length %ld < %ld"),
+ (long) verlen, (long) sverlen);
+ return NULL;
+ }
stverlen -= sverlen;
verlen -= sverlen;
@@ -1122,18 +1322,25 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
vi->type = VERINFO_VAR;
- get_version_header (wrbfd, data, length, "VarFileInfo",
- (unichar **) NULL, &verlen, &vallen, &type,
- &off);
+ if (!get_version_header (wrbfd, data, length, "VarFileInfo",
+ (unichar **) NULL, &verlen, &vallen,
+ &type, &off))
+ return NULL;
if (vallen != 0)
- fatal (_("unexpected varfileinfo value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected varfileinfo value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
data += off;
length -= off;
- get_version_header (wrbfd, data, length, (const char *) NULL,
- &vi->u.var.key, &verlen, &vallen, &type, &off);
+ if (!get_version_header (wrbfd, data, length, (const char *) NULL,
+ &vi->u.var.key, &verlen, &vallen,
+ &type, &off))
+ return NULL;
data += off;
length -= off;
@@ -1146,7 +1353,10 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_ver_varinfo *vv;
if (length < 4)
- toosmall (_("version varfileinfo"));
+ {
+ toosmall (_("version varfileinfo"));
+ return NULL;
+ }
vv = (rc_ver_varinfo *) res_alloc (sizeof (rc_ver_varinfo));
@@ -1161,7 +1371,11 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
length -= 4;
if (vallen < 4)
- fatal (_("unexpected version value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected version value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
vallen -= 4;
}
@@ -1171,10 +1385,14 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
if (length == 8)
/* Padding - skip. */
break;
- fatal (_("nul bytes found in version string"));
+ non_fatal (_("nul bytes found in version string"));
+ return NULL;
}
else
- fatal (_("unexpected version string character: %x"), ch);
+ {
+ non_fatal (_("unexpected version string character: %x"), ch);
+ return NULL;
+ }
vi->next = NULL;
*pp = vi;
@@ -1216,12 +1434,18 @@ bin_to_res_userdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
}
static rc_res_resource *
-bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
+bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
rc_toolbar *ri;
rc_res_resource *r;
rc_uint_type i;
+ if (length < 12)
+ {
+ toosmall (_("toolbar"));
+ return NULL;
+ }
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);
@@ -1229,14 +1453,18 @@ bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
ri->items = NULL;
data += 12;
- for (i=0 ; i < ri->nitems; i++)
+ length -= 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;
+ if (length < 4)
+ toosmall (_("toolbar item"));
it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
it->prev = it->next = NULL;
data += 4;
+ length -= 4;
if(ri->items) {
rc_toolbar_item *ii = ri->items;
while (ii->next != NULL)
@@ -1740,11 +1968,12 @@ res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *i
if (wrbfd)
{
windres_put_16 (wrbfd, bmi.flags, flags);
- if (mi->popup == NULL)
+ 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);
+ (mi->popup == NULL
+ ? BIN_MENUITEM_SIZE
+ : BIN_MENUITEM_POPUP_SIZE));
}
off += (mi->popup == NULL ? BIN_MENUITEM_SIZE : BIN_MENUITEM_POPUP_SIZE);
@@ -1855,22 +2084,22 @@ res_to_bin_rcdata (windres_bfd *wrbfd, rc_uint_type off, const rc_rcdata_item *i
break;
case RCDATA_STRING:
hp = (bfd_byte *) ri->u.string.s;
- break;
- case RCDATA_WSTRING:
- {
+ break;
+ case RCDATA_WSTRING:
+ {
rc_uint_type i;
hp = (bfd_byte *) reswr_alloc (len);
- for (i = 0; i < ri->u.wstring.length; i++)
+ 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:
+ case RCDATA_BUFFER:
hp = (bfd_byte *) ri->u.buffer.data;
- break;
- }
+ break;
+ }
set_windres_bfd_content (wrbfd, hp, off, len);
- }
+ }
off += len;
}
return off;
@@ -1902,10 +2131,10 @@ res_to_bin_stringtable (windres_bfd *wrbfd, rc_uint_type off,
hp = (bfd_byte *) reswr_alloc (length);
windres_put_16 (wrbfd, hp, slen);
- for (j = 0; j < slen; j++)
+ 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;
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
index f9a1e70..98e5eb0 100644
--- a/binutils/rescoff.c
+++ b/binutils/rescoff.c
@@ -120,27 +120,38 @@ read_coff_rsrc (const char *filename, const char *target)
struct coff_file_info flaginfo;
if (filename == NULL)
- fatal (_("filename required for COFF input"));
+ {
+ non_fatal (_("filename required for COFF input"));
+ return NULL;
+ }
abfd = bfd_openr (filename, target);
if (abfd == NULL)
- bfd_fatal (filename);
+ {
+ bfd_nonfatal (filename);
+ return NULL;
+ }
if (! bfd_check_format_matches (abfd, bfd_object, &matching))
{
bfd_nonfatal (bfd_get_filename (abfd));
if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
list_matching_formats (matching);
- xexit (1);
+ free (matching);
+ return NULL;
}
if (bfd_get_flavour (abfd) != bfd_target_coff_flavour
|| !obj_pe (abfd))
- fatal (_("%s: not a PE file"), filename);
+ {
+ non_fatal (_("%s: not a PE file"), filename);
+ return NULL;
+ }
sec = bfd_get_section_by_name (abfd, ".rsrc");
if (sec == NULL)
{
- fatal (_("%s: no resource section"), filename);
+ non_fatal (_("%s: no resource section"), filename);
+ return NULL;
}
set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);
@@ -150,7 +161,10 @@ read_coff_rsrc (const char *filename, const char *target)
but there is no other way to determine if the section size
is reasonable. */
if (size > (bfd_size_type) get_file_size (filename))
- fatal (_("%s: .rsrc section is bigger than the file!"), filename);
+ {
+ non_fatal (_("%s: .rsrc section is bigger than the file!"), filename);
+ return NULL;
+ }
data = (bfd_byte *) res_alloc (size);
get_windres_bfd_content (&wrbfd, data, 0, size);
@@ -178,7 +192,7 @@ read_coff_rsrc (const char *filename, const char *target)
static void
overrun (const struct coff_file_info *flaginfo, const char *msg)
{
- fatal (_("%s: %s: address out of bounds"), flaginfo->filename, msg);
+ non_fatal (_("%s: %s: address out of bounds"), flaginfo->filename, msg);
}
/* Read a resource directory. */
@@ -199,10 +213,16 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
Microsoft only defines 3 levels. Corrupt files however might
claim to use more. */
if (level > 4)
- fatal (_("%s: resources nest too deep"), flaginfo->filename);
+ {
+ non_fatal (_("%s: resources nest too deep"), flaginfo->filename);
+ return NULL;
+ }
if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_directory))
- overrun (flaginfo, _("directory"));
+ {
+ overrun (flaginfo, _("directory"));
+ return NULL;
+ }
erd = (const struct extern_res_directory *) data;
@@ -230,7 +250,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
int length, j;
if ((const bfd_byte *) ere >= flaginfo->data_end)
- overrun (flaginfo, _("named directory entry"));
+ {
+ overrun (flaginfo, _("named directory entry"));
+ return NULL;
+ }
name = windres_get_32 (wrbfd, ere->name, 4);
rva = windres_get_32 (wrbfd, ere->rva, 4);
@@ -239,7 +262,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
name &=~ 0x80000000;
if (name > (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("directory entry name"));
+ {
+ overrun (flaginfo, _("directory entry name"));
+ return NULL;
+ }
ers = flaginfo->data + name;
@@ -252,8 +278,12 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
for (j = 0; j < length; j++)
{
/* PR 17512: file: 05dc4a16. */
- if (length < 0 || ers >= flaginfo->data_end || ers + j * 2 + 4 >= flaginfo->data_end)
- overrun (flaginfo, _("resource name"));
+ if (length < 0 || ers >= flaginfo->data_end
+ || ers + j * 2 + 4 >= flaginfo->data_end)
+ {
+ overrun (flaginfo, _("resource name"));
+ return NULL;
+ }
re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
}
@@ -264,7 +294,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
{
rva &=~ 0x80000000;
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("named subdirectory"));
+ {
+ overrun (flaginfo, _("named subdirectory"));
+ return NULL;
+ }
re->subdir = 1;
re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
level + 1);
@@ -272,7 +305,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
else
{
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("named resource"));
+ {
+ overrun (flaginfo, _("named resource"));
+ return NULL;
+ }
re->subdir = 0;
re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
}
@@ -287,7 +323,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
rc_res_entry *re;
if ((const bfd_byte *) ere >= flaginfo->data_end)
- overrun (flaginfo, _("ID directory entry"));
+ {
+ overrun (flaginfo, _("ID directory entry"));
+ return NULL;
+ }
name = windres_get_32 (wrbfd, ere->name, 4);
rva = windres_get_32 (wrbfd, ere->rva, 4);
@@ -304,7 +343,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
{
rva &=~ 0x80000000;
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("ID subdirectory"));
+ {
+ overrun (flaginfo, _("ID subdirectory"));
+ return NULL;
+ }
re->subdir = 1;
re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
level + 1);
@@ -312,7 +354,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
else
{
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("ID resource"));
+ {
+ overrun (flaginfo, _("ID resource"));
+ return NULL;
+ }
re->subdir = 0;
re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
}
@@ -337,10 +382,16 @@ read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data,
const bfd_byte *resdata;
if (type == NULL)
- fatal (_("resource type unknown"));
+ {
+ non_fatal (_("resource type unknown"));
+ return NULL;
+ }
if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_data))
- overrun (flaginfo, _("data entry"));
+ {
+ overrun (flaginfo, _("data entry"));
+ return NULL;
+ }
erd = (const struct extern_res_data *) data;
@@ -348,18 +399,26 @@ read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data,
rva = windres_get_32 (wrbfd, erd->rva, 4);
if (rva < flaginfo->secaddr
|| rva - flaginfo->secaddr >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("resource data"));
+ {
+ overrun (flaginfo, _("resource data"));
+ return NULL;
+ }
resdata = flaginfo->data + (rva - flaginfo->secaddr);
if (size > (rc_uint_type) (flaginfo->data_end - resdata))
- overrun (flaginfo, _("resource data size"));
+ {
+ overrun (flaginfo, _("resource data size"));
+ return NULL;
+ }
r = bin_to_res (wrbfd, *type, resdata, size);
-
- memset (&r->res_info, 0, sizeof (rc_res_res_info));
- r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage, 4);
- r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved, 4);
+ if (r != NULL)
+ {
+ memset (&r->res_info, 0, sizeof (rc_res_res_info));
+ r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage, 4);
+ r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved, 4);
+ }
return r;
}
@@ -422,9 +481,9 @@ struct coff_write_info
static void coff_bin_sizes (const rc_res_directory *, struct coff_write_info *);
static bfd_byte *coff_alloc (struct bindata_build *, rc_uint_type);
-static void coff_to_bin
+static bool coff_to_bin
(const rc_res_directory *, struct coff_write_info *);
-static void coff_res_to_bin
+static bool coff_res_to_bin
(const rc_res_resource *, struct coff_write_info *);
/* Write resources to a COFF file. RESOURCES should already be
@@ -435,7 +494,7 @@ static void coff_res_to_bin
would require doing the basic work of objcopy, just modifying or
adding the .rsrc section. */
-void
+bool
write_coff_file (const char *filename, const char *target,
const rc_res_directory *resources)
{
@@ -448,44 +507,77 @@ write_coff_file (const char *filename, const char *target,
unsigned long length, offset;
if (filename == NULL)
- fatal (_("filename required for COFF output"));
+ {
+ non_fatal (_("filename required for COFF output"));
+ return false;
+ }
abfd = bfd_openw (filename, target);
if (abfd == NULL)
- bfd_fatal (filename);
+ {
+ bfd_nonfatal (filename);
+ return false;
+ }
if (! bfd_set_format (abfd, bfd_object))
- bfd_fatal ("bfd_set_format");
+ {
+ bfd_nonfatal ("bfd_set_format");
+ return false;
+ }
#if defined DLLTOOL_SH
if (! bfd_set_arch_mach (abfd, bfd_arch_sh, 0))
- bfd_fatal ("bfd_set_arch_mach(sh)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(sh)");
+ return false;
+ }
#elif defined DLLTOOL_MIPS
if (! bfd_set_arch_mach (abfd, bfd_arch_mips, 0))
- bfd_fatal ("bfd_set_arch_mach(mips)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(mips)");
+ return false;
+ }
#elif defined DLLTOOL_ARM
if (! bfd_set_arch_mach (abfd, bfd_arch_arm, 0))
- bfd_fatal ("bfd_set_arch_mach(arm)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(arm)");
+ return false;
+ }
#elif defined DLLTOOL_AARCH64
if (! bfd_set_arch_mach (abfd, bfd_arch_aarch64, 0))
- bfd_fatal ("bfd_set_arch_mach(aarch64)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(aarch64)");
+ return false;
+ }
#else
/* FIXME: This is obviously i386 specific. */
if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0))
- bfd_fatal ("bfd_set_arch_mach(i386)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(i386)");
+ return false;
+ }
#endif
if (! bfd_set_file_flags (abfd, HAS_SYMS | HAS_RELOC))
- bfd_fatal ("bfd_set_file_flags");
+ {
+ bfd_nonfatal ("bfd_set_file_flags");
+ return false;
+ }
sec = bfd_make_section_with_flags (abfd, ".rsrc",
(SEC_HAS_CONTENTS | SEC_ALLOC
| SEC_LOAD | SEC_DATA | SEC_READONLY));
if (sec == NULL)
- bfd_fatal ("bfd_make_section");
+ {
+ bfd_nonfatal ("bfd_make_section");
+ return false;
+ }
if (! bfd_set_symtab (abfd, &sec->symbol, 1))
- bfd_fatal ("bfd_set_symtab");
+ {
+ bfd_nonfatal ("bfd_set_symtab");
+ return false;
+ }
/* Requiring this is probably a bug in BFD. */
sec->output_section = sec;
@@ -529,7 +621,8 @@ write_coff_file (const char *filename, const char *target,
cwi.dirstrsize = (cwi.dirstrsize + 7) & ~7;
/* Actually convert the resources to binary. */
- coff_to_bin (resources, &cwi);
+ if (!coff_to_bin (resources, &cwi))
+ return false;
/* Add another few bytes to the directory strings if needed for
alignment. */
@@ -554,7 +647,10 @@ write_coff_file (const char *filename, const char *target,
+ cwi.resources.length);
if (!bfd_set_section_size (sec, length))
- bfd_fatal ("bfd_set_section_size");
+ {
+ bfd_nonfatal ("bfd_set_section_size");
+ return false;
+ }
bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);
@@ -562,7 +658,10 @@ write_coff_file (const char *filename, const char *target,
for (d = cwi.dirs.d; d != NULL; d = d->next)
{
if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
- bfd_fatal ("bfd_set_section_contents");
+ {
+ bfd_nonfatal ("bfd_set_section_contents");
+ return false;
+ }
offset += d->length;
}
for (d = cwi.dirstrs.d; d != NULL; d = d->next)
@@ -577,17 +676,23 @@ write_coff_file (const char *filename, const char *target,
}
for (rd = cwi.resources.d; rd != NULL; rd = rd->next)
{
- res_to_bin (cwi.wrbfd, (rc_uint_type) offset, rd->res);
+ if (res_to_bin (cwi.wrbfd, (rc_uint_type) offset, rd->res)
+ == (rc_uint_type) -1)
+ return false;
offset += rd->length;
}
assert (offset == length);
if (! bfd_close (abfd))
- bfd_fatal ("bfd_close");
+ {
+ bfd_nonfatal ("bfd_close");
+ return false;
+ }
/* We allocated the relocs array using malloc. */
free (cwi.relocs);
+ return true;
}
/* Work out the sizes of the various fixed size resource directory
@@ -640,7 +745,7 @@ coff_alloc (struct bindata_build *bb, rc_uint_type size)
/* Convert the resource directory RESDIR to binary. */
-static void
+static bool
coff_to_bin (const rc_res_directory *resdir, struct coff_write_info *cwi)
{
struct extern_res_directory *erd;
@@ -701,21 +806,24 @@ coff_to_bin (const rc_res_directory *resdir, struct coff_write_info *cwi)
if (e->subdir)
{
windres_put_32 (cwi->wrbfd, ere->rva, 0x80000000 | cwi->dirs.length);
- coff_to_bin (e->u.dir, cwi);
+ if (!coff_to_bin (e->u.dir, cwi))
+ return false;
}
else
{
windres_put_32 (cwi->wrbfd, ere->rva,
- cwi->dirsize + cwi->dirstrsize + cwi->dataents.length);
+ cwi->dirsize + cwi->dirstrsize + cwi->dataents.length);
- coff_res_to_bin (e->u.res, cwi);
+ if (!coff_res_to_bin (e->u.res, cwi))
+ return false;
}
}
+ return true;
}
/* Convert the resource RES to binary. */
-static void
+static bool
coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
{
arelent *r;
@@ -735,7 +843,10 @@ coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
r->addend = 0;
r->howto = bfd_reloc_type_lookup (WR_BFD (cwi->wrbfd), BFD_RELOC_RVA);
if (r->howto == NULL)
- bfd_fatal (_("can't get BFD_RELOC_RVA relocation type"));
+ {
+ bfd_nonfatal (_("can't get BFD_RELOC_RVA relocation type"));
+ return false;
+ }
cwi->relocs = xrealloc (cwi->relocs,
(cwi->reloc_count + 2) * sizeof (arelent *));
@@ -755,6 +866,8 @@ coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
d = (coff_res_data *) reswr_alloc (sizeof (coff_res_data));
d->length = res_to_bin (NULL, (rc_uint_type) 0, res);
+ if (d->length == (rc_uint_type) -1)
+ return false;
d->res = res;
d->next = NULL;
@@ -770,4 +883,5 @@ coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
/* Force the next resource to have 64 bit alignment. */
d->length = (d->length + 7) & ~7;
+ return true;
}
diff --git a/binutils/resrc.c b/binutils/resrc.c
index d265818..8f9451b 100644
--- a/binutils/resrc.c
+++ b/binutils/resrc.c
@@ -1938,7 +1938,7 @@ indent (FILE *e, int c)
refer to that file, we use the user-data model for that to express it binary
without the need to store it somewhere externally. */
-void
+bool
write_rc_file (const char *filename, const rc_res_directory *res_dir)
{
FILE *e;
@@ -1950,12 +1950,17 @@ write_rc_file (const char *filename, const rc_res_directory *res_dir)
{
e = fopen (filename, FOPEN_WT);
if (e == NULL)
- fatal (_("can't open `%s' for output: %s"), filename, strerror (errno));
+ {
+ non_fatal (_("can't open `%s' for output: %s"),
+ filename, strerror (errno));
+ return false;
+ }
}
language = (rc_uint_type) ((bfd_signed_vma) -1);
write_rc_directory (e, res_dir, (const rc_res_id *) NULL,
(const rc_res_id *) NULL, &language, 1);
+ return true;
}
/* Write out a directory. E is the file to write to. RD is the
diff --git a/binutils/resres.c b/binutils/resres.c
index ab5aa66..d96fb14 100644
--- a/binutils/resres.c
+++ b/binutils/resres.c
@@ -109,14 +109,14 @@ read_res_file (const char *fn)
}
/* Write resource file */
-void
+bool
write_res_file (const char *fn,const rc_res_directory *resdir)
{
asection *sec;
rc_uint_type language;
bfd *abfd;
windres_bfd wrbfd;
- unsigned long sec_length = 0,sec_length_wrote;
+ rc_uint_type 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,
@@ -130,7 +130,10 @@ write_res_file (const char *fn,const rc_res_directory *resdir)
(SEC_HAS_CONTENTS | SEC_ALLOC
| SEC_LOAD | SEC_DATA));
if (sec == NULL)
- bfd_fatal ("bfd_make_section");
+ {
+ bfd_nonfatal ("bfd_make_section");
+ return false;
+ }
/* Requiring this is probably a bug in BFD. */
sec->output_section = sec;
@@ -142,8 +145,13 @@ write_res_file (const char *fn,const rc_res_directory *resdir)
sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
(const rc_res_id *) NULL,
(const rc_res_id *) NULL, &language, 1);
+ if (sec_length == (rc_uint_type) -1)
+ return false;
if (!bfd_set_section_size (sec, (sec_length + 3) & ~3))
- bfd_fatal ("bfd_set_section_size");
+ {
+ bfd_nonfatal ("bfd_set_section_size");
+ return false;
+ }
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));
@@ -152,12 +160,16 @@ write_res_file (const char *fn,const rc_res_directory *resdir)
(const rc_res_id *) NULL,
(const rc_res_id *) NULL,
&language, 1);
+ if (sec_length_wrote == (rc_uint_type) -1)
+ return false;
if (sec_length != sec_length_wrote)
- fatal ("res write failed with different sizes (%lu/%lu).",
- (unsigned long) sec_length, (unsigned long) sec_length_wrote);
+ {
+ non_fatal ("res write failed with different sizes (%lu/%lu).",
+ (unsigned long) sec_length, (unsigned long) sec_length_wrote);
+ return false;
+ }
- bfd_close (abfd);
- return;
+ return bfd_close (abfd);
}
/* Read a resource entry, returns 0 when all resources are read */
@@ -252,8 +264,12 @@ write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_director
}
if (re->subdir)
- off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
- level + 1);
+ {
+ off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
+ level + 1);
+ if (off == (rc_uint_type) -1)
+ return off;
+ }
else
{
if (level == 3)
@@ -265,12 +281,16 @@ write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_director
resource itself records if anything. */
off = write_res_resource (wrbfd, off, type, name, re->u.res,
language);
+ if (off == (rc_uint_type) -1)
+ return off;
}
else
{
fprintf (stderr, "// Resource at unexpected level %d\n", level);
off = write_res_resource (wrbfd, off, type, (rc_res_id *) NULL,
re->u.res, language);
+ if (off == (rc_uint_type) -1)
+ return off;
}
}
}
@@ -378,6 +398,8 @@ write_res_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res,
rc_uint_type datasize = 0;
noff = res_to_bin ((windres_bfd *) NULL, off, res);
+ if (noff == (rc_uint_type) -1)
+ return noff;
datasize = noff - off;
off = write_res_header (wrbfd, off, datasize, type, name, resinfo);
diff --git a/binutils/testsuite/binutils-all/nm-coff-1.s b/binutils/testsuite/binutils-all/nm-coff-1.s
new file mode 100644
index 0000000..3efc10e
--- /dev/null
+++ b/binutils/testsuite/binutils-all/nm-coff-1.s
@@ -0,0 +1,26 @@
+ .globl text_symbol1
+ .globl text_symbol2
+ .globl text_symbol3
+ .macro ENDFN name:req
+ .def \name
+ .type 0x20 /* DT_FUNC */
+ .scl 2 /* C_EXT */
+ .endef
+ .def \name
+ .scl 0xff /* C_EFCN */
+ .val .
+ .endef
+ .endm
+ .text
+text_symbol1:
+ .long 0
+ .long 0
+ .long 0
+ ENDFN text_symbol1
+text_symbol2:
+ .long 0
+ .long 0
+ ENDFN text_symbol2
+text_symbol3:
+ .long 0
+ ENDFN text_symbol3
diff --git a/binutils/testsuite/binutils-all/nm-coff-sdef-1.s b/binutils/testsuite/binutils-all/nm-coff-sdef-1.s
new file mode 100644
index 0000000..f1a10bb
--- /dev/null
+++ b/binutils/testsuite/binutils-all/nm-coff-sdef-1.s
@@ -0,0 +1,26 @@
+ .globl text_symbol1
+ .globl text_symbol2
+ .globl text_symbol3
+ .macro ENDFN name:req
+ .sdef \name
+ .type 0x20 /* DT_FUNC */
+ .scl 2 /* C_EXT */
+ .endef
+ .sdef \name
+ .scl 0xff /* C_EFCN */
+ .val .
+ .endef
+ .endm
+ .text
+text_symbol1:
+ .byte 0,0,0,0
+ .byte 0,0,0,0
+ .byte 0,0,0,0
+ ENDFN text_symbol1
+text_symbol2:
+ .byte 0,0,0,0
+ .byte 0,0,0,0
+ ENDFN text_symbol2
+text_symbol3:
+ .byte 0,0,0,0
+ ENDFN text_symbol3
diff --git a/binutils/testsuite/binutils-all/nm.exp b/binutils/testsuite/binutils-all/nm.exp
index e1b2d16..b81126b 100644
--- a/binutils/testsuite/binutils-all/nm.exp
+++ b/binutils/testsuite/binutils-all/nm.exp
@@ -163,6 +163,12 @@ if { [is_elf_format]
|| [istarget wasm32-*-*]
|| [istarget bpf-*-*]} {
set nm_1_src "nm-elf-1.s"
+} elseif {[is_coff_format] && ![istarget arm*-*-*]} {
+ if {[istarget *c4x-*-*] || [istarget *c54x-*-*]} {
+ set nm_1_src "nm-coff-sdef-1.s"
+ } else {
+ set nm_1_src "nm-coff-1.s"
+ }
} else {
set nm_1_src "nm-1.s"
}
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index a706efb..ff93fea 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -1463,7 +1463,6 @@ if [is_elf_format] {
run_dump_test "pr23633"
run_dump_test "set-section-alignment"
-run_dump_test "section-alignment"
setup_xfail "hppa*-*-*"
setup_xfail "spu-*-*"
diff --git a/binutils/testsuite/binutils-all/section-alignment.d b/binutils/testsuite/binutils-all/section-alignment.d
deleted file mode 100644
index d62528c..0000000
--- a/binutils/testsuite/binutils-all/section-alignment.d
+++ /dev/null
@@ -1,9 +0,0 @@
-#source: pr23633.s
-#PROG: objcopy
-#objcopy: --section-alignment=512
-#objdump: -P sections
-#target: [is_pecoff_format]
-
-#...
-.* Align: 512.*
-#pass
diff --git a/binutils/testsuite/binutils-all/set-section-alignment.d b/binutils/testsuite/binutils-all/set-section-alignment.d
index a193bb7..2f6379a 100644
--- a/binutils/testsuite/binutils-all/set-section-alignment.d
+++ b/binutils/testsuite/binutils-all/set-section-alignment.d
@@ -2,8 +2,8 @@
#PROG: objcopy
#objcopy: --set-section-alignment .text=16
#objdump: --section-headers
-#target: [is_elf_format]
-#xfail: rx-*-*
+#target: [is_elf_format] || [is_coff_format]
+#xfail: rx-*-* *c30-*-* z8k-*-*
#...
.*\.text.*2\*\*4
diff --git a/binutils/windres.c b/binutils/windres.c
index 18062f5..b41353b 100644
--- a/binutils/windres.c
+++ b/binutils/windres.c
@@ -1056,23 +1056,24 @@ main (int argc, char **argv)
/* Write the output file. */
reswr_init ();
+ bool ok;
switch (output_format)
{
default:
abort ();
case RES_FORMAT_RC:
- write_rc_file (output_filename, resources);
+ ok = write_rc_file (output_filename, resources);
break;
case RES_FORMAT_RES:
- write_res_file (output_filename, resources);
+ ok = write_res_file (output_filename, resources);
break;
case RES_FORMAT_COFF:
- write_coff_file (output_filename, target, resources);
+ ok = write_coff_file (output_filename, target, resources);
break;
}
- xexit (0);
- return 0;
+ xexit (ok ? 0 : 1);
+ return ok ? 0 : 1;
}
static void
@@ -1094,13 +1095,18 @@ windres_open_as_binary (const char *filename, int rdmode)
{
bfd *abfd;
- abfd = (rdmode ? bfd_openr (filename, "binary") : bfd_openw (filename, "binary"));
- if (! abfd)
- fatal ("can't open `%s' for %s", filename, (rdmode ? "input" : "output"));
-
- if (rdmode && ! bfd_check_format (abfd, bfd_object))
- fatal ("can't open `%s' for input.", filename);
-
+ if (rdmode)
+ {
+ abfd = bfd_openr (filename, "binary");
+ if (abfd == NULL || !bfd_check_format (abfd, bfd_object))
+ fatal ("can't open `%s' for input", filename);
+ }
+ else
+ {
+ abfd = bfd_openw (filename, "binary");
+ if (abfd == NULL || !bfd_set_format (abfd, bfd_object))
+ fatal ("can't open `%s' for output", filename);
+ }
return abfd;
}
diff --git a/binutils/windres.h b/binutils/windres.h
index 309564e..15c6ad0 100644
--- a/binutils/windres.h
+++ b/binutils/windres.h
@@ -35,9 +35,9 @@ extern int verbose;
extern rc_res_directory *read_rc_file (const char *, const char *, const char *, int, int);
extern rc_res_directory *read_res_file (const char *);
extern rc_res_directory *read_coff_rsrc (const char *, const char *);
-extern void write_rc_file (const char *, const rc_res_directory *);
-extern void write_res_file (const char *, const rc_res_directory *);
-extern void write_coff_file (const char *, const char *, const rc_res_directory *);
+extern bool write_rc_file (const char *, const rc_res_directory *);
+extern bool write_res_file (const char *, const rc_res_directory *);
+extern bool write_coff_file (const char *, const char *, const rc_res_directory *);
extern rc_res_resource *bin_to_res (windres_bfd *, rc_res_id, const bfd_byte *,
rc_uint_type);