h23840
s 00139/00000/00000
d D 1.1 82/08/02 15:15:07 cecily 1 0
e
u
U
t
T
I 1
#
/*
 *
 *	UNIX debugger
 *
 */

#include "defs.h"


MSG		NOCFN;

INT		callpc;
INT		*rsave;
BOOL		localok;
SYMTAB		symbol;
POS		*endhdr;
#ifdef interdata
INSTR		instr;
#endif

STRING		errflg;


/*
 * Given current stack frame pointer cframe, and current pc callpc,
 * find currently active function.
 * Set symbol to function name, rsave to address on stack where caller's regs
 * are saved, callpc to return address
 */
findroutine(cframe)
	L_INT		cframe;
{
#ifdef interdata
	REG INT		callpt, inst, narg;
	INT		lastpc;

	localok = FALSE;
	lastpc = callpc;
	IF findbase(callpc, cframe) == 0
	ANDF findbase(endhdr[r15], cframe) == 0
	THEN	errflg = NOCFN;
		return(0);
	FI
	callpc = callpt = get(rsave+7, DSP);	/* return address */
	IF ((inst=get(callpt-6, ISP)) >> 24) == 0101	/* rx3 */
	THEN	inst = get(callpt-4, ISP) & 0xfffff;
	ELIF ((inst>>8) & LOBYTE) == 0101	/* rx1, rx2 */
	THEN	inst = get(callpt-4, ISP) & 0xffff;
		IF inst & 0x8000		/* rx2 */
		THEN	IF inst & 0x4000
			THEN	inst |= (-1)<<16;
			ELSE	inst &= 0x3fff;
			FI
			inst =+ callpt;
		FI
	ELSE
		errflg = NOCFN;
		return(0);
	FI
	localok = TRUE;
	inst = get(callpt, ISP);
	IF (inst>>20) == 0x267		/* ais sp,X */
	THEN	return(((inst>>16)&15)/4);
	FI
	IF (inst>>20) == 0xc57		/* ahi sp,X */
	THEN	return((inst&0xffff)/4);
	FI
	IF (inst>>20) == 0xfa7		/* ai sp, X */
	THEN	return(get(callpt+2, ISP)/4);
	FI
	return(0);
#else
	REG INT		narg, inst;
	INT		lastpc, back2;
	BOOL		v;

	rsave = cframe;
	v=FALSE; localok=FALSE; lastpc=callpc;
	callpc=get(cframe+2, DSP); back2=get(leng(callpc-2), ISP);
	IF (inst=get(leng(callpc-4), ISP)) == 04737	/* jsr pc,*$... */
	THEN	narg = 1;
	ELIF (inst&~077)==04700			/* jsr pc,... */
	THEN	narg=0; v=(inst!=04767);
	ELIF (back2&~077)==04700
	THEN	narg=0; v=TRUE;
	ELSE	errflg=NOCFN;
		return(0);
	FI
	IF findsym( (v ? lastpc : ((inst==04767?callpc:0) + back2) ),ISYM) == -1
	    ANDF !v
	THEN	symbol.symc[0] = '?';
		symbol.symc[1] = 0;
		symbol.symv = 0;
	ELSE	localok=TRUE;
	FI
	inst = get(leng(callpc), ISP);
	IF inst == 05726		/* tst (sp)+ */
	THEN	return(narg+1);
	FI
	IF inst == 022626		/* cmp (sp)+,(sp)+ */
	THEN	return(narg+2);
	FI
	IF inst == 062706		/* add $n,sp */
	THEN	return(narg+get(leng(callpc+2), ISP)/2);
	FI
	return(narg);
#endif
}


/*
 * Given current pc apc, and current stack frame pointer arbase,
 * set rsave to point to stack location of saved registers
 * Return 1 for success, 0 for failure
 */
#define	SHI	0xcb
#define	SI	0xfb
#define	STM	0xd0
findbase(apc, arbase)
INT *arbase;
{
	register loc;

	IF findsym(apc, ISYM) == -1	/* name of current function */
	THEN	return(0);
	FI
	loc = symbol.symv;		/* entry pt of current function */
	loc += disasm(loc, ISP, get(loc, ISP));	/* skip SI */
	IF instr.op != SI ANDF instr.op != SHI
	THEN	return(0);
	FI
	loc += disasm(loc, ISP, get(loc, ISP));	/* check STM */
	IF instr.op != STM ORF apc < loc + 2
	THEN	return(0);
	FI
	rsave = (int)arbase + instr.disp;	/* register save offset from STM */
	return(1);
}
E 1
