V5/usr/source/s1/cdb.c
#
/*
C debugger
*/
#include "/usr/sys/param.h"
#include "/usr/sys/user.h"
int fcore;
int fsym;
int symoff;
char *lp;
int errflg;
int symlen;
int symct;
char symbol[8];
int symflg;
int symval;
char ssymbol[8];
int ssymflg;
int ssymval;
char line[128];
int regbuf[512];
char **uregs ®buf[512];
char *rtsize;
int pc -2;
int r5 -9;
int dot;
int tdot;
int dotinc 2;
int lastcom '/';
int lastype 'o';
char *symfil "a.out";
char *corfil "core";
int callist[50];
int *callp &callist[0];
main(argc, argv)
char **argv;
{
int onintr();
if (argc==2)
symfil = argv[1];
if (argc>2) {
corfil = argv[1];
symfil = argv[2];
}
if ((fcore = open(corfil, 0)) < 0) {
printf("%s not found\n", corfil);
return;
}
if ((fsym = open(symfil, 0)) < 0) {
printf("%s not found\n", symfil);
return;
}
read(fsym, regbuf, 020);
if (regbuf[0]!=0410 && regbuf[0]!=0407) { /* magic */
printf("Bad format: %s\n", symfil);
return;
}
symoff = regbuf[1] + regbuf[2];
symlen = regbuf[4];
if (regbuf[7] != 1)
symoff =<< 1;
symoff =+ 020;
read(fcore, regbuf, 1024);
regbuf->u_tsize =<< 6;
regbuf->u_dsize =<< 6;
regbuf->u_ssize =<< 6;
rtsize = (regbuf->u_tsize+017777) & ~017777;
setexit();
signal(2, onintr);
loop:
if (errflg) {
printf("?\n");
errflg = 0;
}
lp = line;
while ((*lp = getchar()) != '\n')
if (*lp++ == '\0')
return;
lp = line;
command();
goto loop;
}
command()
{
register adrflg, n;
adrflg = expr();
if (errflg)
return;
n = getcnt();
if (lastcom=='$')
lastcom = '/';
if (*lp == '\n') {
if (!adrflg)
dot =+ dotinc;
} else
lastcom = *lp++;
if (*lp != '\n')
lastype = *lp++;
if (*lp != '\n') {
errflg++;
return;
}
if (adrflg)
dot = tdot;
while(n) {
scommand(n);
if (errflg)
return;
if (--n)
dot =+ dotinc;
}
}
scommand(n)
{
register w, c;
double fw;
struct { int i[4]; };
switch(lastcom) {
case '/':
w = cget(dot);
switch(lastype) {
case 'o':
printf("%.1o\n", w);
dotinc = 2;
return;
case 'i':
printf("%d\n", w);
dotinc = 2;
return;
case 'f':
fw = 0.0;
fw.i[0] = w;
fw.i[1] = cget(dot+2);
printf("%e\n", fw);
dotinc = 4;
return;
case 'd':
fw.i[0] = w;
fw.i[1] = cget(dot+2);
fw.i[2] = cget(dot+4);
fw.i[3] = cget(dot+6);
printf("%e\n", fw);
dotinc = 8;
return;
}
errflg++;
return;
case '\\':
printf("%.1o\n", cget(dot) & 0377);
dotinc = 1;
return;
case '=':
printf("%.1o\n", dot);
return;
case '\'':
printc(cget(dot) & 0377);
if (n<=1)
putchar('\n');
dotinc = 1;
return;
case '"':
w = cget(dot);
while(c = cget(w++)&0377)
printc(c);
putchar('\n');
return;
case '&':
vallook(cget(dot));
if (errflg)
reset();
printf("%.8s\n", ssymbol);
return;
case '$':
printtrace();
return;
}
errflg++;
}
getcnt()
{
register t1, t2;
if (*lp != ',')
return(1);
lp++;
t1 = tdot;
if (expr() == 0) {
tdot = t1;
return(1);
}
t2 = tdot;
tdot = t1;
return(t2);
}
cget(n)
{
register w;
w = get(n);
if (errflg)
reset();
return(w);
}
printc(c)
{
if (c<' ' || c>'}')
printf("\\%o", c);
else
printf("%c", c);
}
expr()
{
char tsym[10];
int i, t1, t2, donef, adrflg, lastop, b;
tdot = 0;
adrflg = 0;
lastop = '+';
ssymval = 0;
donef = 0;
loop:
if (*lp >= 'a' && *lp <= 'z' || *lp=='_') {
i = 0;
tsym[i++] = '_';
adrflg++;
while(*lp>='a'&&*lp<='z' || *lp>='0'&&*lp<='9' || *lp=='_') {
if (i < 8)
tsym[i++] = *lp;
lp++;
}
while (i<8)
tsym[i++] = '\0';
if (symlook(tsym) == 0) {
errflg++;
reset();
}
goto loop;
}
if (*lp>='0' && *lp<='9') {
adrflg++;
ssymval = 0;
if (*lp == '0')
b = 8;
else
b = 10;
while (*lp>='0' && *lp<='9') {
ssymval =* b;
ssymval =+ *lp++ -'0';
}
goto loop;
}
switch (*lp) {
default:
donef++;
case '+':
case '-':
switch(lastop) {
case '+':
tdot =+ ssymval;
goto op;
case '-':
tdot =- ssymval;
op:
if (donef)
return(adrflg);
else
lastop = *lp++;
}
goto loop;
case ' ':
case '\t':
lp++;
goto loop;
case '(':
lp++;
adrflg++;
t1 = tdot;
ssymval = getarg();
tdot = t1;
goto loop;
case '[':
lp++;
t1 = ssymval;
t2 = tdot;
if (expr() == 0)
tdot = 0;
ssymval = get(t1 + (tdot<<1));
if (errflg)
reset();
tdot = t2;
if (*lp == ']')
lp++;
goto loop;
}
}
getarg()
{
register level, arg, t1;
t1 = tdot;
expr();
level = tdot;
if (*lp++ != ',')
error();
expr();
arg = tdot;
if (*lp++ != ')')
error();
if (level >= callp-callist)
error();
ssymval = callist[level] - 8 - 2*arg;
tdot = t1;
}
error()
{
errflg++;
reset();
}
printtrace()
{
int tpc, tr5, narg, argp, i;
tpc = uregs[pc];
tr5 = uregs[r5];
if (symlook("savr5"))
if (narg = get(ssymval))
tr5 = narg;
callp = &callist[0];
while (errflg == 0) {
narg = findroutine(tpc, tr5);
printf("%2d: %.8s(", callp-callist, ssymbol);
if (--narg >= 0)
printf("%.1o", get(tr5+4));
argp = tr5+4;
while(--narg >= 0)
printf(",%.1o", get(argp =+ 2));
printf(")\n");
tpc = get(tr5+2);
if (callp < &callist[50])
*callp++ = tr5;
if ((tr5 = get(tr5)) == 0)
break;
}
}
findroutine(rpc, rr5)
{
int callpt, inst, narg;
callpt = get(rr5+2);
if ((inst=get(callpt-4)) == 04737) /* jsr pc,*$... */
narg = 1;
else if ((inst&~077)==04700) /* jsr pc,... */
narg = 0;
else {
errflg++;
return(0);
}
vallook((inst==04767?callpt:0) + get(callpt-2));
inst = get(callpt);
if (inst == 05726) /* tst (sp)+ */
return(narg+1);
if (inst == 022626) /* cmp (sp)+,(sp)+ */
return(narg+2);
if (inst == 062706) /* add $n,sp */
return(narg+get(callpt+2)/2);
return(narg);
}
symlook(symstr)
char *symstr;
{
symset();
while(symget()) {
if (eqstr(symbol, symstr)) {
savsym();
return(1);
}
}
return(0);
}
eqstr(as1, as2)
int *as1, *as2;
{
register int *s1, *s2, *es1;
s1 = as1;
s2 = as2;
for (es1 = s1+4; s1 < es1; )
if (*s1++ != *s2++)
return(0);
return(1);
}
vallook(value)
{
symset();
while(symget())
if (symval == value && (symflg&037) == 2) {
savsym('_');
return;
}
errflg++;
}
get(aaddr)
char *aaddr;
{
int w;
register char *addr;
addr = aaddr;
w = 0;
if (addr < regbuf->u_tsize) {
seek(fsym, addr+020, 0);
if (read(fsym, &w, 2) != 2)
errflg++;
return(w);
}
if (addr < rtsize+regbuf->u_dsize)
addr =- rtsize;
else if (-addr < regbuf->u_ssize)
addr =+ regbuf->u_dsize + regbuf->u_ssize;
else
errflg++;
seek(fcore, addr+1024, 0);
if (read(fcore, &w, 2) < 2)
errflg++;
return(w);
}
symset()
{
symct = symlen;
seek(fsym, symoff, 0);
}
symget()
{
if ((symct =- 12) < 0)
return(0);
return(read(fsym, symbol, 12) == 12);
}
savsym(skip)
{
int ch;
char *p, *q;
p = symbol;
q = ssymbol;
while (p<symbol+8 && (ch = *p++)) {
if (ch == skip)
continue;
*q++ = ch;
}
while (q < ssymbol+8)
*q++ = '\0';
ssymflg = symflg;
ssymval = symval;
}
onintr()
{
putchar('\n');
errflg++;
reset();
}