122514Sdist /*
222514Sdist  * Copyright (c) 1980 Regents of the University of California.
322514Sdist  * All rights reserved.  The Berkeley software License Agreement
422514Sdist  * specifies the terms and conditions for redistribution.
522514Sdist  */
65510Slinton 
722514Sdist #ifndef lint
8*36538Smckusick static char sccsid[] = "@(#)start.c	5.3 (Berkeley) 01/09/89";
922514Sdist #endif not lint
1030848Smckusick 
115510Slinton /*
125510Slinton  * Begin execution.
135510Slinton  *
145510Slinton  * For px, pstart does a traced exec to read in px and then stop.  But we
155510Slinton  * want control after px has read in the obj file and before it starts
165653Slinton  * executing.  The zeroth argument to px tells it to give us control
175510Slinton  * by sending itself a signal just prior to interpreting.
185510Slinton  *
195510Slinton  * We set a "END_BP" breakpoint at the end of the code so that the
205510Slinton  * process data doesn't disappear after the program terminates.
215510Slinton  */
225510Slinton 
235510Slinton #include "defs.h"
245510Slinton #include <signal.h>
255510Slinton #include "process.h"
265510Slinton #include "machine.h"
275653Slinton #include "main.h"
285510Slinton #include "breakpoint.h"
295510Slinton #include "source.h"
305510Slinton #include "object.h"
315510Slinton #include "mappings.h"
325510Slinton #include "sym.h"
335510Slinton #include "process.rep"
345510Slinton 
3530848Smckusick #include "pxinfo.h"
365510Slinton 
375510Slinton start(argv, infile, outfile)
385510Slinton char **argv;
395510Slinton char *infile, *outfile;
405510Slinton {
415714Slinton     char *cmd;
425510Slinton 
435714Slinton     setsigtrace();
44*36538Smckusick     cmd = "px";
455714Slinton     pstart(process, cmd, argv, infile, outfile);
465714Slinton     if (process->status == STOPPED) {
4730848Smckusick 	TRAPARGS *ap, t;
485653Slinton 
4930848Smckusick 	pcont(process);
5030848Smckusick 	if (process->status != STOPPED) {
5130848Smckusick 	    if (option('t')) {
5230848Smckusick 		quit(process->exitval);
5330848Smckusick 	    } else {
5430848Smckusick 		panic("px exited with %d", process->exitval);
555714Slinton 	    }
5630848Smckusick 	}
5730848Smckusick #ifdef tahoe
5830848Smckusick 	dread(&ap, process->fp, sizeof(ap));
5930848Smckusick 	ap = (TRAPARGS *)((unsigned)ap - 4);
6030848Smckusick 	dread(&RETLOC, process->fp - 8, sizeof(RETLOC));
6130848Smckusick #else
6230848Smckusick 	dread(&ap, process->fp + 2*sizeof(int), sizeof(ap));
6330848Smckusick #endif
6430848Smckusick 	dread(&t, ap, sizeof(TRAPARGS));
6530848Smckusick 
6630848Smckusick #define NARGS 5
6730848Smckusick #ifdef tahoe
6830848Smckusick #	define STKNARGS (sizeof(int)*(NARGS+1))
6930848Smckusick #	define NARGLOC  t.trp_removed
7030848Smckusick #else
7130848Smckusick #	define STKNARGS (NARGS)
7230848Smckusick #	define NARGLOC  t.nargs
7330848Smckusick #endif
7430848Smckusick 	if (NARGLOC != STKNARGS) {
7530848Smckusick 	    if (option('t')) {
7630848Smckusick 		unsetsigtraces(process);
7730848Smckusick 		pcont(process);
7830848Smckusick 		quit(process->exitval);
7930848Smckusick 	    } else {
8030848Smckusick 		panic("start: args out of sync");
815714Slinton 	    }
8230848Smckusick 	}
8330848Smckusick 	DISPLAY = t.disp;
8430848Smckusick 	DP = t.dp;
8530848Smckusick 	ENDOFF = t.objstart;
86*36538Smckusick 	PCADDR = t.pcaddr;
8730848Smckusick 	LOOPADDR = t.loopaddr;
885714Slinton 	pc = 0;
895714Slinton 	curfunc = program;
905714Slinton 	if (objsize != 0) {
915714Slinton 	    addbp(lastaddr(), END_BP, NIL, NIL, NIL, 0);
925510Slinton 	}
935714Slinton     }
945510Slinton }
955510Slinton 
965510Slinton /*
975510Slinton  * Note the termination of the program.  We do this so as to avoid
985510Slinton  * having the process exit, which would make the values of variables
995510Slinton  * inaccessible.
1005510Slinton  *
1015510Slinton  * Although the END_BP should really be deleted, it is taken
1025510Slinton  * care of by fixbps the next time the program runs.
1035510Slinton  */
1045510Slinton 
1055510Slinton endprogram()
1065510Slinton {
1075714Slinton     if (ss_variables) {
1085714Slinton 	prvarnews();
1095714Slinton     }
1105714Slinton     printf("\nexecution completed\n");
1115714Slinton     curfunc = program;
1125761Slinton     skimsource(srcfilename(pc));
1135714Slinton     curline = lastlinenum;
1145714Slinton     erecover();
1155510Slinton }
1165510Slinton 
1175510Slinton /*
1185510Slinton  * set up what signals we want to trace
1195510Slinton  */
1205510Slinton 
1215510Slinton LOCAL setsigtrace()
1225510Slinton {
1235714Slinton     register PROCESS *p;
1245510Slinton 
1255714Slinton     p = process;
1265714Slinton     psigtrace(p, SIGINT, TRUE);
1275714Slinton     psigtrace(p, SIGTRAP, TRUE);
1285714Slinton     psigtrace(p, SIGIOT, TRUE);
1295739Slinton     psigtrace(p, SIGILL, TRUE);
1305761Slinton     psigtrace(p, SIGBUS, TRUE);
1315510Slinton }
132