X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finfrun.c;h=ea83f13f1dee444e6b23a2216bbabd17b00f4f1a;hb=b9cd6d0b0dc85f23a41f4bb9ce42bbfb5b31cc2d;hp=ff956d3db47eaea33e8a5fd052ced51a4bb555f8;hpb=73b65bb0693827163135f5af96ebba03470badd4;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infrun.c b/gdb/infrun.c index ff956d3db4..ea83f13f1d 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2,8 +2,8 @@ process. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software - Foundation, Inc. + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -61,9 +61,6 @@ static int hook_stop_stub (void *); static void delete_breakpoint_current_contents (void *); -static void set_follow_fork_mode_command (char *arg, int from_tty, - struct cmd_list_element *c); - static int restore_selected_frame (void *); static void build_infrun (void); @@ -153,10 +150,6 @@ static int may_follow_exec = MAY_FOLLOW_EXEC; #define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0 #endif -#ifndef SKIP_SOLIB_RESOLVER -#define SKIP_SOLIB_RESOLVER(pc) 0 -#endif - /* This function returns TRUE if pc is the address of an instruction that lies within the dynamic linker (such as the event hook, or the dld itself). @@ -344,12 +337,10 @@ static struct } pending_follow; -static const char follow_fork_mode_ask[] = "ask"; static const char follow_fork_mode_child[] = "child"; static const char follow_fork_mode_parent[] = "parent"; static const char *follow_fork_mode_kind_names[] = { - follow_fork_mode_ask, follow_fork_mode_child, follow_fork_mode_parent, NULL @@ -361,16 +352,7 @@ static const char *follow_fork_mode_string = follow_fork_mode_parent; static int follow_fork (void) { - const char *follow_mode = follow_fork_mode_string; - int follow_child = (follow_mode == follow_fork_mode_child); - - /* Or, did the user not know, and want us to ask? */ - if (follow_fork_mode_string == follow_fork_mode_ask) - { - internal_error (__FILE__, __LINE__, - "follow_inferior_fork: \"ask\" mode not implemented"); - /* follow_mode = follow_fork_mode_...; */ - } + int follow_child = (follow_fork_mode_string == follow_fork_mode_child); return target_follow_fork (follow_child); } @@ -495,7 +477,6 @@ static int singlestep_breakpoints_inserted_p = 0; /* Things to clean up if we QUIT out of resume (). */ -/* ARGSUSED */ static void resume_cleanups (void *ignore) { @@ -520,7 +501,7 @@ set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c) the set command passed as a parameter. The clone operation will include (BUG?) any ``set'' command callback, if present. Commands like ``info set'' call all the ``show'' command - callbacks. Unfortunatly, for ``show'' commands cloned from + callbacks. Unfortunately, for ``show'' commands cloned from ``set'', this includes callbacks belonging to ``set'' commands. Making this worse, this only occures if add_show_from_set() is called after add_cmd_sfunc() (BUG?). */ @@ -992,6 +973,7 @@ struct execution_control_state void init_execution_control_state (struct execution_control_state *ecs); +static void handle_step_into_function (struct execution_control_state *ecs); void handle_inferior_event (struct execution_control_state *ecs); static void check_sigtramp2 (struct execution_control_state *ecs); @@ -1241,6 +1223,168 @@ pc_in_sigtramp (CORE_ADDR pc) return PC_IN_SIGTRAMP (pc, name); } +/* Handle the inferior event in the cases when we just stepped + into a function. */ + +static void +handle_step_into_function (struct execution_control_state *ecs) +{ + CORE_ADDR real_stop_pc; + + if ((step_over_calls == STEP_OVER_NONE) + || ((step_range_end == 1) + && in_prologue (prev_pc, ecs->stop_func_start))) + { + /* I presume that step_over_calls is only 0 when we're + supposed to be stepping at the assembly language level + ("stepi"). Just stop. */ + /* Also, maybe we just did a "nexti" inside a prolog, + so we thought it was a subroutine call but it was not. + Stop as well. FENN */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc)) + { + /* We're doing a "next". */ + + if (pc_in_sigtramp (stop_pc) + && frame_id_inner (step_frame_id, + frame_id_build (read_sp (), 0))) + /* We stepped out of a signal handler, and into its + calling trampoline. This is misdetected as a + subroutine call, but stepping over the signal + trampoline isn't such a bad idea. In order to do that, + we have to ignore the value in step_frame_id, since + that doesn't represent the frame that'll reach when we + return from the signal trampoline. Otherwise we'll + probably continue to the end of the program. */ + step_frame_id = null_frame_id; + + step_over_function (ecs); + keep_going (ecs); + return; + } + + /* If we are in a function call trampoline (a stub between + the calling routine and the real function), locate the real + function. That's what tells us (a) whether we want to step + into it at all, and (b) what prologue we want to run to + the end of, if we do step into it. */ + real_stop_pc = skip_language_trampoline (stop_pc); + if (real_stop_pc == 0) + real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); + if (real_stop_pc != 0) + ecs->stop_func_start = real_stop_pc; + + /* If we have line number information for the function we + are thinking of stepping into, step into it. + + If there are several symtabs at that PC (e.g. with include + files), just want to know whether *any* of them have line + numbers. find_pc_line handles this. */ + { + struct symtab_and_line tmp_sal; + + tmp_sal = find_pc_line (ecs->stop_func_start, 0); + if (tmp_sal.line != 0) + { + step_into_function (ecs); + return; + } + } + + /* If we have no line number and the step-stop-if-no-debug + is set, we stop the step so that the user has a chance to + switch in assembly mode. */ + if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug) + { + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + step_over_function (ecs); + keep_going (ecs); + return; +} + +static void +adjust_pc_after_break (struct execution_control_state *ecs) +{ + CORE_ADDR stop_pc; + + /* If this target does not decrement the PC after breakpoints, then + we have nothing to do. */ + if (DECR_PC_AFTER_BREAK == 0) + return; + + /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP. If + we aren't, just return. + + We assume that waitkinds other than TARGET_WAITKIND_STOPPED are not + affected by DECR_PC_AFTER_BREAK. Other waitkinds which are implemented + by software breakpoints should be handled through the normal breakpoint + layer. + + NOTE drow/2004-01-31: On some targets, breakpoints may generate + different signals (SIGILL or SIGEMT for instance), but it is less + clear where the PC is pointing afterwards. It may not match + DECR_PC_AFTER_BREAK. I don't know any specific target that generates + these signals at breakpoints (the code has been in GDB since at least + 1992) so I can not guess how to handle them here. + + In earlier versions of GDB, a target with HAVE_NONSTEPPABLE_WATCHPOINTS + would have the PC after hitting a watchpoint affected by + DECR_PC_AFTER_BREAK. I haven't found any target with both of these set + in GDB history, and it seems unlikely to be correct, so + HAVE_NONSTEPPABLE_WATCHPOINTS is not checked here. */ + + if (ecs->ws.kind != TARGET_WAITKIND_STOPPED) + return; + + if (ecs->ws.value.sig != TARGET_SIGNAL_TRAP) + return; + + /* Find the location where (if we've hit a breakpoint) the breakpoint would + be. */ + stop_pc = read_pc_pid (ecs->ptid) - DECR_PC_AFTER_BREAK; + + /* If we're software-single-stepping, then assume this is a breakpoint. + NOTE drow/2004-01-17: This doesn't check that the PC matches, or that + we're even in the right thread. The software-single-step code needs + some modernization. + + If we're not software-single-stepping, then we first check that there + is an enabled software breakpoint at this address. If there is, and + we weren't using hardware-single-step, then we've hit the breakpoint. + + If we were using hardware-single-step, we check prev_pc; if we just + stepped over an inserted software breakpoint, then we should decrement + the PC and eventually report hitting the breakpoint. The prev_pc check + prevents us from decrementing the PC if we just stepped over a jump + instruction and landed on the instruction after a breakpoint. + + The last bit checks that we didn't hit a breakpoint in a signal handler + without an intervening stop in sigtramp, which is detected by a new + stack pointer value below any usual function calling stack adjustments. + + NOTE drow/2004-01-17: I'm not sure that this is necessary. The check + predates checking for software single step at the same time. Also, + if we've moved into a signal handler we should have seen the + signal. */ + + if ((SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + || (software_breakpoint_inserted_here_p (stop_pc) + && !(currently_stepping (ecs) + && prev_pc != stop_pc + && !(step_range_end && INNER_THAN (read_sp (), (step_sp - 16)))))) + write_pc_pid (stop_pc, ecs->ptid); +} /* Given an execution control state that has been freshly filled in by an event from the inferior, figure out what it means and take @@ -1249,7 +1393,6 @@ pc_in_sigtramp (CORE_ADDR pc) void handle_inferior_event (struct execution_control_state *ecs) { - CORE_ADDR real_stop_pc; /* NOTE: cagney/2003-03-28: If you're looking at this code and thinking that the variable stepped_after_stopped_by_watchpoint isn't used, then you're wrong! The macro STOPPED_BY_WATCHPOINT, @@ -1262,6 +1405,8 @@ handle_inferior_event (struct execution_control_state *ecs) target_last_wait_ptid = ecs->ptid; target_last_waitstatus = *ecs->wp; + adjust_pc_after_break (ecs); + switch (ecs->infwait_state) { case infwait_thread_hop_state: @@ -1367,7 +1512,22 @@ handle_inferior_event (struct execution_control_state *ecs) terminal for any messages produced by breakpoint_re_set. */ target_terminal_ours_for_output (); - SOLIB_ADD (NULL, 0, NULL, auto_solib_add); + /* NOTE: cagney/2003-11-25: Make certain that the target + stack's section table is kept up-to-date. Architectures, + (e.g., PPC64), use the section table to perform + operations such as address => section name and hence + require the table to contain all sections (including + those found in shared libraries). */ + /* NOTE: cagney/2003-11-25: Pass current_target and not + exec_ops to SOLIB_ADD. This is because current GDB is + only tooled to propagate section_table changes out from + the "current_target" (see target_resize_to_sections), and + not up from the exec stratum. This, of course, isn't + right. "infrun.c" should only interact with the + exec/process stratum, instead relying on the target stack + to propagate relevant changes (stop, section table + changed, ...) up to other layers. */ + SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); target_terminal_inferior (); /* Reinsert breakpoints and continue. */ @@ -1429,13 +1589,7 @@ handle_inferior_event (struct execution_control_state *ecs) stop_pc = read_pc (); - /* Assume that catchpoints are not really software breakpoints. If - some future target implements them using software breakpoints then - that target is responsible for fudging DECR_PC_AFTER_BREAK. Thus - we pass 1 for the NOT_A_SW_BREAKPOINT argument, so that - bpstat_stop_status will not decrement the PC. */ - - stop_bpstat = bpstat_stop_status (&stop_pc, 1); + stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); ecs->random_signal = !bpstat_explains_signal (stop_bpstat); @@ -1484,13 +1638,7 @@ handle_inferior_event (struct execution_control_state *ecs) ecs->saved_inferior_ptid = inferior_ptid; inferior_ptid = ecs->ptid; - /* Assume that catchpoints are not really software breakpoints. If - some future target implements them using software breakpoints then - that target is responsible for fudging DECR_PC_AFTER_BREAK. Thus - we pass 1 for the NOT_A_SW_BREAKPOINT argument, so that - bpstat_stop_status will not decrement the PC. */ - - stop_bpstat = bpstat_stop_status (&stop_pc, 1); + stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); ecs->random_signal = !bpstat_explains_signal (stop_bpstat); inferior_ptid = ecs->saved_inferior_ptid; @@ -1600,19 +1748,15 @@ handle_inferior_event (struct execution_control_state *ecs) /* Check if a regular breakpoint has been hit before checking for a potential single step breakpoint. Otherwise, GDB will not see this breakpoint hit when stepping onto breakpoints. */ - if (breakpoints_inserted - && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK)) + if (breakpoints_inserted && breakpoint_here_p (stop_pc)) { ecs->random_signal = 0; - if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, - ecs->ptid)) + if (!breakpoint_thread_match (stop_pc, ecs->ptid)) { int remove_status; /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */ - if (DECR_PC_AFTER_BREAK) - write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->ptid); remove_status = remove_breakpoints (); /* Did we fail to remove breakpoints? If so, try @@ -1625,7 +1769,7 @@ handle_inferior_event (struct execution_control_state *ecs) if (remove_status != 0) { /* FIXME! This is obviously non-portable! */ - write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, ecs->ptid); + write_pc_pid (stop_pc + 4, ecs->ptid); /* We need to restart all the threads now, * unles we're running in scheduler-locked mode. * Use currently_stepping to determine whether to @@ -1659,17 +1803,6 @@ handle_inferior_event (struct execution_control_state *ecs) } else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) { - /* Readjust the stop_pc as it is off by DECR_PC_AFTER_BREAK - compared to the value it would have if the system stepping - capability was used. This allows the rest of the code in - this function to use this address without having to worry - whether software single step is in use or not. */ - if (DECR_PC_AFTER_BREAK) - { - stop_pc -= DECR_PC_AFTER_BREAK; - write_pc_pid (stop_pc, ecs->ptid); - } - sw_single_step_trap_p = 1; ecs->random_signal = 0; } @@ -1801,9 +1934,6 @@ handle_inferior_event (struct execution_control_state *ecs) includes evaluating watchpoints, things will come to a stop in the correct manner. */ - if (DECR_PC_AFTER_BREAK) - write_pc (stop_pc - DECR_PC_AFTER_BREAK); - remove_breakpoints (); registers_changed (); target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); /* Single step */ @@ -1845,15 +1975,20 @@ handle_inferior_event (struct execution_control_state *ecs) will be made according to the signal handling tables. */ /* First, distinguish signals caused by the debugger from signals - that have to do with the program's own actions. - Note that breakpoint insns may cause SIGTRAP or SIGILL - or SIGEMT, depending on the operating system version. - Here we detect when a SIGILL or SIGEMT is really a breakpoint - and change it to SIGTRAP. */ + that have to do with the program's own actions. Note that + breakpoint insns may cause SIGTRAP or SIGILL or SIGEMT, depending + on the operating system version. Here we detect when a SIGILL or + SIGEMT is really a breakpoint and change it to SIGTRAP. We do + something similar for SIGSEGV, since a SIGSEGV will be generated + when we're trying to execute a breakpoint instruction on a + non-executable stack. This happens for call dummy breakpoints + for architectures like SPARC that place call dummies on the + stack. */ if (stop_signal == TARGET_SIGNAL_TRAP || (breakpoints_inserted && (stop_signal == TARGET_SIGNAL_ILL + || stop_signal == TARGET_SIGNAL_SEGV || stop_signal == TARGET_SIGNAL_EMT)) || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP) @@ -1898,29 +2033,8 @@ handle_inferior_event (struct execution_control_state *ecs) else { /* See if there is a breakpoint at the current PC. */ + stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); - /* The second argument of bpstat_stop_status is meant to help - distinguish between a breakpoint trap and a singlestep trap. - This is only important on targets where DECR_PC_AFTER_BREAK - is non-zero. The prev_pc test is meant to distinguish between - singlestepping a trap instruction, and singlestepping thru a - jump to the instruction following a trap instruction. - - Therefore, pass TRUE if our reason for stopping is - something other than hitting a breakpoint. We do this by - checking that either: we detected earlier a software single - step trap or, 1) stepping is going on and 2) we didn't hit - a breakpoint in a signal handler without an intervening stop - in sigtramp, which is detected by a new stack pointer value - below any usual function calling stack adjustments. */ - stop_bpstat = - bpstat_stop_status - (&stop_pc, - sw_single_step_trap_p - || (currently_stepping (ecs) - && prev_pc != stop_pc - DECR_PC_AFTER_BREAK - && !(step_range_end - && INNER_THAN (read_sp (), (step_sp - 16))))); /* Following in case break condition called a function. */ stop_print_frame = 1; @@ -1937,10 +2051,14 @@ handle_inferior_event (struct execution_control_state *ecs) If someone ever tries to get get call dummys on a non-executable stack to work (where the target would stop - with something like a SIGSEG), then those tests might need to - be re-instated. Given, however, that the tests were only + with something like a SIGSEGV), then those tests might need + to be re-instated. Given, however, that the tests were only enabled when momentary breakpoints were not being used, I - suspect that it won't be the case. */ + suspect that it won't be the case. + + NOTE: kettenis/2004-02-05: Indeed such checks don't seem to + be necessary for call dummies on a non-executable stack on + SPARC. */ if (stop_signal == TARGET_SIGNAL_TRAP) ecs->random_signal @@ -2190,7 +2308,22 @@ process_event_stop_test: terminal for any messages produced by breakpoint_re_set. */ target_terminal_ours_for_output (); - SOLIB_ADD (NULL, 0, NULL, auto_solib_add); + /* NOTE: cagney/2003-11-25: Make certain that the target + stack's section table is kept up-to-date. Architectures, + (e.g., PPC64), use the section table to perform + operations such as address => section name and hence + require the table to contain all sections (including + those found in shared libraries). */ + /* NOTE: cagney/2003-11-25: Pass current_target and not + exec_ops to SOLIB_ADD. This is because current GDB is + only tooled to propagate section_table changes out from + the "current_target" (see target_resize_to_sections), and + not up from the exec stratum. This, of course, isn't + right. "infrun.c" should only interact with the + exec/process stratum, instead relying on the target stack + to propagate relevant changes (stop, section table + changed, ...) up to other layers. */ + SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); target_terminal_inferior (); /* Try to reenable shared library breakpoints, additional @@ -2201,7 +2334,7 @@ process_event_stop_test: gdb of events. This allows the user to get control and place breakpoints in initializer routines for dynamically loaded objects (among other things). */ - if (stop_on_solib_events) + if (stop_on_solib_events || stop_stack_dummy) { stop_stepping (ecs); return; @@ -2336,7 +2469,8 @@ process_event_stop_test: if (step_over_calls == STEP_OVER_UNDEBUGGABLE && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc)) { - CORE_ADDR pc_after_resolver = SKIP_SOLIB_RESOLVER (stop_pc); + CORE_ADDR pc_after_resolver = + gdbarch_skip_solib_resolver (current_gdbarch, stop_pc); if (pc_after_resolver) { @@ -2453,88 +2587,8 @@ process_event_stop_test: || ecs->stop_func_name == 0) { /* It's a subroutine call. */ - - if ((step_over_calls == STEP_OVER_NONE) - || ((step_range_end == 1) - && in_prologue (prev_pc, ecs->stop_func_start))) - { - /* I presume that step_over_calls is only 0 when we're - supposed to be stepping at the assembly language level - ("stepi"). Just stop. */ - /* Also, maybe we just did a "nexti" inside a prolog, - so we thought it was a subroutine call but it was not. - Stop as well. FENN */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc)) - { - /* We're doing a "next". */ - - if (pc_in_sigtramp (stop_pc) - && frame_id_inner (step_frame_id, - frame_id_build (read_sp (), 0))) - /* We stepped out of a signal handler, and into its - calling trampoline. This is misdetected as a - subroutine call, but stepping over the signal - trampoline isn't such a bad idea. In order to do that, - we have to ignore the value in step_frame_id, since - that doesn't represent the frame that'll reach when we - return from the signal trampoline. Otherwise we'll - probably continue to the end of the program. */ - step_frame_id = null_frame_id; - - step_over_function (ecs); - keep_going (ecs); - return; - } - - /* If we are in a function call trampoline (a stub between - the calling routine and the real function), locate the real - function. That's what tells us (a) whether we want to step - into it at all, and (b) what prologue we want to run to - the end of, if we do step into it. */ - real_stop_pc = skip_language_trampoline (stop_pc); - if (real_stop_pc == 0) - real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); - if (real_stop_pc != 0) - ecs->stop_func_start = real_stop_pc; - - /* If we have line number information for the function we - are thinking of stepping into, step into it. - - If there are several symtabs at that PC (e.g. with include - files), just want to know whether *any* of them have line - numbers. find_pc_line handles this. */ - { - struct symtab_and_line tmp_sal; - - tmp_sal = find_pc_line (ecs->stop_func_start, 0); - if (tmp_sal.line != 0) - { - step_into_function (ecs); - return; - } - } - - /* If we have no line number and the step-stop-if-no-debug - is set, we stop the step so that the user has a chance to - switch in assembly mode. */ - if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug) - { - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - step_over_function (ecs); - keep_going (ecs); + handle_step_into_function (ecs); return; - } /* We've wandered out of the step range. */ @@ -2556,7 +2610,7 @@ process_event_stop_test: if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) { /* Determine where this trampoline returns. */ - real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); + CORE_ADDR real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); /* Only proceed through if we know where it's going. */ if (real_stop_pc) @@ -2637,6 +2691,22 @@ process_event_stop_test: /* In the case where we just stepped out of a function into the middle of a line of the caller, continue stepping, but step_frame_id must be modified to current frame */ +#if 0 + /* NOTE: cagney/2003-10-16: I think this frame ID inner test is too + generous. It will trigger on things like a step into a frameless + stackless leaf function. I think the logic should instead look + at the unwound frame ID has that should give a more robust + indication of what happened. */ + if (step-ID == current-ID) + still stepping in same function; + else if (step-ID == unwind (current-ID)) + stepped into a function; + else + stepped out of a function; + /* Of course this assumes that the frame ID unwind code is robust + and we're willing to introduce frame unwind logic into this + function. Fortunately, those days are nearly upon us. */ +#endif { struct frame_id current_frame = get_frame_id (get_current_frame ()); if (!(frame_id_inner (current_frame, step_frame_id))) @@ -2715,15 +2785,33 @@ step_into_function (struct execution_control_state *ecs) /* If the prologue ends in the middle of a source line, continue to the end of that source line (if it is still within the function). Otherwise, just go to end of prologue. */ -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* no, don't either. It skips any code that's legitimately on the - first line. */ -#else if (ecs->sal.end && ecs->sal.pc != ecs->stop_func_start && ecs->sal.end < ecs->stop_func_end) ecs->stop_func_start = ecs->sal.end; -#endif + + /* Architectures which require breakpoint adjustment might not be able + to place a breakpoint at the computed address. If so, the test + ``ecs->stop_func_start == stop_pc'' will never succeed. Adjust + ecs->stop_func_start to an address at which a breakpoint may be + legitimately placed. + + Note: kevinb/2004-01-19: On FR-V, if this adjustment is not + made, GDB will enter an infinite loop when stepping through + optimized code consisting of VLIW instructions which contain + subinstructions corresponding to different source lines. On + FR-V, it's not permitted to place a breakpoint on any but the + first subinstruction of a VLIW instruction. When a breakpoint is + set, GDB will adjust the breakpoint address to the beginning of + the VLIW instruction. Thus, we need to make the corresponding + adjustment here when computing the stop address. */ + + if (gdbarch_adjust_breakpoint_address_p (current_gdbarch)) + { + ecs->stop_func_start + = gdbarch_adjust_breakpoint_address (current_gdbarch, + ecs->stop_func_start); + } if (ecs->stop_func_start == stop_pc) { @@ -2792,7 +2880,7 @@ step_over_function (struct execution_control_state *ecs) - avoid handling the case where the PC hasn't been saved in the prologue analyzer - Unfortunatly, not five lines further down, is a call to + Unfortunately, not five lines further down, is a call to get_frame_id() and that is guarenteed to trigger the prologue analyzer. @@ -2908,17 +2996,6 @@ keep_going (struct execution_control_state *ecs) if (stop_signal == TARGET_SIGNAL_TRAP && !signal_program[stop_signal]) stop_signal = TARGET_SIGNAL_0; -#ifdef SHIFT_INST_REGS - /* I'm not sure when this following segment applies. I do know, - now, that we shouldn't rewrite the regs when we were stopped - by a random signal from the inferior process. */ - /* FIXME: Shouldn't this be based on the valid bit of the SXIP? - (this is only used on the 88k). */ - - if (!bpstat_explains_signal (stop_bpstat) - && (stop_signal != TARGET_SIGNAL_CHLD) && !stopped_by_random_signal) - SHIFT_INST_REGS (); -#endif /* SHIFT_INST_REGS */ resume (currently_stepping (ecs), stop_signal); } @@ -3077,6 +3154,7 @@ normal_stop (void) previous_inferior_ptid = inferior_ptid; } + /* NOTE drow/2004-01-17: Is this still necessary? */ /* Make sure that the current_frame's pc is correct. This is a correction for setting up the frame info before doing DECR_PC_AFTER_BREAK */ @@ -3623,7 +3701,7 @@ void write_inferior_status_register (struct inferior_status *inf_status, int regno, LONGEST val) { - int size = REGISTER_RAW_SIZE (regno); + int size = DEPRECATED_REGISTER_RAW_SIZE (regno); void *buf = alloca (size); store_signed_integer (buf, size, val); regcache_raw_write (inf_status->registers, regno, buf); @@ -3915,8 +3993,8 @@ build_infrun (void) void _initialize_infrun (void) { - register int i; - register int numsigs; + int i; + int numsigs; struct cmd_list_element *c; register_gdbarch_swap (&stop_registers, sizeof (stop_registers), NULL); @@ -4029,31 +4107,12 @@ to the user would be loading/unloading of a new library.\n", &setlist), &showlis c = add_set_enum_cmd ("follow-fork-mode", class_run, follow_fork_mode_kind_names, &follow_fork_mode_string, -/* ??rehrauer: The "both" option is broken, by what may be a 10.20 - kernel problem. It's also not terribly useful without a GUI to - help the user drive two debuggers. So for now, I'm disabling - the "both" option. */ -/* "Set debugger response to a program call of fork \ - or vfork.\n\ - A fork or vfork creates a new process. follow-fork-mode can be:\n\ - parent - the original process is debugged after a fork\n\ - child - the new process is debugged after a fork\n\ - both - both the parent and child are debugged after a fork\n\ - ask - the debugger will ask for one of the above choices\n\ - For \"both\", another copy of the debugger will be started to follow\n\ - the new child process. The original debugger will continue to follow\n\ - the original parent process. To distinguish their prompts, the\n\ - debugger copy's prompt will be changed.\n\ - For \"parent\" or \"child\", the unfollowed process will run free.\n\ - By default, the debugger will follow the parent process.", - */ "Set debugger response to a program call of fork \ or vfork.\n\ A fork or vfork creates a new process. follow-fork-mode can be:\n\ parent - the original process is debugged after a fork\n\ child - the new process is debugged after a fork\n\ - ask - the debugger will ask for one of the above choices\n\ -For \"parent\" or \"child\", the unfollowed process will run free.\n\ +The unfollowed process will continue to run.\n\ By default, the debugger will follow the parent process.", &setlist); add_show_from_set (c, &showlist);