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