1*22515Sdist /*
2*22515Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22515Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22515Sdist  * specifies the terms and conditions for redistribution.
5*22515Sdist  */
65511Slinton 
7*22515Sdist #ifndef lint
8*22515Sdist static char sccsid[] = "@(#)step.c	5.1 (Berkeley) 06/06/85";
9*22515Sdist #endif not lint
105511Slinton /*
115511Slinton  * Continue execution up to the next source line.
125511Slinton  *
135511Slinton  * We call "nextaddr" from the machine module to figure out
145511Slinton  * what the object address is that corresponds to the next source line.
155511Slinton  * If nextaddr returns -1, then the end of the program has been reached.
165511Slinton  *
175511Slinton  * There are two ways to define the next source line depending on what
185511Slinton  * is desired when a procedure or function call is encountered.  Step
195511Slinton  * stops at the beginning of the procedure or call; next skips over it.
205511Slinton  */
215511Slinton 
225511Slinton #include "defs.h"
235511Slinton #include "process.h"
245511Slinton #include "machine.h"
255511Slinton #include "breakpoint.h"
265511Slinton #include "source.h"
275511Slinton #include "mappings.h"
285511Slinton #include "process.rep"
295511Slinton 
305761Slinton #   if (isvax)
315761Slinton #       include "machine/vaxops.h"
325511Slinton 
335761Slinton 	LOCAL ADDRESS getcall();
345761Slinton #   endif
355511Slinton 
365511Slinton /*
375511Slinton  * Stepc is what is called when the step command is given.
385511Slinton  * It has to play with the "isstopped" information.
395511Slinton  */
405511Slinton 
415511Slinton stepc()
425511Slinton {
435761Slinton     if (!isstopped) {
445761Slinton 	error("can't continue execution");
455761Slinton     }
465761Slinton     isstopped = FALSE;
475761Slinton     dostep(FALSE);
485761Slinton     isstopped = TRUE;
495511Slinton }
505511Slinton 
515511Slinton next()
525511Slinton {
535761Slinton     if (!isstopped) {
545761Slinton 	error("can't continue execution");
555761Slinton     }
565761Slinton     isstopped = FALSE;
575761Slinton     dostep(TRUE);
585761Slinton     isstopped = TRUE;
595511Slinton }
605511Slinton 
615511Slinton step()
625511Slinton {
635761Slinton     dostep(FALSE);
645511Slinton }
655511Slinton 
665511Slinton /*
675511Slinton  * Resume execution up to the given address.  It is assumed that
685511Slinton  * no breakpoints exist between the current address and the one
695511Slinton  * we're stepping to.  This saves us from setting all the breakpoints.
705511Slinton  */
715511Slinton 
725511Slinton stepto(addr)
735511Slinton ADDRESS addr;
745511Slinton {
755761Slinton     setbp(addr);
765761Slinton     resume();
775761Slinton     unsetbp(addr);
785761Slinton     if (!isbperr()) {
795761Slinton 	printstatus();
805761Slinton     }
815511Slinton }
825511Slinton 
835511Slinton LOCAL dostep(isnext)
845511Slinton BOOLEAN isnext;
855511Slinton {
865761Slinton     register ADDRESS addr;
875761Slinton     register LINENO line;
885761Slinton     char *filename;
895511Slinton 
905761Slinton     addr = pc;
915761Slinton     do {
925761Slinton #       if (isvaxpx)
935761Slinton 	    addr = nextaddr(addr, isnext);
945761Slinton #       else
955761Slinton 	    if (isnext && (addr = getcall(addr)) != 0) {
965761Slinton 		stepto(addr);
975761Slinton 	    } else {
985761Slinton 		pstep(process);
995761Slinton 		addr = process->pc;
1005761Slinton 		pc = process->pc;
1015761Slinton 		errnum = process->signo;
1025761Slinton 		if (!isbperr()) {
1035761Slinton 		    printstatus();
1045761Slinton 		}
1055761Slinton 	    }
1065761Slinton #       endif
1075761Slinton 	line = linelookup(addr);
1085761Slinton     } while (line == 0 && !ss_instructions);
1095761Slinton     stepto(addr);
1105761Slinton     curline = line;
1115511Slinton }
1125511Slinton 
1135511Slinton # if (isvax)
1145511Slinton 
1155511Slinton /*
1165511Slinton  * If the current address contains a call instruction, return the
1175511Slinton  * address of the instruction where control will return.
1185511Slinton  *
1195511Slinton  * This function is intentionally dependent on a particular type
1205511Slinton  * of calling sequence.
1215511Slinton  */
1225511Slinton 
1235511Slinton LOCAL ADDRESS getcall(addr)
1245511Slinton ADDRESS addr;
1255511Slinton {
1265761Slinton     VAXOP op;
1275511Slinton 
1285761Slinton     iread(&op, addr, sizeof(addr));
1295761Slinton     if (op == O_CALLS) {
1305761Slinton 	return(addr + 7);
1315761Slinton     } else {
1325761Slinton 	return(0);
1335761Slinton     }
1345511Slinton }
1355511Slinton 
1365511Slinton # endif
137