mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 02:24:46 +08:00
2003-06-09 Andrew Cagney <cagney@redhat.com>
* printcmd.c (print_frame_nameless_args): Moved to "stack.c". (print_frame_args): Moved to "stack.c". * stack.c: Include "gdb_assert.h". (print_frame_nameless_args): Moved from "printcmd.c", made static. (print_frame_args): Moved from "printcmd.c". * frame.h (print_frame_args): Delete declaration. * Makefile.in (stack.o): Update dependencies.
This commit is contained in:
parent
4b7ffdb2af
commit
8d3b0994cd
@ -1,3 +1,13 @@
|
||||
2003-06-09 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* printcmd.c (print_frame_nameless_args): Moved to "stack.c".
|
||||
(print_frame_args): Moved to "stack.c".
|
||||
* stack.c: Include "gdb_assert.h".
|
||||
(print_frame_nameless_args): Moved from "printcmd.c", made static.
|
||||
(print_frame_args): Moved from "printcmd.c".
|
||||
* frame.h (print_frame_args): Delete declaration.
|
||||
* Makefile.in (stack.o): Update dependencies.
|
||||
|
||||
2003-06-08 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* frame.c (get_prev_frame): Remove reference to
|
||||
|
@ -2265,7 +2265,8 @@ stabsread.o: stabsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(gdb_obstack_h) \
|
||||
stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \
|
||||
$(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_h) \
|
||||
$(gdbcore_h) $(target_h) $(source_h) $(breakpoint_h) $(demangle_h) \
|
||||
$(inferior_h) $(annotate_h) $(ui_out_h) $(block_h) $(stack_h)
|
||||
$(inferior_h) $(annotate_h) $(ui_out_h) $(block_h) $(stack_h) \
|
||||
$(gdb_assert_h)
|
||||
standalone.o: standalone.c $(gdb_stat_h) $(defs_h) $(symtab_h) $(frame_h) \
|
||||
$(inferior_h) $(gdb_wait_h)
|
||||
std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) $(gdbtypes_h) \
|
||||
|
@ -458,9 +458,6 @@ extern CORE_ADDR get_pc_function_start (CORE_ADDR);
|
||||
|
||||
extern int frameless_look_for_prologue (struct frame_info *);
|
||||
|
||||
extern void print_frame_args (struct symbol *, struct frame_info *,
|
||||
int, struct ui_file *);
|
||||
|
||||
extern struct frame_info *find_relative_frame (struct frame_info *, int *);
|
||||
|
||||
extern void show_and_print_stack_frame (struct frame_info *fi, int level,
|
||||
|
225
gdb/printcmd.c
225
gdb/printcmd.c
@ -140,9 +140,6 @@ static void disable_display_command (char *, int);
|
||||
|
||||
static void printf_command (char *, int);
|
||||
|
||||
static void print_frame_nameless_args (struct frame_info *, long,
|
||||
int, int, struct ui_file *);
|
||||
|
||||
static void display_info (char *, int);
|
||||
|
||||
static void do_one_display (struct display *);
|
||||
@ -1745,228 +1742,6 @@ print_variable_value (struct symbol *var, struct frame_info *frame,
|
||||
value_print (val, stream, 0, Val_pretty_default);
|
||||
}
|
||||
|
||||
/* Print the arguments of a stack frame, given the function FUNC
|
||||
running in that frame (as a symbol), the info on the frame,
|
||||
and the number of args according to the stack frame (or -1 if unknown). */
|
||||
|
||||
/* References here and elsewhere to "number of args according to the
|
||||
stack frame" appear in all cases to refer to "number of ints of args
|
||||
according to the stack frame". At least for VAX, i386, isi. */
|
||||
|
||||
void
|
||||
print_frame_args (struct symbol *func, struct frame_info *fi, int num,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
struct block *b = NULL;
|
||||
int first = 1;
|
||||
register int i;
|
||||
register struct symbol *sym;
|
||||
struct value *val;
|
||||
/* Offset of next stack argument beyond the one we have seen that is
|
||||
at the highest offset.
|
||||
-1 if we haven't come to a stack argument yet. */
|
||||
long highest_offset = -1;
|
||||
int arg_size;
|
||||
/* Number of ints of arguments that we have printed so far. */
|
||||
int args_printed = 0;
|
||||
struct cleanup *old_chain, *list_chain;
|
||||
struct ui_stream *stb;
|
||||
|
||||
stb = ui_out_stream_new (uiout);
|
||||
old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||
|
||||
if (func)
|
||||
{
|
||||
b = SYMBOL_BLOCK_VALUE (func);
|
||||
/* Function blocks are order sensitive, and thus should not be
|
||||
hashed. */
|
||||
gdb_assert (BLOCK_HASHTABLE (b) == 0);
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, i, sym)
|
||||
{
|
||||
QUIT;
|
||||
|
||||
/* Keep track of the highest stack argument offset seen, and
|
||||
skip over any kinds of symbols we don't care about. */
|
||||
|
||||
switch (SYMBOL_CLASS (sym))
|
||||
{
|
||||
case LOC_ARG:
|
||||
case LOC_REF_ARG:
|
||||
{
|
||||
long current_offset = SYMBOL_VALUE (sym);
|
||||
arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym));
|
||||
|
||||
/* Compute address of next argument by adding the size of
|
||||
this argument and rounding to an int boundary. */
|
||||
current_offset =
|
||||
((current_offset + arg_size + sizeof (int) - 1)
|
||||
& ~(sizeof (int) - 1));
|
||||
|
||||
/* If this is the highest offset seen yet, set highest_offset. */
|
||||
if (highest_offset == -1
|
||||
|| (current_offset > highest_offset))
|
||||
highest_offset = current_offset;
|
||||
|
||||
/* Add the number of ints we're about to print to args_printed. */
|
||||
args_printed += (arg_size + sizeof (int) - 1) / sizeof (int);
|
||||
}
|
||||
|
||||
/* We care about types of symbols, but don't need to keep track of
|
||||
stack offsets in them. */
|
||||
case LOC_REGPARM:
|
||||
case LOC_REGPARM_ADDR:
|
||||
case LOC_LOCAL_ARG:
|
||||
case LOC_BASEREG_ARG:
|
||||
case LOC_COMPUTED_ARG:
|
||||
break;
|
||||
|
||||
/* Other types of symbols we just skip over. */
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have to look up the symbol because arguments can have
|
||||
two entries (one a parameter, one a local) and the one we
|
||||
want is the local, which lookup_symbol will find for us.
|
||||
This includes gcc1 (not gcc2) on the sparc when passing a
|
||||
small structure and gcc2 when the argument type is float
|
||||
and it is passed as a double and converted to float by
|
||||
the prologue (in the latter case the type of the LOC_ARG
|
||||
symbol is double and the type of the LOC_LOCAL symbol is
|
||||
float). */
|
||||
/* But if the parameter name is null, don't try it.
|
||||
Null parameter names occur on the RS/6000, for traceback tables.
|
||||
FIXME, should we even print them? */
|
||||
|
||||
if (*DEPRECATED_SYMBOL_NAME (sym))
|
||||
{
|
||||
struct symbol *nsym;
|
||||
nsym = lookup_symbol
|
||||
(DEPRECATED_SYMBOL_NAME (sym),
|
||||
b, VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL);
|
||||
if (SYMBOL_CLASS (nsym) == LOC_REGISTER)
|
||||
{
|
||||
/* There is a LOC_ARG/LOC_REGISTER pair. This means that
|
||||
it was passed on the stack and loaded into a register,
|
||||
or passed in a register and stored in a stack slot.
|
||||
GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER.
|
||||
|
||||
Reasons for using the LOC_ARG:
|
||||
(1) because find_saved_registers may be slow for remote
|
||||
debugging,
|
||||
(2) because registers are often re-used and stack slots
|
||||
rarely (never?) are. Therefore using the stack slot is
|
||||
much less likely to print garbage.
|
||||
|
||||
Reasons why we might want to use the LOC_REGISTER:
|
||||
(1) So that the backtrace prints the same value as
|
||||
"print foo". I see no compelling reason why this needs
|
||||
to be the case; having the backtrace print the value which
|
||||
was passed in, and "print foo" print the value as modified
|
||||
within the called function, makes perfect sense to me.
|
||||
|
||||
Additional note: It might be nice if "info args" displayed
|
||||
both values.
|
||||
One more note: There is a case with sparc structure passing
|
||||
where we need to use the LOC_REGISTER, but this is dealt with
|
||||
by creating a single LOC_REGPARM in symbol reading. */
|
||||
|
||||
/* Leave sym (the LOC_ARG) alone. */
|
||||
;
|
||||
}
|
||||
else
|
||||
sym = nsym;
|
||||
}
|
||||
|
||||
/* Print the current arg. */
|
||||
if (!first)
|
||||
ui_out_text (uiout, ", ");
|
||||
ui_out_wrap_hint (uiout, " ");
|
||||
|
||||
annotate_arg_begin ();
|
||||
|
||||
list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (sym),
|
||||
SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI);
|
||||
ui_out_field_stream (uiout, "name", stb);
|
||||
annotate_arg_name_end ();
|
||||
ui_out_text (uiout, "=");
|
||||
|
||||
/* Avoid value_print because it will deref ref parameters. We just
|
||||
want to print their addresses. Print ??? for args whose address
|
||||
we do not know. We pass 2 as "recurse" to val_print because our
|
||||
standard indentation here is 4 spaces, and val_print indents
|
||||
2 for each recurse. */
|
||||
val = read_var_value (sym, fi);
|
||||
|
||||
annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val));
|
||||
|
||||
if (val)
|
||||
{
|
||||
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
|
||||
VALUE_ADDRESS (val),
|
||||
stb->stream, 0, 0, 2, Val_no_prettyprint);
|
||||
ui_out_field_stream (uiout, "value", stb);
|
||||
}
|
||||
else
|
||||
ui_out_text (uiout, "???");
|
||||
|
||||
/* Invoke ui_out_tuple_end. */
|
||||
do_cleanups (list_chain);
|
||||
|
||||
annotate_arg_end ();
|
||||
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't print nameless args in situations where we don't know
|
||||
enough about the stack to find them. */
|
||||
if (num != -1)
|
||||
{
|
||||
long start;
|
||||
|
||||
if (highest_offset == -1)
|
||||
start = FRAME_ARGS_SKIP;
|
||||
else
|
||||
start = highest_offset;
|
||||
|
||||
print_frame_nameless_args (fi, start, num - args_printed,
|
||||
first, stream);
|
||||
}
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Print nameless args on STREAM.
|
||||
FI is the frameinfo for this frame, START is the offset
|
||||
of the first nameless arg, and NUM is the number of nameless args to
|
||||
print. FIRST is nonzero if this is the first argument (not just
|
||||
the first nameless arg). */
|
||||
|
||||
static void
|
||||
print_frame_nameless_args (struct frame_info *fi, long start, int num,
|
||||
int first, struct ui_file *stream)
|
||||
{
|
||||
int i;
|
||||
CORE_ADDR argsaddr;
|
||||
long arg_value;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
QUIT;
|
||||
argsaddr = get_frame_args_address (fi);
|
||||
if (!argsaddr)
|
||||
return;
|
||||
arg_value = read_memory_integer (argsaddr + start, sizeof (int));
|
||||
if (!first)
|
||||
fprintf_filtered (stream, ", ");
|
||||
fprintf_filtered (stream, "%ld", arg_value);
|
||||
first = 0;
|
||||
start += sizeof (int);
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
printf_command (char *arg, int from_tty)
|
||||
|
223
gdb/stack.c
223
gdb/stack.c
@ -41,6 +41,7 @@
|
||||
#include "ui-out.h"
|
||||
#include "block.h"
|
||||
#include "stack.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
/* Prototypes for exported functions. */
|
||||
|
||||
@ -167,6 +168,228 @@ struct print_args_args
|
||||
|
||||
static int print_args_stub (void *);
|
||||
|
||||
/* Print nameless args on STREAM.
|
||||
FI is the frameinfo for this frame, START is the offset
|
||||
of the first nameless arg, and NUM is the number of nameless args to
|
||||
print. FIRST is nonzero if this is the first argument (not just
|
||||
the first nameless arg). */
|
||||
|
||||
static void
|
||||
print_frame_nameless_args (struct frame_info *fi, long start, int num,
|
||||
int first, struct ui_file *stream)
|
||||
{
|
||||
int i;
|
||||
CORE_ADDR argsaddr;
|
||||
long arg_value;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
QUIT;
|
||||
argsaddr = get_frame_args_address (fi);
|
||||
if (!argsaddr)
|
||||
return;
|
||||
arg_value = read_memory_integer (argsaddr + start, sizeof (int));
|
||||
if (!first)
|
||||
fprintf_filtered (stream, ", ");
|
||||
fprintf_filtered (stream, "%ld", arg_value);
|
||||
first = 0;
|
||||
start += sizeof (int);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the arguments of a stack frame, given the function FUNC
|
||||
running in that frame (as a symbol), the info on the frame,
|
||||
and the number of args according to the stack frame (or -1 if unknown). */
|
||||
|
||||
/* References here and elsewhere to "number of args according to the
|
||||
stack frame" appear in all cases to refer to "number of ints of args
|
||||
according to the stack frame". At least for VAX, i386, isi. */
|
||||
|
||||
static void
|
||||
print_frame_args (struct symbol *func, struct frame_info *fi, int num,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
struct block *b = NULL;
|
||||
int first = 1;
|
||||
register int i;
|
||||
register struct symbol *sym;
|
||||
struct value *val;
|
||||
/* Offset of next stack argument beyond the one we have seen that is
|
||||
at the highest offset.
|
||||
-1 if we haven't come to a stack argument yet. */
|
||||
long highest_offset = -1;
|
||||
int arg_size;
|
||||
/* Number of ints of arguments that we have printed so far. */
|
||||
int args_printed = 0;
|
||||
struct cleanup *old_chain, *list_chain;
|
||||
struct ui_stream *stb;
|
||||
|
||||
stb = ui_out_stream_new (uiout);
|
||||
old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||
|
||||
if (func)
|
||||
{
|
||||
b = SYMBOL_BLOCK_VALUE (func);
|
||||
/* Function blocks are order sensitive, and thus should not be
|
||||
hashed. */
|
||||
gdb_assert (BLOCK_HASHTABLE (b) == 0);
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, i, sym)
|
||||
{
|
||||
QUIT;
|
||||
|
||||
/* Keep track of the highest stack argument offset seen, and
|
||||
skip over any kinds of symbols we don't care about. */
|
||||
|
||||
switch (SYMBOL_CLASS (sym))
|
||||
{
|
||||
case LOC_ARG:
|
||||
case LOC_REF_ARG:
|
||||
{
|
||||
long current_offset = SYMBOL_VALUE (sym);
|
||||
arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym));
|
||||
|
||||
/* Compute address of next argument by adding the size of
|
||||
this argument and rounding to an int boundary. */
|
||||
current_offset =
|
||||
((current_offset + arg_size + sizeof (int) - 1)
|
||||
& ~(sizeof (int) - 1));
|
||||
|
||||
/* If this is the highest offset seen yet, set highest_offset. */
|
||||
if (highest_offset == -1
|
||||
|| (current_offset > highest_offset))
|
||||
highest_offset = current_offset;
|
||||
|
||||
/* Add the number of ints we're about to print to args_printed. */
|
||||
args_printed += (arg_size + sizeof (int) - 1) / sizeof (int);
|
||||
}
|
||||
|
||||
/* We care about types of symbols, but don't need to keep track of
|
||||
stack offsets in them. */
|
||||
case LOC_REGPARM:
|
||||
case LOC_REGPARM_ADDR:
|
||||
case LOC_LOCAL_ARG:
|
||||
case LOC_BASEREG_ARG:
|
||||
case LOC_COMPUTED_ARG:
|
||||
break;
|
||||
|
||||
/* Other types of symbols we just skip over. */
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have to look up the symbol because arguments can have
|
||||
two entries (one a parameter, one a local) and the one we
|
||||
want is the local, which lookup_symbol will find for us.
|
||||
This includes gcc1 (not gcc2) on the sparc when passing a
|
||||
small structure and gcc2 when the argument type is float
|
||||
and it is passed as a double and converted to float by
|
||||
the prologue (in the latter case the type of the LOC_ARG
|
||||
symbol is double and the type of the LOC_LOCAL symbol is
|
||||
float). */
|
||||
/* But if the parameter name is null, don't try it.
|
||||
Null parameter names occur on the RS/6000, for traceback tables.
|
||||
FIXME, should we even print them? */
|
||||
|
||||
if (*DEPRECATED_SYMBOL_NAME (sym))
|
||||
{
|
||||
struct symbol *nsym;
|
||||
nsym = lookup_symbol
|
||||
(DEPRECATED_SYMBOL_NAME (sym),
|
||||
b, VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL);
|
||||
if (SYMBOL_CLASS (nsym) == LOC_REGISTER)
|
||||
{
|
||||
/* There is a LOC_ARG/LOC_REGISTER pair. This means that
|
||||
it was passed on the stack and loaded into a register,
|
||||
or passed in a register and stored in a stack slot.
|
||||
GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER.
|
||||
|
||||
Reasons for using the LOC_ARG:
|
||||
(1) because find_saved_registers may be slow for remote
|
||||
debugging,
|
||||
(2) because registers are often re-used and stack slots
|
||||
rarely (never?) are. Therefore using the stack slot is
|
||||
much less likely to print garbage.
|
||||
|
||||
Reasons why we might want to use the LOC_REGISTER:
|
||||
(1) So that the backtrace prints the same value as
|
||||
"print foo". I see no compelling reason why this needs
|
||||
to be the case; having the backtrace print the value which
|
||||
was passed in, and "print foo" print the value as modified
|
||||
within the called function, makes perfect sense to me.
|
||||
|
||||
Additional note: It might be nice if "info args" displayed
|
||||
both values.
|
||||
One more note: There is a case with sparc structure passing
|
||||
where we need to use the LOC_REGISTER, but this is dealt with
|
||||
by creating a single LOC_REGPARM in symbol reading. */
|
||||
|
||||
/* Leave sym (the LOC_ARG) alone. */
|
||||
;
|
||||
}
|
||||
else
|
||||
sym = nsym;
|
||||
}
|
||||
|
||||
/* Print the current arg. */
|
||||
if (!first)
|
||||
ui_out_text (uiout, ", ");
|
||||
ui_out_wrap_hint (uiout, " ");
|
||||
|
||||
annotate_arg_begin ();
|
||||
|
||||
list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (sym),
|
||||
SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI);
|
||||
ui_out_field_stream (uiout, "name", stb);
|
||||
annotate_arg_name_end ();
|
||||
ui_out_text (uiout, "=");
|
||||
|
||||
/* Avoid value_print because it will deref ref parameters. We just
|
||||
want to print their addresses. Print ??? for args whose address
|
||||
we do not know. We pass 2 as "recurse" to val_print because our
|
||||
standard indentation here is 4 spaces, and val_print indents
|
||||
2 for each recurse. */
|
||||
val = read_var_value (sym, fi);
|
||||
|
||||
annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val));
|
||||
|
||||
if (val)
|
||||
{
|
||||
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
|
||||
VALUE_ADDRESS (val),
|
||||
stb->stream, 0, 0, 2, Val_no_prettyprint);
|
||||
ui_out_field_stream (uiout, "value", stb);
|
||||
}
|
||||
else
|
||||
ui_out_text (uiout, "???");
|
||||
|
||||
/* Invoke ui_out_tuple_end. */
|
||||
do_cleanups (list_chain);
|
||||
|
||||
annotate_arg_end ();
|
||||
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't print nameless args in situations where we don't know
|
||||
enough about the stack to find them. */
|
||||
if (num != -1)
|
||||
{
|
||||
long start;
|
||||
|
||||
if (highest_offset == -1)
|
||||
start = FRAME_ARGS_SKIP;
|
||||
else
|
||||
start = highest_offset;
|
||||
|
||||
print_frame_nameless_args (fi, start, num - args_printed,
|
||||
first, stream);
|
||||
}
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Pass the args the way catch_errors wants them. */
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user