|
|
Power 6/32 Unix version 1.2b
static char sccsid[] = "@(#)bp.c 2.6";
#include <ctype.h>
#include "cdb.h"
#ifdef M68000
#define cbBp 2 /* size of a breakpoint */
#ifdef SUN
short vinsBp = 0x4e4f; /* a 'trap #15' instruction */
#else
short vinsBp = 0x4e41; /* the breakpoint instruction */
#endif
#endif
#ifdef ONYX
#define cbBp 2 /* size of a breakpoint */
int vinsBp = 0x7fff; /* the breakpoint instruction */
#endif
#ifdef TAHOE
#define cbBp 1 /* size of BPT instruction */
int vinsBp = 0x30; /* a BPT instruction */
#endif
#ifdef VAX
#define cbBp 1 /* size of BPT instruction */
int vinsBp = 03; /* a BPT instruction */
#endif
export int vibpMac, vibpMax;
export int vibpTemp; /* always 0, used for temp BP execution */
export pBPR vrgBp; /* allocated in InitAll */
#ifdef REGULUS
local void CopyBp(bp1, bp2)
pBPR bp1, bp2;
{
bp1->adr = bp2->adr;
bp1->count = bp2->count;
bp1->inst = bp2->inst;
strncpy(bp1->sbBp, bp2->sbBp, 100);
} /* CopyBp */
#endif
/* L I S T B P */
export void ListBp()
{
int ibp;
for (ibp=vibpTemp+1; ibp< vibpMac; ibp++) {
printf("%2d ", ibp);
PrintPos(vrgBp[ibp].adr, fmtProc+fmtLn+fmtSave);
printf(" count: %d", vrgBp[ibp].count);
/* for debugging purposes
printf(" addr: %d", vrgBp[ibp].adr);
printf(" inst: %d", vrgBp[ibp].inst);
*/
if (vrgBp[ibp].count <= 0)
printf(" (temp)");
if (vrgBp[ibp].sbBp[0] != chNull)
printf(" <%s>", vrgBp[ibp].sbBp);
printf("\n");
} /* for */
} /* ListBp */
/* F C L E A R B P */
export FLAGT FClearBp(adr)
ADRT adr;
{
int ibp;
for (ibp=vibpTemp+1; ibp<vibpMac; ibp++) {
if (vrgBp[ibp].adr == adr) {
#ifdef REGULUS
CopyBp(vrgBp+ibp, vrgBp+(vibpMac-1));
#else
vrgBp[ibp] = vrgBp[vibpMac-1];
#endif
vibpMac--;
return(true);
} /* if */
} /* for */
return(false);
} /* FClearBp */
/* C L E A R A L L */
export void ClearAll()
{
vibpMac = 1; /* we allow for the temp in 0 */
printf("All breakpoints deleted\n");
} /* ClearAll */
/* I B P F B R K I N */
export int IbpFBrkIn(pc)
ADRT pc;
{
int i;
for (i=vibpTemp+1; i < vibpMac; i++) {
if (vrgBp[i].adr == pc)
return(i); /* don't install anything if we are on a break */
} /* for */
for (i=vibpTemp+1; i < vibpMac; i++) {
GetBlock(vrgBp[i].adr, spaceText, (ADRT)&(vrgBp[i].inst), cbBp);
#ifdef TAHOE
PutBlock(vrgBp[i].adr, spaceText, ((char *)&vinsBp)+3, cbBp);
#else
PutBlock(vrgBp[i].adr, spaceText, (ADRT)&vinsBp, cbBp);
#endif
} /* for */
return(ibpNil);
} /* IbpFBrkIn */
/* B R K O U T */
export int BrkOut(padr)
ADRT *padr;
{
int ibp, i;
#ifdef M68000
ushort val;
#else
uint val;
#endif
pBPR bp;
ADRT adr;
adr = *padr;
#ifndef BSD41
/* vax backs up pc for us */
GetBlock(adr-cbBp, spaceText, (ADRT)&val, cbBp);
if (val == vinsBp) /* back up, if we are at a breakpoint */
*padr = adr -= cbBp;
#endif
/* we now restore original instructions for all active bp's */
ibp = ibpNil;
for (i=vibpTemp+1; i < vibpMac; i++) {
bp = vrgBp + i;
PutBlock(bp->adr, spaceText, (ADRT)&(bp->inst), cbBp);
/* put back the real instruction */
if (bp->count == 0) { /* it was set by single-step */
FClearBp(vrgBp[i].adr);
i--; /* FClearBp shuffles things, back up one */
}
else if (bp->adr == adr) {
/* this is THE break that we hit, adjust its count */
ibp = ibpContinue; /* ignore break, will change if appropriate */
if (bp->count < 0) {
/* it's a temp break */
if ((bp->count += 1) == 0) {
#ifdef REGULUS
CopyBp(vrgBp+vibpTemp, bp);
#else
vrgBp[vibpTemp] = *bp; /* transfer into the holding slot */
#endif
ibp = vibpTemp;
FClearBp(vrgBp[i].adr);
i--; /* FClearBp shuffles things, back up one */
} /* if */
}
else {
/* it's a permanent break, deal with it */
if ((bp->count -= 1) <= 0) {
bp->count = 1; /* we refresh it if it goes 0 */
ibp = i;
} /* if */
} /* if */
} /* if */
} /* if */
return(ibp);
} /* BrkOut */
/* I B P F A D R */
export int IbpFAdr(adr, count, sbCmd)
ADRT adr;
int count;
char *sbCmd;
{
int ibp;
/* see if we already have this one - if so, reuse the slot */
for (ibp=vibpTemp+1; ibp<vibpMac; ibp++) {
if (vrgBp[ibp].adr == adr) {
if (count == 0)
return(ibp); /* there's already a PERMANENT one there */
else break;
} /* if */
} /* for */
if (ibp == vibpMac) {
if (vibpMac >= vibpMax)
UError("Ran out of breakpoints");
vibpMac++;
} /* if */
vrgBp[ibp].adr = adr;
vrgBp[ibp].count = count;
if (sbCmd == sbNil) {
vrgBp[ibp].sbBp[0] = chNull;
}
else {
strcpy(vrgBp[ibp].sbBp, sbCmd);
} /* if */
return(ibp);
} /* IbpFAdr */
/* I B P F S E T */
export int IbpFSet(chStyle, cnt, sbCmd)
char chStyle;
int cnt;
char *sbCmd;
{
int ipd, ibp, ipdSave, ilnSave, ifdSave, cb;
char *sbSave, sbTok[50];
FLAGT fTemp;
ADRT pc, fp, ap;
TKE tk;
ipd = ipdSave = vipd;
ifdSave = vifd;
ilnSave = viln;
if (isupper(chStyle)) {
fTemp = true; /* upper gives a one shot breakpoint */
chStyle = tolower(chStyle);
}
else {
fTemp = false;
} /* if */
fp = vfp;
ap = vap;
pc = vpc;
if (cnt >= 0) {
/* they want to do this stack relative */
while ((cnt > 0) AND fp) {
NextFrame(&fp, &ap, &pc);
--cnt;
}
if (fp == 0)
UError("Stack isn't that deep!");
} /* if */
switch (chStyle) {
default:
UError("Unknown breakpoint type `%c'", chStyle);
case 't': /* trace breakpoint */
if (cnt >= 0) {
if ((ipd = IpdFAdr(pc)) == ipdNil)
UError("No symbols for that procedure");
vipd = ipd;
}
else {
sbSave = sbCmd; /* in case we want to undo next line */
tk = TkFStr(&sbCmd, sbTok, &cb); /* look at first item */
if ( (tk == tkStr)
AND ((ipd = IpdFName(sbTok)) != ipdNil) ) {
vipd = ipd;
}
else {
/* restore string */
sbCmd = sbSave;
} /* if */
} /* if */
/* set break at exit */
ibp = IbpFSet( ((fTemp) ? 'X':'x'), -1, "Q;$result/d;c");
/* set break at entrance */
if ((sbCmd == sbNil) OR (*sbCmd == chNull))
sbCmd = "Q;2t;c"; /* print caller and continue on entry */
ibp = IbpFSet( ((fTemp) ? 'B':'b'), -1, sbCmd);
printf("Tracing %s\n", vrgPd[vipd].sbProc);
ibp = ibpNil; /* a signal to caller not to print anything */
pc = adrNil;
break;
case 'b':
if (cnt >= 0) {
if ((ipd = IpdFAdr(pc)) == ipdNil)
UError("No symbols for that procedure");
}
else {
ipd = vipd;
} /* if */
OpenIpd(ipd, true); /* force it open */
pc = AdrFIfdLn(vifd, viln);
break;
case 'x':
if (cnt >= 0) {
if ((ipd = IpdFAdr(pc)) == ipdNil)
UError("No symbols for that procedure");
}
else {
ipd = vipd;
} /* if */
pc = AdrFEndOfProc(ipd);
break;
case 'u':
/* move past instruction which fixes the stack pointer */
pc = AdrFStackFix(pc);
break;
} /* switch */
if (pc != adrNil)
ibp = IbpFAdr(pc, (fTemp) ? -1 : 1, sbCmd);
vipd = ipdSave;
vifd = ifdSave;
viln = ilnSave;
return(ibp);
} /* IbpFSet */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.