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