X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/9f5772857f4f3b1b09e72963c59f61c131785e59..3f1739b32a0a74c9a138d4b26cdcaebc7eee6829:/gdb/infcmd.c diff --git a/gdb/infcmd.c b/gdb/infcmd.c index ff97d3ace5..eddd89a228 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1,5 +1,5 @@ -/* Memory-access and commands for "inferior" (child) process, for GDB. - Copyright 1986, 1987, 1988, 1989, 1991, 1992 Free Software Foundation, Inc. +/* Memory-access and commands for "inferior" process, for GDB. + Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1995, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -15,12 +15,12 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include #include -#include +#include "gdb_string.h" #include "symtab.h" #include "gdbtypes.h" #include "frame.h" @@ -32,80 +32,61 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "target.h" #include "language.h" -static void -continue_command PARAMS ((char *, int)); +static void continue_command PARAMS ((char *, int)); -static void -until_next_command PARAMS ((int)); +static void until_next_command PARAMS ((int)); -static void -until_command PARAMS ((char *, int)); +static void until_command PARAMS ((char *, int)); -static void -path_info PARAMS ((char *, int)); +static void path_info PARAMS ((char *, int)); -static void -path_command PARAMS ((char *, int)); +static void path_command PARAMS ((char *, int)); -static void -unset_command PARAMS ((char *, int)); +static void unset_command PARAMS ((char *, int)); -static void -float_info PARAMS ((char *, int)); +static void float_info PARAMS ((char *, int)); -static void -detach_command PARAMS ((char *, int)); +static void detach_command PARAMS ((char *, int)); -static void -nofp_registers_info PARAMS ((char *, int)); +static void nofp_registers_info PARAMS ((char *, int)); -static void -all_registers_info PARAMS ((char *, int)); +static void all_registers_info PARAMS ((char *, int)); -static void -registers_info PARAMS ((char *, int)); +static void registers_info PARAMS ((char *, int)); -static void -do_registers_info PARAMS ((int, int)); +#if !defined (DO_REGISTERS_INFO) +static void do_registers_info PARAMS ((int, int)); +#endif -static void -unset_environment_command PARAMS ((char *, int)); +static void unset_environment_command PARAMS ((char *, int)); -static void -set_environment_command PARAMS ((char *, int)); +static void set_environment_command PARAMS ((char *, int)); -static void -environment_info PARAMS ((char *, int)); +static void environment_info PARAMS ((char *, int)); -static void -program_info PARAMS ((char *, int)); +static void program_info PARAMS ((char *, int)); -static void -finish_command PARAMS ((char *, int)); +static void finish_command PARAMS ((char *, int)); -static void -signal_command PARAMS ((char *, int)); +static void signal_command PARAMS ((char *, int)); -static void -jump_command PARAMS ((char *, int)); +static void jump_command PARAMS ((char *, int)); -static void -step_1 PARAMS ((int, int, char *)); +static void step_1 PARAMS ((int, int, char *)); -static void -nexti_command PARAMS ((char *, int)); +static void nexti_command PARAMS ((char *, int)); -static void -stepi_command PARAMS ((char *, int)); +static void stepi_command PARAMS ((char *, int)); -static void -next_command PARAMS ((char *, int)); +static void next_command PARAMS ((char *, int)); -static void -step_command PARAMS ((char *, int)); +static void step_command PARAMS ((char *, int)); -static void -run_command PARAMS ((char *, int)); +static void run_command PARAMS ((char *, int)); + +#ifdef CALL_DUMMY_BREAKPOINT_OFFSET +static void breakpoint_auto_delete_contents PARAMS ((PTR)); +#endif #define ERROR_NO_INFERIOR \ if (!target_has_execution) error ("The program is not being run."); @@ -134,10 +115,6 @@ enum target_signal stop_signal; CORE_ADDR stop_pc; -/* Stack frame when program stopped. */ - -FRAME_ADDR stop_frame_address; - /* Chain containing status of breakpoint(s) that we have stopped at. */ bpstat stop_bpstat; @@ -171,7 +148,11 @@ 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. */ -FRAME_ADDR step_frame_address; +CORE_ADDR step_frame_address; + +/* Our notion of the current stack pointer. */ + +CORE_ADDR step_sp; /* 1 means step over all subroutine calls. 0 means don't step over calls (used by stepi). @@ -212,8 +193,7 @@ run_command (args, from_tty) dont_repeat (); - /* Shouldn't this be target_has_execution? FIXME. */ - if (inferior_pid) + if (inferior_pid != 0 && target_has_execution) { if ( !query ("The program being debugged has been started already.\n\ @@ -349,7 +329,7 @@ step_1 (skip_subroutines, single_inst, count_string) char *count_string; { register int count = 1; - FRAME fr; + struct frame_info *frame; struct cleanup *cleanups = 0; ERROR_NO_INFERIOR; @@ -365,10 +345,11 @@ step_1 (skip_subroutines, single_inst, count_string) { clear_proceed_status (); - fr = get_current_frame (); - if (!fr) /* Avoid coredump here. Why tho? */ + frame = get_current_frame (); + if (!frame) /* Avoid coredump here. Why tho? */ error ("No current frame"); - step_frame_address = FRAME_FP (fr); + step_frame_address = FRAME_FP (frame); + step_sp = read_sp (); if (! single_inst) { @@ -384,7 +365,6 @@ step_1 (skip_subroutines, single_inst, count_string) printf_filtered ("\ Single stepping until exit from function %s, \n\ which has no line number information.\n", name); - gdb_flush (gdb_stdout); } } else @@ -498,19 +478,13 @@ signal_command (signum_exp, from_tty) if (oursig == TARGET_SIGNAL_UNKNOWN) { - /* Not found as a name, try it as an expression. */ - /* The numeric signal refers to our own internal signal numbering - from target.h, not to host/target signal number. This is a - feature; users really should be using symbolic names anyway, - and the common ones like SIGHUP, SIGINT, SIGALRM, etc. will - work right anyway. */ - int signum = parse_and_eval_address (signum_exp); - if (signum < 0 - || signum >= (int)TARGET_SIGNAL_LAST - || signum == (int)TARGET_SIGNAL_UNKNOWN - || signum == (int)TARGET_SIGNAL_DEFAULT) - error ("Invalid signal number %d.", signum); - oursig = signum; + /* No, try numeric. */ + int num = parse_and_eval_address (signum_exp); + + if (num == 0) + oursig = TARGET_SIGNAL_0; + else + oursig = target_signal_from_command (num); } if (from_tty) @@ -523,18 +497,27 @@ signal_command (signum_exp, from_tty) } clear_proceed_status (); - proceed (stop_pc, oursig, 0); + /* "signal 0" should not get stuck if we are stopped at a breakpoint. + FIXME: Neither should "signal foo" but when I tried passing + (CORE_ADDR)-1 unconditionally I got a testsuite failure which I haven't + tried to track down yet. */ + 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 *). */ -void + +#ifdef CALL_DUMMY_BREAKPOINT_OFFSET + +static void breakpoint_auto_delete_contents (arg) PTR arg; { breakpoint_auto_delete (*(bpstat *)arg); } +#endif /* CALL_DUMMY_BREAKPOINT_OFFSET */ + /* Execute a "stack dummy", a piece of code stored in the stack by the debugger to be executed in the inferior. @@ -598,7 +581,7 @@ run_stack_dummy (addr, buffer) bpt = set_momentary_breakpoint (sal, get_current_frame (), bp_call_dummy); - bpt->disposition = delete; + bpt->disposition = 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 @@ -634,7 +617,7 @@ static void until_next_command (from_tty) int from_tty; { - FRAME frame; + struct frame_info *frame; CORE_ADDR pc; struct symbol *func; struct symtab_and_line sal; @@ -670,7 +653,8 @@ until_next_command (from_tty) step_over_calls = 1; step_frame_address = FRAME_FP (frame); - + step_sp = read_sp (); + step_multi = 0; /* Only one call to proceed */ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); @@ -698,8 +682,7 @@ finish_command (arg, from_tty) int from_tty; { struct symtab_and_line sal; - register FRAME frame; - struct frame_info *fi; + register struct frame_info *frame; register struct symbol *function; struct breakpoint *breakpoint; struct cleanup *old_chain; @@ -717,9 +700,8 @@ finish_command (arg, from_tty) clear_proceed_status (); - fi = get_frame_info (frame); - sal = find_pc_line (fi->pc, 0); - sal.pc = fi->pc; + sal = find_pc_line (frame->pc, 0); + sal.pc = frame->pc; breakpoint = set_momentary_breakpoint (sal, frame, bp_finish); @@ -727,8 +709,7 @@ finish_command (arg, from_tty) /* Find the function we will return from. */ - fi = get_frame_info (selected_frame); - function = find_pc_function (fi->pc); + function = find_pc_function (selected_frame->pc); /* Print info on the selected frame, including level number but not source. */ @@ -761,7 +742,7 @@ finish_command (arg, from_tty) val = value_being_returned (value_type, stop_registers, using_struct_return (value_of_variable (function, NULL), funcaddr, - value_type, + check_typedef (value_type), BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)))); printf_filtered ("Value returned is $%d = ", record_latest_value (val)); @@ -952,9 +933,13 @@ path_command (dirname, from_tty) int from_tty; { char *exec_path; - + char *env; dont_repeat (); - exec_path = strsave (get_in_environ (inferior_environ, path_var_name)); + env = get_in_environ (inferior_environ, path_var_name); + /* Can be null if path is not set */ + if (!env) + env = ""; + exec_path = strsave (env); mod_path (dirname, &exec_path); set_in_environ (inferior_environ, path_var_name, exec_path); free (exec_path); @@ -962,7 +947,9 @@ path_command (dirname, from_tty) path_info ((char *)NULL, from_tty); } -const char * const reg_names[] = REGISTER_NAMES; +/* The array of register names. */ + +char *reg_names[] = REGISTER_NAMES; /* Print out the machine register regnum. If regnum is -1, print all registers (fpregs == 1) or all non-float registers @@ -976,15 +963,18 @@ const char * const reg_names[] = REGISTER_NAMES; to provide that format. */ #if !defined (DO_REGISTERS_INFO) + #define DO_REGISTERS_INFO(regnum, fp) do_registers_info(regnum, fp) + static void do_registers_info (regnum, fpregs) int regnum; int fpregs; { register int i; + int numregs = ARCH_NUM_REGS; - for (i = 0; i < NUM_REGS; i++) + for (i = 0; i < numregs; i++) { char raw_buffer[MAX_REGISTER_RAW_SIZE]; char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; @@ -998,6 +988,11 @@ do_registers_info (regnum, fpregs) continue; } + /* If the register name is empty, it is undefined for this + processor, so don't display anything. */ + if (reg_names[i] == NULL || *(reg_names[i]) == '\0') + continue; + fputs_filtered (reg_names[i], gdb_stdout); print_spaces_filtered (15 - strlen (reg_names[i]), gdb_stdout); @@ -1021,17 +1016,25 @@ do_registers_info (regnum, fpregs) 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 - && ! INVALID_FLOAT (virtual_buffer, REGISTER_VIRTUAL_SIZE (i))) + if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) { register int j; - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); +#ifdef INVALID_FLOAT + if (INVALID_FLOAT (virtual_buffer, REGISTER_VIRTUAL_SIZE (i))) + printf_filtered (""); + else +#endif + val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, + gdb_stdout, 0, 1, 0, Val_pretty_default); printf_filtered ("\t(raw 0x"); for (j = 0; j < REGISTER_RAW_SIZE (i); j++) - printf_filtered ("%02x", (unsigned char)raw_buffer[j]); + { + register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j + : REGISTER_RAW_SIZE (i) - 1 - j; + printf_filtered ("%02x", (unsigned char)raw_buffer[idx]); + } printf_filtered (")"); } @@ -1039,7 +1042,7 @@ do_registers_info (regnum, fpregs) /* Else if virtual format is too long for printf, print in hex a byte at a time. */ - else if (REGISTER_VIRTUAL_SIZE (i) > sizeof (long)) + else if (REGISTER_VIRTUAL_SIZE (i) > (int) sizeof (long)) { register int j; printf_filtered ("0x"); @@ -1072,11 +1075,13 @@ registers_info (addr_exp, fpregs) char *addr_exp; int fpregs; { - int regnum; + int regnum, numregs; register char *end; if (!target_has_registers) error ("The program has no registers now."); + if (selected_frame == NULL) + error ("No selected frame."); if (!addr_exp) { @@ -1091,13 +1096,14 @@ registers_info (addr_exp, fpregs) end = addr_exp; while (*end != '\0' && *end != ' ' && *end != '\t') ++end; - for (regnum = 0; regnum < NUM_REGS; regnum++) + numregs = ARCH_NUM_REGS; + for (regnum = 0; regnum < numregs; regnum++) if (!strncmp (addr_exp, reg_names[regnum], end - addr_exp) && strlen (reg_names[regnum]) == end - addr_exp) goto found; if (*addr_exp >= '0' && *addr_exp <= '9') regnum = atoi (addr_exp); /* Take a number */ - if (regnum >= NUM_REGS) /* Bad name, or bad number */ + if (regnum >= numregs) /* Bad name, or bad number */ error ("%.*s: invalid register", end - addr_exp, addr_exp); found: @@ -1146,6 +1152,10 @@ attach_command (args, from_tty) char *args; int from_tty; { +#ifdef SOLIB_ADD + extern int auto_solib_add; +#endif + dont_repeat (); /* Not for the faint of heart */ if (target_has_execution) @@ -1171,16 +1181,19 @@ attach_command (args, from_tty) clear_proceed_status (); stop_soon_quietly = 1; -#ifndef MACH - /* Mach 3 does not generate any traps when attaching to inferior, - and to set up frames we can do this. */ - + /* No traps are generated when attaching to inferior under Mach 3 + or GNU hurd. */ +#ifndef ATTACH_NO_WAIT wait_for_inferior (); #endif #ifdef SOLIB_ADD - /* Add shared library symbols from the newly attached process, if any. */ - SOLIB_ADD ((char *)0, from_tty, (struct target_ops *)0); + if (auto_solib_add) + { + /* Add shared library symbols from the newly attached process, if any. */ + SOLIB_ADD ((char *)0, from_tty, (struct target_ops *)0); + re_enable_breakpoints_in_shlibs (); + } #endif normal_stop (); @@ -1302,7 +1315,8 @@ If a process, it is no longer traced, and it continues its execution. If you\n\ were debugging a file, the file is closed and gdb no longer accesses it."); add_com ("signal", class_run, signal_command, - "Continue program giving it signal number SIGNUMBER."); + "Continue program giving it signal specified by the argument.\n\ +An argument of \"0\" means continue program without giving it a signal."); add_com ("stepi", class_run, stepi_command, "Step one instruction exactly.\n\