* 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.
This commit is contained in:
Jim Kingdon 1993-07-12 03:42:35 +00:00
parent f6365bd696
commit f1ed43304a
6 changed files with 205 additions and 115 deletions

View 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).

View 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)
{

View 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);
}
/* 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

View 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\

View 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);
}
}

View 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));