15511Slinton /* Copyright (c) 1982 Regents of the University of California */
25511Slinton 
3*5761Slinton static char sccsid[] = "@(#)step.c 1.2 02/11/82";
45511Slinton 
55511Slinton /*
65511Slinton  * Continue execution up to the next source line.
75511Slinton  *
85511Slinton  * We call "nextaddr" from the machine module to figure out
95511Slinton  * what the object address is that corresponds to the next source line.
105511Slinton  * If nextaddr returns -1, then the end of the program has been reached.
115511Slinton  *
125511Slinton  * There are two ways to define the next source line depending on what
135511Slinton  * is desired when a procedure or function call is encountered.  Step
145511Slinton  * stops at the beginning of the procedure or call; next skips over it.
155511Slinton  */
165511Slinton 
175511Slinton #include "defs.h"
185511Slinton #include "process.h"
195511Slinton #include "machine.h"
205511Slinton #include "breakpoint.h"
215511Slinton #include "source.h"
225511Slinton #include "mappings.h"
235511Slinton #include "process.rep"
245511Slinton 
25*5761Slinton #   if (isvax)
26*5761Slinton #       include "machine/vaxops.h"
275511Slinton 
28*5761Slinton 	LOCAL ADDRESS getcall();
29*5761Slinton #   endif
305511Slinton 
315511Slinton /*
325511Slinton  * Stepc is what is called when the step command is given.
335511Slinton  * It has to play with the "isstopped" information.
345511Slinton  */
355511Slinton 
365511Slinton stepc()
375511Slinton {
38*5761Slinton     if (!isstopped) {
39*5761Slinton 	error("can't continue execution");
40*5761Slinton     }
41*5761Slinton     isstopped = FALSE;
42*5761Slinton     dostep(FALSE);
43*5761Slinton     isstopped = TRUE;
445511Slinton }
455511Slinton 
465511Slinton next()
475511Slinton {
48*5761Slinton     if (!isstopped) {
49*5761Slinton 	error("can't continue execution");
50*5761Slinton     }
51*5761Slinton     isstopped = FALSE;
52*5761Slinton     dostep(TRUE);
53*5761Slinton     isstopped = TRUE;
545511Slinton }
555511Slinton 
565511Slinton step()
575511Slinton {
58*5761Slinton     dostep(FALSE);
595511Slinton }
605511Slinton 
615511Slinton /*
625511Slinton  * Resume execution up to the given address.  It is assumed that
635511Slinton  * no breakpoints exist between the current address and the one
645511Slinton  * we're stepping to.  This saves us from setting all the breakpoints.
655511Slinton  */
665511Slinton 
675511Slinton stepto(addr)
685511Slinton ADDRESS addr;
695511Slinton {
70*5761Slinton     setbp(addr);
71*5761Slinton     resume();
72*5761Slinton     unsetbp(addr);
73*5761Slinton     if (!isbperr()) {
74*5761Slinton 	printstatus();
75*5761Slinton     }
765511Slinton }
775511Slinton 
785511Slinton LOCAL dostep(isnext)
795511Slinton BOOLEAN isnext;
805511Slinton {
81*5761Slinton     register ADDRESS addr;
82*5761Slinton     register LINENO line;
83*5761Slinton     char *filename;
845511Slinton 
85*5761Slinton     addr = pc;
86*5761Slinton     do {
87*5761Slinton #       if (isvaxpx)
88*5761Slinton 	    addr = nextaddr(addr, isnext);
89*5761Slinton #       else
90*5761Slinton 	    if (isnext && (addr = getcall(addr)) != 0) {
91*5761Slinton 		stepto(addr);
92*5761Slinton 	    } else {
93*5761Slinton 		pstep(process);
94*5761Slinton 		addr = process->pc;
95*5761Slinton 		pc = process->pc;
96*5761Slinton 		errnum = process->signo;
97*5761Slinton 		if (!isbperr()) {
98*5761Slinton 		    printstatus();
99*5761Slinton 		}
100*5761Slinton 	    }
101*5761Slinton #       endif
102*5761Slinton 	line = linelookup(addr);
103*5761Slinton     } while (line == 0 && !ss_instructions);
104*5761Slinton     stepto(addr);
105*5761Slinton     curline = line;
1065511Slinton }
1075511Slinton 
1085511Slinton # if (isvax)
1095511Slinton 
1105511Slinton /*
1115511Slinton  * If the current address contains a call instruction, return the
1125511Slinton  * address of the instruction where control will return.
1135511Slinton  *
1145511Slinton  * This function is intentionally dependent on a particular type
1155511Slinton  * of calling sequence.
1165511Slinton  */
1175511Slinton 
1185511Slinton LOCAL ADDRESS getcall(addr)
1195511Slinton ADDRESS addr;
1205511Slinton {
121*5761Slinton     VAXOP op;
1225511Slinton 
123*5761Slinton     iread(&op, addr, sizeof(addr));
124*5761Slinton     if (op == O_CALLS) {
125*5761Slinton 	return(addr + 7);
126*5761Slinton     } else {
127*5761Slinton 	return(0);
128*5761Slinton     }
1295511Slinton }
1305511Slinton 
1315511Slinton # endif
132