V10/cmd/adb/cray/trcrun.c

Compare this file to the similar file:
Show the results in this format:

/*
 * machine-specific functions for running the debugged process
 * v7-style (ptrace)
 */

#include "defs.h"
#include "regs.h"
#include "ptrace.h"
#include "bkpt.h"
#include "space.h"
#include <sys/param.h>
#include <signal.h>

extern char lastc, peekc;
extern ADDR txtsize;

static BKPT stepbk, step2bk;

/*
 * kill process
 */

killpcs()
{

	ptrace(P_KILL, pid, 0, 0);
}

/*
 * grab the process already opened (but not traced);
 * stop it so we can look at it
 */

grab()
{

	error("antique system, can't grab");
}

/*
 * turn off tracing & let it go
 */

ungrab()
{

	error("antique system, can't ungrab");
}

/*
 * get the program to be debugged ready to run
 * program is left stopped at the beginning (so we can poke in breakpoints)
 */

extern int (*sigint)(), (*sigqit)();

startpcs()
{

	if ((pid = fork()) == 0) {
		close(fsym);
		close(fcor);
		signal(SIGINT, sigint);
		signal(SIGQUIT, sigqit);
		doexec();
		exit(0);
	}
	if (pid == -1)
		error("cannot fork");
	bpwait();
	if (adrflg)
		rput(PC, wtoa(adrval));
	while (rdc() != EOR)
		;
	reread();
}

/*
 * set process running, single-stepped
 */

runstep(keepsig)
int keepsig;
{
	WORD ins;
	ADDR pc;
	BKPT bk;

	/*
	 * this is the hard part:
	 * the cray can't single step
	 */
	pc = (ADDR)rtow(rget(PC));
	ins = stow(sget(pc, CORF|INSTSP));
	switch (ins & 0177000) {
	case 05000:	/* j bXX */
		pc = (ADDR)rtow(rget(B00 + (ins&077))) * 2;
		break;

	case 010000:	/* jaz exp */
	case 011000:	/* jan exp */
	case 012000:	/* jap exp */
	case 013000:	/* jam exp */
	case 014000:	/* jsz exp */
	case 015000:	/* jsn exp */
	case 016000:	/* jsp exp */
	case 017000:	/* jsm exp */
		/* conditional branch: need 2 breaks */
		step2bk.loc = pc + 4;
		bkput(&step2bk, 1);
		step2bk.flag = BKPTTMP;
		/* fall through ... */
	case 06000:	/* j exp */
	case 07000:	/* r exp */

		pc = (ADDR)(((ins & 0777)<<16) | stow(sget(pc+2, CORF|INSTSP))) * 2;
		break;

	case 020000:
	case 021000:
	case 040000:
	case 041000:
	case 0100000:
	case 0101000:
	case 0102000:
	case 0103000:
	case 0104000:
	case 0105000:
	case 0106000:
	case 0107000:
	case 0110000:
	case 0111000:
	case 0112000:
	case 0113000:
	case 0114000:
	case 0115000:
	case 0116000:
	case 0117000:
	case 0120000:
	case 0121000:
	case 0122000:
	case 0123000:
	case 0124000:
	case 0125000:
	case 0126000:
	case 0127000:
	case 0130000:
	case 0131000:
	case 0132000:
	case 0133000:
	case 0134000:
	case 0135000:
	case 0136000:
	case 0137000:
		pc += 4;	/* two-parcel instruction */
		break;

	default:
		pc += 2;
		break;
	}
	stepbk.loc = pc;
	bkput(&stepbk, 1);
	stepbk.flag = BKPTTMP;
	runrun(keepsig);
}

/*
 * set process running
 */

runrun(keepsig)
int keepsig;
{

	ptrace(P_CONT, pid, CONTNEXT, keepsig ? signo : 0);
}

/*
 * exec the program to be debugged
 * opening standard input and output as requested
 */

extern char **environ;

doexec()
{
	char *argl[MAXARG];
	char args[LINSIZ];
	register char *p;
	register char **ap;
	register char *thisarg;

	ap = argl;
	p = args;
	*ap++ = symfil;
	for (rdc(); lastc != EOR;) {
		thisarg = p;
		if (lastc == '<' || lastc == '>') {
			*p++ = lastc;
			rdc();
		}
		while (lastc != EOR && lastc != SPC && lastc != TB) {
			*p++ = lastc;
			readchar();
		}
		if (lastc == SPC || lastc == TB)
			rdc();
		*p++ = 0;
		if (*thisarg == '<') {
			close(0);
			if (open(&thisarg[1], 0) < 0) {
				printf("%s: cannot open\n", &thisarg[1]);
				_exit(0);
			}
		}
		else if (*thisarg == '>') {
			close(1);
			if (creat(&thisarg[1], 0666) < 0) {
				printf("%s: cannot create\n", &thisarg[1]);
				_exit(0);
			}
		}
		else
			*ap++ = thisarg;
	}
	*ap = NULL;
	ptrace(P_INIT, 0, (int *)0, 0);
	execve(symfil, argl, environ);
	perror(symfil);
}

/*
 * wait for the process to stop;
 * pick up status and registers when it does
 */

#define	WSLEEP	10

extern int errno;

bpwait()
{
	register int w;
	int stat;
	int (*isig)();
	int nulsig();

	isig = signal(SIGINT, SIG_IGN);
	while ((w = wait(&stat)) != -1 && w != pid)
		;
	signal(SIGINT, isig);
	if (w == -1)
		errflg = "wait failed";
	else if ((stat & 0177) == 0177) {	/* trace status */
		signo = (stat >> 8) & 0177;
		mapimage();
		/*
		 * awful hack to get breakpoints right
		 */
		if (signo == SIGEMT)
			rput(PC, wtor(rtow(rget(PC))-2));
		if (signo == SIGTRAP || signo == SIGEMT)
			signo = 0;
		else {
			sigprint();
			newline();
		}
		if (stepbk.flag) {
			stepbk.flag = 0;
			bkput(&stepbk, 0);
		}
		if (step2bk.flag) {
			step2bk.flag = 0;
			bkput(&step2bk, 0);
		}
		return;
	}
	else {
		errflg = "process terminated";
		sigcode = 0;
		if ((signo = stat & 0177) != 0)
			sigprint();
		if (stat & 0200) {
			prints(" - core dumped");
			corfil = "core";
		}
		pid = 0;
		setcor();
	}
}

/*
 * is the right-hand file a process image?
 */

trcimage()
{

	return (pid != 0);
}

/*
 * grab some data from the user block,
 * before maps are set up (ugh)
 */

int
trcunab(off)
int off;
{
	int data;

	errno = 0;
	data = ptrace(P_RDU, pid, off, 0);
	if (errno) {
		errflg = "can't read user block";
		return (0);
	}
	return (data);
}