/*
 * functions for running the debugged process
 */

#include "defs.h"
#include "fns.h"


int child;
int msgfd = -1;
int notefd = -1;
int pcspid = -1;
int pcsactive = 0;

void
setpcs(void)
{
	char buf[128];

	if(pid && pid != pcspid){
		if(msgfd >= 0){
			close(msgfd);
			msgfd = -1;
		}
		if(notefd >= 0){
			close(notefd);
			notefd = -1;
		}
		pcspid = -1;
		sprint(buf, "/proc/%d/ctl", pid);
		msgfd = open(buf, OWRITE);
		if(msgfd < 0)
			error("can't open control file");
		sprint(buf, "/proc/%d/note", pid);
		notefd = open(buf, ORDWR);
		if(notefd < 0)
			error("can't open note file");
		pcspid = pid;
	}
}

void
msgpcs(char *msg)
{
	char err[ERRMAX];

	setpcs();
	if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
		errstr(err, sizeof err);
		if(strcmp(err, "interrupted") != 0)
			endpcs();
		errors("can't write control file", err);
	}
}

/*
 * empty the note buffer and toss pending breakpoint notes
 */
void
unloadnote(void)
{
	char err[ERRMAX];

	setpcs();
	for(; nnote<NNOTE; nnote++){
		switch(read(notefd, note[nnote], sizeof note[nnote])){
		case -1:
			errstr(err, sizeof err);
			if(strcmp(err, "interrupted") != 0)
				endpcs();
			errors("can't read note file", err);
		case 0:
			return;
		}
		note[nnote][ERRMAX-1] = '\0';
		if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
			--nnote;
	}
}

/*
 * reload the note buffer
 */
void
loadnote(void)
{
	int i;
	char err[ERRMAX];

	setpcs();
	for(i=0; i<nnote; i++){
		if(write(notefd, note[i], strlen(note[i])) < 0){
			errstr(err, sizeof err);
			if(strcmp(err, "interrupted") != 0)
				endpcs();
			errors("can't write note file", err);
		}
	}
	nnote = 0;
}

void
notes(void)
{
	int n;

	if(nnote == 0)
		return;
	dprint("notes:\n");
	for(n=0; n<nnote; n++)
		dprint("%d:\t%s\n", n, note[n]);
}

void
killpcs(void)
{
	msgpcs("kill");
}

void
grab(void)
{
	flush();
	msgpcs("stop");
	bpwait();
}

void
ungrab(void)
{
	msgpcs("start");
}

void
doexec(void)
{
	char *argl[MAXARG];
	char args[LINSIZ];
	char *p;
	char **ap;
	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], OREAD) < 0) {
				print("%s: cannot open\n", &thisarg[1]);
				_exits(0);
			}
		}
		else if (*thisarg == '>') {
			close(1);
			if (create(&thisarg[1], OWRITE, 0666) < 0) {
				print("%s: cannot create\n", &thisarg[1]);
				_exits(0);
			}
		}
		else
			*ap++ = thisarg;
	}
	*ap = 0;
	exec(symfil, argl);
	perror(symfil);
}

char	procname[100];

void
startpcs(void)
{
	if ((pid = fork()) == 0) {
		pid = getpid();
		msgpcs("hang");
		doexec();
		exits(0);
	}

	if (pid == -1)
		error("can't fork");
	child++;
	sprint(procname, "/proc/%d/mem", pid);
	corfil = procname;
	msgpcs("waitstop");
	bpwait();
	if (adrflg)
		rput(correg, mach->pc, adrval);
	while (rdc() != EOR)
		;
	reread();
}

void
runstep(ulong loc, int keepnote)
{
	int nfoll;
	ulong foll[3];
	BKPT bkpt[3];
	int i;

	if(mach->foll == 0){
		dprint("stepping unimplemented; assuming not a branch\n");
		nfoll = 1;
		foll[0] = loc+mach->pcquant;
	}else {
		nfoll = mach->foll(cormap, correg, loc, foll);
		if (nfoll < 0)
			error("%r");
	}
	memset(bkpt, 0, sizeof bkpt);
	for(i=0; i<nfoll; i++){
		if(foll[i] == loc)
			error("can't single step: next instruction is dot");
		bkpt[i].loc = foll[i];
		bkput(&bkpt[i], 1);
	}
	runrun(keepnote);
	for(i=0; i<nfoll; i++)
		bkput(&bkpt[i], 0);
}

void
bpwait(void)
{
	setcor();
	unloadnote();
}

void
runrun(int keepnote)
{
	int on;

	on = nnote;
	unloadnote();
	if(on != nnote){
		notes();
		error("not running: new notes pending");
	}
	if(keepnote)
		loadnote();
	else
		nnote = 0;
	flush();
	msgpcs("startstop");
	bpwait();
}

void
bkput(BKPT *bp, int install)
{
	char buf[256];
	ulong loc;
	int ret;

	errstr(buf, sizeof buf);
/*
	if(mach->bpfix)
		loc = (*mach->bpfix)(bp->loc);
	else
*/
	loc = bp->loc;
	if(install){
		ret = get1(cormap, loc, bp->save, mach->bpsize);
		if (ret > 0)
			ret = put1(cormap, loc, mach->bpinst, mach->bpsize);
	}else
		ret = put1(cormap, loc, bp->save, mach->bpsize);
	if(ret < 0){
		sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
		print(buf);
		read(0, buf, 100);
	}
}
