From 8d3b0994cd3d164c1fa5bce161ba26cb8e079ac2 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Mon, 9 Jun 2003 15:20:21 +0000 Subject: [PATCH] 2003-06-09 Andrew Cagney * 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. --- gdb/ChangeLog | 10 +++ gdb/Makefile.in | 3 +- gdb/frame.h | 3 - gdb/printcmd.c | 225 ------------------------------------------------ gdb/stack.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 235 insertions(+), 229 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 14907da6cf..beb2cc9162 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2003-06-09 Andrew Cagney + + * 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 * frame.c (get_prev_frame): Remove reference to diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 7733f94338..922d392d00 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) \ diff --git a/gdb/frame.h b/gdb/frame.h index 04fa67dfd0..f3640b458c 100644 --- a/gdb/frame.h +++ b/gdb/frame.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, diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 11fd1df946..410b950fe3 100644 --- a/gdb/printcmd.c +++ b/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) diff --git a/gdb/stack.c b/gdb/stack.c index fd9a9f81ce..1f874e6eab 100644 --- a/gdb/stack.c +++ b/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