gas: fix bumping to architectures >v9 in sparc64-* targets.
[deliverable/binutils-gdb.git] / binutils / stabs.c
index ea0a61e411890378de2fa39f115846dd7bc95956..2a2674d2a7f488029c4b63b27db7f9239c8b8777 100644 (file)
@@ -1,6 +1,5 @@
 /* stabs.c -- Parse stabs debugging information
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1995-2014 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
@@ -677,7 +676,7 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
 
 static bfd_boolean
 parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
-                  int desc, bfd_vma value, const char *string)
+                  int desc ATTRIBUTE_UNUSED, bfd_vma value, const char *string)
 {
   const char *p;
   char *name;
@@ -685,7 +684,6 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
   debug_type dtype;
   bfd_boolean synonym;
   bfd_boolean self_crossref;
-  unsigned int lineno;
   debug_type *slot;
 
   p = strchr (string, ':');
@@ -703,14 +701,6 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
        }
     }
 
-  /* GCC 2.x puts the line number in desc.  SunOS apparently puts in
-     the number of bytes occupied by a type or object, which we
-     ignore.  */
-  if (info->gcc_compiled >= 2)
-    lineno = desc;
-  else
-    lineno = 0;
-
   /* FIXME: Sometimes the special C++ names start with '.'.  */
   name = NULL;
   if (string[0] == '$')
@@ -1105,6 +1095,26 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
        return FALSE;
       break;
 
+    case 'Y':
+      /* SUNPro C++ Namespace =Yn0.  */
+      /* Skip the namespace mapping, as it is not used now.  */
+      if (*(++p) == 'n' && *(++p) == '0')
+       {
+         /* =Yn0name; */
+         while (*p != ';')
+           ++p;
+         ++p;
+         return TRUE;
+       }
+      /* TODO SUNPro C++ support:
+         Support default arguments after F,P parameters
+         Ya = Anonymous unions
+         YM,YD = Pointers to class members
+         YT,YI = Templates
+         YR = Run-time type information (RTTI)  */
+
+      /* Fall through.  */
+
     default:
       bad_stab (string);
       return FALSE;
@@ -1122,7 +1132,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
    store the slot used if the type is being defined.  */
 
 static debug_type
-parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename, const char **pp, debug_type **slotp)
+parse_stab_type (void *dhandle, struct stab_handle *info, const char *type_name, const char **pp, debug_type **slotp)
 {
   const char *orig;
   int typenums[2];
@@ -1286,9 +1296,9 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
               fleep:T20=xsfleep:
           which define structures in terms of themselves.  We need to
           tell the caller to avoid building a circular structure.  */
-       if (typename != NULL
-           && strncmp (typename, *pp, p - *pp) == 0
-           && typename[p - *pp] == '\0')
+       if (type_name != NULL
+           && strncmp (type_name, *pp, p - *pp) == 0
+           && type_name[p - *pp] == '\0')
          info->self_crossref = TRUE;
 
        dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
@@ -1519,7 +1529,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
 
     case 'r':
       /* Range type.  */
-      dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
+      dtype = parse_stab_range_type (dhandle, info, type_name, pp, typenums);
       break;
 
     case 'b':
@@ -1541,7 +1551,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
     case 's':
     case 'u':
       /* Struct or union type.  */
-      dtype = parse_stab_struct_type (dhandle, info, typename, pp,
+      dtype = parse_stab_struct_type (dhandle, info, type_name, pp,
                                      descriptor == 's', typenums);
       break;
 
@@ -1631,7 +1641,7 @@ parse_stab_type_number (const char **pp, int *typenums)
 /* Parse a range type.  */
 
 static debug_type
-parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *typename, const char **pp, const int *typenums)
+parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type_name, const char **pp, const int *typenums)
 {
   const char *orig;
   int rangenums[2];
@@ -1730,11 +1740,11 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
                 long long int:t6=r1;0;-1;
                 long long unsigned int:t7=r1;0;-1;
             We hack here to handle this reasonably.  */
-         if (typename != NULL)
+         if (type_name != NULL)
            {
-             if (strcmp (typename, "long long int") == 0)
+             if (strcmp (type_name, "long long int") == 0)
                return debug_make_int_type (dhandle, 8, FALSE);
-             else if (strcmp (typename, "long long unsigned int") == 0)
+             else if (strcmp (type_name, "long long unsigned int") == 0)
                return debug_make_int_type (dhandle, 8, TRUE);
            }
          /* FIXME: The size here really depends upon the target.  */
@@ -1837,11 +1847,13 @@ parse_stab_sun_builtin_type (void *dhandle, const char **pp)
     }
   ++*pp;
 
-  /* For some odd reason, all forms of char put a c here.  This is strange
-     because no other type has this honor.  We can safely ignore this because
-     we actually determine 'char'acterness by the number of bits specified in
-     the descriptor.  */
-  if (**pp == 'c')
+  /* OpenSolaris source code indicates that one of "cbv" characters
+     can come next and specify the intrinsic 'iformat' encoding.
+     'c' is character encoding, 'b' is boolean encoding, and 'v' is
+     varargs encoding.  This field can be safely ignored because
+     the type of the field is determined from the bitwidth extracted
+     below.  */
+  if (**pp == 'c' || **pp == 'b' || **pp == 'v')
     ++*pp;
 
   /* The first number appears to be the number of bytes occupied
@@ -1967,6 +1979,9 @@ parse_stab_enum_type (void *dhandle, const char **pp)
       if (**pp != ',')
        {
          bad_stab (orig);
+         free (name);
+         free (names);
+         free (values);
          return DEBUG_TYPE_NULL;
        }
       ++*pp;
@@ -2006,17 +2021,14 @@ parse_stab_struct_type (void *dhandle, struct stab_handle *info,
                        const char *tagname, const char **pp,
                        bfd_boolean structp, const int *typenums)
 {
-  const char *orig;
   bfd_vma size;
   debug_baseclass *baseclasses;
-  debug_field *fields;
+  debug_field *fields = NULL;
   bfd_boolean statics;
   debug_method *methods;
   debug_type vptrbase;
   bfd_boolean ownvptr;
 
-  orig = *pp;
-
   /* Get the size.  */
   size = parse_number (pp, (bfd_boolean *) NULL);
 
@@ -2026,7 +2038,11 @@ parse_stab_struct_type (void *dhandle, struct stab_handle *info,
       || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
       || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
                                   &ownvptr))
-    return DEBUG_TYPE_NULL;
+    {
+      if (fields != NULL)
+       free (fields);
+      return DEBUG_TYPE_NULL;
+    }
 
   if (! statics
       && baseclasses == NULL
@@ -2095,7 +2111,7 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
 
   for (i = 0; i < c; i++)
     {
-      bfd_boolean virtual;
+      bfd_boolean is_virtual;
       enum debug_visibility visibility;
       bfd_vma bitpos;
       debug_type type;
@@ -2103,14 +2119,14 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
       switch (**pp)
        {
        case '0':
-         virtual = FALSE;
+         is_virtual = FALSE;
          break;
        case '1':
-         virtual = TRUE;
+         is_virtual = TRUE;
          break;
        default:
          warn_stab (orig, _("unknown virtual character for baseclass"));
-         virtual = FALSE;
+         is_virtual = FALSE;
          break;
        }
       ++*pp;
@@ -2149,7 +2165,7 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
       if (type == DEBUG_TYPE_NULL)
        return FALSE;
 
-      classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
+      classes[i] = debug_make_baseclass (dhandle, type, bitpos, is_virtual,
                                         visibility);
       if (classes[i] == DEBUG_BASECLASS_NULL)
        return FALSE;
@@ -2230,7 +2246,10 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
        {
          ++*pp;
          if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
-           return FALSE;
+           {
+             free (fields);
+             return FALSE;
+           }
          ++c;
          continue;
        }
@@ -2244,6 +2263,7 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
       if (p == NULL)
        {
          bad_stab (orig);
+         free (fields);
          return FALSE;
        }
 
@@ -2274,7 +2294,7 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
   int cpp_abbrev;
   debug_type context;
   const char *name;
-  const char *typename;
+  const char *type_name;
   debug_type type;
   bfd_vma bitpos;
 
@@ -2310,13 +2330,13 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
       break;
     case 'b':
       /* $vb -- a virtual bsomethingorother */
-      typename = debug_get_type_name (dhandle, context);
-      if (typename == NULL)
+      type_name = debug_get_type_name (dhandle, context);
+      if (type_name == NULL)
        {
          warn_stab (orig, _("unnamed $vb type"));
-         typename = "FOO";
+         type_name = "FOO";
        }
-      name = concat ("_vb$", typename, (const char *) NULL);
+      name = concat ("_vb$", type_name, (const char *) NULL);
       break;
     default:
       warn_stab (orig, _("unrecognized C++ abbreviation"));
@@ -2405,7 +2425,10 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                          (debug_type **) NULL);
   if (type == DEBUG_TYPE_NULL)
-    return FALSE;
+    {
+      free (name);
+      return FALSE;
+    }
 
   if (**pp == ':')
     {
@@ -2417,6 +2440,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
       if (p == NULL)
        {
          bad_stab (orig);
+         free (name);
          return FALSE;
        }
 
@@ -2434,6 +2458,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   if (**pp != ',')
     {
       bad_stab (orig);
+      free (name);
       return FALSE;
     }
   ++*pp;
@@ -2442,6 +2467,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   if (**pp != ',')
     {
       bad_stab (orig);
+      free (name);
       return FALSE;
     }
   ++*pp;
@@ -2450,6 +2476,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   if (**pp != ';')
     {
       bad_stab (orig);
+      free (name);
       return FALSE;
     }
   ++*pp;
@@ -2501,6 +2528,9 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
   debug_method *methods;
   unsigned int c;
   unsigned int alloc;
+  char *name = NULL;
+  debug_method_variant *variants = NULL;
+  char *argtypes = NULL;
 
   *retp = NULL;
 
@@ -2513,8 +2543,6 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
   while (**pp != ';')
     {
       const char *p;
-      char *name;
-      debug_method_variant *variants;
       unsigned int cvars;
       unsigned int allocvars;
       debug_type look_ahead_type;
@@ -2543,7 +2571,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
          if (*p != '.')
            {
              bad_stab (orig);
-             return FALSE;
+             goto fail;
            }
          name = savestring (*pp, p - *pp);
          *pp = p + 1;
@@ -2560,7 +2588,6 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
        {
          debug_type type;
          bfd_boolean stub;
-         char *argtypes;
          enum debug_visibility visibility;
          bfd_boolean constp, volatilep, staticp;
          bfd_vma voffset;
@@ -2579,11 +2606,12 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
              type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                                      (debug_type **) NULL);
              if (type == DEBUG_TYPE_NULL)
-               return FALSE;
+               goto fail;
+
              if (**pp != ':')
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
            }
 
@@ -2592,7 +2620,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
          if (p == NULL)
            {
              bad_stab (orig);
-             return FALSE;
+             goto fail;
            }
 
          stub = FALSE;
@@ -2663,7 +2691,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
              if (**pp != ';')
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
              ++*pp;
              voffset &= 0x7fffffff;
@@ -2694,7 +2722,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                      if (**pp != ';')
                        {
                          bad_stab (orig);
-                         return FALSE;
+                         goto fail;
                        }
                      ++*pp;
                    }
@@ -2729,26 +2757,25 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
              argtypes string is the mangled form of the argument
              types, and the full type and the physical name must be
              extracted from them.  */
-         if (! stub)
-           physname = argtypes;
-         else
+         physname = argtypes;
+         if (stub)
            {
              debug_type class_type, return_type;
 
              class_type = stab_find_type (dhandle, info, typenums);
              if (class_type == DEBUG_TYPE_NULL)
-               return FALSE;
+               goto fail;
              return_type = debug_get_return_type (dhandle, type);
              if (return_type == DEBUG_TYPE_NULL)
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
              type = parse_stab_argtypes (dhandle, info, class_type, name,
                                          tagname, return_type, argtypes,
                                          constp, volatilep, &physname);
              if (type == DEBUG_TYPE_NULL)
-               return FALSE;
+               goto fail;
            }
 
          if (cvars + 1 >= allocvars)
@@ -2772,7 +2799,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                                                                constp,
                                                                volatilep);
          if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
-           return FALSE;
+           goto fail;
 
          ++cvars;
        }
@@ -2801,6 +2828,15 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
   *retp = methods;
 
   return TRUE;
+
+ fail:
+  if (name != NULL)
+    free (name);
+  if (variants != NULL)
+    free (variants);
+  if (argtypes != NULL)
+    free (argtypes);
+  return FALSE;
 }
 
 /* Parse a string representing argument types for a method.  Stabs
@@ -2841,9 +2877,7 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
                   || CONST_STRNEQ (argtypes, "__dt"));
   is_v3 = argtypes[0] == '_' && argtypes[1] == 'Z';
 
-  if (is_destructor || is_full_physname_constructor || is_v3)
-    *pphysname = argtypes;
-  else
+  if (!(is_destructor || is_full_physname_constructor || is_v3))
     {
       unsigned int len;
       const char *const_prefix;
@@ -3255,26 +3289,26 @@ static debug_type *
 stab_find_slot (struct stab_handle *info, const int *typenums)
 {
   int filenum;
-  int index;
+  int tindex;
   struct stab_types **ps;
 
   filenum = typenums[0];
-  index = typenums[1];
+  tindex = typenums[1];
 
   if (filenum < 0 || (unsigned int) filenum >= info->files)
     {
       fprintf (stderr, _("Type file number %d out of range\n"), filenum);
       return NULL;
     }
-  if (index < 0)
+  if (tindex < 0)
     {
-      fprintf (stderr, _("Type index number %d out of range\n"), index);
+      fprintf (stderr, _("Type index number %d out of range\n"), tindex);
       return NULL;
     }
 
   ps = info->file_types + filenum;
 
-  while (index >= STAB_TYPES_SLOTS)
+  while (tindex >= STAB_TYPES_SLOTS)
     {
       if (*ps == NULL)
        {
@@ -3282,7 +3316,7 @@ stab_find_slot (struct stab_handle *info, const int *typenums)
          memset (*ps, 0, sizeof **ps);
        }
       ps = &(*ps)->next;
-      index -= STAB_TYPES_SLOTS;
+      tindex -= STAB_TYPES_SLOTS;
     }
   if (*ps == NULL)
     {
@@ -3290,7 +3324,7 @@ stab_find_slot (struct stab_handle *info, const int *typenums)
       memset (*ps, 0, sizeof **ps);
     }
 
-  return (*ps)->types + index;
+  return (*ps)->types + tindex;
 }
 
 /* Find a type given a type number.  If the type has not been
@@ -4098,7 +4132,10 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
 
                      ft = debug_get_field_type (minfo->dhandle, *fields);
                      if (ft == NULL)
-                       return FALSE;
+                       {
+                         free (name);
+                         return FALSE;
+                       }
                      dn = debug_get_type_name (minfo->dhandle, ft);
                      if (dn != NULL && strcmp (dn, name) == 0)
                        {
@@ -4645,7 +4682,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
     case 'M':
     case 'O':
       {
-       bfd_boolean memberp, constp, volatilep;
+       bfd_boolean memberp;
        debug_type class_type = DEBUG_TYPE_NULL;
        debug_type *args;
        bfd_boolean varargs;
@@ -4653,8 +4690,6 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
        const char *name;
 
        memberp = **pp == 'M';
-       constp = FALSE;
-       volatilep = FALSE;
        args = NULL;
        varargs = FALSE;
 
@@ -4698,12 +4733,10 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
          {
            if (**pp == 'C')
              {
-               constp = TRUE;
                ++*pp;
              }
            else if (**pp == 'V')
              {
-               volatilep = TRUE;
                ++*pp;
              }
            if (**pp != 'F')
@@ -4764,9 +4797,6 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
 
     case 'Q':
       {
-       const char *hold;
-
-       hold = *pp;
        if (! stab_demangle_qualified (minfo, pp, ptype))
          return FALSE;
       }
@@ -5135,6 +5165,11 @@ stab_demangle_v3_arglist (void *dhandle, struct stab_handle *info,
          return NULL;
        }
 
+      /* PR 13925: Cope if the demangler returns an empty
+        context for a function with no arguments.  */
+      if (dc->u.s_binary.left == NULL)
+       break;
       arg = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
                                  NULL, &varargs);
       if (arg == NULL)
This page took 0.039521 seconds and 4 git commands to generate.