X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finfcmd.c;h=6831d6be8f93504118d9c9d9a8b1bd4a444fe550;hb=6c7d17ba3a5d982ae1c2b972417aedce0f404cf5;hp=95ee3e6195de000f264bf851ba942074e8c09ee3;hpb=e76f1f2e332de69d2a48bd8ac7bf6d0390991f43;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 95ee3e6195..6831d6be8f 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. @@ -41,19 +41,28 @@ #include "event-top.h" #include "parser-defs.h" #include "regcache.h" +#include "reggroups.h" +#include "block.h" +#include -/* 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 *); @@ -72,7 +81,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); @@ -92,10 +101,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); @@ -112,8 +117,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."); @@ -180,7 +183,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. */ @@ -276,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; @@ -286,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'; @@ -616,7 +628,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) @@ -731,7 +743,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) @@ -843,7 +855,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 */ @@ -938,115 +950,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, struct regcache *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. */ - regcache_cpy_no_passthrough (buffer, stop_registers); - 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. @@ -1094,7 +997,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 +1031,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. */ @@ -1261,19 +1195,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 +1216,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 @@ -1550,23 +1484,32 @@ path_command (char *dirname, int from_tty) char *gdb_register_names[] = REGISTER_NAMES; #endif /* Print out the machine register regnum. If regnum is -1, print all - registers (all == 1) or all non-float and non-vector registers (all - == 0). + 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 print_all) +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++) { @@ -1574,11 +1517,14 @@ do_registers_info (int regnum, int print_all) specific reg. */ if (regnum == -1) { - if (!print_all) + if (print_all) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) + if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup)) continue; - if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (i))) + } + else + { + if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup)) continue; } } @@ -1593,20 +1539,23 @@ do_registers_info (int regnum, int print_all) 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 @@ -1615,40 +1564,43 @@ do_registers_info (int regnum, int print_all) 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"); + fprintf_filtered (file, "\t(raw 0x"); for (j = 0; j < 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 = 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"); } } @@ -1660,43 +1612,100 @@ registers_info (char *addr_exp, int fpregs) 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", (int) (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 @@ -1705,7 +1714,7 @@ 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); @@ -1715,22 +1724,24 @@ 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 (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (regnum))) + if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup)) { printed_something = 1; -#if 0 gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1); -#else - do_registers_info (regnum, 1); -#endif } } if (!printed_something) @@ -1741,7 +1752,7 @@ print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, static void vector_info (char *args, int from_tty) { - print_vector_info (current_gdbarch, gdb_stdout, selected_frame, args); + print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args); } @@ -1794,8 +1805,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 /* @@ -1863,16 +1879,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 ()) @@ -1887,41 +1916,36 @@ static void print_float_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_float_info_p (gdbarch)) gdbarch_print_float_info (gdbarch, file, frame, args); else { -#ifdef FLOAT_INFO -#if GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL -#error "FLOAT_INFO defined in multi-arch" -#endif - FLOAT_INFO; -#else int regnum; int printed_something = 0; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup)) { printed_something = 1; -#if 0 gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1); -#else - do_registers_info (regnum, 1); -#endif } } if (!printed_something) fprintf_filtered (file, "\ No floating-point info available for this processor.\n"); -#endif } } static void float_info (char *args, int from_tty) { - print_float_info (current_gdbarch, gdb_stdout, selected_frame, args); + print_float_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args); } /* ARGSUSED */ @@ -2013,6 +2037,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."); @@ -2047,11 +2076,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\