* config/tc-v850.c (md_apply_fix3): Use little endian get/put
[deliverable/binutils-gdb.git] / binutils / stabs.c
index 76b221b0f4acb85c4883795d06b17d2e2172d4ab..59291dd1f4b4bc1230ce2febbd67376aba291189 100644 (file)
@@ -51,9 +51,14 @@ struct stab_handle
 {
   /* True if this is stabs in sections.  */
   boolean sections;
-  /* The type of the last stab symbol, so that we can detect N_SO
-     pairs.  */
-  int last_type;
+  /* The symbol table.  */
+  asymbol **syms;
+  /* The number of symbols.  */
+  long symcount;
+  /* The accumulated file name string.  */
+  char *so_string;
+  /* The value of the last N_SO symbol.  */
+  bfd_vma so_value;
   /* The value of the start of the file, so that we can handle file
      relative N_LBRAC and N_RBRAC symbols.  */
   bfd_vma file_start_offset;
@@ -193,7 +198,7 @@ static debug_type stab_find_tagged_type
   PARAMS ((PTR, struct stab_handle *, const char *, int,
           enum debug_type_kind));
 static debug_type *stab_demangle_argtypes
-  PARAMS ((PTR, struct stab_handle *, const char *));
+  PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
 
 /* Save a string in memory.  */
 
@@ -341,15 +346,19 @@ warn_stab (p, err)
 
 /*ARGSUSED*/
 PTR
-start_stab (dhandle, sections)
+start_stab (dhandle, sections, syms, symcount)
      PTR dhandle;
      boolean sections;
+     asymbol **syms;
+     long symcount;
 {
   struct stab_handle *ret;
 
   ret = (struct stab_handle *) xmalloc (sizeof *ret);
   memset (ret, 0, sizeof *ret);
   ret->sections = sections;
+  ret->syms = syms;
+  ret->symcount = symcount;
   ret->files = 1;
   ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
   ret->file_types[0] = NULL;
@@ -369,7 +378,8 @@ finish_stab (dhandle, handle)
 
   if (info->within_function)
     {
-      if (! debug_end_function (dhandle, (bfd_vma) -1))
+      if (! stab_emit_pending_vars (dhandle, info)
+         || ! debug_end_function (dhandle, (bfd_vma) -1))
        return false;
       info->within_function = false;
     }
@@ -386,9 +396,6 @@ finish_stab (dhandle, handle)
        return false;
     }
 
-  if (info->pending)
-    fprintf (stderr, "Left over pending variables in stabs debugging\n");
-
   return true;
 }
 
@@ -405,6 +412,38 @@ parse_stab (dhandle, handle, type, desc, value, string)
 {
   struct stab_handle *info = (struct stab_handle *) handle;
 
+  /* gcc will emit two N_SO strings per compilation unit, one for the
+     directory name and one for the file name.  We just collect N_SO
+     strings as we see them, and start the new compilation unit when
+     we see a non N_SO symbol.  */
+  if (info->so_string != NULL
+      && (type != N_SO || *string == '\0' || value != info->so_value))
+    {
+      if (! debug_set_filename (dhandle, info->so_string))
+       return false;
+      info->main_filename = info->so_string;
+
+      info->gcc_compiled = 0;
+      info->n_opt_found = false;
+
+      /* Generally, for stabs in the symbol table, the N_LBRAC and
+        N_RBRAC symbols are relative to the N_SO symbol value.  */
+      if (! info->sections)
+       info->file_start_offset = info->so_value;
+
+      /* We need to reset the mapping from type numbers to types.  We
+        can't free the old mapping, because of the use of
+        debug_make_indirect_type.  */
+      info->files = 1;
+      info->file_types = ((struct stab_types **)
+                         xmalloc (sizeof *info->file_types));
+      info->file_types[0] = NULL;
+
+      info->so_string = NULL;
+
+      /* Now process whatever type we just got.  */
+    }
+
   switch (type)
     {
     case N_FN:
@@ -463,58 +502,40 @@ parse_stab (dhandle, handle, type, desc, value, string)
       break;
 
     case N_SO:
-      /* Start a file.  If we get two in a row, the first is the
-         directory name.  An empty string is emitted by gcc at the end
-         of a compilation unit.  */
-      if (*string == '\0')
-       {
-         if (info->within_function)
-           {
-             if (! debug_end_function (dhandle, value))
-               return false;
-             info->within_function = false;
-           }
-         return true;
-       }
-      info->gcc_compiled = 0;
-      info->n_opt_found = false;
-      if (info->last_type == N_SO)
+      /* This always ends a function.  */
+      if (info->within_function)
        {
-         char *o;
-
-         if (! debug_append_filename (dhandle, string))
+         if (! stab_emit_pending_vars (dhandle, info)
+             || ! debug_end_function (dhandle, value))
            return false;
-         o = info->main_filename;
-         info->main_filename = concat (o, string, (const char *) NULL);
-         free (o);
+         info->within_function = false;
        }
+
+      /* An empty string is emitted by gcc at the end of a compilation
+         unit.  */
+      if (*string == '\0')
+       return true;
+
+      /* Just accumulate strings until we see a non N_SO symbol.  If
+         the string starts with '/', we discard the previously
+         accumulated strings.  */
+      if (info->so_string == NULL)
+       info->so_string = xstrdup (string);
       else
        {
-         if (info->within_function)
-           {
-             if (! debug_end_function (dhandle, value))
-               return false;
-             info->within_function = false;
-           }
-         if (! debug_set_filename (dhandle, string))
-           return false;
-         if (info->main_filename != NULL)
-           free (info->main_filename);
-         info->main_filename = xstrdup (string);
-
-         /* Generally, for stabs in the symbol table, the N_LBRAC and
-             N_RBRAC symbols are relative to the N_SO symbol value.  */
-         if (! info->sections)
-           info->file_start_offset = value;
-
-         /* We need to reset the mapping from type numbers to types.
-             We can't free the old mapping, because of the use of
-             debug_make_indirect_type.  */
-         info->files = 1;
-         info->file_types = ((struct stab_types **)
-                             xmalloc (sizeof *info->file_types));
-         info->file_types[0] = NULL;
+         char *f;
+
+         f = info->so_string;
+         if (*string == '/')
+           info->so_string = xstrdup (string);
+         else
+           info->so_string = concat (info->so_string, string,
+                                     (const char *) NULL);
+         free (f);
        }
+
+      info->so_value = value;
+
       break;
 
     case N_SOL:
@@ -577,7 +598,8 @@ parse_stab (dhandle, handle, type, desc, value, string)
          {
            if (info->within_function)
              {
-               if (! debug_end_function (dhandle, value))
+               if (! stab_emit_pending_vars (dhandle, info)
+                   || ! debug_end_function (dhandle, value))
                  return false;
              }
            /* For stabs in sections, line numbers and block addresses
@@ -607,8 +629,6 @@ parse_stab (dhandle, handle, type, desc, value, string)
       break;
     }
 
-  info->last_type = type;
-
   return true;
 }
 
@@ -788,15 +808,30 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
       break;
 
     case 'G':
-      /* A global symbol.  The value must be extracted from the symbol
-         table.  */
-      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
-      if (dtype == DEBUG_TYPE_NULL)
-       return false;
-      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
-                                 (bfd_vma) -1))
-       return false;
+      {
+       long c;
+       asymbol **ps;
+
+       /* A global symbol.  The value must be extracted from the
+          symbol table.  */
+       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+                                (debug_type **) NULL);
+       if (dtype == DEBUG_TYPE_NULL)
+         return false;
+       for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+         {
+           const char *n;
+
+           n = bfd_asymbol_name (*ps);
+           if (*n == *name && strcmp (n, name) == 0)
+             break;
+         }
+       if (c > 0)
+         value = bfd_asymbol_value (*ps);
+       if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
+                                   value))
+         return false;
+      }
       break;
 
       /* This case is faked by a conditional above, when there is no
@@ -827,9 +862,13 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
          dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                                   (debug_type **) NULL);
          if (dtype != DEBUG_TYPE_NULL)
-           dtype = debug_make_pointer_type (dhandle,
-                                            debug_make_function_type (dhandle,
-                                                                      dtype));
+           {
+             debug_type ftype;
+
+             ftype = debug_make_function_type (dhandle, dtype,
+                                               (debug_type *) NULL, false);
+             dtype = debug_make_pointer_type (dhandle, ftype);
+           }
        }
       if (dtype == DEBUG_TYPE_NULL)
        return false;
@@ -1278,7 +1317,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
       dtype = (debug_make_function_type
               (dhandle,
                parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                (debug_type **) NULL)));
+                                (debug_type **) NULL),
+               (debug_type *) NULL, false));
       break;
 
     case 'k':
@@ -1348,7 +1388,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
            }
          ++*pp;
          dtype = debug_make_method_type (dhandle, return_type,
-                                         DEBUG_TYPE_NULL, NULL);
+                                         DEBUG_TYPE_NULL,
+                                         (debug_type *) NULL, false);
        }
       else
        {
@@ -1357,6 +1398,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
          debug_type *args;
          unsigned int n;
          unsigned int alloc;
+         boolean varargs;
 
          domain = parse_stab_type (dhandle, info, (const char *) NULL,
                                    pp, (debug_type **) NULL);
@@ -1402,30 +1444,22 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
            }
          ++*pp;
 
-         /* If the last type is void, then this function does not
-            take a variable number of arguments.  If the last is not
-            void, then it does.  */
-         if (n > 0
-             && debug_get_type_kind (dhandle, args[n - 1]) == DEBUG_KIND_VOID)
-           --n;
+         /* If the last type is not void, then this function takes a
+            variable number of arguments.  Otherwise, we must strip
+            the void type.  */
+         if (n == 0
+             || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
+           varargs = true;
          else
            {
-             if (n + 1 >= alloc)
-               {
-                 alloc += 10;
-                 args = ((debug_type *)
-                         xrealloc ((PTR) args, alloc * sizeof *args));
-               }
-
-             args[n] = debug_make_ellipsis_type (dhandle);
-             if (args[n] == DEBUG_TYPE_NULL)
-               return DEBUG_TYPE_NULL;
-             ++n;
+             --n;
+             varargs = false;
            }
 
          args[n] = DEBUG_TYPE_NULL;
 
-         dtype = debug_make_method_type (dhandle, return_type, domain, args);
+         dtype = debug_make_method_type (dhandle, return_type, domain, args,
+                                         varargs);
        }
       break;
 
@@ -1632,6 +1666,11 @@ parse_stab_range_type (dhandle, info, typename, pp, typenums)
       if (self_subrange && n2 == 0 && n3 == 0)
        return debug_make_void_type (dhandle);
 
+      /* A type defined as a subrange of itself, with n2 positive and
+        n3 zero, is a complex type, and n2 is the number of bytes.  */
+      if (self_subrange && n3 == 0 && n2 > 0)
+       return debug_make_complex_type (dhandle, n2);
+
       /* If n3 is zero and n2 is positive, this is a floating point
          type, and n2 is the number of bytes.  */
       if (n3 == 0 && n2 > 0)
@@ -2499,6 +2538,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
          bfd_vma voffset;
          debug_type context;
          const char *physname;
+         boolean varargs;
 
          if (look_ahead_type != DEBUG_TYPE_NULL)
            {
@@ -2583,12 +2623,8 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
            {
            case '*':
              /* virtual member function, followed by index.  The sign
-                bit is set to distinguish pointers-to-methods from
-                virtual function indicies.  Since the array is in
-                words, the quantity must be shifted left by 1 on 16
-                bit machine, and by 2 on 32 bit machine, forcing the
-                sign bit out, and usable as a valid index into the
-                array.  Remove the sign bit here.  */
+                bit is supposedly set to distinguish
+                pointers-to-methods from virtual function indicies.  */
              ++*pp;
              voffset = parse_number (pp, (boolean *) NULL);
              if (**pp != ';')
@@ -2598,7 +2634,6 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
                }
              ++*pp;
              voffset &= 0x7fffffff;
-             voffset += 2;
 
              if (**pp == ';' || *pp == '\0')
                {
@@ -2661,7 +2696,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
             and the argument types, must be deduced from it.  */
 
          if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
-             && debug_get_parameter_types (dhandle, type) != NULL)
+             && debug_get_parameter_types (dhandle, type, &varargs) != NULL)
            physname = argtypes;
          else
            {
@@ -2759,6 +2794,7 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
   boolean is_constructor;
   boolean is_destructor;
   debug_type *args;
+  boolean varargs;
 
   /* Constructors are sometimes handled specially.  */
   is_full_physname_constructor = ((argtypes[0] == '_'
@@ -2847,14 +2883,16 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
     {
       args = (debug_type *) xmalloc (sizeof *args);
       *args = NULL;
-      return debug_make_method_type (dhandle, return_type, class_type, args);
+      return debug_make_method_type (dhandle, return_type, class_type, args,
+                                    false);
     }
 
-  args = stab_demangle_argtypes (dhandle, info, *pphysname);
+  args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
   if (args == NULL)
     return DEBUG_TYPE_NULL;
 
-  return debug_make_method_type (dhandle, return_type, class_type, args);
+  return debug_make_method_type (dhandle, return_type, class_type, args,
+                                varargs);
 }
 
 /* The tail end of stabs for C++ classes that contain a virtual function
@@ -2949,6 +2987,8 @@ parse_stab_array_type (dhandle, info, pp, stringp)
      boolean stringp;
 {
   const char *orig;
+  const char *p;
+  int typenums[2];
   debug_type index_type;
   boolean adjustable;
   bfd_signed_vma lower, upper;
@@ -2965,8 +3005,27 @@ parse_stab_array_type (dhandle, info, pp, stringp)
 
   /* FIXME: gdb checks os9k_stabs here.  */
 
-  index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                               (debug_type **) NULL);
+  /* If the index type is type 0, we take it as int.  */
+  p = *pp;
+  if (! parse_stab_type_number (&p, typenums))
+    return false;
+  if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
+    {
+      index_type = debug_find_named_type (dhandle, "int");
+      if (index_type == DEBUG_TYPE_NULL)
+       {
+         index_type = debug_make_int_type (dhandle, 4, false);
+         if (index_type == DEBUG_TYPE_NULL)
+           return false;
+       }
+      *pp = p;
+    }
+  else
+    {
+      index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+                                   (debug_type **) NULL);
+    }
+
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -3492,6 +3551,8 @@ struct stab_demangle_info
   struct stab_handle *info;
   /* The array of arguments we are building.  */
   debug_type *args;
+  /* Whether the method takes a variable number of arguments.  */
+  boolean varargs;
   /* The array of types we have remembered.  */
   struct stab_demangle_typestring *typestrings;
   /* The number of typestrings.  */
@@ -3517,7 +3578,8 @@ static boolean stab_demangle_template
 static boolean stab_demangle_class
   PARAMS ((struct stab_demangle_info *, const char **, const char **));
 static boolean stab_demangle_args
-  PARAMS ((struct stab_demangle_info *, const char **, debug_type **));
+  PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+          boolean *));
 static boolean stab_demangle_arg
   PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
           unsigned int *, unsigned int *));
@@ -3596,16 +3658,18 @@ stab_demangle_get_count (pp, pi)
    terminated array of argument types.  */
 
 static debug_type *
-stab_demangle_argtypes (dhandle, info, physname)
+stab_demangle_argtypes (dhandle, info, physname, pvarargs)
      PTR dhandle;
      struct stab_handle *info;
      const char *physname;
+     boolean *pvarargs;
 {
   struct stab_demangle_info minfo;
 
   minfo.dhandle = dhandle;
   minfo.info = info;
   minfo.args = NULL;
+  minfo.varargs = false;
   minfo.typestring_alloc = 10;
   minfo.typestrings = ((struct stab_demangle_typestring *)
                       xmalloc (minfo.typestring_alloc
@@ -3630,6 +3694,7 @@ stab_demangle_argtypes (dhandle, info, physname)
   if (minfo.args == NULL)
     fprintf (stderr, "no argument types in mangled string\n");
 
+  *pvarargs = minfo.varargs;
   return minfo.args;
 
  error_return:
@@ -3820,7 +3885,7 @@ stab_demangle_signature (minfo, pp)
          hold = NULL;
          func_done = true;
          ++*pp;
-         if (! stab_demangle_args (minfo, pp, &minfo->args))
+         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
            return false;
          break;
 
@@ -3848,7 +3913,7 @@ stab_demangle_signature (minfo, pp)
          /* Assume we have stumbled onto the first outermost function
             argument token, and start processing args.  */
          func_done = true;
-         if (! stab_demangle_args (minfo, pp, &minfo->args))
+         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
            return false;
          break;
        }
@@ -3856,7 +3921,7 @@ stab_demangle_signature (minfo, pp)
       if (expect_func)
        {
          func_done = true;
-         if (! stab_demangle_args (minfo, pp, &minfo->args))
+         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
            return false;
        }
     }
@@ -3867,7 +3932,7 @@ stab_demangle_signature (minfo, pp)
         bar__3fooi is 'foo::bar(int)'.  We get here when we find the
         first case, and need to ensure that the '(void)' gets added
         to the current declp.  */
-      if (! stab_demangle_args (minfo, pp, &minfo->args))
+      if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
        return false;
     }
 
@@ -4250,10 +4315,11 @@ stab_demangle_class (minfo, pp, pstart)
    is set to a NULL terminated array holding the arguments.  */
 
 static boolean
-stab_demangle_args (minfo, pp, pargs)
+stab_demangle_args (minfo, pp, pargs, pvarargs)
      struct stab_demangle_info *minfo;
      const char **pp;
      debug_type **pargs;
+     boolean *pvarargs;
 {
   const char *orig;
   unsigned int alloc, count;
@@ -4262,7 +4328,10 @@ stab_demangle_args (minfo, pp, pargs)
 
   alloc = 10;
   if (pargs != NULL)
-    *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+    {
+      *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+      *pvarargs = false;
+    }
   count = 0;
 
   while (**pp != '_' && **pp != '\0' && **pp != 'e')
@@ -4313,32 +4382,16 @@ stab_demangle_args (minfo, pp, pargs)
        }
     }
 
+  if (pargs != NULL)
+    (*pargs)[count] = DEBUG_TYPE_NULL;
+
   if (**pp == 'e')
     {
       if (pargs != NULL)
-       {
-         debug_type type;
-
-         type = debug_make_ellipsis_type (minfo->dhandle);
-         if (type == DEBUG_TYPE_NULL)
-           return false;
-
-         if (count + 1 >= alloc)
-           {
-             alloc += 10;
-             *pargs = ((debug_type *)
-                       xrealloc (*pargs, alloc * sizeof **pargs));
-           }
-         (*pargs)[count] = type;
-         ++count;
-       }
-
+       *pvarargs = true;
       ++*pp;
     }
 
-  if (pargs != NULL)
-    (*pargs)[count] = DEBUG_TYPE_NULL;
-
   return true;
 }
 
@@ -4478,23 +4531,35 @@ stab_demangle_type (minfo, pp, ptype)
 
     case 'F':
       /* A function.  */
-      ++*pp;
-      /* FIXME: We should pick up the argument types.  */
-      if (! stab_demangle_args (minfo, pp, (debug_type **) NULL))
-       return false;
-      if (**pp != '_')
-       {
-         /* cplus_demangle will accept a function without a return
-             type, but I don't know when that will happen, or what to
-             do if it does.  */
-         stab_bad_demangle (orig);
+      {
+       debug_type *args;
+       boolean varargs;
+
+       ++*pp;
+       if (! stab_demangle_args (minfo, pp,
+                                 (ptype == NULL
+                                  ? (debug_type **) NULL
+                                  : &args),
+                                 (ptype == NULL
+                                  ? (boolean *) NULL
+                                  : &varargs)))
          return false;
-       }
-      ++*pp;
-      if (! stab_demangle_type (minfo, pp, ptype))
-       return false;
-      if (ptype != NULL)
-       *ptype = debug_make_function_type (minfo->dhandle, *ptype);
+       if (**pp != '_')
+         {
+           /* cplus_demangle will accept a function without a return
+              type, but I don't know when that will happen, or what
+              to do if it does.  */
+           stab_bad_demangle (orig);
+           return false;
+         }
+       ++*pp;
+       if (! stab_demangle_type (minfo, pp, ptype))
+         return false;
+       if (ptype != NULL)
+         *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
+                                            varargs);
+
+      }
       break;
 
     case 'M':
@@ -4502,6 +4567,7 @@ stab_demangle_type (minfo, pp, ptype)
       {
        boolean memberp, constp, volatilep;
        debug_type *args;
+       boolean varargs;
        unsigned int n;
        const char *name;
 
@@ -4509,6 +4575,7 @@ stab_demangle_type (minfo, pp, ptype)
        constp = false;
        volatilep = false;
        args = NULL;
+       varargs = false;
 
        ++*pp;
        if (! isdigit ((unsigned char) **pp))
@@ -4546,7 +4613,10 @@ stab_demangle_type (minfo, pp, ptype)
            if (! stab_demangle_args (minfo, pp,
                                      (ptype == NULL
                                       ? (debug_type **) NULL
-                                      : &args)))
+                                      : &args),
+                                     (ptype == NULL
+                                      ? (boolean *) NULL
+                                      : &varargs)))
              return false;
          }
 
@@ -4578,7 +4648,7 @@ stab_demangle_type (minfo, pp, ptype)
                /* FIXME: We have no way to record constp or
                    volatilep.  */
                *ptype = debug_make_method_type (minfo->dhandle, *ptype,
-                                                class_type, args);
+                                                class_type, args, varargs);
              }
          }
       }
This page took 0.03073 seconds and 4 git commands to generate.