* infrun.c (wait_for_inferior): Clean up comments which were at

the top of the file, making them more concise and moving them with
	the code (Sorry, Randy, but these stream-of-consciousness comments
	really have to go).  Switch the order of the "&&", which makes
	things clearer and turns out to be an improvement with respect to
	side effects and speed.
This commit is contained in:
Jim Kingdon 1993-10-17 14:30:20 +00:00
parent fb63d460a7
commit c0c14c1e8d

View File

@ -18,90 +18,6 @@ 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. */
/* Notes on the algorithm used in wait_for_inferior to determine if we
just did a subroutine call when stepping. We have the following
information at that point:
Current and previous (just before this step) pc.
Current and previous sp.
Current and previous start of current function.
If the starts of the functions don't match, then
a) We did a subroutine call.
In this case, the pc will be at the beginning of a function.
b) We did a subroutine return.
Otherwise.
c) We did a longjmp.
If we did a longjump, we were doing "nexti", since a next would
have attempted to skip over the assembly language routine in which
the longjmp is coded and would have simply been the equivalent of a
continue. I consider this ok behaivior. We'd like one of two
things to happen if we are doing a nexti through the longjmp()
routine: 1) It behaves as a stepi, or 2) It acts like a continue as
above. Given that this is a special case, and that anybody who
thinks that the concept of sub calls is meaningful in the context
of a longjmp, I'll take either one. Let's see what happens.
Acts like a subroutine return. I can handle that with no problem
at all.
-->So: If the current and previous beginnings of the current
function don't match, *and* the pc is at the start of a function,
we've done a subroutine call. If the pc is not at the start of a
function, we *didn't* do a subroutine call.
-->If the beginnings of the current and previous function do match,
either:
a) We just did a recursive call.
In this case, we would be at the very beginning of a
function and 1) it will have a prologue (don't jump to
before prologue, or 2) (we assume here that it doesn't have
a prologue) there will have been a change in the stack
pointer over the last instruction. (Ie. it's got to put
the saved pc somewhere. The stack is the usual place. In
a recursive call a register is only an option if there's a
prologue to do something with it. This is even true on
register window machines; the prologue sets up the new
window. It might not be true on a register window machine
where the call instruction moved the register window
itself. Hmmm. One would hope that the stack pointer would
also change. If it doesn't, somebody send me a note, and
I'll work out a more general theory.
bug-gdb@prep.ai.mit.edu). This is true (albeit slipperly
so) on all machines I'm aware of:
m68k: Call changes stack pointer. Regular jumps don't.
sparc: Recursive calls must have frames and therefor,
prologues.
vax: All calls have frames and hence change the
stack pointer.
b) We did a return from a recursive call. I don't see that we
have either the ability or the need to distinguish this
from an ordinary jump. The stack frame will be printed
when and if the frame pointer changes; if we are in a
function without a frame pointer, it's the users own
lookout.
c) We did a jump within a function. We assume that this is
true if we didn't do a recursive call.
d) We are in no-man's land ("I see no symbols here"). We
don't worry about this; it will make calls look like simple
jumps (and the stack frames will be printed when the frame
pointer moves), which is a reasonably non-violent response.
*/
#include "defs.h"
#include <string.h>
#include <ctype.h>
@ -1051,15 +967,48 @@ wait_for_inferior ()
SKIP_PROLOGUE (prologue_pc);
}
/* ==> See comments at top of file on this algorithm. <==*/
if ((/* Might be a non-recursive call. If the symbols are missing
enough that stop_func_start == prev_func_start even though
they are really two functions, we will treat some calls as
jumps. */
stop_func_start != prev_func_start
if ((stop_pc < stop_func_start
|| stop_pc >= stop_func_end
|| stop_pc == stop_func_start
|| IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name))
&& (stop_func_start != prev_func_start
|| prologue_pc != stop_func_start
|| stop_sp != prev_sp))
/* Might be a recursive call if either we have a prologue
or the call instruction itself saves the PC on the stack. */
|| prologue_pc != stop_func_start
|| stop_sp != prev_sp)
&& (/* I think this can only happen if stop_func_start is zero
(e.g. stop_pc is in some objfile we don't know about).
If the stop_pc does that (ends up someplace unknown), it
must be some sort of subroutine call. */
stop_pc < stop_func_start
|| stop_pc >= stop_func_end
/* If we do a call, we will be at the start of a function. */
|| stop_pc == stop_func_start
#if 0
/* Not conservative enough for 4.11. FIXME: enable this
after 4.11. */
/* Except on the Alpha with -O (and perhaps other machines
with similar calling conventions), in which we might
call the address after the load of gp. Since prologues
don't contain calls, we can't return to within one, and
we don't jump back into them, so this check is OK. */
|| stop_pc < prologue_pc
#endif
/* If we end up in certain places, it means we did a subroutine
call. I'm not completely sure this is necessary now that we
have the above checks with stop_func_start (and now that
find_pc_partial_function is pickier. */
|| IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)
/* If none of the above apply, it is a jump within a function,
or a return from a subroutine. The other case is longjmp,
which can no longer happen here as long as the
handling_longjmp stuff is working. */
))
{
/* It's a subroutine call. */