From f1ed43304a848d01f5a4c68a7b0f41990824f293 Mon Sep 17 00:00:00 2001 From: Jim Kingdon Date: Mon, 12 Jul 1993 03:42:35 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 17 ++++++ gdb/breakpoint.c | 2 +- gdb/printcmd.c | 58 +++--------------- gdb/source.c | 58 +++++++++++++----- gdb/symtab.c | 181 ++++++++++++++++++++++++++++++++++++++++--------------- gdb/symtab.h | 4 +- 6 files changed, 205 insertions(+), 115 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 66c5f11..8ba35ed 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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). diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 8ef00b7..94cbcd7 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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) { diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 191e573..48ced2a 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -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); } -/* 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 diff --git a/gdb/source.c b/gdb/source.c index 3ea5518..581eabc 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -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\ diff --git a/gdb/symtab.c b/gdb/symtab.c index 0de7b43..f8b2d81 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -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); } } diff --git a/gdb/symtab.h b/gdb/symtab.h index 489e4d9..76e359c 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -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)); -- 2.7.4