Skip ARM vcmp-noprefix-imm test on non-ELF targets
[binutils-gdb.git] / binutils / stabs.c
index f8fb48c678d6bc380e1604ac4aa48d0fdd139906..3861f83857cc999066a6fdd0e8ea90e1be55030d 100644 (file)
@@ -1,6 +1,5 @@
 /* stabs.c -- Parse stabs debugging information
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
@@ -233,6 +232,10 @@ parse_number (const char **pp, bfd_boolean *poverflow)
 
   orig = *pp;
 
+  /* Stop early if we are passed an empty string.  */
+  if (*orig == 0)
+    return (bfd_vma) 0;
+
   errno = 0;
   ul = strtoul (*pp, (char **) pp, 0);
   if (ul + 1 != 0 || errno == 0)
@@ -837,8 +840,6 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
 
     case 'G':
       {
-       char leading;
-       long c;
        asymbol **ps;
 
        /* A global symbol.  The value must be extracted from the
@@ -847,19 +848,27 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
                                 (debug_type **) NULL);
        if (dtype == DEBUG_TYPE_NULL)
          return FALSE;
-       leading = bfd_get_symbol_leading_char (info->abfd);
-       for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+       if (name != NULL)
          {
-           const char *n;
+           char leading;
+           long c;
 
-           n = bfd_asymbol_name (*ps);
-           if (leading != '\0' && *n == leading)
-             ++n;
-           if (*n == *name && strcmp (n, name) == 0)
-             break;
+           leading = bfd_get_symbol_leading_char (info->abfd);
+           for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+             {
+               const char *n;
+
+               n = bfd_asymbol_name (*ps);
+               if (leading != '\0' && *n == leading)
+                 ++n;
+               if (*n == *name && strcmp (n, name) == 0)
+                 break;
+             }
+
+           if (c > 0)
+             value = bfd_asymbol_value (*ps);
          }
-       if (c > 0)
-         value = bfd_asymbol_value (*ps);
+
        if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
                                    value))
          return FALSE;
@@ -1769,7 +1778,7 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
          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))
+         else if (n3 == (bfd_signed_vma) 0xffffffffffffffffLL)
            return debug_make_int_type (dhandle, 8, TRUE);
 #endif
        }
@@ -1970,9 +1979,17 @@ parse_stab_enum_type (void *dhandle, const char **pp)
       bfd_signed_vma val;
 
       p = *pp;
-      while (*p != ':')
+      while (*p != ':' && *p != 0)
        ++p;
 
+      if (*p == 0)
+       {
+         bad_stab (orig);
+         free (names);
+         free (values);
+         return DEBUG_TYPE_NULL;
+       }
+
       name = savestring (*pp, p - *pp);
 
       *pp = p + 1;
@@ -1980,6 +1997,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;
@@ -2021,7 +2041,7 @@ parse_stab_struct_type (void *dhandle, struct stab_handle *info,
 {
   bfd_vma size;
   debug_baseclass *baseclasses;
-  debug_field *fields;
+  debug_field *fields = NULL;
   bfd_boolean statics;
   debug_method *methods;
   debug_type vptrbase;
@@ -2036,7 +2056,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
@@ -2240,7 +2264,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;
        }
@@ -2254,6 +2281,7 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
       if (p == NULL)
        {
          bad_stab (orig);
+         free (fields);
          return FALSE;
        }
 
@@ -2415,7 +2443,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 == ':')
     {
@@ -2427,6 +2458,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
       if (p == NULL)
        {
          bad_stab (orig);
+         free (name);
          return FALSE;
        }
 
@@ -2444,6 +2476,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   if (**pp != ',')
     {
       bad_stab (orig);
+      free (name);
       return FALSE;
     }
   ++*pp;
@@ -2452,6 +2485,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   if (**pp != ',')
     {
       bad_stab (orig);
+      free (name);
       return FALSE;
     }
   ++*pp;
@@ -2460,6 +2494,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   if (**pp != ';')
     {
       bad_stab (orig);
+      free (name);
       return FALSE;
     }
   ++*pp;
@@ -2511,6 +2546,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;
 
@@ -2523,8 +2561,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;
@@ -2553,7 +2589,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;
@@ -2570,7 +2606,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;
@@ -2589,11 +2624,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;
                }
            }
 
@@ -2602,7 +2638,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
          if (p == NULL)
            {
              bad_stab (orig);
-             return FALSE;
+             goto fail;
            }
 
          stub = FALSE;
@@ -2667,18 +2703,18 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
            case '*':
              /* virtual member function, followed by index.  The sign
                 bit is supposedly set to distinguish
-                pointers-to-methods from virtual function indicies.  */
+                pointers-to-methods from virtual function indices.  */
              ++*pp;
              voffset = parse_number (pp, (bfd_boolean *) NULL);
              if (**pp != ';')
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
              ++*pp;
              voffset &= 0x7fffffff;
 
-             if (**pp == ';' || *pp == '\0')
+             if (**pp == ';' || **pp == '\0')
                {
                  /* Must be g++ version 1.  */
                  context = DEBUG_TYPE_NULL;
@@ -2704,7 +2740,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                      if (**pp != ';')
                        {
                          bad_stab (orig);
-                         return FALSE;
+                         goto fail;
                        }
                      ++*pp;
                    }
@@ -2739,26 +2775,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)
@@ -2782,7 +2817,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                                                                constp,
                                                                volatilep);
          if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
-           return FALSE;
+           goto fail;
 
          ++cvars;
        }
@@ -2811,6 +2846,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
@@ -2851,9 +2895,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;
@@ -3402,6 +3444,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
     case 9:
       name = "unsigned";
       rettype = debug_make_int_type (dhandle, 4, TRUE);
+      break;
     case 10:
       name = "unsigned long";
       rettype = debug_make_int_type (dhandle, 4, TRUE);
@@ -4108,7 +4151,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)
                        {
@@ -5138,6 +5184,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)