h64952
s 00211/00000/00000
d D 1.1 82/08/02 15:14:41 cecily 1 0
e
u
U
t
T
I 1
#
/*
 *
 *	UNIX debugger
 *
 */

#include "defs.h"


MSG		ODDADR;
MSG		BADDAT;
MSG		BADTXT;
MAP		txtmap;
MAP		datmap;
INT		wtflag;
STRING		errflg;
INT		errno;

INT		pid;




/* file handling and access routines */

/*
 * Write a short integer value
 */
puts(adr,space,value)
L_INT	adr;
S_INT	value;
{
	access(WT,adr,space,&value,sizeof(value));
}

/*
 * Write a long integer value
 */
putl(adr,space,value)
L_INT	adr;
L_INT	value;
{
	access(WT,adr,space,&value,sizeof(value));
}

/*
 * Read a short integer value
 */
POS
getsh(adr, space)
L_INT		adr;
{
	unsigned short int	w;

	access(RD,adr,space,&w,sizeof(w));
	return(w);
}

/*
 * Read a long integer value
 */
L_INT
getl(adr, space)
L_INT	adr;
{
	L_INT	w;

	access(RD,adr,space,&w,sizeof(w));
	return(w);
}

/*
 * Read an integer value & check for errors
 */
POS
chkget(n, space)
L_INT		n;
{
	REG POS		w;

	w = get(n, space);
	chkerr();
	return(w);
}

/*
 * Common routine to read / write child process / dump / file
 */
access(mode,adr,space,avalue,len)
L_INT	adr;
union {
	L_INT	*lap;
	S_INT	*sap;
} avalue;
{
	INT		w, w1, pmode, rd, file;
	rd = mode==RD;

	IF space == NSP
	THEN	IF rd
		THEN	IF len == sizeof(L_INT)
			THEN *avalue.lap = 0L;
			ELSE *avalue.sap = 0;
			FI
		FI
		return;
	FI

#ifndef STANDALONE
	IF pid		/* tracing on? */
	THEN	errno = 0;
		IF rd		/* read from child process */
		THEN	pmode = (space&DSP?RDUSER:RIUSER);
#ifdef interdata
			IF len == sizeof(L_INT)
			THEN	w = ptrace(pmode, pid, adr&~01, 0);
				IF adr&01
				THEN	w <<= 8;
					w |= ptrace(pmode, pid, adr+3, 0)&0377;
				FI
				*avalue.lap = w;
			ELSE	w = ptrace(pmode, pid, adr&~01, 0);
				IF adr&01
				THEN	w >>= 8;
				ELSE	w >>= 16;
				FI
				*avalue.sap = w;
			FI
#else
			IF len == sizeof(L_INT)
			THEN	access(mode,adr,space,avalue.sap,sizeof(S_INT));
				access(mode,adr+sizeof(S_INT),space,
					avalue.sap+1,sizeof(S_INT));
			ELSE	w = ptrace(pmode,pid,shorten(adr&~01),0);
				IF adr&01
				THEN	w = (w>>8)&LOBYTE;
					w |= ptrace(pmode,pid,shorten(adr+1),0);
				FI
				*avalue.sap = w;
			FI
#endif
		ELSE		/* write to child process */
			IF adr&01 THEN error(ODDADR); FI
			pmode = (space&DSP?WDUSER:WIUSER);
#ifdef interdata
			IF len == sizeof(L_INT)
			THEN	ptrace(pmode, pid, adr, *avalue.lap);
			ELSE	w = ptrace(space&DSP?RDUSER:RIUSER,pid,adr,0);
				w = (*avalue.sap<<16) | (w&0xffff);
				ptrace(pmode, pid, adr, w);
			FI
#else
			IF len == sizeof(L_INT)
			THEN	access(mode,adr,space,avalue.sap,sizeof(S_INT));
				access(mode,adr+sizeof(S_INT),space,
					avalue.sap+1,sizeof(S_INT));
			ELSE	w = ptrace(pmode,pid,shorten(adr),*avalue.sap);
			FI
#endif
		FI
		IF errno
		THEN errflg = (space&DSP ? BADDAT : BADTXT);
		FI
		return;
	FI
#endif

	/*
	 * Access file
	 */
	IF !rd ANDF !wtflag
	THEN	error("not in write mode");
	FI
	IF !chkmap(&adr,space)
	THEN	IF rd
		THEN	IF len == sizeof(L_INT)
			THEN *avalue.lap = 0L;
			ELSE *avalue.sap = 0;
			FI
		FI
		return;
	FI
	file=(space&DSP?datmap.ufd:txtmap.ufd);
	IF longseek(file,adr)==0 ORF
	   (rd ? read(file, avalue.sap, len) : write(file, avalue.sap, len)) < 1
	THEN	errflg=(space&DSP?BADDAT:BADTXT);
	FI
}

chkmap(adr,space)
	REG L_INT	*adr;
	REG INT		space;
{
	REG MAPPTR amap;
	amap=((space&DSP?&datmap:&txtmap));
	IF space&STAR ORF !within(*adr,amap->b1,amap->e1)
	THEN IF within(*adr,amap->b2,amap->e2)
	     THEN *adr += (amap->f2)-(amap->b2);
	     ELSE errflg=(space&DSP?BADDAT:BADTXT); return(0);
	     FI
	ELSE *adr += (amap->f1)-(amap->b1);
	FI
	return(1);
}

within(adr,lbd,ubd)
L_INT	adr, lbd, ubd;
{
	return(adr>=lbd && adr<ubd);
}
E 1
