File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / cdb / proc.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b

static char sccsid[] = "@(#)proc.c	2.8";

#include <setjmp.h>
#ifndef REGULUS

#ifdef BSD42
#include <machine/reg.h>
#else
#include <sys/reg.h>
#endif

#endif
#include "macdefs.h"
#include "cdb.h"

export ADRT	vadrBreak; /* the place we break at when doing proc calls */
export ADRT	vadrCall;  /* location of call instruction in _end_ */
export int	vcNestProc;	/* nesting depth of proc's from cmd line */


/* D O   P R O C */

export long DoProc(ipd, rgTy, adr)
int	ipd;
pTYR	rgTy;
ADRT	adr;
{
	short	sigSave, iarg, iargMac, ibp;
	long	isym, result, reg, rgArgs[20];
	char	*sbProc, sbSave[50];
	pTYR	ty;
	TKE		tk;
	TYR		rgTyLoc[cTyMax];
	REGT	regs[uregMax];
	int		*envSave;
	jmp_buf	envProc;
	STUFFU	stuff;

	if (vpid == pidNil) {
		/* we have no child! we will start one - may not be correct */
		ibp = IbpFNewChild(vsbArgsChild);
		if (ibp != ibpNil) {
			/* this is obscure.  We have a break point on the
				     * first line of the program.  In this case we MUST
				     * ignore it and throw away any commands associated
				     * with it.  Otherwise, we would screw up the state
				     * of the expression evaluator.
				     */
			vsbCmd = PopCmd();
		}
	} /* if */

	if (setjmp(envProc)==0) {
		/* save register values and prepare for errors */
		envSave = venv;
		sigSave = vsig;
		venv = envProc;
		SaveRegs(regs);
	} 
	else {
		/* error city, wonder what went wrong??? */
		RestoreRegs(regs);
		vsig = sigSave;
		venv = envSave;
		if (--vcNestProc == 0)
			FClearBp(vadrBreak);
		return(0L);
	} /* if */

	if (ipd != ipdNil) {
		/* a 'known procedure' */
		isym = vrgPd[ipd].isym;
		adr = vrgPd[ipd].adrStart;
		sbProc = vrgPd[ipd].sbProc;
	} 
	else {
		/* a label-type procedure call */
		isym = -1;
		LabelFAdr(adr);
#ifdef BSD41
		strcpy(sbSave, SbInCore(vsymCur->sbSym));
#else
		strncpy(sbSave, SbInCore(vsymCur->sbSym), 8);
#endif
		sbProc = (sbSave[0] == '_') ? sbSave+1 : sbSave;
	} /* if */
	iargMac = 0;

	/* so far, we have eaten `procname(' */
	/* eat the arguments */
	if ((tk = TkPeek()) == tkRP)
		tk = TkNext();	/* acutally eat the ')' */
	while (tk != tkRP) {
		rgArgs[iargMac] = GetExpr(&ty, vtk);
		if (ty == tyNil)
			UError("Bad expression in proc call: %s", vsbCmd);
		if (isym != -1) {
			SetSym(isym);
			if (FNextLocal(false, true, sbNil)) {
				isym = visym;	/* remember where we are */
				TyFLocal(rgTyLoc, SbInCore(vsymCur->sbSym+1), isym);
			} 
			else {
				CopyTy(rgTyLoc, ty);
			} /* if */
		} 
		else {
			CopyTy(rgTyLoc, ty);
		} /* if */
		CopyTy(rgTy+iargMac, rgTyLoc);
		iargMac++;
		tk = vtk;
		if (tk != tkComma)
			break;
	} /* while */

	if (isym != -1) {
		SetSym(isym);/* point at symbol after what we just ate */
		if (FNextLocal(false, true, sbNil)) {
			printf("WARNING: too few parameters: ");
			DispFrame(adrNil, ipd, adrNil, adrNil, -1, false, false);
		} /* if */
	} /* if */

	for (iarg = iargMac-1; iarg >= 0; iarg--) { /* push in reverse order */
		/* there is a problem here when there is no .d file and
			 * the last arg is other than the size of an INT.
			 * see CbFLoc for the gory details.
			 */
		/* MACHINE DEPENDENT - BYTE SEX, SIZE */
		vsp -= CBINT;
#ifdef TAHOE
		PutWord(vsp, spaceData, rgArgs[iarg]);
#endif
#ifdef VAX
		PutWord(vsp, spaceData, rgArgs[iarg]);
#endif
#ifdef SUN
		PutWord(vsp, spaceData, rgArgs[iarg]);
#endif
#ifdef ONYX
		stuff.lng = rgArgs[iarg];
		PutWord(vsp, spaceData, stuff.shorts.shortLo);	/* put low order word */
		if (CbFTy(rgTy+iarg) == 4) {
			vsp -= CBINT; /* a double word arg, put the high order one */
			PutWord(vsp, spaceData, stuff.shorts.shortHi);
		} /* if */
#endif
	} /* for */

	vfp = 0;
#ifdef M68000
	vsp -= CBPOINT;
	/* we will pretend we are calling from location `_end_' */
	PutBlock(vsp, spaceData, &vadrBreak, CBPOINT);	/* return address */
	vpc = adr;
#endif
#ifdef ONYX
	vsp -= CBINT;
	/* we will pretend we are calling from location `_end_' */
	PutWord(vsp, spaceData, vadrBreak);	/* return address */
	vpc = adr;
#endif
#ifdef TAHOE
	PutReg(u1, 4 + 4*iargMac);	
	/* argument counter (have to see Tahoe architecture to understand this) */
	PutReg(u0, adr); /* callee's address in r0 */
	vpc = vadrCall;
#endif
#ifdef VAX
	PutReg(u1, iargMac);	/* argument counter */
	PutReg(u0, adr); /* callee's address in r0 */
	vpc = vadrCall;
#endif
	if (vcNestProc == 0)
		ibp = IbpFAdr(vadrBreak, 1, "Q;q");	/* and set a break there */
	vcNestProc++;	/* count of proc call nesting */

	/* and away we go........ */
	IbpFRun(ptResume);
	while (ibp != vibp)
		DebugIt(false);

	if (isym != -1) {
		TyFLocal(rgTy, vrgPd[ipd].sbProc, vrgPd[ipd].isym);
	} 
	else {
		CopyTy(rgTy, vtyInt);
	} /* if */

	if (4 == CbFTy(rgTy)) {
		FAdrFSpecial("$long", rgTy, &adr);
		result = ValFAdr(lengthen(adr), rgTy);
		CopyTy(rgTy, vtyCnLong);
	} 
	else {
		FAdrFSpecial("$short", rgTy, &adr);
		result = ValFAdr(lengthen(adr), rgTy);
		CopyTy(rgTy, vtyCnShort);
	}
#ifdef BSD41
	rgTy[0].sbVar = bitHigh | (int)(sbProc);
	/* what a CROCK!!!!! */
#else
	strncpy(rgTy[0].sbVar, sbProc, 8);
#endif
	if (--vcNestProc == 0)
		FClearBp(vadrBreak);
	RestoreRegs(regs);
	vsig = sigSave;
	venv = envSave;	/* return to normal error handling */
	return(result);
} /* DoProc */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.