This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: binutils pr 17531 for 2.25?
- From: Nicholas Clifton <nickc at redhat dot com>
- To: Matthias Klose <doko at ubuntu dot com>, Tristan Gingold <gingold at adacore dot com>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Tue, 24 Mar 2015 12:28:41 +0000
- Subject: Re: binutils pr 17531 for 2.25?
- Authentication-results: sourceware.org; auth=none
- References: <54B76668 dot 8060100 at ubuntu dot com>
Hi Matthias, Hi Tristan,
I have now committed the rest of the changes to the binutils
sub-directory. Now on to bfd...
Cheers
Nick
binutils/ChangeLog
Apply from master:
2015-02-26 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* coffgrok.c (do_type): Check for an out of range tag index.
Check for integer overflow computing array dimension.
(do_define): Likewise.
2015-02-26 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* resrc.c (write_rc_messagetable): Tighten check for invalid
message lengths.
2015-02-13 Nick Clifton <nickc@redhat.com>
* coffgrok.c (do_define): Add check for type size overflow.
* srconv.c (walk_tree_sfile): Check that enough sections are
available before parsing.
(prescan): Likewise.
2015-02-03 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* objdump.c (display_any_bfd): Fail if archives nest too deeply.
2015-01-27 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* dlltool.c (identify_search_archive): If the last archive was the
same as the current archive, terminate the loop.
* addr2line.c (slurp_symtab): If the symcount is zero, free the
symbol table pointer.
* rcparse.y: Add checks to avoid integer divide by zero.
* rescoff.c (read_coff_rsrc): Add check on the size of the
resource section.
(read_coff_res_dir): Add check on the nesting level.
Check for resource names overrunning the buffer.
* resrc.c (write_rc_messagetable): Update formatting.
Add check of 'elen' being zero.
2015-01-23 Nick Clifton <nickc@redhat.com>
* nlmconv.c (powerpc_mangle_relocs): Fix build errors introduced
by recent delta, when compiling on for a 32-bit host.
2015-01-21 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* addr2line.c (main): Call bfd_set_error_program_name.
* ar.c (main): Likewise.
* coffdump.c (main): Likewise.
* cxxfilt.c (main): Likewise.
* dlltool.c (main): Likewise.
* nlmconv.c (main): Likewise.
* nm.c (main): Likewise.
* objdump.c (main): Likewise.
* size.c (main): Likewise.
* srconv.c (main): Likewise.
* strings.c (main): Likewise.
* sysdump.c (main): Likewise.
* windmc.c (main): Likewise.
* windres.c (main): Likewise.
* objcopy.c (main): Likewise.
(copy_relocations_in_section): Check for relocs without associated
symbol pointers.
2015-01-21 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* coffgrok.c (do_type): Check that computed ref exists.
(doit): Add range checks when computing section for scope.
2015-01-08 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* ojcopy.c (copy_object): Free the symbol table if no symbols
could be loaded.
(copy_file): Use bfd_close_all_done to close files that could not
be copied.
* sysdump.c (getINT): Fail if reading off the end of the buffer.
Replace call to abort with a call to fatal.
(getCHARS): Prevetn reading off the end of the buffer.
* nlmconv.c (i386_mangle_relocs): Skip relocs without an
associated symbol.
(powerpc_mangle_relocs): Skip unrecognised relocs. Check address
range before applying a reloc.
2015-01-07 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* dlltool.c (scan_obj_file): Break loop if the last archive
displayed matches the current archive.
* objdump.c (display_any_bfd): Add a depth limit to nested archive
display in order to avoid infinite loops.
* srconv.c: Replace calls to abort with calls to fatal with an
error message.
2015-01-06 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* coffdump.c (dump_coff_section): Check for a symbol being
available before printing its name.
(main): Check the return value from coff_grok.
* coffgrok.c: Reformat and tidy.
Add range checks to most functions.
(coff_grok): Return NULL if the input bfd is not in a COFF
format.
* coffgrok.h: Reformat and tidy.
(struct coff_section): Change the nrelocs field to unsigned.
* srconv.c (main): Check the return value from coff_grok.
2015-01-05 Nick Clifton <nickc@redhat.com>
PR binutils/17512
* nm.c (print_symbol): Add 'is_synthetic' parameter. Use it to
help initialize the info.elfinfo field.
(print_size_symbols): Add 'synth_count' parameter. Use it to set
the is_synthetic parameter when calling print_symbol.
(print_symbols): Likewise.
(display_rel_file): Pass synth_count to printing function.
(display_archive): Break loop if the last archive displayed
matches the current archive.
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index a4bb426..9f3d3b1 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -4,6 +4,138 @@
2015-02-26 Nick Clifton <nickc@redhat.com>
PR binutils/17512
+ * coffgrok.c (do_type): Check for an out of range tag index.
+ Check for integer overflow computing array dimension.
+ (do_define): Likewise.
+
+ 2015-02-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * resrc.c (write_rc_messagetable): Tighten check for invalid
+ message lengths.
+
+ 2015-02-13 Nick Clifton <nickc@redhat.com>
+
+ * coffgrok.c (do_define): Add check for type size overflow.
+ * srconv.c (walk_tree_sfile): Check that enough sections are
+ available before parsing.
+ (prescan): Likewise.
+
+ 2015-02-03 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * objdump.c (display_any_bfd): Fail if archives nest too deeply.
+
+ 2015-01-27 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * dlltool.c (identify_search_archive): If the last archive was the
+ same as the current archive, terminate the loop.
+
+ * addr2line.c (slurp_symtab): If the symcount is zero, free the
+ symbol table pointer.
+
+ * rcparse.y: Add checks to avoid integer divide by zero.
+ * rescoff.c (read_coff_rsrc): Add check on the size of the
+ resource section.
+ (read_coff_res_dir): Add check on the nesting level.
+ Check for resource names overrunning the buffer.
+ * resrc.c (write_rc_messagetable): Update formatting.
+ Add check of 'elen' being zero.
+
+ 2015-01-23 Nick Clifton <nickc@redhat.com>
+
+ * nlmconv.c (powerpc_mangle_relocs): Fix build errors introduced
+ by recent delta, when compiling on for a 32-bit host.
+
+ 2015-01-21 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * addr2line.c (main): Call bfd_set_error_program_name.
+ * ar.c (main): Likewise.
+ * coffdump.c (main): Likewise.
+ * cxxfilt.c (main): Likewise.
+ * dlltool.c (main): Likewise.
+ * nlmconv.c (main): Likewise.
+ * nm.c (main): Likewise.
+ * objdump.c (main): Likewise.
+ * size.c (main): Likewise.
+ * srconv.c (main): Likewise.
+ * strings.c (main): Likewise.
+ * sysdump.c (main): Likewise.
+ * windmc.c (main): Likewise.
+ * windres.c (main): Likewise.
+ * objcopy.c (main): Likewise.
+ (copy_relocations_in_section): Check for relocs without associated
+ symbol pointers.
+
+ 2015-01-21 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffgrok.c (do_type): Check that computed ref exists.
+ (doit): Add range checks when computing section for scope.
+
+ 2015-01-08 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * ojcopy.c (copy_object): Free the symbol table if no symbols
+ could be loaded.
+ (copy_file): Use bfd_close_all_done to close files that could not
+ be copied.
+
+ * sysdump.c (getINT): Fail if reading off the end of the buffer.
+ Replace call to abort with a call to fatal.
+ (getCHARS): Prevetn reading off the end of the buffer.
+
+ * nlmconv.c (i386_mangle_relocs): Skip relocs without an
+ associated symbol.
+ (powerpc_mangle_relocs): Skip unrecognised relocs. Check address
+ range before applying a reloc.
+
+ 2015-01-07 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * dlltool.c (scan_obj_file): Break loop if the last archive
+ displayed matches the current archive.
+
+ * objdump.c (display_any_bfd): Add a depth limit to nested archive
+ display in order to avoid infinite loops.
+ * srconv.c: Replace calls to abort with calls to fatal with an
+ error message.
+
+ 2015-01-06 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffdump.c (dump_coff_section): Check for a symbol being
+ available before printing its name.
+ (main): Check the return value from coff_grok.
+ * coffgrok.c: Reformat and tidy.
+ Add range checks to most functions.
+ (coff_grok): Return NULL if the input bfd is not in a COFF
+ format.
+ * coffgrok.h: Reformat and tidy.
+ (struct coff_section): Change the nrelocs field to unsigned.
+ * srconv.c (main): Check the return value from coff_grok.
+
+ 2015-01-05 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * nm.c (print_symbol): Add 'is_synthetic' parameter. Use it to
+ help initialize the info.elfinfo field.
+ (print_size_symbols): Add 'synth_count' parameter. Use it to set
+ the is_synthetic parameter when calling print_symbol.
+ (print_symbols): Likewise.
+ (display_rel_file): Pass synth_count to printing function.
+ (display_archive): Break loop if the last archive displayed
+ matches the current archive.
+ * size.c (display_archive): Likewise.
+
+2015-03-24 Nick Clifton <nickc@redhat.com>
+
+ Apply from master:
+ 2015-02-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
* dwarf.c (display_debug_loc): Pacify the undefined behaviour
sanitizer by simplifying address difference calculation.
(struct Frame_Chunk): Change type of cfa_offset to dwarf_vma in
diff --git a/binutils/addr2line.c b/binutils/addr2line.c
index f88e745..7cabb8b 100644
--- a/binutils/addr2line.c
+++ b/binutils/addr2line.c
@@ -140,6 +140,14 @@ slurp_symtab (bfd *abfd)
syms = xmalloc (storage);
symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
}
+
+ /* PR 17512: file: 2a1d3b5b.
+ Do not pretend that we have some symbols when we don't. */
+ if (symcount <= 0)
+ {
+ free (syms);
+ syms = NULL;
+ }
}
/* These global variables are used to pass information between
@@ -423,6 +431,7 @@ main (int argc, char **argv)
program_name = *argv;
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);
diff --git a/binutils/ar.c b/binutils/ar.c
index 117826d..7c3c869 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -691,6 +691,7 @@ main (int argc, char **argv)
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
#if BFD_SUPPORTS_PLUGINS
bfd_plugin_set_program_name (program_name);
#endif
diff --git a/binutils/coffdump.c b/binutils/coffdump.c
index b4c8415..bf62915 100644
--- a/binutils/coffdump.c
+++ b/binutils/coffdump.c
@@ -417,21 +417,23 @@ dump_coff_sfile (struct coff_sfile *p)
static void
dump_coff_section (struct coff_section *ptr)
{
- int i;
+ unsigned int i;
tab (1);
- printf (_("section %s %d %d address %x size %x number %d nrelocs %d"),
+ printf (_("section %s %d %d address %x size %x number %d nrelocs %u"),
ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
ptr->number, ptr->nrelocs);
nl ();
for (i = 0; i < ptr->nrelocs; i++)
{
+ struct coff_reloc * r = ptr->relocs + i;
tab (0);
printf ("(%x %s %x)",
- ptr->relocs[i].offset,
- ptr->relocs[i].symbol->name,
- ptr->relocs[i].addend);
+ r->offset,
+ /* PR 17512: file: 0a38fb7c. */
+ r->symbol == NULL ? _("<no sym>") : r->symbol->name,
+ r->addend);
nl ();
}
@@ -498,6 +500,7 @@ main (int ac, char **av)
program_name = av[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&ac, &av);
@@ -549,9 +552,11 @@ main (int ac, char **av)
}
tree = coff_grok (abfd);
-
- coff_dump (tree);
- printf ("\n");
+ if (tree)
+ {
+ coff_dump (tree);
+ printf ("\n");
+ }
return 0;
}
diff --git a/binutils/coffgrok.c b/binutils/coffgrok.c
index f37f266..e2d520e 100644
--- a/binutils/coffgrok.c
+++ b/binutils/coffgrok.c
@@ -122,6 +122,9 @@ push_scope (int slink)
static void
pop_scope (void)
{
+ /* PR 17512: file: 809933ac. */
+ if (top_scope == NULL)
+ fatal (_("Out of context scope change encountered"));
top_scope = top_scope->parent;
}
@@ -138,10 +141,14 @@ do_sections_p1 (struct coff_ofile *head)
for (idx = 0, section = abfd->sections; section; section = section->next, idx++)
{
long relsize;
- int i = section->target_index;
+ unsigned int i = section->target_index;
arelent **relpp;
long relcount;
+ /* PR 17512: file: 2d6effca. */
+ if (i > abfd->section_count)
+ fatal (_("Invalid section target index: %u"), i);
+
relsize = bfd_get_reloc_upper_bound (abfd, section);
if (relsize < 0)
bfd_fatal (bfd_get_filename (abfd));
@@ -182,26 +189,51 @@ do_sections_p2 (struct coff_ofile *head)
{
unsigned int j;
+ /* PR 17512: file: 7c1a36e8.
+ A corrupt COFF binary might have a reloc count but no relocs.
+ Handle this here. */
+ if (section->relocation == NULL)
+ continue;
+
for (j = 0; j < section->reloc_count; j++)
{
- int idx;
+ unsigned int idx;
int i = section->target_index;
- struct coff_reloc *r = head->sections[i].relocs + j;
+ struct coff_reloc *r;
arelent *sr = section->relocation + j;
+
+ if (i > head->nsections)
+ fatal (_("Invalid section target index: %d"), i);
+ /* PR 17512: file: db850ff4. */
+ if (j >= head->sections[i].nrelocs)
+ fatal (_("Target section has insufficient relocs"));
+ r = head->sections[i].relocs + j;
r->offset = sr->address;
r->addend = sr->addend;
idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;
+ if (idx >= rawcount)
+ {
+ if (rawcount == 0)
+ fatal (_("Symbol index %u encountered when there are no symbols"), idx);
+ non_fatal (_("Invalid symbol index %u encountered"), idx);
+ idx = 0;
+ }
r->symbol = tindex[idx];
}
}
}
static struct coff_where *
-do_where (int i)
+do_where (unsigned int i)
{
- struct internal_syment *sym = &rawsyms[i].u.syment;
+ struct internal_syment *sym;
struct coff_where *where =
(struct coff_where *) (xmalloc (sizeof (struct coff_where)));
+
+ if (i >= rawcount)
+ fatal ("Invalid symbol index: %d\n", i);
+
+ sym = &rawsyms[i].u.syment;
where->offset = sym->n_value;
if (sym->n_scnum == -1)
@@ -231,7 +263,16 @@ do_where (int i)
case C_EXTDEF:
case C_LABEL:
where->where = coff_where_memory;
- where->section = &ofile->sections[sym->n_scnum];
+ /* PR 17512: file: 07a37c40. */
+ /* PR 17512: file: 0c2eb101. */
+ if (sym->n_scnum >= ofile->nsections || sym->n_scnum < 0)
+ {
+ non_fatal (_("Invalid section number (%d) encountered"),
+ sym->n_scnum);
+ where->section = ofile->sections;
+ }
+ else
+ where->section = &ofile->sections[sym->n_scnum];
break;
case C_REG:
case C_REGPARM:
@@ -248,47 +289,61 @@ do_where (int i)
where->where = coff_where_typedef;
break;
default:
- abort ();
+ fatal (_("Unrecognized symbol class: %d"), sym->n_sclass);
break;
}
return where;
}
-static
-struct coff_line *
+static struct coff_line *
do_lines (int i, char *name ATTRIBUTE_UNUSED)
{
struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);
asection *s;
unsigned int l;
- /* Find out if this function has any line numbers in the table */
+ /* Find out if this function has any line numbers in the table. */
for (s = abfd->sections; s; s = s->next)
{
+ /* PR 17512: file: 07a37c40.
+ A corrupt COFF binary can have a linenumber count in the header
+ but no line number table. This should be reported elsewhere, but
+ do not rely upon this. */
+ if (s->lineno == NULL)
+ continue;
+
for (l = 0; l < s->lineno_count; l++)
{
if (s->lineno[l].line_number == 0)
{
if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native)
{
- /* These lines are for this function - so count them and stick them on */
+ /* These lines are for this function - so count them and stick them on. */
int c = 0;
/* Find the linenumber of the top of the function, since coff linenumbers
are relative to the start of the function. */
int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;
l++;
- for (c = 0; s->lineno[l + c + 1].line_number; c++)
+ for (c = 0;
+ /* PR 17512: file: c2825452. */
+ l + c + 1 < s->lineno_count
+ && s->lineno[l + c + 1].line_number;
+ c++)
;
- /* Add two extra records, one for the prologue and one for the epilogue */
+ /* Add two extra records, one for the prologue and one for the epilogue. */
c += 1;
res->nlines = c;
res->lines = (int *) (xcalloc (sizeof (int), c));
res->addresses = (int *) (xcalloc (sizeof (int), c));
res->lines[0] = start_line;
res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;
- for (c = 0; s->lineno[l + c + 1].line_number; c++)
+ for (c = 0;
+ /* PR 17512: file: c2825452. */
+ l + c + 1 < s->lineno_count
+ && s->lineno[l + c + 1].line_number;
+ c++)
{
res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1;
res->addresses[c + 1] = s->lineno[l + c].u.offset;
@@ -301,18 +356,30 @@ do_lines (int i, char *name ATTRIBUTE_UNUSED)
return res;
}
-static
-struct coff_type *
-do_type (int i)
+static struct coff_type *
+do_type (unsigned int i)
{
- struct internal_syment *sym = &rawsyms[i].u.syment;
- union internal_auxent *aux = &rawsyms[i + 1].u.auxent;
- struct coff_type *res =
- (struct coff_type *) xmalloc (sizeof (struct coff_type));
- int type = sym->n_type;
+ struct internal_syment *sym;
+ union internal_auxent *aux;
+ struct coff_type *res = (struct coff_type *) xmalloc (sizeof (struct coff_type));
+ int type;
int which_dt = 0;
int dimind = 0;
+ if (i >= rawcount)
+ fatal (_("Type entry %u does not have enough symbolic information"), i);
+
+ if (!rawsyms[i].is_sym)
+ fatal (_("Type entry %u does not refer to a symbol"), i);
+ sym = &rawsyms[i].u.syment;
+
+ if (sym->n_numaux == 0 || i >= rawcount -1 || rawsyms[i + 1].is_sym)
+ aux = NULL;
+ else
+ aux = &rawsyms[i + 1].u.auxent;
+
+ type = sym->n_type;
+
res->type = coff_basic_type;
res->u.basic = type & 0xf;
@@ -322,28 +389,33 @@ do_type (int i)
case T_VOID:
if (sym->n_numaux && sym->n_sclass == C_STAT)
{
- /* This is probably a section definition */
+ /* This is probably a section definition. */
res->type = coff_secdef_type;
+ if (aux == NULL)
+ fatal (_("Section definition needs a section length"));
res->size = aux->x_scn.x_scnlen;
+
+ /* PR 17512: file: 081c955d.
+ Fill in the asecdef structure as well. */
+ res->u.asecdef.address = 0;
+ res->u.asecdef.size = 0;
}
else
{
if (type == 0)
{
- /* Don't know what this is, let's make it a simple int */
+ /* Don't know what this is, let's make it a simple int. */
res->size = INT_SIZE;
res->u.basic = T_UINT;
}
else
{
- /* Else it could be a function or pointer to void */
+ /* Else it could be a function or pointer to void. */
res->size = 0;
}
}
break;
-
- break;
case T_UCHAR:
case T_CHAR:
res->size = 1;
@@ -370,17 +442,39 @@ do_type (int i)
case T_UNION:
if (sym->n_numaux)
{
+ if (aux == NULL)
+ fatal (_("Aggregate definition needs auxillary information"));
+
if (aux->x_sym.x_tagndx.p)
{
- /* Referring to a struct defined elsewhere */
+ unsigned int idx;
+
+ /* PR 17512: file: e72f3988. */
+ if (aux->x_sym.x_tagndx.l < 0 || aux->x_sym.x_tagndx.p < rawsyms)
+ {
+ non_fatal (_("Invalid tag index %#lx encountered"), aux->x_sym.x_tagndx.l);
+ idx = 0;
+ }
+ else
+ idx = INDEXOF (aux->x_sym.x_tagndx.p);
+
+ if (idx >= rawcount)
+ {
+ if (rawcount == 0)
+ fatal (_("Symbol index %u encountered when there are no symbols"), idx);
+ non_fatal (_("Invalid symbol index %u encountered"), idx);
+ idx = 0;
+ }
+
+ /* Referring to a struct defined elsewhere. */
res->type = coff_structref_type;
- res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
+ res->u.astructref.ref = tindex[idx];
res->size = res->u.astructref.ref ?
res->u.astructref.ref->type->size : 0;
}
else
{
- /* A definition of a struct */
+ /* A definition of a struct. */
last_struct = res;
res->type = coff_structdef_type;
res->u.astructdef.elements = empty_scope ();
@@ -391,23 +485,34 @@ do_type (int i)
}
else
{
- /* No auxents - it's anonymous */
+ /* No auxents - it's anonymous. */
res->type = coff_structref_type;
res->u.astructref.ref = 0;
res->size = 0;
}
break;
case T_ENUM:
+ if (aux == NULL)
+ fatal (_("Enum definition needs auxillary information"));
if (aux->x_sym.x_tagndx.p)
{
- /* Referring to a enum defined elsewhere */
+ unsigned int idx = INDEXOF (aux->x_sym.x_tagndx.p);
+
+ /* PR 17512: file: 1ef037c7. */
+ if (idx >= rawcount)
+ fatal (_("Invalid enum symbol index %u encountered"), idx);
+ /* Referring to a enum defined elsewhere. */
res->type = coff_enumref_type;
- res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
- res->size = res->u.aenumref.ref->type->size;
+ res->u.aenumref.ref = tindex[idx];
+ /* PR 17512: file: b85b67e8. */
+ if (res->u.aenumref.ref)
+ res->size = res->u.aenumref.ref->type->size;
+ else
+ res->size = 0;
}
else
{
- /* A definition of an enum */
+ /* A definition of an enum. */
last_enum = res;
res->type = coff_enumdef_type;
res->u.aenumdef.elements = empty_scope ();
@@ -428,12 +533,27 @@ do_type (int i)
{
struct coff_type *ptr = ((struct coff_type *)
xmalloc (sizeof (struct coff_type)));
- int els = (dimind < DIMNUM
- ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
- : 0);
+ int els;
+
+ if (aux == NULL)
+ fatal (_("Array definition needs auxillary information"));
+ els = (dimind < DIMNUM
+ ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
+ : 0);
+
++dimind;
ptr->type = coff_array_type;
- ptr->size = els * res->size;
+ /* PR 17512: file: ae1971e2.
+ Check for integer overflow. */
+ {
+ long long a, z;
+ a = els;
+ z = res->size;
+ a *= z;
+ ptr->size = (int) a;
+ if (ptr->size != a)
+ non_fatal (_("Out of range sum for els (%#x) * size (%#x)"), els, res->size);
+ }
ptr->u.array.dim = els;
ptr->u.array.array_of = res;
res = ptr;
@@ -443,6 +563,7 @@ do_type (int i)
{
struct coff_type *ptr =
(struct coff_type *) xmalloc (sizeof (struct coff_type));
+
ptr->size = PTR_SIZE;
ptr->type = coff_pointer_type;
ptr->u.pointer.points_to = res;
@@ -453,11 +574,12 @@ do_type (int i)
{
struct coff_type *ptr
= (struct coff_type *) xmalloc (sizeof (struct coff_type));
+
ptr->size = 0;
ptr->type = coff_function_type;
ptr->u.function.function_returns = res;
ptr->u.function.parameters = empty_scope ();
- ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);
+ ptr->u.function.lines = do_lines (i, N(sym));
ptr->u.function.code = 0;
last_function_type = ptr;
res = ptr;
@@ -475,6 +597,7 @@ do_visible (int i)
struct coff_visible *visible =
(struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));
enum coff_vis_type t;
+
switch (sym->n_sclass)
{
case C_MOS:
@@ -485,11 +608,9 @@ do_visible (int i)
case C_MOE:
t = coff_vis_member_of_enum;
break;
-
case C_REGPARM:
t = coff_vis_regparam;
break;
-
case C_REG:
t = coff_vis_register;
break;
@@ -504,8 +625,6 @@ do_visible (int i)
t = coff_vis_autoparam;
break;
case C_AUTO:
-
-
t = coff_vis_auto;
break;
case C_LABEL:
@@ -524,27 +643,32 @@ do_visible (int i)
t = coff_vis_ext_def;
break;
default:
- abort ();
+ fatal (_("Unrecognised symbol class: %d"), sym->n_sclass);
break;
-
}
visible->type = t;
return visible;
}
+/* Define a symbol and attach to block B. */
+
static int
-do_define (int i, struct coff_scope *b)
+do_define (unsigned int i, struct coff_scope *b)
{
static int symbol_index;
- struct internal_syment *sym = &rawsyms[i].u.syment;
-
- /* Define a symbol and attach to block b */
+ struct internal_syment *sym;
struct coff_symbol *s = empty_symbol ();
+ if (b == NULL)
+ fatal (_("ICE: do_define called without a block"));
+ if (i >= rawcount)
+ fatal (_("Out of range symbol index: %u"), i);
+
+ sym = &rawsyms[i].u.syment;
s->number = ++symbol_index;
- s->name = sym->_n._n_nptr[1];
+ s->name = N(sym);
s->sfile = cur_sfile;
- /* Glue onto the ofile list */
+ /* Glue onto the ofile list. */
if (lofile >= 0)
{
if (ofile->symbol_list_tail)
@@ -552,7 +676,7 @@ do_define (int i, struct coff_scope *b)
else
ofile->symbol_list_head = s;
ofile->symbol_list_tail = s;
- /* And the block list */
+ /* And the block list. */
}
if (b->vars_tail)
b->vars_tail->next = s;
@@ -567,21 +691,42 @@ do_define (int i, struct coff_scope *b)
tindex[i] = s;
- /* We remember the lowest address in each section for each source file */
-
+ /* We remember the lowest address in each section for each source file. */
if (s->where->where == coff_where_memory
&& s->type->type == coff_secdef_type)
{
- struct coff_isection *is = cur_sfile->section + s->where->section->number;
+ struct coff_isection *is;
- if (!is->init)
+ /* PR 17512: file: 4676c97f. */
+ if (cur_sfile == NULL)
+ non_fatal (_("Section referenced before any file is defined"));
+ else
{
- is->low = s->where->offset;
- is->high = s->where->offset + s->type->size;
- is->init = 1;
- is->parent = s->where->section;
- }
+ is = cur_sfile->section + s->where->section->number;
+ if (!is->init)
+ {
+ is->low = s->where->offset;
+ /* PR 17512: file: 37e7a80d.
+ Check for integer overflow computing low + size. */
+ {
+ long long a, z;
+
+ a = s->where->offset;
+ z = s->type->size;
+ a += z;
+ is->high = (int) a;
+ if (a != is->high)
+ non_fatal (_("Out of range sum for offset (%#x) + size (%#x)"),
+ is->low, s->type->size);
+ }
+ /* PR 17512: file: 37e7a80d. */
+ if (is->high < s->where->offset)
+ fatal (_("Out of range type size: %u"), s->type->size);
+ is->init = 1;
+ is->parent = s->where->section;
+ }
+ }
}
if (s->type->type == coff_function_type)
@@ -590,15 +735,14 @@ do_define (int i, struct coff_scope *b)
return i + sym->n_numaux + 1;
}
-
-static
-struct coff_ofile *
+static struct coff_ofile *
doit (void)
{
- int i;
- int infile = 0;
+ unsigned int i;
+ bfd_boolean infile = FALSE;
struct coff_ofile *head =
(struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));
+
ofile = head;
head->source_head = 0;
head->source_tail = 0;
@@ -611,23 +755,25 @@ doit (void)
for (i = 0; i < rawcount;)
{
struct internal_syment *sym = &rawsyms[i].u.syment;
+
switch (sym->n_sclass)
{
case C_FILE:
{
- /* new source file announced */
+ /* New source file announced. */
struct coff_sfile *n =
(struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));
+
n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);
cur_sfile = n;
- n->name = sym->_n._n_nptr[1];
+ n->name = N(sym);
n->next = 0;
if (infile)
- {
- pop_scope ();
- }
- infile = 1;
+ pop_scope ();
+ else
+ infile = TRUE;
+
push_scope (1);
file_scope = n->scope = top_scope;
@@ -642,20 +788,29 @@ doit (void)
break;
case C_FCN:
{
- char *name = sym->_n._n_nptr[1];
+ char *name = N(sym);
+
if (name[1] == 'b')
{
- /* Function start */
+ /* Function start. */
push_scope (0);
- last_function_type->u.function.code = top_scope;
- top_scope->sec = ofile->sections + sym->n_scnum;
+ /* PR 17512: file: 0ef7fbaf. */
+ if (last_function_type)
+ last_function_type->u.function.code = top_scope;
+ /* PR 17512: file: 22908266. */
+ if (sym->n_scnum < ofile->nsections && sym->n_scnum >= 0)
+ top_scope->sec = ofile->sections + sym->n_scnum;
+ else
+ top_scope->sec = NULL;
top_scope->offset = sym->n_value;
}
else
{
+ /* PR 17512: file: e92e42e1. */
+ if (top_scope == NULL)
+ fatal (_("Function start encountered without a top level scope."));
top_scope->size = sym->n_value - top_scope->offset + 1;
pop_scope ();
-
}
i += sym->n_numaux + 1;
}
@@ -663,17 +818,23 @@ doit (void)
case C_BLOCK:
{
- char *name = sym->_n._n_nptr[1];
+ char *name = N(sym);
+
if (name[1] == 'b')
{
- /* Block start */
+ /* Block start. */
push_scope (1);
- top_scope->sec = ofile->sections + sym->n_scnum;
+ /* PR 17512: file: af7e8e83. */
+ if (sym->n_scnum < ofile->nsections && sym->n_scnum >= 0)
+ top_scope->sec = ofile->sections + sym->n_scnum;
+ else
+ top_scope->sec = NULL;
top_scope->offset = sym->n_value;
-
}
else
{
+ if (top_scope == NULL)
+ fatal (_("Block start encountered without a scope for it."));
top_scope->size = sym->n_value - top_scope->offset + 1;
pop_scope ();
}
@@ -682,37 +843,50 @@ doit (void)
break;
case C_REGPARM:
case C_ARG:
+ if (last_function_symbol == NULL)
+ fatal (_("Function arguments encountered without a function definition"));
i = do_define (i, last_function_symbol->type->u.function.parameters);
break;
case C_MOS:
case C_MOU:
case C_FIELD:
+ /* PR 17512: file: 43ab21f4. */
+ if (last_struct == NULL)
+ fatal (_("Structure element encountered without a structure definition"));
i = do_define (i, last_struct->u.astructdef.elements);
break;
case C_MOE:
+ if (last_enum == NULL)
+ fatal (_("Enum element encountered without an enum definition"));
i = do_define (i, last_enum->u.aenumdef.elements);
break;
case C_STRTAG:
case C_ENTAG:
case C_UNTAG:
- /* Various definition */
+ /* Various definition. */
+ if (top_scope == NULL)
+ fatal (_("Aggregate defintion encountered without a scope"));
i = do_define (i, top_scope);
break;
case C_EXT:
case C_LABEL:
+ if (file_scope == NULL)
+ fatal (_("Label defintion encountered without a file scope"));
i = do_define (i, file_scope);
break;
case C_STAT:
case C_TPDEF:
case C_AUTO:
case C_REG:
+ if (top_scope == NULL)
+ fatal (_("Variable defintion encountered without a scope"));
i = do_define (i, top_scope);
break;
- default:
- abort ();
case C_EOS:
i += sym->n_numaux + 1;
break;
+ default:
+ fatal (_("Unrecognised symbol class: %d"), sym->n_sclass);
}
}
do_sections_p2 (head);
@@ -725,6 +899,13 @@ coff_grok (bfd *inabfd)
long storage;
struct coff_ofile *p;
abfd = inabfd;
+
+ if (! bfd_family_coff (abfd))
+ {
+ non_fatal (_("%s: is not a COFF format file"), bfd_get_filename (abfd));
+ return NULL;
+ }
+
storage = bfd_get_symtab_upper_bound (abfd);
if (storage < 0)
diff --git a/binutils/coffgrok.h b/binutils/coffgrok.h
index 75e0824..830da39 100644
--- a/binutils/coffgrok.h
+++ b/binutils/coffgrok.h
@@ -19,22 +19,22 @@
MA 02110-1301, USA. */
#define T_NULL 0
-#define T_VOID 1 /* function argument (only used by compiler) */
-#define T_CHAR 2 /* character */
-#define T_SHORT 3 /* short integer */
-#define T_INT 4 /* integer */
-#define T_LONG 5 /* long integer */
-#define T_FLOAT 6 /* floating point */
-#define T_DOUBLE 7 /* double word */
-#define T_STRUCT 8 /* structure */
-#define T_UNION 9 /* union */
-#define T_ENUM 10 /* enumeration */
-#define T_MOE 11 /* member of enumeration*/
-#define T_UCHAR 12 /* unsigned character */
-#define T_USHORT 13 /* unsigned short */
-#define T_UINT 14 /* unsigned integer */
-#define T_ULONG 15 /* unsigned long */
-#define T_LNGDBL 16 /* long double */
+#define T_VOID 1 /* Function argument (only used by compiler). */
+#define T_CHAR 2 /* Character */
+#define T_SHORT 3 /* Short integer */
+#define T_INT 4 /* Integer */
+#define T_LONG 5 /* Long integer */
+#define T_FLOAT 6 /* Floating point */
+#define T_DOUBLE 7 /* Double word */
+#define T_STRUCT 8 /* Structure */
+#define T_UNION 9 /* Union */
+#define T_ENUM 10 /* Enumeration */
+#define T_MOE 11 /* Member of enumeration*/
+#define T_UCHAR 12 /* Unsigned character */
+#define T_USHORT 13 /* Unsigned short */
+#define T_UINT 14 /* Unsigned integer */
+#define T_ULONG 15 /* Unsigned long */
+#define T_LNGDBL 16 /* Long double */
struct coff_reloc
@@ -51,7 +51,7 @@ struct coff_section
int data;
int address;
int number; /* 0..n, .text = 0 */
- int nrelocs;
+ unsigned int nrelocs;
int size;
struct coff_reloc *relocs;
struct bfd_section *bfd_section;
@@ -68,7 +68,8 @@ struct coff_ofile
struct coff_symbol *symbol_list_tail;
};
-struct coff_isection {
+struct coff_isection
+{
int low;
int high;
int init;
@@ -82,145 +83,139 @@ struct coff_sfile
struct coff_sfile *next;
/* Vector which maps where in each output section
- the input file has it's data */
+ the input file has it's data. */
struct coff_isection *section;
-
};
-
- struct coff_type
+struct coff_type
{
int size;
enum
{
coff_pointer_type, coff_function_type, coff_array_type, coff_structdef_type, coff_basic_type,
coff_structref_type, coff_enumref_type, coff_enumdef_type, coff_secdef_type
- } type;
+ } type;
+
union
{
struct
- {
+ {
int address;
int size;
} asecdef;
struct
- {
- int isstruct;
- struct coff_scope *elements;
- int idx;
- }
- astructdef;
+ {
+ int isstruct;
+ struct coff_scope *elements;
+ int idx;
+ } astructdef;
+
struct
- {
- struct coff_symbol *ref;
- } astructref;
+ {
+ struct coff_symbol *ref;
+ } astructref;
struct
- {
- struct coff_scope *elements;
- int idx;
- } aenumdef;
+ {
+ struct coff_scope *elements;
+ int idx;
+ } aenumdef;
+
struct
- {
- struct coff_symbol *ref;
- } aenumref;
+ {
+ struct coff_symbol *ref;
+ } aenumref;
struct
- {
- struct coff_type *points_to;
- } pointer;
+ {
+ struct coff_type *points_to;
+ } pointer;
+
struct
- {
- int dim;
- struct coff_type *array_of;
- } array;
+ {
+ int dim;
+ struct coff_type *array_of;
+ } array;
struct
- {
- struct coff_type *function_returns;
- struct coff_scope *parameters;
- struct coff_scope *code;
- struct coff_line *lines;
- } function;
+ {
+ struct coff_type * function_returns;
+ struct coff_scope * parameters;
+ struct coff_scope * code;
+ struct coff_line * lines;
+ } function;
+
int basic; /* One of T_VOID.. T_UINT */
- } u;
+ } u;
+};
+
+struct coff_line
+{
+ int nlines;
+ int * lines;
+ int * addresses;
};
+struct coff_scope
+{
+ struct coff_section * sec; /* Which section. */
+ int offset; /* Where. */
+ int size; /* How big. */
+ struct coff_scope * parent; /* One up. */
+ struct coff_scope * next; /* Next along. */
+ int nvars;
+ struct coff_symbol * vars_head; /* Symbols. */
+ struct coff_symbol * vars_tail;
+ struct coff_scope * list_head; /* Children. */
+ struct coff_scope * list_tail;
+};
+
+struct coff_visible
+{
+ enum coff_vis_type
+ {
+ coff_vis_ext_def,
+ coff_vis_ext_ref,
+ coff_vis_int_def,
+ coff_vis_common,
+ coff_vis_auto,
+ coff_vis_register,
+ coff_vis_tag,
+ coff_vis_member_of_struct,
+ coff_vis_member_of_enum,
+ coff_vis_autoparam,
+ coff_vis_regparam,
+ } type;
+};
+
+struct coff_where
+{
+ enum
+ {
+ coff_where_stack, coff_where_memory, coff_where_register, coff_where_unknown,
+ coff_where_strtag, coff_where_member_of_struct,
+ coff_where_member_of_enum, coff_where_entag, coff_where_typedef
+ } where;
+
+ int offset;
+ int bitoffset;
+ int bitsize;
+ struct coff_section *section;
+};
+
+struct coff_symbol
+{
+ char * name;
+ int tag;
+ struct coff_type * type;
+ struct coff_where * where;
+ struct coff_visible * visible;
+ struct coff_symbol * next;
+ struct coff_symbol * next_in_ofile_list; /* For the ofile list. */
+ int number;
+ int er_number;
+ struct coff_sfile * sfile;
+};
- struct coff_line
- {
- int nlines;
- int *lines;
- int *addresses;
- };
-
-
- struct coff_scope
- {
- struct coff_section *sec; /* What section */
- int offset; /* where */
- int size; /* How big */
- struct coff_scope *parent; /* one up */
-
- struct coff_scope *next; /*next along */
-
- int nvars;
-
- struct coff_symbol *vars_head; /* symbols */
- struct coff_symbol *vars_tail;
-
- struct coff_scope *list_head; /* children */
- struct coff_scope *list_tail;
-
- };
-
-
- struct coff_visible
- {
- enum coff_vis_type
- {
- coff_vis_ext_def,
- coff_vis_ext_ref,
- coff_vis_int_def,
- coff_vis_common,
- coff_vis_auto,
- coff_vis_register,
- coff_vis_tag,
- coff_vis_member_of_struct,
- coff_vis_member_of_enum,
- coff_vis_autoparam,
- coff_vis_regparam,
- } type;
- };
-
- struct coff_where
- {
- enum
- {
- coff_where_stack, coff_where_memory, coff_where_register, coff_where_unknown,
- coff_where_strtag, coff_where_member_of_struct,
- coff_where_member_of_enum, coff_where_entag, coff_where_typedef
-
- } where;
- int offset;
- int bitoffset;
- int bitsize;
- struct coff_section *section;
- };
-
- struct coff_symbol
- {
- char *name;
- int tag;
- struct coff_type *type;
- struct coff_where *where;
- struct coff_visible *visible;
- struct coff_symbol *next;
- struct coff_symbol *next_in_ofile_list; /* For the ofile list */
- int number;
- int er_number;
- struct coff_sfile *sfile;
- };
-
-struct coff_ofile *coff_grok (bfd *);
+struct coff_ofile * coff_grok (bfd *);
diff --git a/binutils/cxxfilt.c b/binutils/cxxfilt.c
index 157ebe0..391eb29 100644
--- a/binutils/cxxfilt.c
+++ b/binutils/cxxfilt.c
@@ -176,6 +176,7 @@ main (int argc, char **argv)
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);
diff --git a/binutils/dlltool.c b/binutils/dlltool.c
index 8b013f0..4d77b02 100644
--- a/binutils/dlltool.c
+++ b/binutils/dlltool.c
@@ -1699,6 +1699,9 @@ scan_obj_file (const char *filename)
scan_open_obj_file (arfile);
next = bfd_openr_next_archived_file (f, arfile);
bfd_close (arfile);
+ /* PR 17512: file: 58715298. */
+ if (next == arfile)
+ break;
arfile = next;
}
@@ -1991,6 +1994,31 @@ assemble_file (const char * source, const char * dest)
run (as_name, cmd);
}
+static const char * temp_file_to_remove[5];
+#define TEMP_EXPORT_FILE 0
+#define TEMP_HEAD_FILE 1
+#define TEMP_TAIL_FILE 2
+#define TEMP_HEAD_O_FILE 3
+#define TEMP_TAIL_O_FILE 4
+
+static void
+unlink_temp_files (void)
+{
+ unsigned i;
+
+ if (dontdeltemps > 0)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE (temp_file_to_remove); i++)
+ {
+ if (temp_file_to_remove[i])
+ {
+ unlink (temp_file_to_remove[i]);
+ temp_file_to_remove[i] = NULL;
+ }
+ }
+}
+
static void
gen_exp_file (void)
{
@@ -2007,6 +2035,8 @@ gen_exp_file (void)
/* xgettext:c-format */
fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
+ temp_file_to_remove[TEMP_EXPORT_FILE] = TMP_ASM;
+
/* xgettext:c-format */
inform (_("Opened temporary file: %s"), TMP_ASM);
@@ -2143,7 +2173,6 @@ gen_exp_file (void)
}
}
-
/* Add to the output file a way of getting to the exported names
without using the import library. */
if (add_indirect)
@@ -2231,7 +2260,10 @@ gen_exp_file (void)
assemble_file (TMP_ASM, exp_name);
if (dontdeltemps == 0)
- unlink (TMP_ASM);
+ {
+ temp_file_to_remove[TEMP_EXPORT_FILE] = NULL;
+ unlink (TMP_ASM);
+ }
inform (_("Generated exports file"));
}
@@ -2936,6 +2968,8 @@ make_head (void)
return NULL;
}
+ temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S;
+
fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
fprintf (f, "\t.section\t.idata$2\n");
@@ -2997,6 +3031,7 @@ make_head (void)
fatal (_("failed to open temporary head file: %s: %s"),
TMP_HEAD_O, bfd_get_errmsg ());
+ temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O;
return abfd;
}
@@ -3012,6 +3047,8 @@ make_delay_head (void)
return NULL;
}
+ temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S;
+
/* Output the __tailMerge__xxx function */
fprintf (f, "%s Import trampoline\n", ASM_C);
fprintf (f, "\t.section\t.text\n");
@@ -3080,6 +3117,7 @@ make_delay_head (void)
fatal (_("failed to open temporary head file: %s: %s"),
TMP_HEAD_O, bfd_get_errmsg ());
+ temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O;
return abfd;
}
@@ -3095,6 +3133,8 @@ make_tail (void)
return NULL;
}
+ temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S;
+
if (!no_idata4)
{
fprintf (f, "\t.section\t.idata$4\n");
@@ -3151,6 +3191,7 @@ make_tail (void)
fatal (_("failed to open temporary tail file: %s: %s"),
TMP_TAIL_O, bfd_get_errmsg ());
+ temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O;
return abfd;
}
@@ -3176,6 +3217,8 @@ gen_lib_file (int delay)
/* xgettext:c-format */
inform (_("Creating library file: %s"), imp_name);
+ xatexit (unlink_temp_files);
+
bfd_set_format (outarch, bfd_archive);
outarch->has_armap = 1;
outarch->is_thin_archive = 0;
@@ -3245,13 +3288,7 @@ gen_lib_file (int delay)
}
/* Delete all the temp files. */
- if (dontdeltemps == 0)
- {
- unlink (TMP_HEAD_O);
- unlink (TMP_HEAD_S);
- unlink (TMP_TAIL_O);
- unlink (TMP_TAIL_S);
- }
+ unlink_temp_files ();
if (dontdeltemps < 2)
{
@@ -3586,7 +3623,15 @@ identify_search_archive (bfd * abfd,
}
if (last_arfile != NULL)
- bfd_close (last_arfile);
+ {
+ bfd_close (last_arfile);
+ /* PR 17512: file: 8b2168d4. */
+ if (last_arfile == arfile)
+ {
+ last_arfile = NULL;
+ break;
+ }
+ }
last_arfile = arfile;
}
@@ -4041,6 +4086,7 @@ main (int ac, char **av)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+ bfd_set_error_program_name (program_name);
expandargv (&ac, &av);
while ((c = getopt_long (ac, av,
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
index f1502b9..063662a 100644
--- a/binutils/elfcomm.c
+++ b/binutils/elfcomm.c
@@ -51,7 +51,7 @@ warn (const char *message, ...)
/* Try to keep warning messages in sync with the program's normal output. */
fflush (stdout);
-
+
va_start (args, message);
fprintf (stderr, _("%s: Warning: "), program_name);
vfprintf (stderr, message, args);
@@ -386,10 +386,11 @@ byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
char *
adjust_relative_path (const char *file_name, const char *name,
- int name_len)
+ unsigned long name_len)
{
char * member_file_name;
const char * base_name = lbasename (file_name);
+ size_t amt;
/* This is a proxy entry for a thin archive member.
If the extended name table contains an absolute path
@@ -399,7 +400,10 @@ adjust_relative_path (const char *file_name, const char *name,
archive is located. */
if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
{
- member_file_name = (char *) malloc (name_len + 1);
+ amt = name_len + 1;
+ if (amt == 0)
+ return NULL;
+ member_file_name = (char *) malloc (amt);
if (member_file_name == NULL)
{
error (_("Out of memory\n"));
@@ -413,7 +417,18 @@ adjust_relative_path (const char *file_name, const char *name,
/* Concatenate the path components of the archive file name
to the relative path name from the extended name table. */
size_t prefix_len = base_name - file_name;
- member_file_name = (char *) malloc (prefix_len + name_len + 1);
+
+ amt = prefix_len + name_len + 1;
+ /* PR 17531: file: 2896dc8b
+ Catch wraparound. */
+ if (amt < prefix_len || amt < name_len)
+ {
+ error (_("Abnormal length of thin archive member name: %lx\n"),
+ name_len);
+ return NULL;
+ }
+
+ member_file_name = (char *) malloc (amt);
if (member_file_name == NULL)
{
error (_("Out of memory\n"));
@@ -445,6 +460,14 @@ process_archive_index_and_symbols (struct archive_info * arch,
unsigned long size;
size = strtoul (arch->arhdr.ar_size, NULL, 10);
+ /* PR 17531: file: 912bd7de. */
+ if ((signed long) size < 0)
+ {
+ error (_("%s: invalid archive header size: %ld\n"),
+ arch->file_name, size);
+ return FALSE;
+ }
+
size = size + (size & 1);
arch->next_arhdr_offset += sizeof arch->arhdr + size;
@@ -468,7 +491,7 @@ process_archive_index_and_symbols (struct archive_info * arch,
unsigned char * index_buffer;
assert (sizeof_ar_index <= sizeof integer_buffer);
-
+
/* Check the size of the archive index. */
if (size < sizeof_ar_index)
{
@@ -487,9 +510,11 @@ process_archive_index_and_symbols (struct archive_info * arch,
arch->index_num = byte_get_big_endian (integer_buffer, sizeof_ar_index);
size -= sizeof_ar_index;
- if (size < arch->index_num * sizeof_ar_index)
+ if (size < arch->index_num * sizeof_ar_index
+ /* PR 17531: file: 585515d1. */
+ || size < arch->index_num)
{
- error (_("%s: the archive index is supposed to have %ld entries of %d bytes, but the size is only %ld\n"),
+ error (_("%s: the archive index is supposed to have 0x%lx entries of %d bytes, but the size is only 0x%lx\n"),
arch->file_name, (long) arch->index_num, sizeof_ar_index, size);
return FALSE;
}
@@ -623,9 +648,25 @@ setup_archive (struct archive_info *arch, const char *file_name,
{
/* This is the archive string table holding long member names. */
arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
+ /* PR 17531: file: 01068045. */
+ if (arch->longnames_size < 8)
+ {
+ error (_("%s: long name table is too small, (size = %ld)\n"),
+ file_name, arch->longnames_size);
+ return 1;
+ }
+ /* PR 17531: file: 639d6a26. */
+ if ((signed long) arch->longnames_size < 0)
+ {
+ error (_("%s: long name table is too big, (size = 0x%lx)\n"),
+ file_name, arch->longnames_size);
+ return 1;
+ }
+
arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
- arch->longnames = (char *) malloc (arch->longnames_size);
+ /* Plus one to allow for a string terminator. */
+ arch->longnames = (char *) malloc (arch->longnames_size + 1);
if (arch->longnames == NULL)
{
error (_("Out of memory reading long symbol names in archive\n"));
@@ -643,6 +684,8 @@ setup_archive (struct archive_info *arch, const char *file_name,
if ((arch->longnames_size & 1) != 0)
getc (file);
+
+ arch->longnames[arch->longnames_size] = 0;
}
return 0;
@@ -713,23 +756,37 @@ get_archive_member_name (struct archive_info *arch,
error (_("Archive member uses long names, but no longname table found\n"));
return NULL;
}
-
+
arch->nested_member_origin = 0;
k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
if (arch->is_thin_archive && endp != NULL && * endp == ':')
arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
+ if (j > arch->longnames_size)
+ {
+ error (_("Found long name index (%ld) beyond end of long name table\n"),j);
+ return NULL;
+ }
while ((j < arch->longnames_size)
&& (arch->longnames[j] != '\n')
&& (arch->longnames[j] != '\0'))
j++;
- if (arch->longnames[j-1] == '/')
+ if (j > 0 && arch->longnames[j-1] == '/')
j--;
+ if (j > arch->longnames_size)
+ j = arch->longnames_size;
arch->longnames[j] = '\0';
if (!arch->is_thin_archive || arch->nested_member_origin == 0)
return arch->longnames + k;
+ /* PR 17531: file: 2896dc8b. */
+ if (k >= j)
+ {
+ error (_("Invalid Thin archive member name\n"));
+ return NULL;
+ }
+
/* This is a proxy for a member of a nested archive.
Find the name of the member in that archive. */
member_file_name = adjust_relative_path (arch->file_name,
diff --git a/binutils/elfcomm.h b/binutils/elfcomm.h
index d834753..f7f7544 100644
--- a/binutils/elfcomm.h
+++ b/binutils/elfcomm.h
@@ -77,7 +77,7 @@ struct archive_info
};
/* Return the path name for a proxy entry in a thin archive. */
-extern char *adjust_relative_path (const char *, const char *, int);
+extern char *adjust_relative_path (const char *, const char *, unsigned long);
/* Read the symbol table and long-name table from an archive. */
extern int setup_archive (struct archive_info *, const char *, FILE *,
diff --git a/binutils/nlmconv.c b/binutils/nlmconv.c
index 0513f29..fecb110 100644
--- a/binutils/nlmconv.c
+++ b/binutils/nlmconv.c
@@ -211,6 +211,7 @@ main (int argc, char **argv)
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);
@@ -1415,6 +1416,9 @@ i386_mangle_relocs (bfd *outbfd, asection *insec, arelent ***relocs_ptr,
bfd_vma addend;
rel = *relocs++;
+ /* PR 17512: file: 057f89c1. */
+ if (rel->sym_ptr_ptr == NULL)
+ continue;
sym = *rel->sym_ptr_ptr;
/* We're moving the relocs from the input section to the output
@@ -1871,7 +1875,7 @@ powerpc_mangle_relocs (bfd *outbfd, asection *insec,
toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
if (toc_howto == (reloc_howto_type *) NULL)
- abort ();
+ fatal (_("Unable to locate PPC_TOC16 reloc information"));
/* If this is the .got section, clear out all the contents beyond
the initial size. We must do this here because copy_sections is
@@ -1910,6 +1914,10 @@ powerpc_mangle_relocs (bfd *outbfd, asection *insec,
}
}
+ /* PR 17512: file: 70cfde95. */
+ if (rel->howto == NULL)
+ continue;
+
/* We must be able to resolve all PC relative relocs at this
point. If we get a branch to an undefined symbol we build a
stub, since NetWare will resolve undefined symbols into a
@@ -1927,6 +1935,13 @@ powerpc_mangle_relocs (bfd *outbfd, asection *insec,
{
bfd_vma val;
+ if (rel->address > contents_size - 4)
+ {
+ non_fatal (_("Out of range relocation: %lx"),
+ (long) rel->address);
+ break;
+ }
+
assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
val = ((val &~ rel->howto->dst_mask)
@@ -1976,6 +1991,13 @@ powerpc_mangle_relocs (bfd *outbfd, asection *insec,
switch (rel->howto->size)
{
case 1:
+ if (rel->address > contents_size - 2)
+ {
+ non_fatal (_("Out of range relocation: %lx"),
+ (long) rel->address);
+ break;
+ }
+
val = bfd_get_16 (outbfd,
(bfd_byte *) contents + rel->address);
val = ((val &~ rel->howto->dst_mask)
@@ -1991,6 +2013,14 @@ powerpc_mangle_relocs (bfd *outbfd, asection *insec,
break;
case 2:
+ /* PR 17512: file: 0455a112. */
+ if (rel->address > contents_size - 4)
+ {
+ non_fatal (_("Out of range relocation: %lx"),
+ (long) rel->address);
+ break;
+ }
+
val = bfd_get_32 (outbfd,
(bfd_byte *) contents + rel->address);
val = ((val &~ rel->howto->dst_mask)
@@ -2002,7 +2032,7 @@ powerpc_mangle_relocs (bfd *outbfd, asection *insec,
break;
default:
- abort ();
+ fatal (_("Unsupported relocation size: %d"), rel->howto->size);
}
if (! bfd_is_und_section (bfd_get_section (sym)))
diff --git a/binutils/nm.c b/binutils/nm.c
index ecd147e..ed1ed12 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -806,7 +806,11 @@ get_relocs (bfd *abfd, asection *sec, void *dataarg)
/* Print a single symbol. */
static void
-print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
+print_symbol (bfd * abfd,
+ asymbol * sym,
+ bfd_vma ssize,
+ bfd * archive_bfd,
+ bfd_boolean is_synthetic)
{
symbol_info syminfo;
struct extended_symbol_info info;
@@ -816,12 +820,12 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
format->print_symbol_filename (archive_bfd, abfd);
bfd_get_symbol_info (abfd, sym, &syminfo);
+
info.sinfo = &syminfo;
info.ssize = ssize;
- if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- info.elfinfo = (elf_symbol_type *) sym;
- else
- info.elfinfo = NULL;
+ /* Synthetic symbols do not have a full elf_symbol_type set of data available. */
+ info.elfinfo = is_synthetic ? NULL : elf_symbol_from (abfd, sym);
+
format->print_symbol_info (&info, abfd);
if (line_numbers)
@@ -941,12 +945,17 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
/* Print the symbols when sorting by size. */
static void
-print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
- struct size_sym *symsizes, long symcount,
- bfd *archive_bfd)
+print_size_symbols (bfd * abfd,
+ bfd_boolean is_dynamic,
+ struct size_sym * symsizes,
+ long symcount,
+ long synth_count,
+ bfd * archive_bfd)
{
asymbol *store;
- struct size_sym *from, *fromend;
+ struct size_sym *from;
+ struct size_sym *fromend;
+ struct size_sym *fromsynth;
store = bfd_make_empty_symbol (abfd);
if (store == NULL)
@@ -954,6 +963,8 @@ print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
from = symsizes;
fromend = from + symcount;
+ fromsynth = symsizes + (symcount - synth_count);
+
for (; from < fromend; from++)
{
asymbol *sym;
@@ -962,20 +973,34 @@ print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
- print_symbol (abfd, sym, from->size, archive_bfd);
+ print_symbol (abfd, sym, from->size, archive_bfd, from >= fromsynth);
}
}
-/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
- containing ABFD. */
+/* Print the symbols of ABFD that are held in MINISYMS.
+
+ If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.
+
+ SYMCOUNT is the number of symbols in MINISYMS and SYNTH_COUNT
+ is the number of these that are synthetic. Synthetic symbols,
+ if any are present, always come at the end of the MINISYMS.
+
+ SIZE is the size of a symbol in MINISYMS. */
static void
-print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
- unsigned int size, bfd *archive_bfd)
+print_symbols (bfd * abfd,
+ bfd_boolean is_dynamic,
+ void * minisyms,
+ long symcount,
+ long synth_count,
+ unsigned int size,
+ bfd * archive_bfd)
{
asymbol *store;
- bfd_byte *from, *fromend;
+ bfd_byte *from;
+ bfd_byte *fromend;
+ bfd_byte *fromsynth;
store = bfd_make_empty_symbol (abfd);
if (store == NULL)
@@ -983,6 +1008,8 @@ print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
from = (bfd_byte *) minisyms;
fromend = from + symcount * size;
+ fromsynth = (bfd_byte *) minisyms + ((symcount - synth_count) * size);
+
for (; from < fromend; from += size)
{
asymbol *sym;
@@ -991,7 +1018,7 @@ print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
- print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd);
+ print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd, from >= fromsynth);
}
}
@@ -1001,6 +1028,7 @@ static void
display_rel_file (bfd *abfd, bfd *archive_bfd)
{
long symcount;
+ long synth_count = 0;
void *minisyms;
unsigned int size;
struct size_sym *symsizes;
@@ -1031,11 +1059,10 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
return;
}
-
+
if (show_synthetic && size == sizeof (asymbol *))
{
asymbol *synthsyms;
- long synth_count;
asymbol **static_syms = NULL;
asymbol **dyn_syms = NULL;
long static_count = 0;
@@ -1061,6 +1088,7 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
bfd_fatal (bfd_get_filename (abfd));
}
}
+
synth_count = bfd_get_synthetic_symtab (abfd, static_count, static_syms,
dyn_count, dyn_syms, &synthsyms);
if (synth_count > 0)
@@ -1106,9 +1134,9 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
}
if (! sort_by_size)
- print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
+ print_symbols (abfd, dynamic, minisyms, symcount, synth_count, size, archive_bfd);
else
- print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
+ print_size_symbols (abfd, dynamic, symsizes, symcount, synth_count, archive_bfd);
free (minisyms);
free (symsizes);
@@ -1181,6 +1209,8 @@ display_archive (bfd *file)
bfd_close (last_arfile);
lineno_cache_bfd = NULL;
lineno_cache_rel_bfd = NULL;
+ if (arfile == last_arfile)
+ return;
}
last_arfile = arfile;
}
@@ -1434,7 +1464,6 @@ print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd)
print_value (abfd, SYM_SIZE (info));
else
print_value (abfd, SYM_VALUE (info));
-
if (print_size && SYM_SIZE (info))
{
printf (" ");
@@ -1541,6 +1570,7 @@ main (int argc, char **argv)
program_name = *argv;
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
#if BFD_SUPPORTS_PLUGINS
bfd_plugin_set_program_name (program_name);
#endif
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 07794cb..da429f5 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -1776,6 +1776,14 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
return FALSE;
}
+ /* PR 17512: file: d6323821
+ If the symbol table could not be loaded do not pretend that we have
+ any symbols. This trips us up later on when we load the relocs. */
+ if (symcount == 0)
+ {
+ free (isympp);
+ osympp = isympp = NULL;
+ }
/* BFD mandates that all output sections be created and sizes set before
any output is done. Thus, we traverse all sections multiple times. */
@@ -2552,7 +2560,11 @@ copy_file (const char *input_filename, const char *output_filename,
if (! copy_object (ibfd, obfd, input_arch))
status = 1;
- if (!bfd_close (obfd))
+ /* PR 17512: file: 0f15796a.
+ If the file could not be copied it may not be in a writeable
+ state. So use bfd_close_all_done to avoid the possibility of
+ writing uninitialised data into the file. */
+ if (! (status ? bfd_close_all_done (obfd) : bfd_close (obfd)))
{
status = 1;
bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
@@ -2948,9 +2960,13 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
temp_relpp = (arelent **) xmalloc (relsize);
for (i = 0; i < relcount; i++)
- if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
- keep_specific_htab))
- temp_relpp [temp_relcount++] = relpp [i];
+ {
+ /* PR 17512: file: 9e907e0c. */
+ if (relpp[i]->sym_ptr_ptr)
+ if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
+ keep_specific_htab))
+ temp_relpp [temp_relcount++] = relpp [i];
+ }
relcount = temp_relcount;
free (relpp);
relpp = temp_relpp;
@@ -4399,6 +4415,9 @@ main (int argc, char *argv[])
create_symbol_htabs ();
+ if (argv != NULL)
+ bfd_set_error_program_name (argv[0]);
+
if (is_strip)
strip_main (argc, argv);
else
diff --git a/binutils/objdump.c b/binutils/objdump.c
index da68f39..44107cf 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -2265,6 +2265,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
section->address = bfd_get_section_vma (abfd, sec);
section->size = bfd_get_section_size (sec);
section->start = NULL;
+ section->user_data = sec;
ret = bfd_get_full_section_contents (abfd, sec, §ion->start);
if (! ret)
@@ -2331,6 +2332,23 @@ free_debug_section (enum dwarf_section_display_enum debug)
if (section->start == NULL)
return;
+ /* PR 17512: file: 0f67f69d. */
+ if (section->user_data != NULL)
+ {
+ asection * sec = (asection *) section->user_data;
+
+ /* If we are freeing contents that are also pointed to by the BFD
+ library's section structure then make sure to update those pointers
+ too. Otherwise, the next time we try to load data for this section
+ we can end up using a stale pointer. */
+ if (section->start == sec->contents)
+ {
+ sec->contents = NULL;
+ sec->flags &= ~ SEC_IN_MEMORY;
+ sec->compress_status = COMPRESS_SECTION_NONE;
+ }
+ }
+
free ((char *) section->start);
section->start = NULL;
section->address = 0;
@@ -2766,7 +2784,8 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
if (!bfd_get_full_section_contents (abfd, section, &data))
{
- non_fatal (_("Reading section failed"));
+ non_fatal (_("Reading section %s failed because: %s"),
+ section->name, bfd_errmsg (bfd_get_error ()));
return;
}
@@ -3375,6 +3394,13 @@ display_any_bfd (bfd *file, int level)
if (level == 0)
printf (_("In archive %s:\n"), bfd_get_filename (file));
+ else if (level > 100)
+ {
+ /* Prevent corrupted files from spinning us into an
+ infinite loop. 100 is an arbitrary heuristic. */
+ fatal (_("Archive nesting is too deep"));
+ return;
+ }
else
printf (_("In nested archive %s:\n"), bfd_get_filename (file));
@@ -3393,7 +3419,15 @@ display_any_bfd (bfd *file, int level)
display_any_bfd (arfile, level + 1);
if (last_arfile != NULL)
- bfd_close (last_arfile);
+ {
+ bfd_close (last_arfile);
+ /* PR 17512: file: ac585d01. */
+ if (arfile == last_arfile)
+ {
+ last_arfile = NULL;
+ break;
+ }
+ }
last_arfile = arfile;
}
@@ -3446,6 +3480,7 @@ main (int argc, char **argv)
program_name = *argv;
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
START_PROGRESS (program_name, 0);
diff --git a/binutils/rcparse.y b/binutils/rcparse.y
index 2d17909..23bd69f 100644
--- a/binutils/rcparse.y
+++ b/binutils/rcparse.y
@@ -1887,12 +1887,12 @@ sizednumexpr:
}
| sizednumexpr '/' sizednumexpr
{
- $$.val = $1.val / $3.val;
+ $$.val = $1.val / ($3.val ? $3.val : 1);
$$.dword = $1.dword || $3.dword;
}
| sizednumexpr '%' sizednumexpr
{
- $$.val = $1.val % $3.val;
+ $$.val = $1.val % ($3.val ? $3.val : 1);
$$.dword = $1.dword || $3.dword;
}
| sizednumexpr '+' sizednumexpr
@@ -1966,12 +1966,13 @@ sizedposnumexpr:
}
| sizedposnumexpr '/' sizednumexpr
{
- $$.val = $1.val / $3.val;
+ $$.val = $1.val / ($3.val ? $3.val : 1);
$$.dword = $1.dword || $3.dword;
}
| sizedposnumexpr '%' sizednumexpr
{
- $$.val = $1.val % $3.val;
+ /* PR 17512: file: 89105a25. */
+ $$.val = $1.val % ($3.val ? $3.val : 1);
$$.dword = $1.dword || $3.dword;
}
| sizedposnumexpr '+' sizednumexpr
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
index 607c823..dadc683 100644
--- a/binutils/rescoff.c
+++ b/binutils/rescoff.c
@@ -142,8 +142,14 @@ read_coff_rsrc (const char *filename, const char *target)
set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);
size = bfd_section_size (abfd, sec);
- data = (bfd_byte *) res_alloc (size);
+ /* PR 17512: file: 1b25ba5d
+ The call to get_file_size here may be expensive
+ but there is no other way to determine if the section size
+ is reasonable. */
+ if (size > (bfd_size_type) get_file_size (filename))
+ fatal (_("%s: .rsrc section is bigger than the file!"), filename);
+ data = (bfd_byte *) res_alloc (size);
get_windres_bfd_content (&wrbfd, data, 0, size);
flaginfo.filename = filename;
@@ -185,6 +191,13 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
rc_res_entry **pp;
const struct extern_res_entry *ere;
+ /* PR 17512: file: 09d80f53.
+ Whilst in theory resources can nest to any level, in practice
+ Microsoft only defines 3 levels. Corrupt files however might
+ claim to use more. */
+ if (level > 4)
+ overrun (flaginfo, _("Resources nest too deep"));
+
if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_directory))
overrun (flaginfo, _("directory"));
@@ -234,7 +247,12 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
re->id.u.n.length = length;
re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar));
for (j = 0; j < length; j++)
- re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
+ {
+ /* PR 17512: file: 05dc4a16. */
+ if (length < 0 || ers >= (bfd_byte *) ere || ers + j * 2 + 4 >= (bfd_byte *) ere)
+ overrun (flaginfo, _("resource name"));
+ re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
+ }
if (level == 0)
type = &re->id;
diff --git a/binutils/resrc.c b/binutils/resrc.c
index 65f1c11..4126abd 100644
--- a/binutils/resrc.c
+++ b/binutils/resrc.c
@@ -2923,6 +2923,7 @@ write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data)
{
int has_error = 0;
const struct bin_messagetable *mt;
+
fprintf (e, "BEGIN\n");
write_rc_datablock (e, length, data, 0, 0, 0);
@@ -2932,53 +2933,68 @@ write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data)
if (length < BIN_MESSAGETABLE_SIZE)
has_error = 1;
else
- do {
- rc_uint_type m, i;
- mt = (const struct bin_messagetable *) data;
- m = windres_get_32 (&wrtarget, mt->cblocks, length);
- if (length < (BIN_MESSAGETABLE_SIZE + m * BIN_MESSAGETABLE_BLOCK_SIZE))
- {
- has_error = 1;
- break;
- }
- for (i = 0; i < m; i++)
- {
- rc_uint_type low, high, offset;
- const struct bin_messagetable_item *mti;
+ do
+ {
+ rc_uint_type m, i;
+
+ mt = (const struct bin_messagetable *) data;
+ m = windres_get_32 (&wrtarget, mt->cblocks, length);
+
+ if (length < (BIN_MESSAGETABLE_SIZE + m * BIN_MESSAGETABLE_BLOCK_SIZE))
+ {
+ has_error = 1;
+ break;
+ }
+ for (i = 0; i < m; i++)
+ {
+ rc_uint_type low, high, offset;
+ const struct bin_messagetable_item *mti;
+
+ low = windres_get_32 (&wrtarget, mt->items[i].lowid, 4);
+ high = windres_get_32 (&wrtarget, mt->items[i].highid, 4);
+ offset = windres_get_32 (&wrtarget, mt->items[i].offset, 4);
+
+ while (low <= high)
+ {
+ rc_uint_type elen, flags;
+ if ((offset + BIN_MESSAGETABLE_ITEM_SIZE) > length)
+ {
+ has_error = 1;
+ break;
+ }
+ mti = (const struct bin_messagetable_item *) &data[offset];
+ elen = windres_get_16 (&wrtarget, mti->length, 2);
+ flags = windres_get_16 (&wrtarget, mti->flags, 2);
+ if ((offset + elen) > length)
+ {
+ has_error = 1;
+ break;
+ }
+ wr_printcomment (e, "MessageId = 0x%x", low);
+ wr_printcomment (e, "");
+
+ if ((flags & MESSAGE_RESOURCE_UNICODE) == MESSAGE_RESOURCE_UNICODE)
+ {
+ /* PR 17512: file: 5c3232dc. */
+ if (elen > BIN_MESSAGETABLE_ITEM_SIZE * 2)
+ unicode_print (e, (const unichar *) mti->data,
+ (elen - BIN_MESSAGETABLE_ITEM_SIZE) / 2);
+ }
+ else
+ {
+ if (elen > BIN_MESSAGETABLE_ITEM_SIZE)
+ ascii_print (e, (const char *) mti->data,
+ (elen - BIN_MESSAGETABLE_ITEM_SIZE));
+ }
+
+ wr_printcomment (e,"");
+ ++low;
+ offset += elen;
+ }
+ }
+ }
+ while (0);
- low = windres_get_32 (&wrtarget, mt->items[i].lowid, 4);
- high = windres_get_32 (&wrtarget, mt->items[i].highid, 4);
- offset = windres_get_32 (&wrtarget, mt->items[i].offset, 4);
- while (low <= high)
- {
- rc_uint_type elen, flags;
- if ((offset + BIN_MESSAGETABLE_ITEM_SIZE) > length)
- {
- has_error = 1;
- break;
- }
- mti = (const struct bin_messagetable_item *) &data[offset];
- elen = windres_get_16 (&wrtarget, mti->length, 2);
- flags = windres_get_16 (&wrtarget, mti->flags, 2);
- if ((offset + elen) > length)
- {
- has_error = 1;
- break;
- }
- wr_printcomment (e, "MessageId = 0x%x", low);
- wr_printcomment (e, "");
- if ((flags & MESSAGE_RESOURCE_UNICODE) == MESSAGE_RESOURCE_UNICODE)
- unicode_print (e, (const unichar *) mti->data,
- (elen - BIN_MESSAGETABLE_ITEM_SIZE) / 2);
- else
- ascii_print (e, (const char *) mti->data,
- (elen - BIN_MESSAGETABLE_ITEM_SIZE));
- wr_printcomment (e,"");
- ++low;
- offset += elen;
- }
- }
- } while (0);
if (has_error)
wr_printcomment (e, "Illegal data");
wr_print_flush (e);
@@ -2995,7 +3011,7 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_
fprintf (e, "BEGIN\n");
if (show_comment == -1)
- {
+ {
if (test_rc_datablock_text(length, data))
{
rc_uint_type i, c;
@@ -3008,7 +3024,7 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_
;
if (i < length && data[i] == '\n')
++i, ++c;
- ascii_print (e, (const char *) &data[i - c], c);
+ ascii_print(e, (const char *) &data[i - c], c);
fprintf (e, "\"");
if (i < length)
fprintf (e, "\n");
diff --git a/binutils/size.c b/binutils/size.c
index e727165..8edd7f9 100644
--- a/binutils/size.c
+++ b/binutils/size.c
@@ -133,6 +133,7 @@ main (int argc, char **argv)
program_name = *argv;
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);
@@ -365,7 +366,14 @@ display_archive (bfd *file)
display_bfd (arfile);
if (last_arfile != NULL)
- bfd_close (last_arfile);
+ {
+ bfd_close (last_arfile);
+
+ /* PR 17512: file: a244edbc. */
+ if (last_arfile == arfile)
+ return;
+ }
+
last_arfile = arfile;
}
diff --git a/binutils/srconv.c b/binutils/srconv.c
index 13119b4..1bda313 100644
--- a/binutils/srconv.c
+++ b/binutils/srconv.c
@@ -167,7 +167,8 @@ checksum (FILE *ffile, unsigned char *ptr, int size, int ccode)
last = !(ccode & 0xff00);
if (size & 0x7)
- abort ();
+ fatal (_("Checksum failure"));
+
ptr[0] = ccode | (last ? 0x80 : 0);
ptr[1] = bytes + 1;
@@ -178,7 +179,7 @@ checksum (FILE *ffile, unsigned char *ptr, int size, int ccode)
ptr[bytes] = ~sum;
if (fwrite (ptr, bytes + 1, 1, ffile) != 1)
/* FIXME: Return error status. */
- abort ();
+ fatal (_("Failed to write checksum"));
}
@@ -218,7 +219,7 @@ writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *ffile)
ptr[byte + 3] = n >> 0;
break;
default:
- abort ();
+ fatal (_("Unsupported integer write size: %d"), size);
}
*idx += size * 8;
}
@@ -304,7 +305,7 @@ wr_tr (void)
if (fwrite (b, sizeof (b), 1, file) != 1)
/* FIXME: Return error status. */
- abort ();
+ fatal (_("Failed to write TR block"));
}
static void
@@ -395,7 +396,8 @@ wr_hd (struct coff_ofile *p)
toolname = "C_H8/300S";
break;
default:
- abort();
+ fatal (_("Unrecognized H8300 sub-architecture: %ld"),
+ bfd_get_mach (abfd));
}
rnames = rname_h8300;
break;
@@ -412,7 +414,7 @@ wr_hd (struct coff_ofile *p)
rnames = rname_sh;
break;
default:
- abort ();
+ fatal (_("Unsupported architecture: %d"), bfd_get_arch (abfd));
}
if (! (bfd_get_file_flags(abfd) & EXEC_P))
@@ -866,7 +868,7 @@ walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol,
break;
default:
- abort ();
+ fatal (_("Unrecognised type: %d"), type->type);
}
}
@@ -995,7 +997,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
return;
default:
- abort ();
+ fatal (_("Unrecognised coff symbol type: %d"), symbol->type->type);
}
if (symbol->where->where == coff_where_member_of_struct)
@@ -1057,7 +1059,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
break;
default:
- abort ();
+ fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type);
}
dsy.dlength = symbol->type->size;
@@ -1083,7 +1085,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
break;
default:
- abort ();
+ fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where);
}
switch (symbol->where->where)
@@ -1128,7 +1130,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
break;
default:
- abort ();
+ fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where);
}
if (symbol->where->where == coff_where_register)
@@ -1157,7 +1159,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
break;
default:
- abort ();
+ fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type);
}
dsy.sfn = 0;
@@ -1202,6 +1204,8 @@ walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile)
static void
wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile)
{
+ if (p->nsections < 4)
+ return;
walk_tree_sfile (p->sections + 4, sfile);
}
@@ -1460,7 +1464,7 @@ wr_cs (void)
if (fwrite (b, sizeof (b), 1, file) != 1)
/* FIXME: Return error status. */
- abort ();
+ fatal (_("Failed to write CS struct"));
}
/* Write out the SC records for a unit. Create an SC
@@ -1703,6 +1707,9 @@ prescan (struct coff_ofile *otree)
struct coff_symbol *s;
struct coff_section *common_section;
+ if (otree->nsections < 3)
+ return;
+
/* Find the common section - always section 3. */
common_section = otree->sections + 3;
@@ -1772,6 +1779,7 @@ main (int ac, char **av)
program_name = av[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&ac, &av);
@@ -1883,10 +1891,12 @@ main (int ac, char **av)
printf ("ids %d %d\n", base1, base2);
tree = coff_grok (abfd);
+ if (tree)
+ {
+ if (!noprescan)
+ prescan (tree);
- if (!noprescan)
- prescan (tree);
-
- wr_module (tree);
+ wr_module (tree);
+ }
return 0;
}
diff --git a/binutils/strings.c b/binutils/strings.c
index 7346f55..224f870 100644
--- a/binutils/strings.c
+++ b/binutils/strings.c
@@ -164,6 +164,7 @@ main (int argc, char **argv)
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);
diff --git a/binutils/sysdump.c b/binutils/sysdump.c
index 5ae324f..b8dfec8 100644
--- a/binutils/sysdump.c
+++ b/binutils/sysdump.c
@@ -66,6 +66,9 @@ getCHARS (unsigned char *ptr, int *idx, int size, int max)
if (b == 0)
{
+ /* PR 17512: file: 13caced2. */
+ if (oc >= max)
+ return _("*corrupt*");
/* Got to work out the length of the string from self. */
b = ptr[oc++];
(*idx) += 8;
@@ -166,7 +169,12 @@ getINT (unsigned char *ptr, int *idx, int size, int max)
int byte = *idx / 8;
if (byte >= max)
- return 0;
+ {
+ /* PR 17512: file: id:000001,src:000002,op:flip1,pos:45. */
+ /* Prevent infinite loops re-reading beyond the end of the buffer. */
+ fatal (_("ICE: getINT: Out of buffer space"));
+ return 0;
+ }
if (size == -2)
size = addrsize;
@@ -188,7 +196,7 @@ getINT (unsigned char *ptr, int *idx, int size, int max)
n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]);
break;
default:
- abort ();
+ fatal (_("Unsupported read size: %d"), size);
}
*idx += size * 8;
@@ -615,6 +623,8 @@ module (void)
do
{
c = getc (file);
+ if (c == EOF)
+ break;
ungetc (c, file);
c &= 0x7f;
@@ -676,6 +686,7 @@ main (int ac, char **av)
program_name = av[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&ac, &av);
diff --git a/binutils/windmc.c b/binutils/windmc.c
index 01785db..9364e20 100644
--- a/binutils/windmc.c
+++ b/binutils/windmc.c
@@ -952,6 +952,7 @@ main (int argc, char **argv)
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);
diff --git a/binutils/windres.c b/binutils/windres.c
index 7fa90fc..5750490 100644
--- a/binutils/windres.c
+++ b/binutils/windres.c
@@ -204,6 +204,7 @@ open_file_search (const char *filename, const char *mode, const char *errmsg,
*real_filename = n;
return e;
}
+ free (n);
if (errno != ENOENT)
break;
@@ -807,6 +808,7 @@ main (int argc, char **argv)
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
expandargv (&argc, &argv);