15509Slinton /* Copyright (c) 1982 Regents of the University of California */
25509Slinton 
3*6240Slinton static char sccsid[] = "@(#)runcont.c 1.5 03/15/82";
45509Slinton 
55509Slinton /*
65652Slinton  * Execution management.
75509Slinton  */
85509Slinton 
95509Slinton #include "defs.h"
105509Slinton #include <signal.h>
115509Slinton #include "process.h"
125509Slinton #include "machine.h"
135509Slinton #include "object.h"
145652Slinton #include "main.h"
155509Slinton #include "breakpoint.h"
165509Slinton #include "command.h"
175509Slinton #include "process.rep"
185509Slinton 
196073Slinton #define MAXNARGS 100        /* maximum number of arguments to RUN */
205509Slinton 
215652Slinton typedef char *String;
225509Slinton 
235509Slinton LOCAL BOOLEAN just_started;
245509Slinton LOCAL int argc;
255652Slinton LOCAL String argv[MAXNARGS];
265652Slinton LOCAL String infile;
275652Slinton LOCAL String outfile;
286073Slinton LOCAL PROCESS pbuf;
29*6240Slinton PROCESS *process = &pbuf;
305509Slinton 
315509Slinton /*
325652Slinton  * This is a px-related kludge to deal with the possibility
335652Slinton  * of object code magically coming from a tmp file.
345509Slinton  */
355509Slinton 
365652Slinton LOCAL String mode;
375652Slinton LOCAL String realname;
385652Slinton 
395652Slinton setargs(m, r)
405652Slinton char *m, *r;
415652Slinton {
426073Slinton     mode = m;
436073Slinton     realname = r;
445652Slinton }
455652Slinton 
465652Slinton /*
475652Slinton  * Initialize the argument list.
485652Slinton  */
495652Slinton 
505509Slinton arginit()
515509Slinton {
526073Slinton     infile = NIL;
536073Slinton     outfile = NIL;
546073Slinton #   if (isvaxpx)
556073Slinton 	argv[0] = mode;
566073Slinton 	argv[1] = objname;
576073Slinton 	if (option('t') && realname == NIL) {
586073Slinton 	    argc = 2;
596073Slinton 	} else {
606073Slinton 	    argv[2] = realname;
616073Slinton 	    argc = 3;
626073Slinton 	}
636073Slinton #   else
646073Slinton 	argv[0] = objname;
656073Slinton 	argc = 1;
666073Slinton #   endif
675509Slinton }
685509Slinton 
695509Slinton /*
705652Slinton  * Add an argument to the list for the debuggee.
715509Slinton  */
725509Slinton 
735509Slinton newarg(arg)
745652Slinton String arg;
755509Slinton {
766073Slinton     if (argc >= MAXNARGS) {
776073Slinton 	error("too many arguments to run");
786073Slinton     }
796073Slinton     argv[argc++] = arg;
805509Slinton }
815509Slinton 
825509Slinton /*
835652Slinton  * Set the standard input for the debuggee.
845509Slinton  */
855509Slinton 
865509Slinton inarg(filename)
875652Slinton String filename;
885509Slinton {
896073Slinton     if (infile != NIL) {
906073Slinton 	error("multiple input redirects");
916073Slinton     }
926073Slinton     infile = filename;
935509Slinton }
945509Slinton 
955509Slinton /*
965652Slinton  * Set the standard output for the debuggee.
975652Slinton  * Probably should check to avoid overwriting an existing file.
985509Slinton  */
995509Slinton 
1005509Slinton outarg(filename)
1015652Slinton String filename;
1025509Slinton {
1036073Slinton     if (outfile != NIL) {
1046073Slinton 	error("multiple output redirect");
1056073Slinton     }
1066073Slinton     outfile = filename;
1075509Slinton }
1085509Slinton 
1095509Slinton /*
1105652Slinton  * Initial start of the process.  The idea is to get it to the point
1115652Slinton  * where the object code has been loaded but execution has not begun.
1125509Slinton  */
1135509Slinton 
1145652Slinton initstart()
1155652Slinton {
1166073Slinton     arginit();
1176073Slinton     argv[argc] = NIL;
1186073Slinton     initcache(process);
1196073Slinton     start(argv, infile, outfile);
1206081Slinton     if (process->status != STOPPED) {
1216081Slinton 	panic("could not start program");
1226081Slinton     }
1235652Slinton }
1245652Slinton 
1255652Slinton /*
1265652Slinton  * Run starts debuggee executing.
1275652Slinton  */
1285652Slinton 
1295509Slinton run()
1305509Slinton {
1316073Slinton     fixbps();
1326073Slinton     curline = 0;
1336073Slinton     argv[argc] = NIL;
1346073Slinton     start(argv, infile, outfile);
1356081Slinton     if (process->status == STOPPED) {
1366081Slinton 	just_started = TRUE;
1376081Slinton 	isstopped = FALSE;
1386081Slinton 	cont();
1396081Slinton     } else if (option('r')) {
1406081Slinton 	panic("could not start program");
1416081Slinton     }
1425509Slinton }
1435509Slinton 
1445509Slinton /*
1455652Slinton  * Continue execution wherever we left off.
1465509Slinton  *
1475509Slinton  * Note that this routine never returns.  Eventually bpact() will fail
1485509Slinton  * and we'll call printstatus or step will call it.
1495509Slinton  */
1505509Slinton 
1515509Slinton typedef int INTFUNC();
1525509Slinton 
1535509Slinton LOCAL INTFUNC *dbintr;
1545509Slinton LOCAL intr();
1555509Slinton 
1566073Slinton #define succeeds    == TRUE
1576073Slinton #define fails       == FALSE
1585509Slinton 
1595509Slinton cont()
1605509Slinton {
1616073Slinton     dbintr = signal(SIGINT, intr);
1626073Slinton     if (just_started) {
1636073Slinton 	just_started = FALSE;
1646073Slinton     } else {
1656073Slinton 	if (!isstopped) {
1666073Slinton 	    error("can't continue execution");
1676073Slinton 	}
1686073Slinton 	isstopped = FALSE;
1696073Slinton 	step();
1706073Slinton     }
1716073Slinton     for (;;) {
1726073Slinton 	if (single_stepping) {
1736073Slinton 	    printnews();
1745509Slinton 	} else {
1756073Slinton 	    setallbps();
1766073Slinton 	    resume();
1776073Slinton 	    unsetallbps();
1786073Slinton 	    if (bpact() fails) {
1796073Slinton 		printstatus();
1806073Slinton 	    }
1815509Slinton 	}
1826073Slinton 	step();
1836073Slinton     }
1846073Slinton     /* NOTREACHED */
1855509Slinton }
1865509Slinton 
1875509Slinton /*
1885509Slinton  * This routine is called if we get an interrupt while "running" px
1895509Slinton  * but actually in the debugger.  Could happen, for example, while
1905509Slinton  * processing breakpoints.
1915509Slinton  *
1925509Slinton  * We basically just want to keep going; the assumption is
1935509Slinton  * that when the process resumes it will get the interrupt
1945509Slinton  * which will then be handled.
1955509Slinton  */
1965509Slinton 
1975509Slinton LOCAL intr()
1985509Slinton {
1996073Slinton     signal(SIGINT, intr);
2005509Slinton }
2015509Slinton 
2025509Slinton fixintr()
2035509Slinton {
2046073Slinton     signal(SIGINT, dbintr);
2055509Slinton }
206