122513Sdist /*
222513Sdist  * Copyright (c) 1980 Regents of the University of California.
322513Sdist  * All rights reserved.  The Berkeley software License Agreement
422513Sdist  * specifies the terms and conditions for redistribution.
522513Sdist  */
65509Slinton 
722513Sdist #ifndef lint
8*46291Storek static char sccsid[] = "@(#)runcont.c	5.3 (Berkeley) 02/05/91";
922513Sdist #endif not lint
105509Slinton 
115509Slinton /*
125652Slinton  * Execution management.
135509Slinton  */
145509Slinton 
155509Slinton #include "defs.h"
165509Slinton #include <signal.h>
175509Slinton #include "process.h"
185509Slinton #include "machine.h"
195509Slinton #include "object.h"
205652Slinton #include "main.h"
215509Slinton #include "breakpoint.h"
225509Slinton #include "command.h"
235509Slinton #include "process.rep"
245509Slinton 
256073Slinton #define MAXNARGS 100        /* maximum number of arguments to RUN */
265509Slinton 
275652Slinton typedef char *String;
285509Slinton 
295509Slinton LOCAL BOOLEAN just_started;
305509Slinton LOCAL int argc;
315652Slinton LOCAL String argv[MAXNARGS];
325652Slinton LOCAL String infile;
335652Slinton LOCAL String outfile;
346073Slinton LOCAL PROCESS pbuf;
356240Slinton PROCESS *process = &pbuf;
365509Slinton 
375509Slinton /*
385652Slinton  * This is a px-related kludge to deal with the possibility
395652Slinton  * of object code magically coming from a tmp file.
405509Slinton  */
415509Slinton 
425652Slinton LOCAL String mode;
435652Slinton LOCAL String realname;
445652Slinton 
455652Slinton setargs(m, r)
465652Slinton char *m, *r;
475652Slinton {
486073Slinton     mode = m;
496073Slinton     realname = r;
505652Slinton }
515652Slinton 
525652Slinton /*
535652Slinton  * Initialize the argument list.
545652Slinton  */
555652Slinton 
565509Slinton arginit()
575509Slinton {
586073Slinton     infile = NIL;
596073Slinton     outfile = NIL;
6030848Smckusick     argv[0] = mode;
6130848Smckusick     argv[1] = objname;
6230848Smckusick     if (option('t') && realname == NIL) {
6330848Smckusick 	argc = 2;
6430848Smckusick     } else {
6530848Smckusick 	argv[2] = realname;
6630848Smckusick 	argc = 3;
6730848Smckusick     }
685509Slinton }
695509Slinton 
705509Slinton /*
715652Slinton  * Add an argument to the list for the debuggee.
725509Slinton  */
735509Slinton 
745509Slinton newarg(arg)
755652Slinton String arg;
765509Slinton {
776073Slinton     if (argc >= MAXNARGS) {
786073Slinton 	error("too many arguments to run");
796073Slinton     }
806073Slinton     argv[argc++] = arg;
815509Slinton }
825509Slinton 
835509Slinton /*
845652Slinton  * Set the standard input for the debuggee.
855509Slinton  */
865509Slinton 
875509Slinton inarg(filename)
885652Slinton String filename;
895509Slinton {
906073Slinton     if (infile != NIL) {
916073Slinton 	error("multiple input redirects");
926073Slinton     }
936073Slinton     infile = filename;
945509Slinton }
955509Slinton 
965509Slinton /*
975652Slinton  * Set the standard output for the debuggee.
985652Slinton  * Probably should check to avoid overwriting an existing file.
995509Slinton  */
1005509Slinton 
1015509Slinton outarg(filename)
1025652Slinton String filename;
1035509Slinton {
1046073Slinton     if (outfile != NIL) {
1056073Slinton 	error("multiple output redirect");
1066073Slinton     }
1076073Slinton     outfile = filename;
1085509Slinton }
1095509Slinton 
1105509Slinton /*
1115652Slinton  * Initial start of the process.  The idea is to get it to the point
1125652Slinton  * where the object code has been loaded but execution has not begun.
1135509Slinton  */
1145509Slinton 
1155652Slinton initstart()
1165652Slinton {
1176073Slinton     arginit();
1186073Slinton     argv[argc] = NIL;
1196073Slinton     initcache(process);
1206073Slinton     start(argv, infile, outfile);
1216081Slinton     if (process->status != STOPPED) {
1226081Slinton 	panic("could not start program");
1236081Slinton     }
1245652Slinton }
1255652Slinton 
1265652Slinton /*
1275652Slinton  * Run starts debuggee executing.
1285652Slinton  */
1295652Slinton 
1305509Slinton run()
1315509Slinton {
1326073Slinton     fixbps();
1336073Slinton     curline = 0;
1346073Slinton     argv[argc] = NIL;
1356073Slinton     start(argv, infile, outfile);
1366081Slinton     if (process->status == STOPPED) {
1376081Slinton 	just_started = TRUE;
1386081Slinton 	isstopped = FALSE;
1396081Slinton 	cont();
1406081Slinton     } else if (option('r')) {
1416081Slinton 	panic("could not start program");
1426081Slinton     }
1435509Slinton }
1445509Slinton 
1455509Slinton /*
1465652Slinton  * Continue execution wherever we left off.
1475509Slinton  *
1485509Slinton  * Note that this routine never returns.  Eventually bpact() will fail
1495509Slinton  * and we'll call printstatus or step will call it.
1505509Slinton  */
1515509Slinton 
152*46291Storek typedef void SIGFUN();
1535509Slinton 
154*46291Storek LOCAL SIGFUN *dbintr;
155*46291Storek LOCAL void intr();
1565509Slinton 
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 
197*46291Storek LOCAL void intr()
1985509Slinton {
1996073Slinton     signal(SIGINT, intr);
2005509Slinton }
2015509Slinton 
2025509Slinton fixintr()
2035509Slinton {
2046073Slinton     signal(SIGINT, dbintr);
2055509Slinton }
206