gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / binutils / rddbg.c
index d42d04863eda71df2a0af18501c852993368edd0..930dbf71349bedcc2ecb58ffef3081476bc1973f 100644 (file)
@@ -1,12 +1,12 @@
 /* rddbg.c -- Read debugging information into a generic form.
 /* rddbg.c -- Read debugging information into a generic form.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995-2020 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,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, 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"
 
-static boolean read_section_stabs_debugging_info
-  PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
-static boolean read_symbol_stabs_debugging_info
-  PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
-static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
-static void save_stab PARAMS ((int, int, bfd_vma, const char *));
-static void stab_context PARAMS ((void));
-static void free_saved_stabs PARAMS ((void));
+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 *);
+static void save_stab (int, int, bfd_vma, const char *);
+static void stab_context (void);
+static void free_saved_stabs (void);
 
 /* Read debugging information from a BFD.  Returns a generic debugging
    pointer.  */
 
 
 /* Read debugging information from a BFD.  Returns a generic debugging
    pointer.  */
 
-PTR
-read_debugging_info (abfd, syms, symcount)
-     bfd *abfd;
-     asymbol **syms;
-     long symcount;
+void *
+read_debugging_info (bfd *abfd, asymbol **syms, long symcount, bfd_boolean no_messages)
 {
 {
-  PTR dhandle;
-  boolean found;
+  void *dhandle;
+  bfd_boolean found;
 
   dhandle = debug_init ();
   if (dhandle == NULL)
     return NULL;
 
 
   dhandle = debug_init ();
   if (dhandle == NULL)
     return NULL;
 
-  /* All we know about right now is stabs.  */
-
   if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
                                           &found))
     return NULL;
   if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
                                           &found))
     return NULL;
@@ -67,16 +63,22 @@ read_debugging_info (abfd, syms, symcount)
        return NULL;
     }
 
        return NULL;
     }
 
-  if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
+  /* Try reading the COFF symbols if we didn't find any stabs in COFF
+     sections.  */
+  if (! found
+      && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+      && symcount > 0)
     {
     {
-      if (! read_ieee_debugging_info (abfd, dhandle, &found))
+      if (! parse_coff (abfd, syms, symcount, dhandle))
        return NULL;
        return NULL;
+      found = TRUE;
     }
 
   if (! found)
     {
     }
 
   if (! found)
     {
-      fprintf (stderr, "%s: no recognized debugging information\n",
-              bfd_get_filename (abfd));
+      if (! no_messages)
+       non_fatal (_("%s: no recognized debugging information"),
+                  bfd_get_filename (abfd));
       return NULL;
     }
 
       return NULL;
     }
 
@@ -85,23 +87,25 @@ read_debugging_info (abfd, syms, symcount)
 
 /* Read stabs in sections debugging information from a BFD.  */
 
 
 /* Read stabs in sections debugging information from a BFD.  */
 
-static boolean
-read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
-     bfd *abfd;
-     asymbol **syms;
-     long symcount;
-     PTR dhandle;
-     boolean *pfound;
+static bfd_boolean
+read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
+                                  void *dhandle, bfd_boolean *pfound)
 {
   static struct
     {
       const char *secname;
       const char *strsecname;
 {
   static struct
     {
       const char *secname;
       const char *strsecname;
-    } names[] = { { ".stab", ".stabstr" } };
+    }
+  names[] =
+    {
+      { ".stab", ".stabstr" },
+      { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" },
+      { "$GDB_SYMBOLS$", "$GDB_STRINGS$" }
+    };
   unsigned int i;
   unsigned int i;
-  PTR shandle;
+  void *shandle;
 
 
-  *pfound = false;
+  *pfound = FALSE;
   shandle = NULL;
 
   for (i = 0; i < sizeof names / sizeof names[0]; i++)
   shandle = NULL;
 
   for (i = 0; i < sizeof names / sizeof names[0]; i++)
@@ -117,42 +121,53 @@ read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
          bfd_byte *stab;
          bfd_size_type stroff, next_stroff;
 
          bfd_byte *stab;
          bfd_size_type stroff, next_stroff;
 
-         stabsize = bfd_section_size (abfd, sec);
+         stabsize = bfd_section_size (sec);
          stabs = (bfd_byte *) xmalloc (stabsize);
          if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
            {
              fprintf (stderr, "%s: %s: %s\n",
                       bfd_get_filename (abfd), names[i].secname,
                       bfd_errmsg (bfd_get_error ()));
          stabs = (bfd_byte *) xmalloc (stabsize);
          if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
            {
              fprintf (stderr, "%s: %s: %s\n",
                       bfd_get_filename (abfd), names[i].secname,
                       bfd_errmsg (bfd_get_error ()));
-             return false;
+             free (shandle);
+             free (stabs);
+             return FALSE;
            }
 
            }
 
-         strsize = bfd_section_size (abfd, strsec);
-         strings = (bfd_byte *) xmalloc (strsize);
+         strsize = bfd_section_size (strsec);
+         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 ()));
-             return false;
+             free (shandle);
+             free (strings);
+             free (stabs);
+             return FALSE;
            }
            }
-
+         /* Zero terminate the strings table, just in case.  */
+         strings [strsize] = 0;
          if (shandle == NULL)
            {
          if (shandle == NULL)
            {
-             shandle = start_stab (dhandle, abfd, true, syms, symcount);
+             shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
              if (shandle == NULL)
              if (shandle == NULL)
-               return false;
+               {
+                 free (strings);
+                 free (stabs);
+                 return FALSE;
+               }
            }
 
            }
 
-         *pfound = true;
+         *pfound = TRUE;
 
          stroff = 0;
          next_stroff = 0;
 
          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)
            {
            {
-             bfd_size_type strx;
+             unsigned int strx;
              int type;
              int type;
-             int other;
+             int other ATTRIBUTE_UNUSED;
              int desc;
              bfd_vma value;
 
              int desc;
              bfd_vma value;
 
@@ -167,28 +182,56 @@ read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
              if (type == 0)
                {
                  /* Special type 0 stabs indicate the offset to the
              if (type == 0)
                {
                  /* Special type 0 stabs indicate the offset to the
-                     next string table.  */
+                    next string table.  */
                  stroff = next_stroff;
                  next_stroff += value;
                }
              else
                {
                  stroff = next_stroff;
                  next_stroff += value;
                }
              else
                {
+                 size_t len;
                  char *f, *s;
 
                  char *f, *s;
 
-                 f = NULL;
+                 if (stroff + strx >= strsize)
+                   {
+                     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;
                  s = (char *) strings + stroff + strx;
-                 while (s[strlen (s) - 1] == '\\'
+                 f = NULL;
+
+                 /* 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)
                    {
                         && stab + 12 < stabs + stabsize)
                    {
+                     char *p;
+
                      stab += 12;
                      stab += 12;
-                     s[strlen (s) - 1] = '\0';
-                     s = concat (s,
-                                 ((char *) strings
-                                  + stroff
-                                  + bfd_get_32 (abfd, stab)),
+                     p = s + len - 1;
+                     *p = '\0';
+                     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);
                                  (const char *) NULL);
-                     if (f != NULL)
-                       free (f);
+
+                     /* We have to restore the backslash, because, if
+                        the linker is hashing stabs strings, we may
+                        see the same string more than once.  */
+                     *p = '\\';
+
+                     free (f);
                      f = s;
                    }
 
                      f = s;
                    }
 
@@ -198,12 +241,16 @@ read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
                    {
                      stab_context ();
                      free_saved_stabs ();
                    {
                      stab_context ();
                      free_saved_stabs ();
-                     return false;
+                     free (f);
+                     free (shandle);
+                     free (stabs);
+                     free (strings);
+                     return FALSE;
                    }
 
                  /* Don't free f, since I think the stabs code
                    }
 
                  /* Don't free f, since I think the stabs code
-                     expects strings to hang around.  This should be
-                     straightened out.  FIXME.  */
+                    expects strings to hang around.  This should be
+                    straightened out.  FIXME.  */
                }
            }
 
                }
            }
 
@@ -211,31 +258,27 @@ read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
          free (stabs);
 
          /* Don't free strings, since I think the stabs code expects
          free (stabs);
 
          /* Don't free strings, since I think the stabs code expects
-             the strings to hang around.  This should be straightened
-             out.  FIXME.  */
+            the strings to hang around.  This should be straightened
+            out.  FIXME.  */
        }
     }
 
   if (shandle != NULL)
     {
       if (! finish_stab (dhandle, shandle))
        }
     }
 
   if (shandle != NULL)
     {
       if (! finish_stab (dhandle, shandle))
-       return false;
+       return FALSE;
     }
 
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Read stabs in the symbol table.  */
 
 }
 
 /* Read stabs in the symbol table.  */
 
-static boolean
-read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
-     bfd *abfd;
-     asymbol **syms;
-     long symcount;
-     PTR dhandle;
-     boolean *pfound;
+static bfd_boolean
+read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
+                                 void *dhandle, bfd_boolean *pfound)
 {
 {
-  PTR shandle;
+  void *shandle;
   asymbol **ps, **symend;
 
   shandle = NULL;
   asymbol **ps, **symend;
 
   shandle = NULL;
@@ -253,15 +296,20 @@ read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
 
          if (shandle == NULL)
            {
 
          if (shandle == NULL)
            {
-             shandle = start_stab (dhandle, abfd, false, syms, symcount);
+             shandle = start_stab (dhandle, abfd, FALSE, syms, symcount);
              if (shandle == NULL)
              if (shandle == NULL)
-               return false;
+               return FALSE;
            }
 
            }
 
-         *pfound = true;
+         *pfound = TRUE;
 
          s = i.name;
 
          s = i.name;
-         while (s[strlen (s) - 1] == '\\'
+         if (s == NULL || strlen (s) < 1)
+           return FALSE;
+         f = NULL;
+
+         while (strlen (s) > 0
+                && s[strlen (s) - 1] == '\\'
                 && ps + 1 < symend)
            {
              char *sc, *n;
                 && ps + 1 < symend)
            {
              char *sc, *n;
@@ -271,8 +319,7 @@ read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
              sc[strlen (sc) - 1] = '\0';
              n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
              free (sc);
              sc[strlen (sc) - 1] = '\0';
              n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
              free (sc);
-             if (f != NULL)
-               free (f);
+             free (f);
              f = n;
              s = n;
            }
              f = n;
              s = n;
            }
@@ -284,58 +331,24 @@ read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
            {
              stab_context ();
              free_saved_stabs ();
            {
              stab_context ();
              free_saved_stabs ();
-             return false;
+             return FALSE;
            }
 
            }
 
-         free_saved_stabs ();
-
          /* Don't free f, since I think the stabs code expects
             strings to hang around.  This should be straightened out.
             FIXME.  */
        }
     }
 
          /* Don't free f, since I think the stabs code expects
             strings to hang around.  This should be straightened out.
             FIXME.  */
        }
     }
 
+  free_saved_stabs ();
+
   if (shandle != NULL)
     {
       if (! finish_stab (dhandle, shandle))
   if (shandle != NULL)
     {
       if (! finish_stab (dhandle, shandle))
-       return false;
+       return FALSE;
     }
 
     }
 
-  return true;
-}
-
-/* Read IEEE debugging information.  */
-
-static boolean
-read_ieee_debugging_info (abfd, dhandle, pfound)
-     bfd *abfd;
-     PTR dhandle;
-     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;
+  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.  */
@@ -356,14 +369,9 @@ static int saved_stabs_index;
 /* Save a stabs string.  */
 
 static void
 /* Save a stabs string.  */
 
 static void
-save_stab (type, desc, value, string)
-     int type;
-     int desc;
-     bfd_vma value;
-     const char *string;
+save_stab (int type, int desc, bfd_vma value, const char *string)
 {
 {
-  if (saved_stabs[saved_stabs_index].string != NULL)
-    free (saved_stabs[saved_stabs_index].string);
+  free (saved_stabs[saved_stabs_index].string);
   saved_stabs[saved_stabs_index].type = type;
   saved_stabs[saved_stabs_index].desc = desc;
   saved_stabs[saved_stabs_index].value = value;
   saved_stabs[saved_stabs_index].type = type;
   saved_stabs[saved_stabs_index].desc = desc;
   saved_stabs[saved_stabs_index].value = value;
@@ -374,11 +382,11 @@ save_stab (type, desc, value, string)
 /* Provide context for an error.  */
 
 static void
 /* Provide context for an error.  */
 
 static void
-stab_context ()
+stab_context (void)
 {
   int i;
 
 {
   int i;
 
-  fprintf (stderr, "Last stabs entries before error:\n");
+  fprintf (stderr, _("Last stabs entries before error:\n"));
   fprintf (stderr, "n_type n_desc n_value  string\n");
 
   i = saved_stabs_index;
   fprintf (stderr, "n_type n_desc n_value  string\n");
 
   i = saved_stabs_index;
@@ -412,12 +420,15 @@ stab_context ()
 /* Free the saved stab strings.  */
 
 static void
 /* Free the saved stab strings.  */
 
 static void
-free_saved_stabs ()
+free_saved_stabs (void)
 {
   int i;
 
   for (i = 0; i < SAVE_STABS_COUNT; i++)
 {
   int i;
 
   for (i = 0; i < SAVE_STABS_COUNT; i++)
-    if (saved_stabs[i].string != NULL)
+    {
       free (saved_stabs[i].string);
       free (saved_stabs[i].string);
+      saved_stabs[i].string = NULL;
+    }
+
   saved_stabs_index = 0;
 }
   saved_stabs_index = 0;
 }
This page took 0.03108 seconds and 4 git commands to generate.