X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finfcmd.c;h=2c8631eb3ba634ef9a4200caef44a3cf49d1d6bd;hb=3b0cb2022cab939b993f82041526c09a9498e72a;hp=a7496d1f88cfb1b4279be2d142cb6e937fa2302a;hpb=b31da25ee58e2b01aa0c189474a277b443d94517;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcmd.c b/gdb/infcmd.c index a7496d1f88..2c8631eb3b 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1,6 +1,6 @@ /* Memory-access and commands for "inferior" process, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -40,19 +40,30 @@ #include "ui-out.h" #include "event-top.h" #include "parser-defs.h" +#include "regcache.h" +#include "reggroups.h" +#include "block.h" +#include +#include "gdb_assert.h" -/* Functions exported for general use: */ - -void nofp_registers_info (char *, int); +/* Functions exported for general use, in inferior.h: */ void all_registers_info (char *, int); void registers_info (char *, int); -/* Local functions: */ +void nexti_command (char *, int); + +void stepi_command (char *, int); void continue_command (char *, int); +void interrupt_target_command (char *args, int from_tty); + +/* Local functions: */ + +static void nofp_registers_info (char *, int); + static void print_return_value (int struct_return, struct type *value_type); static void finish_command_continuation (struct continuation_arg *); @@ -71,7 +82,7 @@ static void float_info (char *, int); static void detach_command (char *, int); -static void interrupt_target_command (char *args, int from_tty); +static void disconnect_command (char *, int); static void unset_environment_command (char *, int); @@ -91,10 +102,6 @@ static void step_1 (int, int, char *); static void step_once (int skip_subroutines, int single_inst, int count); static void step_1_continuation (struct continuation_arg *arg); -void nexti_command (char *, int); - -void stepi_command (char *, int); - static void next_command (char *, int); static void step_command (char *, int); @@ -111,8 +118,6 @@ void _initialize_infcmd (void); #define GO_USAGE "Usage: go \n" -static void breakpoint_auto_delete_contents (PTR); - #define ERROR_NO_INFERIOR \ if (!target_has_execution) error ("The program is not being run."); @@ -179,7 +184,7 @@ CORE_ADDR step_range_end; /* Exclusive */ This is how we know when we step into a subroutine call, and how to set the frame for the breakpoint used to step out. */ -CORE_ADDR step_frame_address; +struct frame_id step_frame_id; /* Our notion of the current stack pointer. */ @@ -257,7 +262,6 @@ notice_args_read (char *args, int from_tty, struct cmd_list_element *c) /* Compute command-line string given argument vector. This does the same shell processing as fork_inferior. */ -/* ARGSUSED */ char * construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) { @@ -275,7 +279,7 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) /* We over-compute the size. It shouldn't matter. */ for (i = 0; i < argc; ++i) - length += 2 * strlen (argv[i]) + 1; + length += 2 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0'); result = (char *) xmalloc (length); out = result; @@ -285,11 +289,20 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) if (i > 0) *out++ = ' '; - for (cp = argv[i]; *cp; ++cp) + /* Need to handle empty arguments specially. */ + if (argv[i][0] == '\0') { - if (strchr (special, *cp) != NULL) - *out++ = '\\'; - *out++ = *cp; + *out++ = '\''; + *out++ = '\''; + } + else + { + for (cp = argv[i]; *cp; ++cp) + { + if (strchr (special, *cp) != NULL) + *out++ = '\\'; + *out++ = *cp; + } } } *out = '\0'; @@ -357,7 +370,6 @@ strip_bg_char (char **args) return 0; } -/* ARGSUSED */ void tty_command (char *file, int from_tty) { @@ -530,7 +542,6 @@ continue_command (char *proc_count_exp, int from_tty) /* Step until outside of current statement. */ -/* ARGSUSED */ static void step_command (char *count_string, int from_tty) { @@ -539,7 +550,6 @@ step_command (char *count_string, int from_tty) /* Likewise, but skip over subroutine calls as if single instructions. */ -/* ARGSUSED */ static void next_command (char *count_string, int from_tty) { @@ -548,14 +558,12 @@ next_command (char *count_string, int from_tty) /* Likewise, but step only one instruction. */ -/* ARGSUSED */ void stepi_command (char *count_string, int from_tty) { step_1 (0, 1, count_string); } -/* ARGSUSED */ void nexti_command (char *count_string, int from_tty) { @@ -571,7 +579,7 @@ disable_longjmp_breakpoint_cleanup (void *ignore) static void step_1 (int skip_subroutines, int single_inst, char *count_string) { - register int count = 1; + int count = 1; struct frame_info *frame; struct cleanup *cleanups = 0; int async_exec = 0; @@ -615,7 +623,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) frame = get_current_frame (); if (!frame) /* Avoid coredump here. Why tho? */ error ("No current frame"); - step_frame_address = FRAME_FP (frame); + step_frame_id = get_frame_id (frame); step_sp = read_sp (); if (!single_inst) @@ -730,7 +738,7 @@ step_once (int skip_subroutines, int single_inst, int count) frame = get_current_frame (); if (!frame) /* Avoid coredump here. Why tho? */ error ("No current frame"); - step_frame_address = FRAME_FP (frame); + step_frame_id = get_frame_id (frame); step_sp = read_sp (); if (!single_inst) @@ -793,7 +801,7 @@ which has no line number information.\n", name); static void jump_command (char *arg, int from_tty) { - register CORE_ADDR addr; + CORE_ADDR addr; struct symtabs_and_lines sals; struct symtab_and_line sal; struct symbol *fn; @@ -842,7 +850,7 @@ jump_command (char *arg, int from_tty) if (fn != NULL && sfn != fn) { if (!query ("Line %d is not in `%s'. Jump anyway? ", sal.line, - SYMBOL_SOURCE_NAME (fn))) + SYMBOL_PRINT_NAME (fn))) { error ("Not confirmed."); /* NOTREACHED */ @@ -937,116 +945,6 @@ signal_command (char *signum_exp, int from_tty) proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0); } -/* Call breakpoint_auto_delete on the current contents of the bpstat - pointed to by arg (which is really a bpstat *). */ - -static void -breakpoint_auto_delete_contents (PTR arg) -{ - breakpoint_auto_delete (*(bpstat *) arg); -} - - -/* Execute a "stack dummy", a piece of code stored in the stack - by the debugger to be executed in the inferior. - - To call: first, do PUSH_DUMMY_FRAME. - Then push the contents of the dummy. It should end with a breakpoint insn. - Then call here, passing address at which to start the dummy. - - The contents of all registers are saved before the dummy frame is popped - and copied into the buffer BUFFER. - - The dummy's frame is automatically popped whenever that break is hit. - If that is the first time the program stops, run_stack_dummy - returns to its caller with that frame already gone and returns 0. - - Otherwise, run_stack-dummy returns a non-zero value. - If the called function receives a random signal, we do not allow the user - to continue executing it as this may not work. The dummy frame is poped - and we return 1. - If we hit a breakpoint, we leave the frame in place and return 2 (the frame - will eventually be popped when we do hit the dummy end breakpoint). */ - -int -run_stack_dummy (CORE_ADDR addr, char *buffer) -{ - struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); - int saved_async = 0; - - /* Now proceed, having reached the desired place. */ - clear_proceed_status (); - - if (CALL_DUMMY_BREAKPOINT_OFFSET_P) - { - struct breakpoint *bpt; - struct symtab_and_line sal; - - INIT_SAL (&sal); /* initialize to zeroes */ - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - sal.pc = CALL_DUMMY_ADDRESS (); - } - else - { - sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET; - } - sal.section = find_pc_overlay (sal.pc); - - /* Set up a FRAME for the dummy frame so we can pass it to - set_momentary_breakpoint. We need to give the breakpoint a - frame in case there is only one copy of the dummy (e.g. - CALL_DUMMY_LOCATION == AFTER_TEXT_END). */ - flush_cached_frames (); - set_current_frame (create_new_frame (read_fp (), sal.pc)); - - /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to put - a breakpoint instruction. If not, the call dummy already has the - breakpoint instruction in it. - - addr is the address of the call dummy plus the CALL_DUMMY_START_OFFSET, - so we need to subtract the CALL_DUMMY_START_OFFSET. */ - bpt = set_momentary_breakpoint (sal, - get_current_frame (), - bp_call_dummy); - bpt->disposition = disp_del; - - /* If all error()s out of proceed ended up calling normal_stop (and - perhaps they should; it already does in the special case of error - out of resume()), then we wouldn't need this. */ - make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat); - } - - disable_watchpoints_before_interactive_call_start (); - proceed_to_finish = 1; /* We want stop_registers, please... */ - - if (target_can_async_p ()) - saved_async = target_async_mask (0); - - proceed (addr, TARGET_SIGNAL_0, 0); - - if (saved_async) - target_async_mask (saved_async); - - enable_watchpoints_after_interactive_call_stop (); - - discard_cleanups (old_cleanups); - - /* We can stop during an inferior call because a signal is received. */ - if (stopped_by_random_signal) - return 1; - - /* We may also stop prematurely because we hit a breakpoint in the - called routine. */ - if (!stop_stack_dummy) - return 2; - - /* On normal return, the stack dummy has been popped already. */ - - memcpy (buffer, stop_registers, REGISTER_BYTES); - return 0; -} - /* Proceed until we reach a different source line with pc greater than our current one or exit the function. We skip calls in both cases. @@ -1055,7 +953,6 @@ run_stack_dummy (CORE_ADDR addr, char *buffer) we set. This may involve changes to wait_for_inferior and the proceed status code. */ -/* ARGSUSED */ static void until_next_command (int from_tty) { @@ -1094,7 +991,7 @@ until_next_command (int from_tty) } step_over_calls = STEP_OVER_ALL; - step_frame_address = FRAME_FP (frame); + step_frame_id = get_frame_id (frame); step_sp = read_sp (); step_multi = 0; /* Only one call to proceed */ @@ -1128,10 +1025,41 @@ until_command (char *arg, int from_tty) } if (arg) - until_break_command (arg, from_tty); + until_break_command (arg, from_tty, 0); else until_next_command (from_tty); } + +static void +advance_command (char *arg, int from_tty) +{ + int async_exec = 0; + + if (!target_has_execution) + error ("The program is not running."); + + if (arg == NULL) + error_no_arg ("a location"); + + /* Find out whether we must run in the background. */ + if (arg != NULL) + async_exec = strip_bg_char (&arg); + + /* If we must run in the background, but the target can't do it, + error out. */ + if (event_loop_p && async_exec && !target_can_async_p ()) + error ("Asynchronous execution not supported on this target."); + + /* If we are not asked to run in the bg, then prepare to run in the + foreground, synchronously. */ + if (event_loop_p && !async_exec && target_can_async_p ()) + { + /* Simulate synchronous execution. */ + async_disable_stdin (); + } + + until_break_command (arg, from_tty, 1); +} /* Print the result of a function at the end of a 'finish' command. */ @@ -1143,7 +1071,7 @@ print_return_value (int structure_return, struct type *value_type) if (!structure_return) { - value = value_being_returned (value_type, stop_registers, structure_return); + value = register_value_being_returned (value_type, stop_registers); stb = ui_out_stream_new (uiout); ui_out_text (uiout, "Value returned is "); ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value)); @@ -1152,19 +1080,56 @@ print_return_value (int structure_return, struct type *value_type) ui_out_field_stream (uiout, "return-value", stb); ui_out_text (uiout, "\n"); } - else + /* FIXME: 2003-09-27: When returning from a nested inferior function + call, it's possible (with no help from the architecture vector) + to locate and return/print a "struct return" value. This is just + a more complicated case of what is already being done in in the + inferior function call code. In fact, when inferior function + calls are made async, this will likely be made the norm. */ + else if (gdbarch_return_value_p (current_gdbarch)) + /* We cannot determine the contents of the structure because it is + on the stack, and we don't know where, since we did not + initiate the call, as opposed to the call_function_by_hand + case. */ { - /* We cannot determine the contents of the structure because - it is on the stack, and we don't know where, since we did not - initiate the call, as opposed to the call_function_by_hand case */ -#ifdef VALUE_RETURNED_FROM_STACK - value = 0; + gdb_assert (gdbarch_return_value (current_gdbarch, value_type, NULL, NULL, NULL) + == RETURN_VALUE_STRUCT_CONVENTION); ui_out_text (uiout, "Value returned has type: "); ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type)); ui_out_text (uiout, "."); ui_out_text (uiout, " Cannot determine contents\n"); -#else - value = value_being_returned (value_type, stop_registers, structure_return); + return; + } + else + { + if (EXTRACT_STRUCT_VALUE_ADDRESS_P ()) + { + CORE_ADDR addr = EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers); + if (!addr) + error ("Function return value unknown."); + value = value_at (value_type, addr, NULL); + } + else if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ()) + { + char *buf = deprecated_grub_regcache_for_registers (stop_registers); + CORE_ADDR addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (buf); + if (!addr) + error ("Function return value unknown."); + value = value_at (value_type, addr, NULL); + } + else + { + /* It is "struct return" yet the value is being extracted, + presumably from registers, using EXTRACT_RETURN_VALUE. + This doesn't make sense. Unfortunately, the legacy + interfaces allowed this behavior. Sigh! */ + value = allocate_value (value_type); + CHECK_TYPEDEF (value_type); + /* If the function returns void, don't bother fetching the + return value. */ + EXTRACT_RETURN_VALUE (value_type, stop_registers, + VALUE_CONTENTS_RAW (value)); + } stb = ui_out_stream_new (uiout); ui_out_text (uiout, "Value returned is "); ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value)); @@ -1172,7 +1137,6 @@ print_return_value (int structure_return, struct type *value_type) value_print (value, stb->stream, 0, Val_no_prettyprint); ui_out_field_stream (uiout, "return-value", stb); ui_out_text (uiout, "\n"); -#endif } } @@ -1187,7 +1151,7 @@ print_return_value (int structure_return, struct type *value_type) void finish_command_continuation (struct continuation_arg *arg) { - register struct symbol *function; + struct symbol *function; struct breakpoint *breakpoint; struct cleanup *cleanups; @@ -1215,9 +1179,7 @@ finish_command_continuation (struct continuation_arg *arg) funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); - struct_return = using_struct_return (value_of_variable (function, NULL), - funcaddr, - check_typedef (value_type), + struct_return = using_struct_return (check_typedef (value_type), BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); print_return_value (struct_return, value_type); @@ -1232,8 +1194,8 @@ static void finish_command (char *arg, int from_tty) { struct symtab_and_line sal; - register struct frame_info *frame; - register struct symbol *function; + struct frame_info *frame; + struct symbol *function; struct breakpoint *breakpoint; struct cleanup *old_chain; struct continuation_arg *arg1, *arg2, *arg3; @@ -1261,19 +1223,19 @@ finish_command (char *arg, int from_tty) error ("The \"finish\" command does not take any arguments."); if (!target_has_execution) error ("The program is not running."); - if (selected_frame == NULL) + if (deprecated_selected_frame == NULL) error ("No selected frame."); - frame = get_prev_frame (selected_frame); + frame = get_prev_frame (deprecated_selected_frame); if (frame == 0) error ("\"finish\" not meaningful in the outermost frame."); clear_proceed_status (); - sal = find_pc_line (frame->pc, 0); - sal.pc = frame->pc; + sal = find_pc_line (get_frame_pc (frame), 0); + sal.pc = get_frame_pc (frame); - breakpoint = set_momentary_breakpoint (sal, frame, bp_finish); + breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish); if (!event_loop_p || !target_can_async_p ()) old_chain = make_cleanup_delete_breakpoint (breakpoint); @@ -1282,15 +1244,15 @@ finish_command (char *arg, int from_tty) /* Find the function we will return from. */ - function = find_pc_function (selected_frame->pc); + function = find_pc_function (get_frame_pc (deprecated_selected_frame)); /* Print info on the selected frame, including level number but not source. */ if (from_tty) { printf_filtered ("Run till exit from "); - print_stack_frame (selected_frame, - frame_relative_level (selected_frame), 0); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 0); } /* If running asynchronously and the target support asynchronous @@ -1343,9 +1305,7 @@ finish_command (char *arg, int from_tty) funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); struct_return = - using_struct_return (value_of_variable (function, NULL), - funcaddr, - check_typedef (value_type), + using_struct_return (check_typedef (value_type), BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); print_return_value (struct_return, value_type); @@ -1354,7 +1314,6 @@ finish_command (char *arg, int from_tty) } } -/* ARGSUSED */ static void program_info (char *args, int from_tty) { @@ -1407,7 +1366,7 @@ environment_info (char *var, int from_tty) { if (var) { - register char *val = get_in_environ (inferior_environ, var); + char *val = get_in_environ (inferior_environ, var); if (val) { puts_filtered (var); @@ -1424,7 +1383,7 @@ environment_info (char *var, int from_tty) } else { - register char **vector = environ_vector (inferior_environ); + char **vector = environ_vector (inferior_environ); while (*vector) { puts_filtered (*vector++); @@ -1436,7 +1395,7 @@ environment_info (char *var, int from_tty) static void set_environment_command (char *arg, int from_tty) { - register char *p, *val, *var; + char *p, *val, *var; int nullset = 0; if (arg == 0) @@ -1516,7 +1475,6 @@ unset_environment_command (char *var, int from_tty) static const char path_var_name[] = "PATH"; -/* ARGSUSED */ static void path_info (char *args, int from_tty) { @@ -1546,35 +1504,50 @@ path_command (char *dirname, int from_tty) } -#ifdef REGISTER_NAMES -char *gdb_register_names[] = REGISTER_NAMES; -#endif -/* Print out the machine register regnum. If regnum is -1, - print all registers (fpregs == 1) or all non-float registers - (fpregs == 0). +/* Print out the machine register regnum. If regnum is -1, print all + registers (print_all == 1) or all non-float and non-vector + registers (print_all == 0). For most machines, having all_registers_info() print the - register(s) one per line is good enough. If a different format - is required, (eg, for MIPS or Pyramid 90x, which both have - lots of regs), or there is an existing convention for showing - all the registers, define the macro DO_REGISTERS_INFO(regnum, fp) - to provide that format. */ + register(s) one per line is good enough. If a different format is + required, (eg, for MIPS or Pyramid 90x, which both have lots of + regs), or there is an existing convention for showing all the + registers, define the architecture method PRINT_REGISTERS_INFO to + provide that format. */ void -do_registers_info (int regnum, int fpregs) +default_print_registers_info (struct gdbarch *gdbarch, + struct ui_file *file, + struct frame_info *frame, + int regnum, int print_all) { - register int i; - int numregs = NUM_REGS + NUM_PSEUDO_REGS; - char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); - char *virtual_buffer = (char*) alloca (MAX_REGISTER_VIRTUAL_SIZE); + int i; + const int numregs = NUM_REGS + NUM_PSEUDO_REGS; + char raw_buffer[MAX_REGISTER_SIZE]; + char virtual_buffer[MAX_REGISTER_SIZE]; + + if (DEPRECATED_DO_REGISTERS_INFO_P ()) + { + DEPRECATED_DO_REGISTERS_INFO (regnum, print_all); + return; + } for (i = 0; i < numregs; i++) { - /* Decide between printing all regs, nonfloat regs, or specific reg. */ + /* Decide between printing all regs, non-float / vector regs, or + specific reg. */ if (regnum == -1) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT && !fpregs) - continue; + if (print_all) + { + if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup)) + continue; + } + else + { + if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup)) + continue; + } } else { @@ -1587,62 +1560,68 @@ do_registers_info (int regnum, int fpregs) if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0') continue; - fputs_filtered (REGISTER_NAME (i), gdb_stdout); - print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout); + fputs_filtered (REGISTER_NAME (i), file); + print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), file); /* Get the data in raw format. */ - if (! frame_register_read (selected_frame, i, raw_buffer)) + if (! frame_register_read (frame, i, raw_buffer)) { - printf_filtered ("*value not available*\n"); + fprintf_filtered (file, "*value not available*\n"); continue; } + /* FIXME: cagney/2002-08-03: This code shouldn't be necessary. + The function frame_register_read() should have returned the + pre-cooked register so no conversion is necessary. */ /* Convert raw data to virtual format if necessary. */ - if (REGISTER_CONVERTIBLE (i)) + if (DEPRECATED_REGISTER_CONVERTIBLE (i)) { - REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i), + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (i, register_type (current_gdbarch, i), raw_buffer, virtual_buffer); } else { memcpy (virtual_buffer, raw_buffer, - REGISTER_VIRTUAL_SIZE (i)); + DEPRECATED_REGISTER_VIRTUAL_SIZE (i)); } - /* If virtual format is floating, print it that way, and in raw hex. */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) + /* If virtual format is floating, print it that way, and in raw + hex. */ + if (TYPE_CODE (register_type (current_gdbarch, i)) == TYPE_CODE_FLT) { - register int j; + int j; - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); + val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0, + file, 0, 1, 0, Val_pretty_default); - printf_filtered ("\t(raw 0x"); - for (j = 0; j < REGISTER_RAW_SIZE (i); j++) + fprintf_filtered (file, "\t(raw 0x"); + for (j = 0; j < DEPRECATED_REGISTER_RAW_SIZE (i); j++) { - register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j - : REGISTER_RAW_SIZE (i) - 1 - j; - printf_filtered ("%02x", (unsigned char) raw_buffer[idx]); + int idx; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + idx = j; + else + idx = DEPRECATED_REGISTER_RAW_SIZE (i) - 1 - j; + fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]); } - printf_filtered (")"); + fprintf_filtered (file, ")"); } - /* Else print as integer in hex and in decimal. */ else { - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, - gdb_stdout, 'x', 1, 0, Val_pretty_default); - printf_filtered ("\t"); - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); + /* Print the register in hex. */ + val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0, + file, 'x', 1, 0, Val_pretty_default); + /* If not a vector register, print it also according to its + natural format. */ + if (TYPE_VECTOR (register_type (current_gdbarch, i)) == 0) + { + fprintf_filtered (file, "\t"); + val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0, + file, 0, 1, 0, Val_pretty_default); + } } - /* The SPARC wants to print even-numbered float regs as doubles - in addition to printing them as floats. */ -#ifdef PRINT_REGISTER_HOOK - PRINT_REGISTER_HOOK (i); -#endif - - printf_filtered ("\n"); + fprintf_filtered (file, "\n"); } } @@ -1650,47 +1629,104 @@ void registers_info (char *addr_exp, int fpregs) { int regnum, numregs; - register char *end; + char *end; if (!target_has_registers) error ("The program has no registers now."); - if (selected_frame == NULL) + if (deprecated_selected_frame == NULL) error ("No selected frame."); if (!addr_exp) { - DO_REGISTERS_INFO (-1, fpregs); + gdbarch_print_registers_info (current_gdbarch, gdb_stdout, + deprecated_selected_frame, -1, fpregs); return; } - do + while (*addr_exp != '\0') { - if (addr_exp[0] == '$') - addr_exp++; - end = addr_exp; - while (*end != '\0' && *end != ' ' && *end != '\t') - ++end; - numregs = NUM_REGS + NUM_PSEUDO_REGS; - - regnum = target_map_name_to_register (addr_exp, end - addr_exp); - if (regnum >= 0) - goto found; + char *start; + const char *end; - regnum = numregs; + /* Keep skipping leading white space. */ + if (isspace ((*addr_exp))) + { + addr_exp++; + continue; + } - if (*addr_exp >= '0' && *addr_exp <= '9') - regnum = atoi (addr_exp); /* Take a number */ - if (regnum >= numregs) /* Bad name, or bad number */ - error ("%.*s: invalid register", end - addr_exp, addr_exp); + /* Discard any leading ``$''. Check that there is something + resembling a register following it. */ + if (addr_exp[0] == '$') + addr_exp++; + if (isspace ((*addr_exp)) || (*addr_exp) == '\0') + error ("Missing register name"); - found: - DO_REGISTERS_INFO (regnum, fpregs); + /* Find the start/end of this register name/num/group. */ + start = addr_exp; + while ((*addr_exp) != '\0' && !isspace ((*addr_exp))) + addr_exp++; + end = addr_exp; + + /* Figure out what we've found and display it. */ + + /* A register name? */ + { + int regnum = frame_map_name_to_regnum (deprecated_selected_frame, + start, end - start); + if (regnum >= 0) + { + gdbarch_print_registers_info (current_gdbarch, gdb_stdout, + deprecated_selected_frame, regnum, fpregs); + continue; + } + } + + /* A register number? (how portable is this one?). */ + { + char *endptr; + int regnum = strtol (start, &endptr, 0); + if (endptr == end + && regnum >= 0 + && regnum < NUM_REGS + NUM_PSEUDO_REGS) + { + gdbarch_print_registers_info (current_gdbarch, gdb_stdout, + deprecated_selected_frame, regnum, fpregs); + continue; + } + } + + /* A register group? */ + { + struct reggroup *group; + for (group = reggroup_next (current_gdbarch, NULL); + group != NULL; + group = reggroup_next (current_gdbarch, group)) + { + /* Don't bother with a length check. Should the user + enter a short register group name, go with the first + group that matches. */ + if (strncmp (start, reggroup_name (group), end - start) == 0) + break; + } + if (group != NULL) + { + int regnum; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (gdbarch_register_reggroup_p (current_gdbarch, regnum, + group)) + gdbarch_print_registers_info (current_gdbarch, + gdb_stdout, deprecated_selected_frame, + regnum, fpregs); + } + continue; + } + } - addr_exp = end; - while (*addr_exp == ' ' || *addr_exp == '\t') - ++addr_exp; + /* Nothing matched. */ + error ("Invalid register `%.*s'", (int) (end - start), start); } - while (*addr_exp != '\0'); } void @@ -1699,11 +1735,46 @@ all_registers_info (char *addr_exp, int from_tty) registers_info (addr_exp, 1); } -void +static void nofp_registers_info (char *addr_exp, int from_tty) { registers_info (addr_exp, 0); } + +static void +print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) +{ + if (!target_has_registers) + error ("The program has no registers now."); + if (deprecated_selected_frame == NULL) + error ("No selected frame."); + + if (gdbarch_print_vector_info_p (gdbarch)) + gdbarch_print_vector_info (gdbarch, file, frame, args); + else + { + int regnum; + int printed_something = 0; + + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup)) + { + printed_something = 1; + gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1); + } + } + if (!printed_something) + fprintf_filtered (file, "No vector information\n"); + } +} + +static void +vector_info (char *args, int from_tty) +{ + print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args); +} /* @@ -1755,8 +1826,13 @@ attach_command (char *args, int from_tty) /* No traps are generated when attaching to inferior under Mach 3 or GNU hurd. */ #ifndef ATTACH_NO_WAIT - stop_soon_quietly = 1; + /* Careful here. See comments in inferior.h. Basically some OSes + don't ignore SIGSTOPs on continue requests anymore. We need a + way for handle_inferior_event to reset the stop_signal variable + after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for. */ + stop_soon = STOP_QUIETLY_NO_SIGSTOP; wait_for_inferior (); + stop_soon = NO_STOP_QUIETLY; #endif /* @@ -1824,16 +1900,29 @@ detach_command (char *args, int from_tty) detach_hook (); } -/* Stop the execution of the target while running in async mode, in - the backgound. */ +/* Disconnect from the current target without resuming it (leaving it + waiting for a debugger). -void -interrupt_target_command_wrapper (char *args, int from_tty) + We'd better not have left any breakpoints in the program or the + next debugger will get confused. Currently only supported for some + remote targets, since the normal attach mechanisms don't work on + stopped processes on some native platforms (e.g. GNU/Linux). */ + +static void +disconnect_command (char *args, int from_tty) { - interrupt_target_command (args, from_tty); + dont_repeat (); /* Not for the faint of heart */ + target_disconnect (args, from_tty); +#if defined(SOLIB_RESTART) + SOLIB_RESTART (); +#endif + if (detach_hook) + detach_hook (); } -static void +/* Stop the execution of the target while running in async mode, in + the backgound. */ +void interrupt_target_command (char *args, int from_tty) { if (event_loop_p && target_can_async_p ()) @@ -1843,14 +1932,42 @@ interrupt_target_command (char *args, int from_tty) } } -/* ARGSUSED */ static void -float_info (char *addr_exp, int from_tty) +print_float_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) { - PRINT_FLOAT_INFO (); + if (!target_has_registers) + error ("The program has no registers now."); + if (deprecated_selected_frame == NULL) + error ("No selected frame."); + + if (gdbarch_print_float_info_p (gdbarch)) + gdbarch_print_float_info (gdbarch, file, frame, args); + else + { + int regnum; + int printed_something = 0; + + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup)) + { + printed_something = 1; + gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1); + } + } + if (!printed_something) + fprintf_filtered (file, "\ +No floating-point info available for this processor.\n"); + } +} + +static void +float_info (char *args, int from_tty) +{ + print_float_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args); } -/* ARGSUSED */ static void unset_command (char *args, int from_tty) { @@ -1939,6 +2056,11 @@ to specify the program, and to load its symbol table."); If a process, it is no longer traced, and it continues its execution. If\n\ you were debugging a file, the file is closed and gdb no longer accesses it."); + add_com ("disconnect", class_run, disconnect_command, + "Disconnect from a target.\n\ +The target will wait for another debugger to connect. Not available for\n\ +all targets."); + add_com ("signal", class_run, signal_command, "Continue program giving it signal specified by the argument.\n\ An argument of \"0\" means continue program without giving it a signal."); @@ -1973,11 +2095,15 @@ Argument N means do this N times (or till program stops for another reason)."); c = add_com ("until", class_run, until_command, "Execute until the program reaches a source line greater than the current\n\ -or a specified line or address or function (same args as break command).\n\ -Execution will also stop upon exit from the current stack frame."); +or a specified location (same args as break command) within the current frame."); set_cmd_completer (c, location_completer); add_com_alias ("u", "until", class_run, 1); + c = add_com ("advance", class_run, advance_command, + "Continue the program up to the given location (same form as args for break command).\n\ +Execution will also stop upon exit from the current stack frame."); + set_cmd_completer (c, location_completer); + c = add_com ("jump", class_run, jump_command, "Continue program being debugged at specified line or address.\n\ Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\ @@ -2042,6 +2168,9 @@ Register name as argument means describe only that register."); add_info ("float", float_info, "Print the status of the floating point unit\n"); + add_info ("vector", vector_info, + "Print the status of the vector unit\n"); + inferior_environ = make_environ (); init_environ (inferior_environ); }