Release 2.33.1
[external/binutils.git] / binutils / rddbg.c
index e977d8b..9205278 100644 (file)
@@ -1,13 +1,12 @@
 /* rddbg.c -- Read debugging information into a generic form.
 /* rddbg.c -- Read debugging information into a generic form.
-   Copyright 1995, 1996, 1997, 2000, 2002, 2003, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1995-2019 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
+
 /* This file reads debugging information into a generic form.  This
    file knows how to dig the debugging information out of an object
    file.  */
 
 /* This file reads debugging information into a generic form.  This
    file knows how to dig the debugging information out of an object
    file.  */
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "bfd.h"
-#include "bucomm.h"
 #include "libiberty.h"
 #include "libiberty.h"
+#include "bucomm.h"
 #include "debug.h"
 #include "budbg.h"
 
 #include "debug.h"
 #include "budbg.h"
 
@@ -34,7 +35,6 @@ static bfd_boolean read_section_stabs_debugging_info
   (bfd *, asymbol **, long, void *, bfd_boolean *);
 static bfd_boolean read_symbol_stabs_debugging_info
   (bfd *, asymbol **, long, void *, bfd_boolean *);
   (bfd *, asymbol **, long, void *, bfd_boolean *);
 static bfd_boolean read_symbol_stabs_debugging_info
   (bfd *, asymbol **, long, void *, bfd_boolean *);
-static bfd_boolean read_ieee_debugging_info (bfd *, void *, bfd_boolean *);
 static void save_stab (int, int, bfd_vma, const char *);
 static void stab_context (void);
 static void free_saved_stabs (void);
 static void save_stab (int, int, bfd_vma, const char *);
 static void stab_context (void);
 static void free_saved_stabs (void);
@@ -43,7 +43,7 @@ static void free_saved_stabs (void);
    pointer.  */
 
 void *
    pointer.  */
 
 void *
-read_debugging_info (bfd *abfd, asymbol **syms, long symcount)
+read_debugging_info (bfd *abfd, asymbol **syms, long symcount, bfd_boolean no_messages)
 {
   void *dhandle;
   bfd_boolean found;
 {
   void *dhandle;
   bfd_boolean found;
@@ -63,12 +63,6 @@ read_debugging_info (bfd *abfd, asymbol **syms, long symcount)
        return NULL;
     }
 
        return NULL;
     }
 
-  if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
-    {
-      if (! read_ieee_debugging_info (abfd, dhandle, &found))
-       return NULL;
-    }
-
   /* Try reading the COFF symbols if we didn't find any stabs in COFF
      sections.  */
   if (! found
   /* Try reading the COFF symbols if we didn't find any stabs in COFF
      sections.  */
   if (! found
@@ -82,8 +76,9 @@ read_debugging_info (bfd *abfd, asymbol **syms, long symcount)
 
   if (! found)
     {
 
   if (! found)
     {
-      non_fatal (_("%s: no recognized debugging information"),
-                bfd_get_filename (abfd));
+      if (! no_messages)
+       non_fatal (_("%s: no recognized debugging information"),
+                  bfd_get_filename (abfd));
       return NULL;
     }
 
       return NULL;
     }
 
@@ -133,35 +128,46 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
              fprintf (stderr, "%s: %s: %s\n",
                       bfd_get_filename (abfd), names[i].secname,
                       bfd_errmsg (bfd_get_error ()));
              fprintf (stderr, "%s: %s: %s\n",
                       bfd_get_filename (abfd), names[i].secname,
                       bfd_errmsg (bfd_get_error ()));
+             free (shandle);
+             free (stabs);
              return FALSE;
            }
 
          strsize = bfd_section_size (abfd, strsec);
              return FALSE;
            }
 
          strsize = bfd_section_size (abfd, strsec);
-         strings = (bfd_byte *) xmalloc (strsize);
+         strings = (bfd_byte *) xmalloc (strsize + 1);
          if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
            {
              fprintf (stderr, "%s: %s: %s\n",
                       bfd_get_filename (abfd), names[i].strsecname,
                       bfd_errmsg (bfd_get_error ()));
          if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
            {
              fprintf (stderr, "%s: %s: %s\n",
                       bfd_get_filename (abfd), names[i].strsecname,
                       bfd_errmsg (bfd_get_error ()));
+             free (shandle);
+             free (strings);
+             free (stabs);
              return FALSE;
            }
              return FALSE;
            }
-
+         /* Zero terminate the strings table, just in case.  */
+         strings [strsize] = 0;
          if (shandle == NULL)
            {
              shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
              if (shandle == NULL)
          if (shandle == NULL)
            {
              shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
              if (shandle == NULL)
-               return FALSE;
+               {
+                 free (strings);
+                 free (stabs);
+                 return FALSE;
+               }
            }
 
          *pfound = TRUE;
 
          stroff = 0;
          next_stroff = 0;
            }
 
          *pfound = TRUE;
 
          stroff = 0;
          next_stroff = 0;
-         for (stab = stabs; stab < stabs + stabsize; stab += 12)
+         /* PR 17512: file: 078-60391-0.001:0.1.  */
+         for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
            {
              unsigned int strx;
              int type;
            {
              unsigned int strx;
              int type;
-             int other;
+             int other ATTRIBUTE_UNUSED;
              int desc;
              bfd_vma value;
 
              int desc;
              bfd_vma value;
 
@@ -182,32 +188,42 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
                }
              else
                {
                }
              else
                {
+                 size_t len;
                  char *f, *s;
 
                  char *f, *s;
 
-                 f = NULL;
-
-                 if (stroff + strx > strsize)
+                 if (stroff + strx >= strsize)
                    {
                    {
-                     fprintf (stderr, "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n",
+                     fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
                               bfd_get_filename (abfd), names[i].secname,
                               (long) (stab - stabs) / 12, strx, type);
                      continue;
                    }
 
                  s = (char *) strings + stroff + strx;
                               bfd_get_filename (abfd), names[i].secname,
                               (long) (stab - stabs) / 12, strx, type);
                      continue;
                    }
 
                  s = (char *) strings + stroff + strx;
+                 f = NULL;
 
 
-                 while (s[strlen (s) - 1] == '\\'
+                 /* PR 17512: file: 002-87578-0.001:0.1.
+                    It is possible to craft a file where, without the 'strlen (s) > 0',
+                    an attempt to read the byte before 'strings' would occur.  */
+                 while ((len = strlen (s)) > 0
+                        && s[len  - 1] == '\\'
                         && stab + 12 < stabs + stabsize)
                    {
                      char *p;
 
                      stab += 12;
                         && stab + 12 < stabs + stabsize)
                    {
                      char *p;
 
                      stab += 12;
-                     p = s + strlen (s) - 1;
+                     p = s + len - 1;
                      *p = '\0';
                      *p = '\0';
-                     s = concat (s,
-                                 ((char *) strings
-                                  + stroff
-                                  + bfd_get_32 (abfd, stab)),
+                     strx = stroff + bfd_get_32 (abfd, stab);
+                     if (strx >= strsize)
+                       {
+                         fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
+                                  bfd_get_filename (abfd), names[i].secname,
+                                  (long) (stab - stabs) / 12);
+                         break;
+                       }
+
+                     s = concat (s, (char *) strings + strx,
                                  (const char *) NULL);
 
                      /* We have to restore the backslash, because, if
                                  (const char *) NULL);
 
                      /* We have to restore the backslash, because, if
@@ -215,8 +231,7 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
                         see the same string more than once.  */
                      *p = '\\';
 
                         see the same string more than once.  */
                      *p = '\\';
 
-                     if (f != NULL)
-                       free (f);
+                     free (f);
                      f = s;
                    }
 
                      f = s;
                    }
 
@@ -226,6 +241,10 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
                    {
                      stab_context ();
                      free_saved_stabs ();
                    {
                      stab_context ();
                      free_saved_stabs ();
+                     free (f);
+                     free (shandle);
+                     free (stabs);
+                     free (strings);
                      return FALSE;
                    }
 
                      return FALSE;
                    }
 
@@ -285,8 +304,12 @@ read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
          *pfound = TRUE;
 
          s = i.name;
          *pfound = TRUE;
 
          s = i.name;
+         if (s == NULL || strlen (s) < 1)
+           return FALSE;
          f = NULL;
          f = NULL;
-         while (s[strlen (s) - 1] == '\\'
+
+         while (strlen (s) > 0
+                && s[strlen (s) - 1] == '\\'
                 && ps + 1 < symend)
            {
              char *sc, *n;
                 && ps + 1 < symend)
            {
              char *sc, *n;
@@ -328,37 +351,6 @@ read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
 
   return TRUE;
 }
 
   return TRUE;
 }
-
-/* Read IEEE debugging information.  */
-
-static bfd_boolean
-read_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound)
-{
-  asection *dsec;
-  bfd_size_type size;
-  bfd_byte *contents;
-
-  /* The BFD backend puts the debugging information into a section
-     named .debug.  */
-
-  dsec = bfd_get_section_by_name (abfd, ".debug");
-  if (dsec == NULL)
-    return TRUE;
-
-  size = bfd_section_size (abfd, dsec);
-  contents = (bfd_byte *) xmalloc (size);
-  if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
-    return FALSE;
-
-  if (! parse_ieee (dhandle, abfd, contents, size))
-    return FALSE;
-
-  free (contents);
-
-  *pfound = TRUE;
-
-  return TRUE;
-}
 \f
 /* Record stabs strings, so that we can give some context for errors.  */
 
 \f
 /* Record stabs strings, so that we can give some context for errors.  */