1*5511Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5511Slinton 
3*5511Slinton static char sccsid[] = "@(#)step.c 1.1 01/18/82";
4*5511Slinton 
5*5511Slinton /*
6*5511Slinton  * Continue execution up to the next source line.
7*5511Slinton  *
8*5511Slinton  * We call "nextaddr" from the machine module to figure out
9*5511Slinton  * what the object address is that corresponds to the next source line.
10*5511Slinton  * If nextaddr returns -1, then the end of the program has been reached.
11*5511Slinton  *
12*5511Slinton  * There are two ways to define the next source line depending on what
13*5511Slinton  * is desired when a procedure or function call is encountered.  Step
14*5511Slinton  * stops at the beginning of the procedure or call; next skips over it.
15*5511Slinton  */
16*5511Slinton 
17*5511Slinton #include "defs.h"
18*5511Slinton #include "process.h"
19*5511Slinton #include "machine.h"
20*5511Slinton #include "breakpoint.h"
21*5511Slinton #include "source.h"
22*5511Slinton #include "mappings.h"
23*5511Slinton #include "process.rep"
24*5511Slinton 
25*5511Slinton #	if (isvax)
26*5511Slinton #		include "machine/vaxops.h"
27*5511Slinton 
28*5511Slinton 		LOCAL ADDRESS getcall();
29*5511Slinton #	endif
30*5511Slinton 
31*5511Slinton /*
32*5511Slinton  * Stepc is what is called when the step command is given.
33*5511Slinton  * It has to play with the "isstopped" information.
34*5511Slinton  */
35*5511Slinton 
36*5511Slinton stepc()
37*5511Slinton {
38*5511Slinton 	if (!isstopped) {
39*5511Slinton 		error("can't continue execution");
40*5511Slinton 	}
41*5511Slinton 	isstopped = FALSE;
42*5511Slinton 	dostep(FALSE);
43*5511Slinton 	isstopped = TRUE;
44*5511Slinton }
45*5511Slinton 
46*5511Slinton next()
47*5511Slinton {
48*5511Slinton 	if (!isstopped) {
49*5511Slinton 		error("can't continue execution");
50*5511Slinton 	}
51*5511Slinton 	isstopped = FALSE;
52*5511Slinton 	dostep(TRUE);
53*5511Slinton 	isstopped = TRUE;
54*5511Slinton }
55*5511Slinton 
56*5511Slinton step()
57*5511Slinton {
58*5511Slinton 	dostep(FALSE);
59*5511Slinton }
60*5511Slinton 
61*5511Slinton /*
62*5511Slinton  * Resume execution up to the given address.  It is assumed that
63*5511Slinton  * no breakpoints exist between the current address and the one
64*5511Slinton  * we're stepping to.  This saves us from setting all the breakpoints.
65*5511Slinton  */
66*5511Slinton 
67*5511Slinton stepto(addr)
68*5511Slinton ADDRESS addr;
69*5511Slinton {
70*5511Slinton 	setbp(addr);
71*5511Slinton 	resume();
72*5511Slinton 	unsetbp(addr);
73*5511Slinton 	if (!isbperr()) {
74*5511Slinton 		printstatus();
75*5511Slinton 	}
76*5511Slinton }
77*5511Slinton 
78*5511Slinton LOCAL dostep(isnext)
79*5511Slinton BOOLEAN isnext;
80*5511Slinton {
81*5511Slinton 	register ADDRESS addr;
82*5511Slinton 	register LINENO line;
83*5511Slinton 	char *filename;
84*5511Slinton 
85*5511Slinton 	addr = pc;
86*5511Slinton 	do {
87*5511Slinton #		if (isvaxpx)
88*5511Slinton 			addr = nextaddr(addr, isnext);
89*5511Slinton #		else
90*5511Slinton 			if (isnext && (addr = getcall(addr)) != 0) {
91*5511Slinton 				stepto(addr);
92*5511Slinton 			} else {
93*5511Slinton 				pstep(process);
94*5511Slinton 				addr = process->pc;
95*5511Slinton 				pc = process->pc;
96*5511Slinton 				errnum = process->signo;
97*5511Slinton 				if (!isbperr()) {
98*5511Slinton 					printstatus();
99*5511Slinton 				}
100*5511Slinton 			}
101*5511Slinton #		endif
102*5511Slinton 		line = linelookup(addr);
103*5511Slinton 	} while (line == 0 && !ss_instructions);
104*5511Slinton 	stepto(addr);
105*5511Slinton 	curline = line;
106*5511Slinton 	filename = srcfilename(addr);
107*5511Slinton 	if (filename != cursource) {
108*5511Slinton 		skimsource(filename);
109*5511Slinton 	}
110*5511Slinton }
111*5511Slinton 
112*5511Slinton # if (isvax)
113*5511Slinton 
114*5511Slinton /*
115*5511Slinton  * If the current address contains a call instruction, return the
116*5511Slinton  * address of the instruction where control will return.
117*5511Slinton  *
118*5511Slinton  * This function is intentionally dependent on a particular type
119*5511Slinton  * of calling sequence.
120*5511Slinton  */
121*5511Slinton 
122*5511Slinton LOCAL ADDRESS getcall(addr)
123*5511Slinton ADDRESS addr;
124*5511Slinton {
125*5511Slinton 	VAXOP op;
126*5511Slinton 
127*5511Slinton 	iread(&op, addr, sizeof(addr));
128*5511Slinton 	if (op == O_CALLS) {
129*5511Slinton 		return(addr + 7);
130*5511Slinton 	} else {
131*5511Slinton 		return(0);
132*5511Slinton 	}
133*5511Slinton }
134*5511Slinton 
135*5511Slinton # endif
136