15509Slinton /* Copyright (c) 1982 Regents of the University of California */ 25509Slinton 3*5652Slinton static char sccsid[] = "@(#)runcont.c 1.2 02/02/82"; 45509Slinton 55509Slinton /* 6*5652Slinton * Execution management. 75509Slinton */ 85509Slinton 95509Slinton #include "defs.h" 105509Slinton #include <signal.h> 115509Slinton #include "process.h" 125509Slinton #include "machine.h" 135509Slinton #include "object.h" 14*5652Slinton #include "main.h" 155509Slinton #include "breakpoint.h" 165509Slinton #include "command.h" 175509Slinton #include "process.rep" 185509Slinton 19*5652Slinton #define MAXNARGS 100 /* maximum number of arguments to RUN */ 205509Slinton 21*5652Slinton typedef char *String; 225509Slinton 235509Slinton LOCAL BOOLEAN just_started; 245509Slinton LOCAL int argc; 25*5652Slinton LOCAL String argv[MAXNARGS]; 26*5652Slinton LOCAL String infile; 27*5652Slinton LOCAL String outfile; 285509Slinton 295509Slinton /* 30*5652Slinton * This is a px-related kludge to deal with the possibility 31*5652Slinton * of object code magically coming from a tmp file. 325509Slinton */ 335509Slinton 34*5652Slinton LOCAL String mode; 35*5652Slinton LOCAL String realname; 36*5652Slinton 37*5652Slinton setargs(m, r) 38*5652Slinton char *m, *r; 39*5652Slinton { 40*5652Slinton mode = m; 41*5652Slinton realname = r; 42*5652Slinton } 43*5652Slinton 44*5652Slinton /* 45*5652Slinton * Initialize the argument list. 46*5652Slinton */ 47*5652Slinton 485509Slinton arginit() 495509Slinton { 505509Slinton infile = NIL; 515509Slinton outfile = NIL; 525509Slinton # if (isvaxpx) 53*5652Slinton argv[0] = mode; 54*5652Slinton argv[1] = objname; 55*5652Slinton if (option('t') && realname == NIL) { 56*5652Slinton argc = 2; 57*5652Slinton } else { 58*5652Slinton argv[2] = realname; 59*5652Slinton argc = 3; 60*5652Slinton } 615509Slinton # else 625509Slinton argv[0] = objname; 635509Slinton argc = 1; 645509Slinton # endif 655509Slinton } 665509Slinton 675509Slinton /* 68*5652Slinton * Add an argument to the list for the debuggee. 695509Slinton */ 705509Slinton 715509Slinton newarg(arg) 72*5652Slinton String arg; 735509Slinton { 745509Slinton if (argc >= MAXNARGS) { 75*5652Slinton error("too many arguments to run"); 765509Slinton } 775509Slinton argv[argc++] = arg; 785509Slinton } 795509Slinton 805509Slinton /* 81*5652Slinton * Set the standard input for the debuggee. 825509Slinton */ 835509Slinton 845509Slinton inarg(filename) 85*5652Slinton String filename; 865509Slinton { 875509Slinton if (infile != NIL) { 885509Slinton error("multiple input redirects"); 895509Slinton } 905509Slinton infile = filename; 915509Slinton } 925509Slinton 935509Slinton /* 94*5652Slinton * Set the standard output for the debuggee. 95*5652Slinton * Probably should check to avoid overwriting an existing file. 965509Slinton */ 975509Slinton 985509Slinton outarg(filename) 99*5652Slinton String filename; 1005509Slinton { 1015509Slinton if (outfile != NIL) { 1025509Slinton error("multiple output redirect"); 1035509Slinton } 1045509Slinton outfile = filename; 1055509Slinton } 1065509Slinton 1075509Slinton /* 108*5652Slinton * Initial start of the process. The idea is to get it to the point 109*5652Slinton * where the object code has been loaded but execution has not begun. 1105509Slinton */ 1115509Slinton 112*5652Slinton initstart() 113*5652Slinton { 114*5652Slinton arginit(); 115*5652Slinton argv[argc] = NIL; 116*5652Slinton start(argv, infile, outfile); 117*5652Slinton } 118*5652Slinton 119*5652Slinton /* 120*5652Slinton * Run starts debuggee executing. 121*5652Slinton */ 122*5652Slinton 1235509Slinton run() 1245509Slinton { 1255509Slinton fixbps(); 1265509Slinton curline = 0; 127*5652Slinton argv[argc] = NIL; 1285509Slinton start(argv, infile, outfile); 1295509Slinton just_started = TRUE; 1305509Slinton isstopped = FALSE; 1315509Slinton cont(); 1325509Slinton } 1335509Slinton 1345509Slinton /* 135*5652Slinton * Continue execution wherever we left off. 1365509Slinton * 1375509Slinton * Note that this routine never returns. Eventually bpact() will fail 1385509Slinton * and we'll call printstatus or step will call it. 1395509Slinton */ 1405509Slinton 1415509Slinton typedef int INTFUNC(); 1425509Slinton 1435509Slinton LOCAL INTFUNC *dbintr; 1445509Slinton LOCAL intr(); 1455509Slinton 1465509Slinton #define succeeds == TRUE 1475509Slinton #define fails == FALSE 1485509Slinton 1495509Slinton cont() 1505509Slinton { 1515509Slinton dbintr = signal(SIGINT, &intr); 1525509Slinton if (just_started) { 1535509Slinton just_started = FALSE; 1545509Slinton } else { 1555509Slinton if (!isstopped) { 1565509Slinton error("can't continue execution"); 1575509Slinton } 1585509Slinton isstopped = FALSE; 1595509Slinton step(); 1605509Slinton } 1615509Slinton for (;;) { 1625509Slinton if (single_stepping) { 1635509Slinton printnews(); 1645509Slinton } else { 1655509Slinton setallbps(); 1665509Slinton resume(); 1675509Slinton unsetallbps(); 1685509Slinton if (bpact() fails) { 1695509Slinton printstatus(); 1705509Slinton } 1715509Slinton } 1725509Slinton step(); 1735509Slinton } 174*5652Slinton /* NOTREACHED */ 1755509Slinton } 1765509Slinton 1775509Slinton /* 1785509Slinton * This routine is called if we get an interrupt while "running" px 1795509Slinton * but actually in the debugger. Could happen, for example, while 1805509Slinton * processing breakpoints. 1815509Slinton * 1825509Slinton * We basically just want to keep going; the assumption is 1835509Slinton * that when the process resumes it will get the interrupt 1845509Slinton * which will then be handled. 1855509Slinton */ 1865509Slinton 1875509Slinton LOCAL intr() 1885509Slinton { 1895509Slinton signal(SIGINT, &intr); 1905509Slinton } 1915509Slinton 1925509Slinton fixintr() 1935509Slinton { 1945509Slinton signal(SIGINT, &dbintr); 1955509Slinton } 196