1*48096Sbostic /*-
2*48096Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*48096Sbostic  * All rights reserved.
4*48096Sbostic  *
5*48096Sbostic  * %sccs.include.redist.c%
622513Sdist  */
75509Slinton 
822513Sdist #ifndef lint
9*48096Sbostic static char sccsid[] = "@(#)runcont.c	5.4 (Berkeley) 04/16/91";
10*48096Sbostic #endif /* not lint */
115509Slinton 
125509Slinton /*
135652Slinton  * Execution management.
145509Slinton  */
155509Slinton 
165509Slinton #include "defs.h"
175509Slinton #include <signal.h>
185509Slinton #include "process.h"
195509Slinton #include "machine.h"
205509Slinton #include "object.h"
215652Slinton #include "main.h"
225509Slinton #include "breakpoint.h"
235509Slinton #include "command.h"
245509Slinton #include "process.rep"
255509Slinton 
266073Slinton #define MAXNARGS 100        /* maximum number of arguments to RUN */
275509Slinton 
285652Slinton typedef char *String;
295509Slinton 
305509Slinton LOCAL BOOLEAN just_started;
315509Slinton LOCAL int argc;
325652Slinton LOCAL String argv[MAXNARGS];
335652Slinton LOCAL String infile;
345652Slinton LOCAL String outfile;
356073Slinton LOCAL PROCESS pbuf;
366240Slinton PROCESS *process = &pbuf;
375509Slinton 
385509Slinton /*
395652Slinton  * This is a px-related kludge to deal with the possibility
405652Slinton  * of object code magically coming from a tmp file.
415509Slinton  */
425509Slinton 
435652Slinton LOCAL String mode;
445652Slinton LOCAL String realname;
455652Slinton 
465652Slinton setargs(m, r)
475652Slinton char *m, *r;
485652Slinton {
496073Slinton     mode = m;
506073Slinton     realname = r;
515652Slinton }
525652Slinton 
535652Slinton /*
545652Slinton  * Initialize the argument list.
555652Slinton  */
565652Slinton 
575509Slinton arginit()
585509Slinton {
596073Slinton     infile = NIL;
606073Slinton     outfile = NIL;
6130848Smckusick     argv[0] = mode;
6230848Smckusick     argv[1] = objname;
6330848Smckusick     if (option('t') && realname == NIL) {
6430848Smckusick 	argc = 2;
6530848Smckusick     } else {
6630848Smckusick 	argv[2] = realname;
6730848Smckusick 	argc = 3;
6830848Smckusick     }
695509Slinton }
705509Slinton 
715509Slinton /*
725652Slinton  * Add an argument to the list for the debuggee.
735509Slinton  */
745509Slinton 
755509Slinton newarg(arg)
765652Slinton String arg;
775509Slinton {
786073Slinton     if (argc >= MAXNARGS) {
796073Slinton 	error("too many arguments to run");
806073Slinton     }
816073Slinton     argv[argc++] = arg;
825509Slinton }
835509Slinton 
845509Slinton /*
855652Slinton  * Set the standard input for the debuggee.
865509Slinton  */
875509Slinton 
885509Slinton inarg(filename)
895652Slinton String filename;
905509Slinton {
916073Slinton     if (infile != NIL) {
926073Slinton 	error("multiple input redirects");
936073Slinton     }
946073Slinton     infile = filename;
955509Slinton }
965509Slinton 
975509Slinton /*
985652Slinton  * Set the standard output for the debuggee.
995652Slinton  * Probably should check to avoid overwriting an existing file.
1005509Slinton  */
1015509Slinton 
1025509Slinton outarg(filename)
1035652Slinton String filename;
1045509Slinton {
1056073Slinton     if (outfile != NIL) {
1066073Slinton 	error("multiple output redirect");
1076073Slinton     }
1086073Slinton     outfile = filename;
1095509Slinton }
1105509Slinton 
1115509Slinton /*
1125652Slinton  * Initial start of the process.  The idea is to get it to the point
1135652Slinton  * where the object code has been loaded but execution has not begun.
1145509Slinton  */
1155509Slinton 
1165652Slinton initstart()
1175652Slinton {
1186073Slinton     arginit();
1196073Slinton     argv[argc] = NIL;
1206073Slinton     initcache(process);
1216073Slinton     start(argv, infile, outfile);
1226081Slinton     if (process->status != STOPPED) {
1236081Slinton 	panic("could not start program");
1246081Slinton     }
1255652Slinton }
1265652Slinton 
1275652Slinton /*
1285652Slinton  * Run starts debuggee executing.
1295652Slinton  */
1305652Slinton 
1315509Slinton run()
1325509Slinton {
1336073Slinton     fixbps();
1346073Slinton     curline = 0;
1356073Slinton     argv[argc] = NIL;
1366073Slinton     start(argv, infile, outfile);
1376081Slinton     if (process->status == STOPPED) {
1386081Slinton 	just_started = TRUE;
1396081Slinton 	isstopped = FALSE;
1406081Slinton 	cont();
1416081Slinton     } else if (option('r')) {
1426081Slinton 	panic("could not start program");
1436081Slinton     }
1445509Slinton }
1455509Slinton 
1465509Slinton /*
1475652Slinton  * Continue execution wherever we left off.
1485509Slinton  *
1495509Slinton  * Note that this routine never returns.  Eventually bpact() will fail
1505509Slinton  * and we'll call printstatus or step will call it.
1515509Slinton  */
1525509Slinton 
15346291Storek typedef void SIGFUN();
1545509Slinton 
15546291Storek LOCAL SIGFUN *dbintr;
15646291Storek LOCAL void intr();
1575509Slinton 
1586073Slinton #define fails       == FALSE
1595509Slinton 
1605509Slinton cont()
1615509Slinton {
1626073Slinton     dbintr = signal(SIGINT, intr);
1636073Slinton     if (just_started) {
1646073Slinton 	just_started = FALSE;
1656073Slinton     } else {
1666073Slinton 	if (!isstopped) {
1676073Slinton 	    error("can't continue execution");
1686073Slinton 	}
1696073Slinton 	isstopped = FALSE;
1706073Slinton 	step();
1716073Slinton     }
1726073Slinton     for (;;) {
1736073Slinton 	if (single_stepping) {
1746073Slinton 	    printnews();
1755509Slinton 	} else {
1766073Slinton 	    setallbps();
1776073Slinton 	    resume();
1786073Slinton 	    unsetallbps();
1796073Slinton 	    if (bpact() fails) {
1806073Slinton 		printstatus();
1816073Slinton 	    }
1825509Slinton 	}
1836073Slinton 	step();
1846073Slinton     }
1856073Slinton     /* NOTREACHED */
1865509Slinton }
1875509Slinton 
1885509Slinton /*
1895509Slinton  * This routine is called if we get an interrupt while "running" px
1905509Slinton  * but actually in the debugger.  Could happen, for example, while
1915509Slinton  * processing breakpoints.
1925509Slinton  *
1935509Slinton  * We basically just want to keep going; the assumption is
1945509Slinton  * that when the process resumes it will get the interrupt
1955509Slinton  * which will then be handled.
1965509Slinton  */
1975509Slinton 
19846291Storek LOCAL void intr()
1995509Slinton {
2006073Slinton     signal(SIGINT, intr);
2015509Slinton }
2025509Slinton 
2035509Slinton fixintr()
2045509Slinton {
2056073Slinton     signal(SIGINT, dbintr);
2065509Slinton }
207