]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Import fixes from trunk sources to correct invalid memory access issues with various...
authorNick Clifton <nickc@redhat.com>
Tue, 24 Mar 2015 12:25:25 +0000 (12:25 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 24 Mar 2015 12:25:25 +0000 (12:25 +0000)
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.

23 files changed:
binutils/ChangeLog
binutils/addr2line.c
binutils/ar.c
binutils/coffdump.c
binutils/coffgrok.c
binutils/coffgrok.h
binutils/cxxfilt.c
binutils/dlltool.c
binutils/elfcomm.c
binutils/elfcomm.h
binutils/nlmconv.c
binutils/nm.c
binutils/objcopy.c
binutils/objdump.c
binutils/rcparse.y
binutils/rescoff.c
binutils/resrc.c
binutils/size.c
binutils/srconv.c
binutils/strings.c
binutils/sysdump.c
binutils/windmc.c
binutils/windres.c

index a4bb426f464d66342034aa4fbd94cdaff312bab0..9f3d3b13e2fab88dc2bd325d2a9215c575fb41d3 100644 (file)
@@ -1,3 +1,135 @@
+2015-03-24  Nick Clifton  <nickc@redhat.com>
+
+       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.
+       * size.c (display_archive): Likewise.
+
 2015-03-24  Nick Clifton  <nickc@redhat.com>
 
        Apply from master:
index f88e7458cdbbea0fd61415d0d33a0937134e71d4..7cabb8bdbb530420cb6c006ec5345606209dd4e1 100644 (file)
@@ -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;
+    }
 }
 \f
 /* 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);
 
index 117826d18e8b10079fdc01726641945e7e412ec1..7c3c86974ae77adc68967a22945233cdfb4bcbed 100644 (file)
@@ -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
index b4c84155f1995579962afceb4a15dcea10e66fd5..bf6291554177dd8976e28a51babf63078a36bb2a 100644 (file)
@@ -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;
 }
index f37f266340eff62f71603f3096287044e93ef8ab..e2d520e3c14163a456f4b2fcaf6df22f911b9166 100644 (file)
@@ -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)
index 75e08241e778c8baf56491e6cbe68fc1e0c0b18b..830da39b9519f8a58090630f2d53a96691189e49 100644 (file)
    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 *);
index 157ebe02d524ef1658e5d575356430d0367e9272..391eb297858c366277fce6589891128c4686e267 100644 (file)
@@ -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);
 
index 8b013f0e3b095a93544843634406e82a458c8864..4d77b021fa8b9f0aa29328187afc085b62f6296a 100644 (file)
@@ -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,
index f1502b9fdf6953f74f224b48ffa79c1c69e91d2e..063662a9f7fe704a6d86cec9f954c4b21388ddf0 100644 (file)
@@ -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,
index d834753a6c43944d13ff9f585fd9f0ad89781bce..f7f7544f4cb280fa493a8235d6a6e6e0cedeb28d 100644 (file)
@@ -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 *,
index 0513f291494494c9da7f192e7b9b04882d84d879..fecb110a67dc54ece9653caee63d9d091b277d75 100644 (file)
@@ -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)))
index ecd147e040042421ed51ca7ca940ba318f341706..ed1ed12580b0b0852633568b132459b80cc6b199 100644 (file)
@@ -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);
     }
 }
 
 \f
-/* 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
index 07794cbbf8b10c8cc293e1adb0143cf2d5f1f957..da429f54ea84db3039e491dba9b97caa627ed13c 100644 (file)
@@ -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
index da68f39a1157c36c5ef05d6ccdcd7be3c1ebc36a..44107cf8646484f3ee7cf2dec01318213a8613b3 100644 (file)
@@ -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, &section->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);
 
index 2d179097fc01e341c4501a31e68428f16c8da5a6..23bd69f542dec5c8a733ae6881c4b5b35197bafa 100644 (file)
@@ -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
index 607c8231b7d4aa30d379c72e898375402ed5d553..dadc68335869bc1ac26b3a1ffc82852c5a66215a 100644 (file)
@@ -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;
index 65f1c1109b036b9b8df0ee0397271ef61d0c1c68..4126abdd397aa60fdd3fdc065fac37b72122ea67 100644 (file)
@@ -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");
index e727165f019ae0fa692b7a50ec337889cfed6c5a..8edd7f987d971972863d19e91640de5101eba2d8 100644 (file)
@@ -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;
     }
 
index 13119b4f1ea84cfd8e603b93e4edca3ff24c7b90..1bda313fe76c97ddfb4e99b79cc416f6072522a0 100644 (file)
@@ -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;
 }
index 7346f553e192a777b8543b1a28632bcd19f4cc45..224f87085c77253c5b58949903346a0c420372c7 100644 (file)
@@ -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);
 
index 5ae324f880606527031378d1de33e7b049accbed..b8dfec87fd0b332936d955b190b7c80b98158369 100644 (file)
@@ -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);
 
index 01785db58dcc1ced7f2ece82b4aac0fe9e654f6a..9364e2018ede902df41f77270b60ae202855898f 100644 (file)
@@ -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);
 
index 7fa90fc7f78d8c5581ef550ccc612386737bf3f8..57504909b43569af3b305a25f13a19620da00add 100644 (file)
@@ -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);