ppcbug-rom checkin
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 3e751db5e693b612768846516456faa8f52dc806..840efb0ac8f192bb169c71c11d9edf98f3a819c0 100644 (file)
@@ -16,7 +16,7 @@ GNU General Public License for more details.
 
 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -29,18 +29,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "objfiles.h"
 #include "gdbcmd.h"
 #include "call-cmds.h"
-#include "regex.h"
+#include "gnu-regex.h"
 #include "expression.h"
 #include "language.h"
 #include "demangle.h"
 
 #include <obstack.h>
-#include <assert.h>
 
 #include <sys/types.h>
 #include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
 #include <ctype.h>
 
 /* Prototypes for local functions */
@@ -73,7 +72,7 @@ static void
 sources_info PARAMS ((char *, int));
 
 static void
-list_symbols PARAMS ((char *, int, int));
+list_symbols PARAMS ((char *, int, int, int));
 
 static void
 output_source_filename PARAMS ((char *, int *));
@@ -111,8 +110,8 @@ void
 cplusplus_hint (name)
      char *name;
 {
-  printf_unfiltered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
-  printf_unfiltered ("(Note leading single quote.)\n");
+  printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
+  printf_filtered ("(Note leading single quote.)\n");
 }
 
 /* Check for a symtab of a specific name; first in symtabs, then in
@@ -188,7 +187,9 @@ lookup_symtab (name)
      char *name;
 {
   register struct symtab *s;
+#if 0
   register char *copy;
+#endif
 
   s = lookup_symtab_1 (name);
   if (s) return s;
@@ -289,7 +290,6 @@ gdb_mangle_name (type, i, j)
   if (!is_destructor)
     is_destructor = (strncmp(physname, "__dt", 4) == 0); 
 
-#ifndef GCC_MANGLE_BUG
   if (is_destructor || is_full_physname_constructor)
     {
       mangled_name = (char*) xmalloc(strlen(physname)+1);
@@ -303,6 +303,13 @@ gdb_mangle_name (type, i, j)
       if (strcmp(buf, "__") == 0)
        buf[0] = '\0';
     }
+  else if (newname != NULL && strchr (newname, '<') != NULL)
+    {
+      /* Template methods are fully mangled.  */
+      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+      newname = NULL;
+      len = 0;
+    }
   else
     {
       sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
@@ -341,51 +348,6 @@ gdb_mangle_name (type, i, j)
   if (newname != NULL)
     strcat (mangled_name, newname);
 
-#else
-
-  if (is_constructor)
-    {
-      buf[0] = '\0';
-    }
-  else
-    {
-      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
-    }
-
-  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
-                     + strlen (buf) + strlen (physname) + 1);
-
-  /* Only needed for GNU-mangled names.  ANSI-mangled names
-     work with the normal mechanisms.  */
-  if (OPNAME_PREFIX_P (field_name))
-    {
-      char *opname;
-      opname = cplus_mangle_opname (field_name + 3, 0);
-      if (opname == NULL)
-       {
-         error ("No mangling for \"%s\"", field_name);
-       }
-      mangled_name_len += strlen (opname);
-      mangled_name = (char *) xmalloc (mangled_name_len);
-
-      strncpy (mangled_name, field_name, 3);
-      strcpy (mangled_name + 3, opname);
-    }
-  else
-    {
-      mangled_name = (char *) xmalloc (mangled_name_len);
-      if (is_constructor)
-       {
-         mangled_name[0] = '\0';
-       }
-      else
-       {
-         strcpy (mangled_name, field_name);
-       }
-    }
-  strcat (mangled_name, buf);
-
-#endif
   strcat (mangled_name, physname);
   return (mangled_name);
 }
@@ -403,7 +365,36 @@ find_pc_psymtab (pc)
   ALL_PSYMTABS (objfile, pst)
     {
       if (pc >= pst->textlow && pc < pst->texthigh)
-       return (pst);
+       {
+         struct minimal_symbol *msymbol;
+         struct partial_symtab *tpst;
+
+         /* An objfile that has its functions reordered might have
+            many partial symbol tables containing the PC, but
+            we want the partial symbol table that contains the
+            function containing the PC.  */
+         if (!(objfile->flags & OBJF_REORDERED))
+           return (pst);
+
+         msymbol = lookup_minimal_symbol_by_pc (pc);
+         if (msymbol == NULL)
+           return (pst);
+
+         for (tpst = pst; tpst != NULL; tpst = tpst->next)
+           {
+             if (pc >= tpst->textlow && pc < tpst->texthigh)
+               {
+                 struct partial_symbol *p;
+
+                 p = find_pc_psymbol (tpst, pc);
+                 if (p != NULL
+                     && SYMBOL_VALUE_ADDRESS(p)
+                        == SYMBOL_VALUE_ADDRESS (msymbol))
+                   return (tpst);
+               }
+           }
+         return (pst);
+       }
     }
   return (NULL);
 }
@@ -588,20 +579,19 @@ found:
        }
     }
 
-  /* Check for the possibility of the symbol being a global function
-     that is stored in one of the minimal symbol tables.  Eventually, all
-     global symbols might be resolved in this way.  */
+  /* Check for the possibility of the symbol being a function or
+     a mangled variable that is stored in one of the minimal symbol tables.
+     Eventually, all global symbols might be resolved in this way.  */
   
   if (namespace == VAR_NAMESPACE)
     {
-      msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL);
+      msymbol = lookup_minimal_symbol (name, NULL, NULL);
       if (msymbol != NULL)
        {
          s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
-         /* If S is NULL, there are no debug symbols for this file.
-            Skip this stuff and check for matching static symbols below. */
          if (s != NULL)
            {
+             /* This is a function which has a symtab for its address.  */
              bv = BLOCKVECTOR (s);
              block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
              sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
@@ -631,6 +621,18 @@ found:
                *symtab = s;
              return sym;
            }
+         else if (MSYMBOL_TYPE (msymbol) != mst_text
+                  && MSYMBOL_TYPE (msymbol) != mst_file_text
+                  && !STREQ (name, SYMBOL_NAME (msymbol)))
+           {
+             /* This is a mangled variable, look it up by its
+                mangled name.  */
+             return lookup_symbol (SYMBOL_NAME (msymbol), block,
+                                   namespace, is_a_field_of_this, symtab);
+           }
+         /* There are no debug symbols for this file, or we are looking
+            for an unmangled variable.
+            Try to find a matching static symbol below. */
        }
     }
       
@@ -684,42 +686,6 @@ found:
        }
     }
 
-  /* Now search all per-file blocks for static mangled symbols.
-     Do the symtabs first, then check the psymtabs.  */
-
-  if (namespace == VAR_NAMESPACE)
-    {
-      ALL_SYMTABS (objfile, s)
-       {
-         bv = BLOCKVECTOR (s);
-         block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-         sym = lookup_block_symbol (block, name, VAR_NAMESPACE);
-         if (sym) 
-           {
-             block_found = block;
-             if (symtab != NULL)
-               *symtab = s;
-             return sym;
-           }
-       }
-
-      ALL_PSYMTABS (objfile, ps)
-       {
-         if (!ps->readin && lookup_partial_symbol (ps, name, 0, VAR_NAMESPACE))
-           {
-             s = PSYMTAB_TO_SYMTAB(ps);
-             bv = BLOCKVECTOR (s);
-             block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-             sym = lookup_block_symbol (block, name, VAR_NAMESPACE);
-             if (!sym)
-               error ("Internal: mangled static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);
-             if (symtab != NULL)
-               *symtab = s;
-             return sym;
-           }
-       }
-    }
-
   if (symtab != NULL)
     *symtab = NULL;
   return 0;
@@ -763,7 +729,8 @@ lookup_partial_symbol (pst, name, global, namespace)
       while (top > bottom)
        {
          center = bottom + (top - bottom) / 2;
-         assert (center < top);
+         if (!(center < top))
+           abort ();
          if (!do_linear_search && SYMBOL_LANGUAGE (center) == language_cplus)
            {
              do_linear_search = 1;
@@ -777,7 +744,8 @@ lookup_partial_symbol (pst, name, global, namespace)
              bottom = center + 1;
            }
        }
-      assert (top == bottom);
+      if (!(top == bottom))
+       abort ();
       while (STREQ (SYMBOL_NAME (top), name))
        {
          if (SYMBOL_NAMESPACE (top) == namespace)
@@ -1001,8 +969,15 @@ find_pc_symtab (pc)
      to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000
      and symtab b is at 0x2000-0x3000.  So the GLOBAL_BLOCK for a is from
      0x1000-0x4000, but for address 0x2345 we want to return symtab b.
-     This is said to happen for the mips; it might be swifter to create
-     several symtabs with the same name like xcoff does (I'm not sure).  */
+
+     This happens for native ecoff format, where code from included files
+     gets its own symtab. The symtab for the included file should have
+     been read in already via the dependency mechanism.
+     It might be swifter to create several symtabs with the same name
+     like xcoff does (I'm not sure).
+
+     It also happens for objfiles that have their functions reordered.
+     For these, the symtab we are looking for is not necessarily read in.  */
 
   ALL_SYMTABS (objfile, s)
     {
@@ -1013,6 +988,18 @@ find_pc_symtab (pc)
          && (distance == 0
              || BLOCK_END (b) - BLOCK_START (b) < distance))
        {
+         /* For an objfile that has its functions reordered,
+            find_pc_psymtab will find the proper partial symbol table
+            and we simply return its corresponding symtab.  */
+         if (objfile->flags & OBJF_REORDERED)
+           {
+             ps = find_pc_psymtab (pc);
+             if (ps)
+               s = PSYMTAB_TO_SYMTAB (ps);
+             else
+               s = NULL;
+             return (s);
+           }
          distance = BLOCK_END (b) - BLOCK_START (b);
          best_s = s;
        }
@@ -1029,6 +1016,7 @@ find_pc_symtab (pc)
        /* Might want to error() here (in case symtab is corrupt and
           will cause a core dump), but maybe we can successfully
           continue, so let's not.  */
+       /* FIXME-32x64: assumes pc fits in a long */
        warning ("\
 (Internal error: pc 0x%lx in read in psymtab, but not in symtab.)\n",
                 (unsigned long) pc);
@@ -1037,8 +1025,14 @@ find_pc_symtab (pc)
   return (s);
 }
 \f
+#if 0
+
 /* Find the closest symbol value (of any sort -- function or variable)
-   for a given address value.  Slow but complete.  */
+   for a given address value.  Slow but complete.  (currently unused,
+   mainly because it is too slow.  We could fix it if each symtab and
+   psymtab had contained in it the addresses ranges of each of its
+   sections, which also would be required to make things like "info
+   line *0x2345" cause psymtabs to be converted to symtabs).  */
 
 struct symbol *
 find_addr_symbol (addr, symtabp, symaddrp)
@@ -1109,7 +1103,7 @@ find_addr_symbol (addr, symtabp, symaddrp)
     *symaddrp = best_sym_addr;
   return best_sym;
 }
-
+#endif /* 0 */
 
 /* Find the source file and line number for a given PC value.
    Return a structure containing a symtab pointer, a line number,
@@ -1252,6 +1246,10 @@ find_pc_line (pc, notcurrent)
        {
          val.symtab = alt_symtab;
          val.line = alt->line - 1;
+
+         /* Don't return line 0, that means that we didn't find the line.  */
+         if (val.line == 0) ++val.line;
+
          val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
          val.end = alt->pc;
        }
@@ -1491,6 +1489,51 @@ find_pc_line_pc_range (pc, startptr, endptr)
   *endptr = sal.end;
   return sal.symtab != 0;
 }
+
+/* Given a function symbol SYM, find the symtab and line for the start
+   of the function.
+   If the argument FUNFIRSTLINE is nonzero, we want the first line
+   of real code inside the function.  */
+
+static struct symtab_and_line
+find_function_start_sal PARAMS ((struct symbol *sym, int));
+
+static struct symtab_and_line
+find_function_start_sal (sym, funfirstline)
+     struct symbol *sym;
+     int funfirstline;
+{
+  CORE_ADDR pc;
+  struct symtab_and_line sal;
+
+  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+  if (funfirstline)
+    {
+      pc += FUNCTION_START_OFFSET;
+      SKIP_PROLOGUE (pc);
+    }
+  sal = find_pc_line (pc, 0);
+
+#ifdef PROLOGUE_FIRSTLINE_OVERLAP
+  /* Convex: no need to suppress code on first line, if any */
+  sal.pc = pc;
+#else
+  /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+     line is still part of the same function.  */
+  if (sal.pc != pc
+      && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
+      && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+    {
+      /* First pc of next line */
+      pc = sal.end;
+      /* Recalculate the line number (might not be N+1).  */
+      sal = find_pc_line (pc, 0);
+    }
+  sal.pc = pc;
+#endif
+
+  return sal;
+}
 \f
 /* If P is of the form "operator[ \t]+..." where `...' is
    some legitimate operator text, return a pointer to the
@@ -1577,14 +1620,35 @@ operator_chars (p, end)
   return *end;
 }
 
+/* Return the number of methods described for TYPE, including the
+   methods from types it derives from. This can't be done in the symbol
+   reader because the type of the baseclass might still be stubbed
+   when the definition of the derived class is parsed.  */
+
+static int total_number_of_methods PARAMS ((struct type *type));
+
+static int
+total_number_of_methods (type)
+     struct type *type;
+{
+  int n;
+  int count;
+
+  check_stub_type (type);
+  count = TYPE_NFN_FIELDS_TOTAL (type);
+
+  for (n = 0; n < TYPE_N_BASECLASSES (type); n++)
+    count += total_number_of_methods (TYPE_BASECLASS (type, n));
+
+  return count;
+}
+
 /* Recursive helper function for decode_line_1.
- * Look for methods named NAME in type T.
- * Return number of matches.
- * Put matches in SYM_ARR (which better be big enough!).
- * These allocations seem to define "big enough":
- * sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*));
- * Note that this function is g++ specific.
- */
+   Look for methods named NAME in type T.
+   Return number of matches.
+   Put matches in SYM_ARR, which should have been allocated with
+   a size of total_number_of_methods (T) * sizeof (struct symbol *).
+   Note that this function is g++ specific.  */
 
 int
 find_methods (t, name, sym_arr)
@@ -1743,7 +1807,8 @@ build_canonical_line_spec (sal, symname, canonical)
    FUNCTION may be an undebuggable function found in minimal symbol table.
 
    If the argument FUNFIRSTLINE is nonzero, we want the first line
-   of real code inside a function when a function is specified.
+   of real code inside a function when a function is specified, and it is
+   not OK to specify a variable or type to get its line number.
 
    DEFAULT_SYMTAB specifies the file to use if none is specified.
    It defaults to current_source_symtab.
@@ -1804,7 +1869,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   struct symtab_and_line val;
 #endif
   register char *p, *p1;
-  char *q, *q1, *pp;
+  char *q, *pp;
+#if 0
+  char *q1;
+#endif
   register struct symtab *s;
 
   register struct symbol *sym;
@@ -1834,17 +1902,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
 
   if (**argptr == '*')
     {
-      if (**argptr == '*')
-       {
-         (*argptr)++;
-       }
+      (*argptr)++;
       pc = parse_and_eval_address_1 (argptr);
       values.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
       values.nelts = 1;
       values.sals[0] = find_pc_line (pc, 0);
       values.sals[0].pc = pc;
-      build_canonical_line_spec (values.sals, NULL, canonical);
       return values;
     }
 
@@ -1859,13 +1923,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
     {
       if (p[0] == '<') 
        {
-         while(!++p && *p != '>');
+         while(++p && *p != '>');
          if (!p)
            {
-             /* FIXME: Why warning() and then return_to_top_level?
-                What's wrong with error()?  */
-             warning("non-matching '<' and '>' in command");
-             return_to_top_level (RETURN_ERROR);
+             error ("non-matching '<' and '>' in command");
            }
        }
       if (p[0] == ':' || p[0] == ' ' || p[0] == '\t')
@@ -1922,7 +1983,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
                  opname = cplus_mangle_opname (tmp, DMGL_ANSI);
                  if (opname == NULL)
                    {
-                     warning ("no mangling for \"%s\"", tmp);
+                     error_begin ();
+                     printf_filtered ("no mangling for \"%s\"\n", tmp);
                      cplusplus_hint (saved_arg);
                      return_to_top_level (RETURN_ERROR);
                    }
@@ -1947,7 +2009,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
              sym = 0;
              i1 = 0;           /*  counter for the symbol array */
              t = SYMBOL_TYPE (sym_class);
-             sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*));
+             sym_arr = (struct symbol **) alloca(total_number_of_methods (t)
+                                                 * sizeof(struct symbol *));
 
              /* Cfront objects don't have fieldlists.  */
              if (destructor_name_p (copy, t) && TYPE_FN_FIELDLISTS (t) != NULL)
@@ -1978,17 +2041,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
 
                  if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
                    {
-                     /* Arg is the name of a function */
-                     pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-                     if (funfirstline)
-                       {
-                         pc += FUNCTION_START_OFFSET;
-                         SKIP_PROLOGUE (pc);
-                       }
                      values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
                      values.nelts = 1;
-                     values.sals[0] = find_pc_line (pc, 0);
-                     values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc;
+                     values.sals[0] = find_function_start_sal (sym,
+                                                               funfirstline);
                    }
                  else
                    {
@@ -2014,21 +2070,25 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
                    }
                  else
                    tmp = copy;
+                 error_begin ();
                  if (tmp[0] == '~')
-                   warning ("the class `%s' does not have destructor defined",
-                            SYMBOL_SOURCE_NAME(sym_class));
+                   printf_filtered
+                     ("the class `%s' does not have destructor defined\n",
+                      SYMBOL_SOURCE_NAME(sym_class));
                  else
-                   warning ("the class %s does not have any method named %s",
-                            SYMBOL_SOURCE_NAME(sym_class), tmp);
+                   printf_filtered
+                     ("the class %s does not have any method named %s\n",
+                      SYMBOL_SOURCE_NAME(sym_class), tmp);
                  cplusplus_hint (saved_arg);
                  return_to_top_level (RETURN_ERROR);
                }
            }
          else
            {
+             error_begin ();
              /* The quotes are important if copy is empty.  */
-             warning ("can't find class, struct, or union named \"%s\"",
-                      copy);
+             printf_filtered
+               ("can't find class, struct, or union named \"%s\"\n", copy);
              cplusplus_hint (saved_arg);
              return_to_top_level (RETURN_ERROR);
            }
@@ -2130,7 +2190,9 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   /* Arg token is not digits => try it as a variable name
      Find the next token (everything up to end or next whitespace).  */
 
-  if (is_quoted)
+  if (**argptr == '$')         /* Convenience variable */
+    p = skip_quoted (*argptr + 1);
+  else if (is_quoted)
     {
       p = skip_quoted (*argptr);
       if (p[-1] != '\'')
@@ -2148,7 +2210,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
   copy[p - *argptr] = '\0';
-  if ((copy[0] == copy [p - *argptr - 1])
+  if (p != *argptr
+      && (copy[0] == copy [p - *argptr - 1])
       && strchr (gdb_completer_quote_characters, copy[0]) != NULL)
     {
       copy [p - *argptr - 1] = '\0';
@@ -2157,6 +2220,32 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   while (*p == ' ' || *p == '\t') p++;
   *argptr = p;
 
+  /* See if it's a convenience variable */
+
+  if (*copy == '$')
+    {
+      value_ptr valx;
+      int need_canonical = (s == 0) ? 1 : 0;
+
+      valx = value_of_internalvar (lookup_internalvar (copy + 1));
+      if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+       error ("Convenience variables used in line specs must have integer values.");
+
+      val.symtab = s ? s : default_symtab;
+      val.line = value_as_long (valx);
+      val.pc = 0;
+
+      values.sals = (struct symtab_and_line *)xmalloc (sizeof val);
+      values.sals[0] = val;
+      values.nelts = 1;
+
+      if (need_canonical)
+       build_canonical_line_spec (values.sals, NULL, canonical);
+
+      return values;
+    }
+
+
   /* Look up that token as a variable.
      If file specified, use that file's per-file block to start with.  */
 
@@ -2170,32 +2259,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
       if (SYMBOL_CLASS (sym) == LOC_BLOCK)
        {
          /* Arg is the name of a function */
-         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-         if (funfirstline)
-           {
-             pc += FUNCTION_START_OFFSET;
-             SKIP_PROLOGUE (pc);
-           }
-         val = find_pc_line (pc, 0);
-#ifdef PROLOGUE_FIRSTLINE_OVERLAP
-         /* Convex: no need to suppress code on first line, if any */
-         val.pc = pc;
-#else
-         /* Check if SKIP_PROLOGUE left us in mid-line, and the next
-            line is still part of the same function.  */
-         if (val.pc != pc
-             && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= val.end
-             && val.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
-           {
-             /* First pc of next line */
-             pc = val.end;
-             /* Recalculate the line number (might not be N+1).  */
-             val = find_pc_line (pc, 0);
-           }
-         val.pc = pc;
-#endif
          values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
-         values.sals[0] = val;
+         values.sals[0] = find_function_start_sal (sym, funfirstline);
          values.nelts = 1;
 
          /* Don't use the SYMBOL_LINE; if used at all it points to
@@ -2213,26 +2278,32 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
            }
          return values;
        }
-      else if (SYMBOL_LINE (sym) != 0)
+      else
        {
-         /* We know its line number.  */
-         values.sals = (struct symtab_and_line *)
-           xmalloc (sizeof (struct symtab_and_line));
-         values.nelts = 1;
-         memset (&values.sals[0], 0, sizeof (values.sals[0]));
-         values.sals[0].symtab = sym_symtab;
-         values.sals[0].line = SYMBOL_LINE (sym);
-         return values;
+         if (funfirstline)
+           error ("\"%s\" is not a function", copy);
+         else if (SYMBOL_LINE (sym) != 0)
+           {
+             /* We know its line number.  */
+             values.sals = (struct symtab_and_line *)
+               xmalloc (sizeof (struct symtab_and_line));
+             values.nelts = 1;
+             memset (&values.sals[0], 0, sizeof (values.sals[0]));
+             values.sals[0].symtab = sym_symtab;
+             values.sals[0].line = SYMBOL_LINE (sym);
+             return values;
+           }
+         else
+           /* This can happen if it is compiled with a compiler which doesn't
+              put out line numbers for variables.  */
+           /* FIXME: Shouldn't we just set .line and .symtab to zero
+              and return?  For example, "info line foo" could print
+              the address.  */
+           error ("Line number not known for symbol \"%s\"", copy);
        }
-      else
-       /* This can happen if it is compiled with a compiler which doesn't
-          put out line numbers for variables.  */
-       /* FIXME: Shouldn't we just set .line and .symtab to zero and
-          return?  For example, "info line foo" could print the address.  */
-       error ("Line number not known for symbol \"%s\"", copy);
     }
 
-  msymbol = lookup_minimal_symbol (copy, (struct objfile *) NULL);
+  msymbol = lookup_minimal_symbol (copy, NULL, NULL);
   if (msymbol != NULL)
     {
       val.symtab = 0;
@@ -2286,7 +2357,6 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
      char ***canonical;
 {
   struct symtabs_and_lines values, return_values;
-  register CORE_ADDR pc;
   char *args, *arg1;
   int i;
   char *prompt;
@@ -2312,20 +2382,15 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
     {
       if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
        {
-         /* Arg is the name of a function */
-         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i]));
-         if (funfirstline)
-           {
-             pc += FUNCTION_START_OFFSET;
-             SKIP_PROLOGUE (pc);
-           }
-         values.sals[i] = find_pc_line (pc, 0);
-         values.sals[i].pc = (values.sals[i].end && values.sals[i].pc != pc) ?
-                              values.sals[i].end                      :  pc;
-         printf_unfiltered("[%d] %s at %s:%d\n", (i+2), SYMBOL_SOURCE_NAME (sym_arr[i]),
-                values.sals[i].symtab->filename, values.sals[i].line);
+         values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
+         printf_unfiltered ("[%d] %s at %s:%d\n",
+                            (i+2),
+                            SYMBOL_SOURCE_NAME (sym_arr[i]),
+                            values.sals[i].symtab->filename,
+                            values.sals[i].line);
        }
-      else printf_unfiltered ("?HERE\n");
+      else
+       printf_unfiltered ("?HERE\n");
       i++;
     }
   
@@ -2336,7 +2401,7 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
   printf_unfiltered("%s ",prompt);
   gdb_flush(gdb_stdout);
 
-  args = command_line_input ((char *) NULL, 0);
+  args = command_line_input ((char *) NULL, 0, "overload-choice");
   
   if (args == 0 || *args == 0)
     error_no_arg ("one or more choice numbers");
@@ -2515,10 +2580,11 @@ sources_info (ignore, from_tty)
    we find.  */
 
 static void
-list_symbols (regexp, class, bpt)
+list_symbols (regexp, class, bpt, from_tty)
      char *regexp;
      int class;
      int bpt;
+     int from_tty;
 {
   register struct symtab *s;
   register struct partial_symtab *ps;
@@ -2538,9 +2604,15 @@ list_symbols (regexp, class, bpt)
   static enum minimal_symbol_type types[]
     = {mst_data, mst_text, mst_abs, mst_unknown};
   static enum minimal_symbol_type types2[]
-    = {mst_bss,  mst_text, mst_abs, mst_unknown};
+    = {mst_bss,  mst_file_text, mst_abs, mst_unknown};
+  static enum minimal_symbol_type types3[]
+    = {mst_file_data,  mst_solib_trampoline, mst_abs, mst_unknown};
+  static enum minimal_symbol_type types4[]
+    = {mst_file_bss,   mst_text, mst_abs, mst_unknown};
   enum minimal_symbol_type ourtype = types[class];
   enum minimal_symbol_type ourtype2 = types2[class];
+  enum minimal_symbol_type ourtype3 = types3[class];
+  enum minimal_symbol_type ourtype4 = types4[class];
 
   if (regexp != NULL)
     {
@@ -2630,24 +2702,38 @@ list_symbols (regexp, class, bpt)
        }
     }
 
-  /* Here, we search through the minimal symbol tables for functions that
-     match, and call find_pc_symtab on them to force their symbols to
-     be read.  The symbol will then be found during the scan of symtabs
-     below.  If find_pc_symtab fails, set found_misc so that we will
-     rescan to print any matching symbols without debug info.  */
+  /* Here, we search through the minimal symbol tables for functions
+     and variables that match, and force their symbols to be read.
+     This is in particular necessary for demangled variable names,
+     which are no longer put into the partial symbol tables.
+     The symbol will then be found during the scan of symtabs below.
+
+     For functions, find_pc_symtab should succeed if we have debug info
+     for the function, for variables we have to call lookup_symbol
+     to determine if the variable has debug info.
+     If the lookup fails, set found_misc so that we will rescan to print
+     any matching symbols without debug info.
+  */
 
-  if (class == 1)
+  if (class == 0 || class == 1)
     {
       ALL_MSYMBOLS (objfile, msymbol)
        {
          if (MSYMBOL_TYPE (msymbol) == ourtype ||
-             MSYMBOL_TYPE (msymbol) == ourtype2)
+             MSYMBOL_TYPE (msymbol) == ourtype2 ||
+             MSYMBOL_TYPE (msymbol) == ourtype3 ||
+             MSYMBOL_TYPE (msymbol) == ourtype4)
            {
              if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
                {
                  if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
                    {
-                     found_misc = 1;
+                     if (class == 1
+                         || lookup_symbol (SYMBOL_NAME (msymbol), 
+                                           (struct block *) NULL,
+                                           VAR_NAMESPACE,
+                                           0, (struct symtab **) NULL) == NULL)
+                       found_misc = 1;
                    }
                }
            }
@@ -2700,15 +2786,19 @@ list_symbols (regexp, class, bpt)
                               same name but in different files.  In order to
                               set breakpoints on all of them, we must give
                               both the file name and the function name to
-                              break_command.  */
+                              break_command.
+                              Quoting the symbol name gets rid of problems
+                              with mangled symbol names that contain
+                              CPLUS_MARKER characters.  */
                            char *string =
                              (char *) alloca (strlen (s->filename)
                                               + strlen (SYMBOL_NAME(sym))
-                                              + 2);
+                                              + 4);
                            strcpy (string, s->filename);
-                           strcat (string, ":");
+                           strcat (string, ":'");
                            strcat (string, SYMBOL_NAME(sym));
-                           break_command (string, 0);
+                           strcat (string, "'");
+                           break_command (string, from_tty);
                          }
                      }
                    else if (!found_in_file)
@@ -2766,7 +2856,9 @@ list_symbols (regexp, class, bpt)
       ALL_MSYMBOLS (objfile, msymbol)
        {
          if (MSYMBOL_TYPE (msymbol) == ourtype ||
-             MSYMBOL_TYPE (msymbol) == ourtype2)
+             MSYMBOL_TYPE (msymbol) == ourtype2 ||
+             MSYMBOL_TYPE (msymbol) == ourtype3 ||
+             MSYMBOL_TYPE (msymbol) == ourtype4)
            {
              if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
                {
@@ -2779,6 +2871,13 @@ list_symbols (regexp, class, bpt)
                                         (struct block *) NULL, VAR_NAMESPACE,
                                         0, (struct symtab **) NULL) == NULL)
                        {
+                          if (bpt)
+                            {
+                              break_command (SYMBOL_NAME (msymbol), from_tty);
+                              printf_filtered ("<function, no debug info> %s;\n",
+                                               SYMBOL_SOURCE_NAME (msymbol));
+                              continue;
+                            }
                          if (!found_in_file)
                            {
                              printf_filtered ("\nNon-debugging symbols:\n");
@@ -2800,7 +2899,7 @@ variables_info (regexp, from_tty)
      char *regexp;
      int from_tty;
 {
-  list_symbols (regexp, 0, 0);
+  list_symbols (regexp, 0, 0, from_tty);
 }
 
 static void
@@ -2808,7 +2907,7 @@ functions_info (regexp, from_tty)
      char *regexp;
      int from_tty;
 {
-  list_symbols (regexp, 1, 0);
+  list_symbols (regexp, 1, 0, from_tty);
 }
 
 static void
@@ -2816,7 +2915,7 @@ types_info (regexp, from_tty)
      char *regexp;
      int from_tty;
 {
-  list_symbols (regexp, 2, 0);
+  list_symbols (regexp, 2, 0, from_tty);
 }
 
 #if 0
@@ -2825,7 +2924,7 @@ static void
 methods_info (regexp)
      char *regexp;
 {
-  list_symbols (regexp, 3, 0);
+  list_symbols (regexp, 3, 0, from_tty);
 }
 #endif /* 0 */
 
@@ -2835,7 +2934,7 @@ rbreak_command (regexp, from_tty)
      char *regexp;
      int from_tty;
 {
-  list_symbols (regexp, 1, 1);
+  list_symbols (regexp, 1, 1, from_tty);
 }
 \f
 
@@ -2930,6 +3029,19 @@ completion_list_add_name (symname, sym_text, sym_text_len, text, word)
        strcat (new, symname);
       }
 
+    /* Recheck for duplicates if we intend to add a modified symbol.  */
+    if (word != sym_text)
+      {
+       for (i = 0; i < return_val_index; ++i)
+         {
+           if (STREQ (new, return_val[i]))
+             {
+               free (new);
+               return;
+             }
+         }
+      }
+
     if (return_val_index + 3 > return_val_size)
       {
        newsize = (return_val_size *= 2) * sizeof (char *);
@@ -3128,51 +3240,51 @@ make_symbol_completion_list (text, word)
   return (return_val);
 }
 
-\f
-#if 0
-/* Add the type of the symbol sym to the type of the current
-   function whose block we are in (assumed).  The type of
-   this current function is contained in *TYPE.
-   
-   This basically works as follows:  When we find a function
-   symbol (N_FUNC with a 'f' or 'F' in the symbol name), we record
-   a pointer to its type in the global in_function_type.  Every 
-   time we come across a parameter symbol ('p' in its name), then
-   this procedure adds the name and type of that parameter
-   to the function type pointed to by *TYPE.  (Which should correspond
-   to in_function_type if it was called correctly).
-
-   Note that since we are modifying a type, the result of 
-   lookup_function_type() should be memcpy()ed before calling
-   this.  When not in strict typing mode, the expression
-   evaluator can choose to ignore this.
-
-   Assumption:  All of a function's parameter symbols will
-   appear before another function symbol is found.  The parameters 
-   appear in the same order in the argument list as they do in the
-   symbol table. */
+/* Determine if PC is in the prologue of a function.  The prologue is the area
+   between the first instruction of a function, and the first executable line.
+   Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
+ */
 
-void
-add_param_to_type (type,sym)
-   struct type **type;
-   struct symbol *sym;
+int
+in_prologue (pc, func_start)
+     CORE_ADDR pc;
+     CORE_ADDR func_start;
 {
-   int num = ++(TYPE_NFIELDS(*type));
-
-   if(TYPE_NFIELDS(*type)-1)
-      TYPE_FIELDS(*type) = (struct field *)
-         (*current_objfile->xrealloc) ((char *)(TYPE_FIELDS(*type)),
-                                       num*sizeof(struct field));
-   else
-      TYPE_FIELDS(*type) = (struct field *)
-         (*current_objfile->xmalloc) (num*sizeof(struct field));
-   
-   TYPE_FIELD_BITPOS(*type,num-1) = num-1;
-   TYPE_FIELD_BITSIZE(*type,num-1) = 0;
-   TYPE_FIELD_TYPE(*type,num-1) = SYMBOL_TYPE(sym);
-   TYPE_FIELD_NAME(*type,num-1) = SYMBOL_NAME(sym);
+  struct symtab_and_line sal;
+  CORE_ADDR func_addr, func_end;
+
+  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+    goto nosyms;               /* Might be in prologue */
+
+  sal = find_pc_line (func_addr, 0);
+
+  if (sal.line == 0)
+    goto nosyms;
+
+  if (sal.end > func_addr
+      && sal.end <= func_end)  /* Is prologue in function? */
+    return pc < sal.end;       /* Yes, is pc in prologue? */
+
+  /* The line after the prologue seems to be outside the function.  In this
+     case, tell the caller to find the prologue the hard way.  */
+
+  return 1;
+
+/* Come here when symtabs don't contain line # info.  In this case, it is
+   likely that the user has stepped into a library function w/o symbols, or
+   is doing a stepi/nexti through code without symbols.  */
+
+ nosyms:
+
+/* We need to call the target-specific prologue skipping functions with the
+   function's start address because PC may be pointing at an instruction that
+   could be mistakenly considered part of the prologue.  */
+
+  SKIP_PROLOGUE (func_start);
+
+  return pc < func_start;
 }
-#endif 
+
 \f
 void
 _initialize_symtab ()
This page took 0.042295 seconds and 4 git commands to generate.