* symtab.c (decode_line_1): Use end of block to figure out whether
authorJim Kingdon <jkingdon@engr.sgi.com>
Mon, 12 Jul 1993 03:42:35 +0000 (03:42 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Mon, 12 Jul 1993 03:42:35 +0000 (03:42 +0000)
val.end is in the same function, not minimal symbols.

* source.c (line_info): Add a few more wrap_here's.

* i386-tdep.c (i386_follow_jump): Do byteswapping where needed and
don't make assumptions about sizes of host data types.

* blockframe.c, symtab.h (find_pc_partial_function): New arg endaddr.
* infrun.c, breakpoint.c, printcmd.c: Change callers.
* printcmd.c (containing_function_bounds): Remove.
* printcmd.c (disassemble_command): Use find_pc_partial_function,
not containing_function_bounds.
* infcmd.c (step_1): Use find_pc_partial_function rather than
trying to roll our own.  Move check for a pc between SIGTRAMP_START and
SIGTRAMP_END in find_pc_partial_function, not step_1.

gdb/ChangeLog
gdb/breakpoint.c
gdb/printcmd.c
gdb/source.c
gdb/symtab.c
gdb/symtab.h

index 66c5f11409c95b598a347786e6ceb8c454d6120f..8ba35ed55bdf8770eee8f86034ea575282a8acba 100644 (file)
@@ -1,5 +1,22 @@
 Sun Jul 11 19:35:05 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
+       * symtab.c (decode_line_1): Use end of block to figure out whether
+       val.end is in the same function, not minimal symbols.
+
+       * source.c (line_info): Add a few more wrap_here's.
+
+       * i386-tdep.c (i386_follow_jump): Do byteswapping where needed and
+       don't make assumptions about sizes of host data types.
+
+       * blockframe.c, symtab.h (find_pc_partial_function): New arg endaddr.
+       * infrun.c, breakpoint.c, printcmd.c: Change callers.
+       * printcmd.c (containing_function_bounds): Remove.
+       * printcmd.c (disassemble_command): Use find_pc_partial_function,
+       not containing_function_bounds.
+       * infcmd.c (step_1): Use find_pc_partial_function rather than
+       trying to roll our own.  Move check for a pc between SIGTRAMP_START and
+       SIGTRAMP_END in find_pc_partial_function, not step_1.
+
        * sparc-tdep.c (sparc_frame_chain, frame_saved_pc):
        Keep unswapped value in array of char, not REGISTER_TYPE.
        Use REGISTER_RAW_SIZE not sizeof (REGISTER_TYPE).
index 8ef00b7c594fa6ea8f95caecafbcc783fc7d549b..94cbcd7ebb349f513ea00e13c056a6e65ed6f545 100644 (file)
@@ -852,7 +852,7 @@ within_scope (valid_block)
   static CORE_ADDR callee_func_start;
   static CORE_ADDR callee_prologue_end;
   
-  find_pc_partial_function (fi->pc, (PTR)NULL, &func_start);
+  find_pc_partial_function (fi->pc, (PTR)NULL, &func_start, (CORE_ADDR *)NULL);
   func_start += FUNCTION_START_OFFSET;
   if (fi->pc == func_start)
     {
index 191e573ca9493d291969de23580a41200d27fc55..48ced2aeb90ba52a89c07cf74f1fd0bd43a97195 100644 (file)
@@ -32,12 +32,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "breakpoint.h"
 #include "demangle.h"
 
-/* These are just for containing_function_bounds.  It might be better
-   to move containing_function_bounds to blockframe.c or thereabouts.  */
-#include "bfd.h"
-#include "symfile.h"
-#include "objfiles.h"
-
 extern int asm_demangle;       /* Whether to demangle syms in asm printouts */
 extern int addressprint;       /* Whether to print hex addresses in HLL " */
 
@@ -128,9 +122,6 @@ disable_display_command PARAMS ((char *, int));
 static void
 disassemble_command PARAMS ((char *, int));
 
-static int
-containing_function_bounds PARAMS ((CORE_ADDR, CORE_ADDR *, CORE_ADDR *));
-
 static void
 printf_command PARAMS ((char *, int));
 
@@ -1904,41 +1895,6 @@ printf_command (arg, from_tty)
   vprintf (string, args_to_vprintf);
 }
 \f
-/* Helper function for asdump_command.  Finds the bounds of a function
-   for a specified section of text.  PC is an address within the
-   function which you want bounds for; *LOW and *HIGH are set to the
-   beginning (inclusive) and end (exclusive) of the function.  This
-   function returns 1 on success and 0 on failure.  */
-
-static int
-containing_function_bounds (pc, low, high)
-     CORE_ADDR pc, *low, *high;
-{
-  CORE_ADDR scan;
-  CORE_ADDR limit;
-  struct obj_section *sec;
-
-  if (!find_pc_partial_function (pc, 0, low))
-    return 0;
-
-  sec = find_pc_section (pc);
-  if (sec == NULL)
-    return 0;
-  limit = sec->endaddr;
-  
-  scan = *low;
-  while (scan < limit)
-    {
-      ++scan;
-      if (!find_pc_partial_function (scan, 0, high))
-       return 0;
-      if (*low != *high)
-       return 1;
-    }
-  *high = limit;
-  return 1;
-}
-
 /* Dump a specified section of assembly code.  With no command line
    arguments, this command will dump the assembly code for the
    function surrounding the pc value in the selected frame.  With one
@@ -1953,24 +1909,26 @@ disassemble_command (arg, from_tty)
      int from_tty;
 {
   CORE_ADDR low, high;
+  char *name;
   CORE_ADDR pc;
   char *space_index;
 
+  name = NULL;
   if (!arg)
     {
       if (!selected_frame)
        error ("No frame selected.\n");
 
       pc = get_frame_pc (selected_frame);
-      if (!containing_function_bounds (pc, &low, &high))
-       error ("No function contains pc specified by selected frame.\n");
+      if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+       error ("No function contains program counter for selected frame.\n");
     }
   else if (!(space_index = (char *) strchr (arg, ' ')))
     {
       /* One argument.  */
       pc = parse_and_eval_address (arg);
-      if (!containing_function_bounds (pc, &low, &high))
-       error ("No function contains specified pc.\n");
+      if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+       error ("No function contains specified address.\n");
     }
   else
     {
@@ -1981,10 +1939,8 @@ disassemble_command (arg, from_tty)
     }
 
   printf_filtered ("Dump of assembler code ");
-  if (!space_index)
+  if (name != NULL)
     {
-      char *name;
-      find_pc_partial_function (pc, &name, 0);
       printf_filtered ("for function %s:\n", name);
     }
   else
index 3ea5518e252e7413613ae332e00c0d91255df531..581eabcc84d7b249131a622edab6b84d9c71ea38 100644 (file)
@@ -351,10 +351,23 @@ mod_path (dirname, which_path)
 
       /* Unless it's a variable, check existence.  */
       if (name[0] != '$') {
+       /* These are warnings, not errors, since we don't want a
+          non-existent directory in a .gdbinit file to stop processing
+          of the .gdbinit file.
+
+          Whether they get added to the path is more debatable.  Current
+          answer is yes, in case the user wants to go make the directory
+          or whatever.  If the directory continues to not exist/not be
+          a directory/etc, then having them in the path should be
+          harmless.  */
        if (stat (name, &st) < 0)
-         perror_with_name (name);
-       if ((st.st_mode & S_IFMT) != S_IFDIR)
-         error ("%s is not a directory.", name);
+         {
+           int save_errno = errno;
+           fprintf (stderr, "Warning: ");
+           print_sys_errmsg (name, save_errno);
+         }
+       else if ((st.st_mode & S_IFMT) != S_IFDIR)
+         warning ("%s is not a directory.", name);
       }
 
     append:
@@ -788,8 +801,9 @@ identify_source_line (s, line, mid_statement, pc)
     get_filename_and_charpos (s, (char **)NULL);
   if (s->fullname == 0)
     return 0;
-  if (line >= s->nlines) 
-   return 0;
+  if (line > s->nlines)
+    /* Don't index off the end of the line_charpos array.  */
+    return 0;
   printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname,
          line, s->line_charpos[line - 1],
          mid_statement ? "middle" : "beg",
@@ -1112,18 +1126,31 @@ line_info (arg, from_tty)
          && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
        {
          if (start_pc == end_pc)
-           printf_filtered ("Line %d of \"%s\" is at pc %s but contains no code.\n",
-                            sal.line, sal.symtab->filename, local_hex_string(start_pc));
+           {
+             printf_filtered ("Line %d of \"%s\"",
+                              sal.line, sal.symtab->filename);
+             wrap_here ("  ");
+             printf_filtered (" is at address ");
+             print_address (start_pc, stdout);
+             wrap_here ("  ");
+             printf_filtered (" but contains no code.\n");
+           }
          else
            {
-             printf_filtered ("Line %d of \"%s\" starts at pc %s",
-                              sal.line, sal.symtab->filename, 
-                              local_hex_string(start_pc));
-             printf_filtered (" and ends at %s.\n",
-                              local_hex_string(end_pc));
+             printf_filtered ("Line %d of \"%s\"",
+                              sal.line, sal.symtab->filename);
+             wrap_here ("  ");
+             printf_filtered (" starts at address ");
+             print_address (start_pc, stdout);
+             wrap_here ("  ");
+             printf_filtered (" and ends at ");
+             print_address (end_pc, stdout);
+             printf_filtered (".\n");
            }
+
          /* x/i should display this line's code.  */
          set_next_address (start_pc);
+
          /* Repeating "info line" should do the following line.  */
          last_line_listed = sal.line + 1;
 
@@ -1297,15 +1324,18 @@ reverse_search_command (regex, from_tty)
 void
 _initialize_source ()
 {
+  struct cmd_list_element *c;
   current_source_symtab = 0;
   init_source_path ();
 
-  add_com ("directory", class_files, directory_command,
+  c = add_cmd ("directory", class_files, directory_command,
           "Add directory DIR to beginning of search path for source files.\n\
 Forget cached info on source file locations and line positions.\n\
 DIR can also be $cwd for the current working directory, or $cdir for the\n\
 directory in which the source file was compiled into object code.\n\
-With no argument, reset the search path to $cdir:$cwd, the default.");
+With no argument, reset the search path to $cdir:$cwd, the default.",
+              &cmdlist);
+  c->completer = filename_completer;
 
   add_cmd ("directories", no_class, show_directories,
           "Current search path for finding source files.\n\
index 0de7b434b2d60c82b0cc0b84f2cb668f36d7cc3d..f8b2d81324bd4930c876f1e2cbc661f51b75993c 100644 (file)
@@ -49,7 +49,7 @@ extern int
 find_methods PARAMS ((struct type *, char *, struct symbol **));
 
 static void
-completion_list_add_name PARAMS ((char *, char *, int));
+completion_list_add_name PARAMS ((char *, char *, int, char *, char *));
 
 static struct symtabs_and_lines
 decode_line_2 PARAMS ((struct symbol *[], int, int));
@@ -836,11 +836,13 @@ lookup_block_symbol (block, name, namespace)
            }
        }
 
-      /* Now scan forward until we run out of symbols, find one whose name is
-        greater than NAME, or find one we want.  If there is more than one
-        symbol with the right name and namespace, we return the first one.
-        dbxread.c is careful to make sure that if one is a register then it
-        comes first.  */
+      /* Now scan forward until we run out of symbols, find one whose
+        name is greater than NAME, or find one we want.  If there is
+        more than one symbol with the right name and namespace, we
+        return the first one; I believe it is now impossible for us
+        to encounter two symbols with the same name and namespace
+        here, because blocks containing argument symbols are no
+        longer sorted.  */
 
       top = BLOCK_NSYMS (block);
       while (bot < top)
@@ -890,7 +892,8 @@ lookup_block_symbol (block, name, namespace)
              if (SYMBOL_CLASS (sym) != LOC_ARG &&
                  SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
                  SYMBOL_CLASS (sym) != LOC_REF_ARG &&
-                 SYMBOL_CLASS (sym) != LOC_REGPARM)
+                 SYMBOL_CLASS (sym) != LOC_REGPARM &&
+                 SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR)
                {
                  break;
                }
@@ -1592,7 +1595,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                    {
                      warning ("no mangling for \"%s\"", tmp);
                      cplusplus_hint (saved_arg);
-                     return_to_top_level ();
+                     return_to_top_level (RETURN_ERROR);
                    }
                  copy = (char*) alloca (3 + strlen(opname));
                  sprintf (copy, "__%s", opname);
@@ -1682,7 +1685,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                    warning ("the class %s does not have any method named %s",
                             SYMBOL_SOURCE_NAME(sym_class), tmp);
                  cplusplus_hint (saved_arg);
-                 return_to_top_level ();
+                 return_to_top_level (RETURN_ERROR);
                }
            }
          else
@@ -1691,7 +1694,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
              warning ("can't find class, struct, or union named \"%s\"",
                       copy);
              cplusplus_hint (saved_arg);
-             return_to_top_level ();
+             return_to_top_level (RETURN_ERROR);
            }
        }
       /*  end of C++  */
@@ -1821,15 +1824,17 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
          /* Convex: no need to suppress code on first line, if any */
          val.pc = pc;
 #else
-         /* If SKIP_PROLOGUE left us in mid-line, and the next line is still
-            part of the same function:
-               advance to next line, 
-               recalculate its line number (might not be N+1).  */
-         if (val.pc != pc && val.end &&
-             lookup_minimal_symbol_by_pc (pc) == lookup_minimal_symbol_by_pc (val.end)) {
-           pc = val.end;       /* First pc of next line */
-           val = find_pc_line (pc, 0);
-         }
+         /* 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));
@@ -1859,6 +1864,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
       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);
     }
 
@@ -2450,29 +2457,33 @@ static int return_val_size;
 static int return_val_index;
 static char **return_val;
 
-#define COMPLETION_LIST_ADD_SYMBOL(symbol, text, len) \
+#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
   do { \
-    completion_list_add_name (SYMBOL_NAME (symbol), text, len); \
-      if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
-      completion_list_add_name (SYMBOL_DEMANGLED_NAME (symbol), text, len); \
+    completion_list_add_name (SYMBOL_NAME (symbol), (sym_text), (len), \
+                             (text), (word)); \
+    if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
+      completion_list_add_name \
+       (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
   } while (0)
 
 /*  Test to see if the symbol specified by SYMNAME (which is already
-    demangled for C++ symbols) matches TEXT in the first TEXT_LEN
+    demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
     characters.  If so, add it to the current completion list. */
 
 static void
-completion_list_add_name (symname, text, text_len)
+completion_list_add_name (symname, sym_text, sym_text_len, text, word)
      char *symname;
+     char *sym_text;
+     int sym_text_len;
      char *text;
-     int text_len;
+     char *word;
 {
   int newsize;
   int i;
 
   /* clip symbols that cannot match */
 
-  if (strncmp (symname, text, text_len) != 0)
+  if (strncmp (symname, sym_text, sym_text_len) != 0)
     {
       return;
     }
@@ -2491,14 +2502,36 @@ completion_list_add_name (symname, text, text_len)
   /* We have a match for a completion, so add SYMNAME to the current list
      of matches. Note that the name is moved to freshly malloc'd space. */
 
-  symname = savestring (symname, strlen (symname));
-  if (return_val_index + 3 > return_val_size)
-    {
-      newsize = (return_val_size *= 2) * sizeof (char *);
-      return_val = (char **) xrealloc ((char *) return_val, newsize);
-    }
-  return_val[return_val_index++] = symname;
-  return_val[return_val_index] = NULL;
+  {
+    char *new;
+    if (word == sym_text)
+      {
+       new = xmalloc (strlen (symname) + 5);
+       strcpy (new, symname);
+      }
+    else if (word > sym_text)
+      {
+       /* Return some portion of symname.  */
+       new = xmalloc (strlen (symname) + 5);
+       strcpy (new, symname + (word - sym_text));
+      }
+    else
+      {
+       /* Return some of SYM_TEXT plus symname.  */
+       new = xmalloc (strlen (symname) + (sym_text - word) + 5);
+       strncpy (new, word, sym_text - word);
+       new[sym_text - word] = '\0';
+       strcat (new, symname);
+      }
+
+    if (return_val_index + 3 > return_val_size)
+      {
+       newsize = (return_val_size *= 2) * sizeof (char *);
+       return_val = (char **) xrealloc ((char *) return_val, newsize);
+      }
+    return_val[return_val_index++] = new;
+    return_val[return_val_index] = NULL;
+  }
 }
 
 /* Return a NULL terminated array of all symbols (regardless of class) which
@@ -2509,8 +2542,9 @@ completion_list_add_name (symname, text, text_len)
    I'm not going to worry about this; hopefully there won't be that many.  */
 
 char **
-make_symbol_completion_list (text)
-  char *text;
+make_symbol_completion_list (text, word)
+     char *text;
+     char *word;
 {
   register struct symbol *sym;
   register struct symtab *s;
@@ -2519,17 +2553,70 @@ make_symbol_completion_list (text)
   register struct objfile *objfile;
   register struct block *b, *surrounding_static_block = 0;
   register int i, j;
-  int text_len;
   struct partial_symbol *psym;
+  /* The symbol we are completing on.  Points in same buffer as text.  */
+  char *sym_text;
+  /* Length of sym_text.  */
+  int sym_text_len;
+
+  /* Now look for the symbol we are supposed to complete on.
+     FIXME: This should be language-specific.  */
+  {
+    char *p;
+    char quote_found;
+    char *quote_pos;
+
+    /* First see if this is a quoted string.  */
+    quote_found = '\0';
+    for (p = text; *p != '\0'; ++p)
+      {
+       if (quote_found != '\0')
+         {
+           if (*p == quote_found)
+             /* Found close quote.  */
+             quote_found = '\0';
+           else if (*p == '\\' && p[1] == quote_found)
+             /* A backslash followed by the quote character
+                doesn't end the string.  */
+             ++p;
+         }
+       else if (*p == '\'' || *p == '"')
+         {
+           quote_found = *p;
+           quote_pos = p;
+         }
+      }
+    if (quote_found == '\'')
+      /* A string within single quotes can be a symbol, so complete on it.  */
+      sym_text = quote_pos + 1;
+    else if (quote_found == '"')
+      /* A double-quoted string is never a symbol, nor does it make sense
+        to complete it any other way.  */
+      return NULL;
+    else
+      {
+       /* It is not a quoted string.  Break it based on the characters
+          which are in symbols.  */
+       while (p > text)
+         {
+           if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+             --p;
+           else
+             break;
+         }
+       sym_text = p;
+      }
+  }
+
+  sym_text_len = strlen (sym_text);
 
-  text_len = strlen (text);
   return_val_size = 100;
   return_val_index = 0;
   return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
   return_val[0] = NULL;
 
   /* Look through the partial symtabs for all symbols which begin
-     by matching TEXT.  Add each one that you find to the list.  */
+     by matching SYM_TEXT.  Add each one that you find to the list.  */
 
   ALL_PSYMTABS (objfile, ps)
     {
@@ -2544,7 +2631,7 @@ make_symbol_completion_list (text)
        {
          /* If interrupted, then quit. */
          QUIT;
-         COMPLETION_LIST_ADD_SYMBOL (psym, text, text_len);
+         COMPLETION_LIST_ADD_SYMBOL (psym, sym_text, sym_text_len, text, word);
        }
       
       for (psym = objfile->static_psymbols.list + ps->statics_offset;
@@ -2553,7 +2640,7 @@ make_symbol_completion_list (text)
           psym++)
        {
          QUIT;
-         COMPLETION_LIST_ADD_SYMBOL (psym, text, text_len);
+         COMPLETION_LIST_ADD_SYMBOL (psym, sym_text, sym_text_len, text, word);
        }
     }
 
@@ -2565,7 +2652,7 @@ make_symbol_completion_list (text)
   ALL_MSYMBOLS (objfile, msymbol)
     {
       QUIT;
-      COMPLETION_LIST_ADD_SYMBOL (msymbol, text, text_len);
+      COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
     }
 
   /* Search upwards from currently selected frame (so that we can
@@ -2584,7 +2671,7 @@ make_symbol_completion_list (text)
       for (i = 0; i < BLOCK_NSYMS (b); i++)
        {
          sym = BLOCK_SYM (b, i);
-         COMPLETION_LIST_ADD_SYMBOL (sym, text, text_len);
+         COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
          if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
            {
              struct type *t = SYMBOL_TYPE (sym);
@@ -2597,7 +2684,7 @@ make_symbol_completion_list (text)
                      if (TYPE_FIELD_NAME (t, j))
                        {
                          completion_list_add_name (TYPE_FIELD_NAME (t, j),
-                                                     text, text_len);
+                                                     sym_text, sym_text_len, text, word);
                        }
                    }
                }
@@ -2615,7 +2702,7 @@ make_symbol_completion_list (text)
       for (i = 0; i < BLOCK_NSYMS (b); i++)
        {
          sym = BLOCK_SYM (b, i);
-         COMPLETION_LIST_ADD_SYMBOL (sym, text, text_len);
+         COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
        }
     }
 
@@ -2628,7 +2715,7 @@ make_symbol_completion_list (text)
       for (i = 0; i < BLOCK_NSYMS (b); i++)
        {
          sym = BLOCK_SYM (b, i);
-         COMPLETION_LIST_ADD_SYMBOL (sym, text, text_len);
+         COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
        }
     }
 
index 489e4d91ecb719c43545e528bd89e8644f955b5b..76e359c127def97e37a0f308738c4518231e4104 100644 (file)
@@ -938,8 +938,8 @@ block_function PARAMS ((struct block *));
 extern struct symbol *
 find_pc_function PARAMS ((CORE_ADDR));
 
-extern int
-find_pc_partial_function PARAMS ((CORE_ADDR, char **, CORE_ADDR *));
+extern int find_pc_partial_function
+  PARAMS ((CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *));
 
 extern void
 clear_pc_function_cache PARAMS ((void));