* gdbserver/remote-util.c (remote_open): Print remote-side's
[deliverable/binutils-gdb.git] / binutils / stabs.c
index c388c5f74e7a66927ea78c071698a0c6e48940b1..bbc06320e747d327a3437d01357ba41bb68ced5d 100644 (file)
@@ -1,5 +1,6 @@
 /* stabs.c -- Parse stabs debugging information
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
    trying to identify the correct address for anything.  */
 
 #include <stdio.h>
-#include <ctype.h>
 
 #include "bfd.h"
 #include "bucomm.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 #include "demangle.h"
 #include "debug.h"
 #include "budbg.h"
+#include "filenames.h"
 
 /* Meaningless definition needs by aout64.h.  FIXME.  */
 #define BYTES_IN_WORD 4
 #include "aout/aout64.h"
 #include "aout/stab_gnu.h"
 
-#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
-#endif
-
 /* The number of predefined XCOFF types.  */
 
 #define XCOFF_TYPE_COUNT 34
@@ -309,11 +307,11 @@ parse_number (pp, poverflow)
          int d;
 
          d = *p++;
-         if (isdigit ((unsigned char) d))
+         if (ISDIGIT (d))
            d -= '0';
-         else if (isupper ((unsigned char) d))
+         else if (ISUPPER (d))
            d -= 'A';
-         else if (islower ((unsigned char) d))
+         else if (ISLOWER (d))
            d -= 'a';
          else
            break;
@@ -371,7 +369,7 @@ warn_stab (p, err)
 /*ARGSUSED*/
 PTR
 start_stab (dhandle, abfd, sections, syms, symcount)
-     PTR dhandle;
+     PTR dhandle ATTRIBUTE_UNUSED;
      bfd *abfd;
      boolean sections;
      asymbol **syms;
@@ -564,12 +562,7 @@ parse_stab (dhandle, handle, type, desc, value, string)
 
          f = info->so_string;
 
-         if (   (string[0] == '/')
-             || (string[0] == DIR_SEPARATOR)
-             || (   (DIR_SEPARATOR == '\\')
-                 && (string[1] == ':')
-                 && (   (string[2] == DIR_SEPARATOR)
-                     || (string[2] == '/'))))
+          if (IS_ABSOLUTE_PATH (string))
            info->so_string = xstrdup (string);
          else
            info->so_string = concat (info->so_string, string,
@@ -702,6 +695,7 @@ parse_stab (dhandle, handle, type, desc, value, string)
     case N_OBJ:
     case N_ENDM:
     case N_MAIN:
+    case N_WARNING:
       break;
     }
 
@@ -787,7 +781,7 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
     }
 
   ++p;
-  if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+  if (ISDIGIT (*p) || *p == '(' || *p == '-')
     type = 'l';
   else
     type = *p++;
@@ -1191,7 +1185,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
   /* Read type number if present.  The type number may be omitted.
      for instance in a two-dimensional array declared with type
      "ar1;1;10;ar1;1;10;4".  */
-  if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
+  if (! ISDIGIT (**pp) && **pp != '(' && **pp != '-')
     {
       /* 'typenums=' not present, type is anonymous.  Read and return
         the definition, but don't put it in the type vector.  */
@@ -1234,7 +1228,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
          const char *p = *pp + 1;
          const char *attr;
 
-         if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+         if (ISDIGIT (*p) || *p == '(' || *p == '-')
            {
              /* Member type.  */
              break;
@@ -1257,6 +1251,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
            {
            case 's':
              size = atoi (attr + 1);
+             size /= 8;  /* Size is in bits.  We store it in bytes.  */
              if (size <= 0)
                size = -1;
              break;
@@ -1312,14 +1307,21 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
            bad_stab (orig);
            return DEBUG_TYPE_NULL;
          }
-       while (q1 != NULL && p > q1 && p[1] == ':')
+       if (q1 != NULL && p > q1 && p[1] == ':')
          {
-           q2 = strchr (q1, '>');
-           if (q2 == NULL || q2 < p)
-             break;
-           p += 2;
-           p = strchr (p, ':');
-           if (p == NULL)
+           int nest = 0;
+
+           for (q2 = q1; *q2 != '\0'; ++q2)
+             {
+               if (*q2 == '<')
+                 ++nest;
+               else if (*q2 == '>')
+                 --nest;
+               else if (*q2 == ':' && nest == 0)
+                 break;
+             }
+           p = q2;
+           if (*p != ':')
              {
                bad_stab (orig);
                return DEBUG_TYPE_NULL;
@@ -1628,7 +1630,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
   if (size != -1)
     {
       if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
-       return false;
+       return DEBUG_TYPE_NULL;
     }
 
   return dtype;
@@ -1807,15 +1809,18 @@ parse_stab_range_type (dhandle, info, typename, pp, typenums)
            return debug_make_int_type (dhandle, 1, true);
          else if (n3 == 0xffff)
            return debug_make_int_type (dhandle, 2, true);
-         /* -1 is used for the upper bound of (4 byte) "unsigned int"
-            and "unsigned long", and we already checked for that, so
-            don't need to test for it here.  */
+         else if (n3 == (bfd_signed_vma) 0xffffffff)
+           return debug_make_int_type (dhandle, 4, true);
+#ifdef BFD64
+         else if (n3 == ((((bfd_signed_vma) 0xffffffff) << 32) | 0xffffffff))
+           return debug_make_int_type (dhandle, 8, true);
+#endif
        }
       else if (n3 == 0
               && n2 < 0
               && (self_subrange || n2 == -8))
        return debug_make_int_type (dhandle, - n2, true);
-      else if (n2 == - n3 - 1)
+      else if (n2 == - n3 - 1 || n2 == n3 + 1)
        {
          if (n3 == 0x7f)
            return debug_make_int_type (dhandle, 1, false);
@@ -1823,6 +1828,10 @@ parse_stab_range_type (dhandle, info, typename, pp, typenums)
            return debug_make_int_type (dhandle, 2, false);
          else if (n3 == 0x7fffffff)
            return debug_make_int_type (dhandle, 4, false);
+#ifdef BFD64
+         else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff))
+           return debug_make_int_type (dhandle, 8, false);
+#endif
        }
     }
 
@@ -2904,7 +2913,7 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
   /* Constructors are sometimes handled specially.  */
   is_full_physname_constructor = ((argtypes[0] == '_'
                                   && argtypes[1] == '_'
-                                  && (isdigit ((unsigned char) argtypes[2])
+                                  && (ISDIGIT (argtypes[2])
                                       || argtypes[2] == 'Q'
                                       || argtypes[2] == 't'))
                                  || strncmp (argtypes, "__ct", 4) == 0);
@@ -3113,7 +3122,7 @@ parse_stab_array_type (dhandle, info, pp, stringp)
   /* If the index type is type 0, we take it as int.  */
   p = *pp;
   if (! parse_stab_type_number (&p, typenums))
-    return false;
+    return DEBUG_TYPE_NULL;
   if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
     {
       index_type = debug_find_named_type (dhandle, "int");
@@ -3121,7 +3130,7 @@ parse_stab_array_type (dhandle, info, pp, stringp)
        {
          index_type = debug_make_int_type (dhandle, 4, false);
          if (index_type == DEBUG_TYPE_NULL)
-           return false;
+           return DEBUG_TYPE_NULL;
        }
       *pp = p;
     }
@@ -3140,7 +3149,7 @@ parse_stab_array_type (dhandle, info, pp, stringp)
 
   adjustable = false;
 
-  if (! isdigit ((unsigned char) **pp) && **pp != '-')
+  if (! ISDIGIT (**pp) && **pp != '-')
     {
       ++*pp;
       adjustable = true;
@@ -3150,11 +3159,11 @@ parse_stab_array_type (dhandle, info, pp, stringp)
   if (**pp != ';')
     {
       bad_stab (orig);
-      return false;
+      return DEBUG_TYPE_NULL;
     }
   ++*pp;
 
-  if (! isdigit ((unsigned char) **pp) && **pp != '-')
+  if (! ISDIGIT (**pp) && **pp != '-')
     {
       ++*pp;
       adjustable = true;
@@ -3164,14 +3173,14 @@ parse_stab_array_type (dhandle, info, pp, stringp)
   if (**pp != ';')
     {
       bad_stab (orig);
-      return false;
+      return DEBUG_TYPE_NULL;
     }
   ++*pp;
 
   element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                                  (debug_type **) NULL);
   if (element_type == DEBUG_TYPE_NULL)
-    return false;
+    return DEBUG_TYPE_NULL;
 
   if (adjustable)
     {
@@ -3421,7 +3430,7 @@ stab_find_type (dhandle, info, typenums)
 
 static boolean
 stab_record_type (dhandle, info, typenums, type)
-     PTR dhandle;
+     PTR dhandle ATTRIBUTE_UNUSED;
      struct stab_handle *info;
      const int *typenums;
      debug_type type;
@@ -3729,7 +3738,7 @@ static boolean stab_demangle_signature
 static boolean stab_demangle_qualified
   PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
 static boolean stab_demangle_template
-  PARAMS ((struct stab_demangle_info *, const char **));
+  PARAMS ((struct stab_demangle_info *, const char **, char **));
 static boolean stab_demangle_class
   PARAMS ((struct stab_demangle_info *, const char **, const char **));
 static boolean stab_demangle_args
@@ -3763,7 +3772,7 @@ stab_demangle_count (pp)
   unsigned int count;
 
   count = 0;
-  while (isdigit ((unsigned char) **pp))
+  while (ISDIGIT (**pp))
     {
       count *= 10;
       count += **pp - '0';
@@ -3780,12 +3789,12 @@ stab_demangle_get_count (pp, pi)
      const char **pp;
      unsigned int *pi;
 {
-  if (! isdigit ((unsigned char) **pp))
+  if (! ISDIGIT (**pp))
     return false;
 
   *pi = **pp - '0';
   ++*pp;
-  if (isdigit ((unsigned char) **pp))
+  if (ISDIGIT (**pp))
     {
       unsigned int count;
       const char *p;
@@ -3798,7 +3807,7 @@ stab_demangle_get_count (pp, pi)
          count += *p - '0';
          ++p;
        }
-      while (isdigit ((unsigned char) *p));
+      while (ISDIGIT (*p));
       if (*p == '_')
        {
          *pp = p + 1;
@@ -3893,7 +3902,7 @@ stab_demangle_prefix (minfo, pp)
     scan += i - 2;
 
   if (scan == *pp
-      && (isdigit ((unsigned char) scan[2])
+      && (ISDIGIT (scan[2])
          || scan[2] == 'Q'
          || scan[2] == 't'))
     {
@@ -3902,7 +3911,7 @@ stab_demangle_prefix (minfo, pp)
       return true;
     }
   else if (scan == *pp
-          && ! isdigit ((unsigned char) scan[2])
+          && ! ISDIGIT (scan[2])
           && scan[2] != 't')
     {
       /* Look for the `__' that separates the prefix from the
@@ -4048,7 +4057,7 @@ stab_demangle_signature (minfo, pp)
          /* Template.  */
          if (hold == NULL)
            hold = *pp;
-         if (! stab_demangle_template (minfo, pp)
+         if (! stab_demangle_template (minfo, pp, (char **) NULL)
              || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
            return false;
          hold = NULL;
@@ -4117,13 +4126,13 @@ stab_demangle_qualified (minfo, pp, ptype)
         preceded by an underscore (to distinguish it from the <= 9
         case) and followed by an underscore.  */
       p = *pp + 2;
-      if (! isdigit ((unsigned char) *p) || *p == '0')
+      if (! ISDIGIT (*p) || *p == '0')
        {
          stab_bad_demangle (orig);
          return false;
        }
       qualifiers = atoi (p);
-      while (isdigit ((unsigned char) *p))
+      while (ISDIGIT (*p))
        ++p;
       if (*p != '_')
        {
@@ -4157,10 +4166,21 @@ stab_demangle_qualified (minfo, pp, ptype)
        ++*pp;
       if (**pp == 't')
        {
-         /* FIXME: I don't know how to handle the ptype != NULL case
-             here.  */
-         if (! stab_demangle_template (minfo, pp))
+         char *name;
+
+         if (! stab_demangle_template (minfo, pp,
+                                       ptype != NULL ? &name : NULL))
            return false;
+
+         if (ptype != NULL)
+           {
+             context = stab_find_tagged_type (minfo->dhandle, minfo->info,
+                                              name, strlen (name),
+                                              DEBUG_KIND_CLASS);
+             free (name);
+             if (context == DEBUG_TYPE_NULL)
+               return false;
+           }
        }
       else
        {
@@ -4256,12 +4276,14 @@ stab_demangle_qualified (minfo, pp, ptype)
   return true;
 }
 
-/* Demangle a template.  */
+/* Demangle a template.  If PNAME is not NULL, this sets *PNAME to a
+   string representation of the template.  */
 
 static boolean
-stab_demangle_template (minfo, pp)
+stab_demangle_template (minfo, pp, pname)
      struct stab_demangle_info *minfo;
      const char **pp;
+     char **pname;
 {
   const char *orig;
   unsigned int r, i;
@@ -4375,7 +4397,7 @@ stab_demangle_template (minfo, pp)
            {
              if (**pp == 'm')
                ++*pp;
-             while (isdigit ((unsigned char) **pp))
+             while (ISDIGIT (**pp))
                ++*pp;
            }
          else if (charp)
@@ -4406,18 +4428,18 @@ stab_demangle_template (minfo, pp)
            {
              if (**pp == 'm')
                ++*pp;
-             while (isdigit ((unsigned char) **pp))
+             while (ISDIGIT (**pp))
                ++*pp;
              if (**pp == '.')
                {
                  ++*pp;
-                 while (isdigit ((unsigned char) **pp))
+                 while (ISDIGIT (**pp))
                    ++*pp;
                }
              if (**pp == 'e')
                {
                  ++*pp;
-                 while (isdigit ((unsigned char) **pp))
+                 while (ISDIGIT (**pp))
                    ++*pp;
                }
            }
@@ -4435,6 +4457,46 @@ stab_demangle_template (minfo, pp)
        }
     }
 
+  /* We can translate this to a string fairly easily by invoking the
+     regular demangling routine.  */
+  if (pname != NULL)
+    {
+      char *s1, *s2, *s3, *s4 = NULL;
+      char *from, *to;
+
+      s1 = savestring (orig, *pp - orig);
+
+      s2 = concat ("NoSuchStrinG__", s1, (const char *) NULL);
+
+      free (s1);
+
+      s3 = cplus_demangle (s2, DMGL_ANSI);
+
+      free (s2);
+
+      if (s3 != NULL)
+       s4 = strstr (s3, "::NoSuchStrinG");
+      if (s3 == NULL || s4 == NULL)
+       {
+         stab_bad_demangle (orig);
+         if (s3 != NULL)
+           free (s3);
+         return false;
+       }
+
+      /* Eliminating all spaces, except those between > characters,
+         makes it more likely that the demangled name will match the
+         name which g++ used as the structure name.  */
+      for (from = to = s3; from != s4; ++from)
+       if (*from != ' '
+           || (from[1] == '>' && from > s3 && from[-1] == '>'))
+         *to++ = *from;
+
+      *pname = savestring (s3, to - s3);
+
+      free (s3);
+    }
+
   return true;
 }
 
@@ -4442,7 +4504,7 @@ stab_demangle_template (minfo, pp)
 
 static boolean
 stab_demangle_class (minfo, pp, pstart)
-     struct stab_demangle_info *minfo;
+     struct stab_demangle_info *minfo ATTRIBUTE_UNUSED;
      const char **pp;
      const char **pstart;
 {
@@ -4630,7 +4692,7 @@ stab_demangle_type (minfo, pp, ptype)
        high = 0;
        while (**pp != '\0' && **pp != '_')
          {
-           if (! isdigit ((unsigned char) **pp))
+           if (! ISDIGIT (**pp))
              {
                stab_bad_demangle (orig);
                return false;
@@ -4721,6 +4783,7 @@ stab_demangle_type (minfo, pp, ptype)
     case 'O':
       {
        boolean memberp, constp, volatilep;
+       debug_type class_type = DEBUG_TYPE_NULL;
        debug_type *args;
        boolean varargs;
        unsigned int n;
@@ -4733,19 +4796,40 @@ stab_demangle_type (minfo, pp, ptype)
        varargs = false;
 
        ++*pp;
-       if (! isdigit ((unsigned char) **pp))
+       if (ISDIGIT (**pp))
          {
-           stab_bad_demangle (orig);
-           return false;
+           n = stab_demangle_count (pp);
+           if (strlen (*pp) < n)
+             {
+               stab_bad_demangle (orig);
+               return false;
+             }
+           name = *pp;
+           *pp += n;
+
+           if (ptype != NULL)
+             {
+               class_type = stab_find_tagged_type (minfo->dhandle,
+                                                   minfo->info,
+                                                   name, (int) n,
+                                                   DEBUG_KIND_CLASS);
+               if (class_type == DEBUG_TYPE_NULL)
+                 return false;
+             }
+         }
+       else if (**pp == 'Q')
+         {
+           if (! stab_demangle_qualified (minfo, pp,
+                                          (ptype == NULL
+                                           ? (debug_type *) NULL
+                                           : &class_type)))
+             return false;
          }
-       n = stab_demangle_count (pp);
-       if (strlen (*pp) < n)
+       else
          {
            stab_bad_demangle (orig);
            return false;
          }
-       name = *pp;
-       *pp += n;
 
        if (memberp)
          {
@@ -4787,14 +4871,6 @@ stab_demangle_type (minfo, pp, ptype)
 
        if (ptype != NULL)
          {
-           debug_type class_type;
-
-           class_type = stab_find_tagged_type (minfo->dhandle, minfo->info,
-                                               name, (int) n,
-                                               DEBUG_KIND_CLASS);
-           if (class_type == DEBUG_TYPE_NULL)
-             return false;
-
            if (! memberp)
              *ptype = debug_make_offset_type (minfo->dhandle, class_type,
                                               *ptype);
@@ -5030,7 +5106,7 @@ stab_demangle_fund_type (minfo, pp, ptype)
 
     case 'G':
       ++*pp;
-      if (! isdigit ((unsigned char) **pp))
+      if (! ISDIGIT (**pp))
        {
          stab_bad_demangle (orig);
          return false;
@@ -5049,6 +5125,7 @@ stab_demangle_fund_type (minfo, pp, ptype)
 
            name = savestring (hold, *pp - hold);
            *ptype = debug_find_named_type (minfo->dhandle, name);
+           free (name);
            if (*ptype == DEBUG_TYPE_NULL)
              {
                /* FIXME: It is probably incorrect to assume that
@@ -5056,29 +5133,30 @@ stab_demangle_fund_type (minfo, pp, ptype)
                *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
                                                hold, *pp - hold,
                                                DEBUG_KIND_ILLEGAL);
+               if (*ptype == DEBUG_TYPE_NULL)
+                 return false;
              }
-           free (name);
          }
       }
       break;
 
     case 't':
-      if (! stab_demangle_template (minfo, pp))
-       return false;
-      if (ptype != NULL)
-       {
-         debug_type t;
-
-         /* FIXME: I really don't know how a template should be
-             represented in the current type system.  Perhaps the
-             template should be demangled into a string, and the type
-             should be represented as a named type.  However, I don't
-             know what the base type of the named type should be.  */
-         t = debug_make_void_type (minfo->dhandle);
-         t = debug_make_pointer_type (minfo->dhandle, t);
-         t = debug_name_type (minfo->dhandle, "TEMPLATE", t);
-         *ptype = t;
-       }
+      {
+       char *name;
+
+       if (! stab_demangle_template (minfo, pp,
+                                     ptype != NULL ? &name : NULL))
+         return false;
+       if (ptype != NULL)
+         {
+           *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
+                                           name, strlen (name),
+                                           DEBUG_KIND_CLASS);
+           free (name);
+           if (*ptype == DEBUG_TYPE_NULL)
+             return false;
+         }
+      }
       break;
 
     default:
This page took 0.032407 seconds and 4 git commands to generate.