Bell 32V release
[unix-history] / usr / src / cmd / sdb / display.c
#include "head.h"
#include <a.out.h>
#include "cdefs.h"
struct user u;
BKPTR bkpthead;
/* initialize frame pointers to top of call stack */
struct proct *
initframe() {
argp = *(ADDR *) (((ADDR) &u) + AP);
frame = *(ADDR *) (((ADDR) &u) + FP);
callpc = *(ADDR *) (((ADDR) &u) + PC);
if ((frame == 0) || (frame & 0xf0000000 != 0x70000000))
return(badproc);
return(adrtoproc(callpc++)); /* ++ because UNIX backs up instrs */
}
struct proct *
nextframe() {
callpc = get(frame+16, DSP);
argp = get(frame+8, DSP);
frame = get(frame+12, DSP) & EVEN;
if ((frame == 0) || (frame & 0xf0000000 != 0x70000000))
return(badproc);
return(adrtoproc(callpc-1));
}
/* print call frame */
prframe() {
int narg;
char *p;
struct proct *procp;
if ((procp = initframe()) == badproc) return;
do {
if (get(frame+12, DSP) == 0) return;
p = procp->pname;
if (p[0] == '_')
printf("%.7s(", p+1);
else
printf("%.8s(", p);
narg = get(argp, DSP);
if (narg & ~0xff) narg = 0;
while (narg) {
printf("%d", get(argp+=4, DSP));
if (--narg != 0) printf(",");
}
printf(")");
if (procp->sfptr != badfile)
printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename,
adrtolineno(callpc-1));
printf("\n");
} while ((procp = nextframe()) != badproc);
}
STRING signals[] = {
"",
"hangup",
"interrupt",
"quit",
"illegal instruction",
"trace/BPT",
"IOT",
"EMT",
"floating exception",
"killed",
"bus error",
"memory fault",
"bad system call",
"broken pipe",
"alarm call",
"terminated",
};
INT signo;
sigprint() {
printf("%s", signals[signo]);
}
/* returns core image address for variable */
formaddr(proc, class, addr)
register char *proc;
register char class;
ADDR addr; {
if (debug) printf("formaddr(%s, %o, %d)\n", proc,class & 0377,addr);
switch(class & STABMASK) {
case N_RSYM:
if (getframe(proc) < 0) return(-1);
case N_GSYM:
case N_SSYM:
case N_STSYM:
return(addr);
case N_PSYM:
if (getframe(proc) < 0) return(-1);
return(argp+addr);
case N_LSYM:
if (getframe(proc) < 0) return(-1);
return(frame+addr);
default:
printf("Bad class in formaddr: 0%o: (%d, %d)\n",
class & 0377, proc, addr);
return(0);
}
}
/* sets frame pointers to procedure proc */
getframe(proc)
register char *proc; {
register struct proct *procp, *fprocp;
procp = findproc(proc);
if (procp == badproc) {
printf("%s: Bad procedure name\n", proc);
return(-1);
}
for (fprocp = initframe(); fprocp != badproc; fprocp = nextframe()) {
if (procp == fprocp) return(0);
}
printf("%s: Not an active procedure\n", proc);
return(-1);
}
char class;
/* returns address of proc:var. Sets externals class and subflag */
ADDR
varaddr(proc, var)
char *proc, *var; {
register struct proct *procp;
register ADDR addr;
char *p;
int localflag;
if (debug) printf("varaddr(%s,%s)\n", proc, var);
localflag = 0;
subflag = 0;
procp = initframe();
do {
if (eqstr(proc, procp->pname)) goto found;
} while ((procp=nextframe()) != badproc);
localflag = 1;
found:
if (eqany(var[0], ".->")) {
class = N_GSYM;
addr = integ;
}
else {
if (localflag || slookup(var, adrtostoffset(callpc-1)) == -1) {
if (globallookup(var,findfile(curfile)->stf_offset) == -1) {
if (localflag)
printf("%.8s not found\n", var);
else
printf("%.8s:%s not found\n", proc, var);
return(-1);
}
}
class = sl_class & STABMASK;
addr = (class == N_LSYM) ? -sl_addr : sl_addr;
addr = formaddr(proc, class, addr);
}
if (addr == -1) return(-1);
for (p=var; *p; p++) {
if (*p == '.' && *(p+1) != '\0') {
if (class == N_RSYM) {
error("Not with a register variable");
return(-1);
}
p++;
if (localflag || slookup(p, adrtostoffset(callpc-1)) == -1) {
if (globallookup(p, findfile(curfile)->stf_offset) == -1) {
if (localflag)
printf("%s not found\n", var);
else
printf("%.8s:%s not found\n", proc, var);
return(-1);
}
}
if ((sl_class & STABMASK) != N_SSYM) {
error("Not a structure element");
return(-1);
}
addr += sl_addr;
subflag = 0;
}
if (eqany(*p, "->") != '\0') {
addr = getindir(class, addr, sl_type);
class = N_GSYM;
if (debug) printf("Address %d after getval\n", addr);
for (; eqany(*p, "->"); p++) ;
if (*p == '\0') break;
if (localflag ||
slookup(p, adrtostoffset(callpc-1)) == -1) {
if (globallookup(p, findfile(curfile)->stf_offset) == -1) {
if (localflag)
printf("%s not found\n", var);
else
printf("%.8s:%s not found\n", proc, var);
return(-1);
}
}
addr += sl_addr;
subflag = 0;
}
if (*p == '[' && *(p+1) != '\0') {
long i;
p++;
i = readint(&p);
if (debug) printf("Size %d\n", typetosize(sl_type, sl_size));
addr = getindir(class, addr, sl_type);
addr += typetosize(sl_type, sl_size)*i;
class = N_GSYM;
subflag++;
}
}
return(addr);
}
/* displays value of proc:var, returns its address */
ADDR
dispvar(proc, var, fmt)
char *proc, *var, *fmt; {
ADDR addr;
addr = varaddr(proc, var);
if (addr == -1) return(-1);
prvar(sl_type, addr, fmt, class, subflag);
return(addr);
}
prvar(type, addr, fmt, class, subflag)
ADDR addr;
char *fmt, class; short type; {
dispf(addr, fmt, class, type, subflag);
}
prdebug() {
register struct proct *procp;
register struct filet *filep;
printf("dot=%d\n", dot);
printf("extstart = %d\n", extstart);
for(filep=files;filep->sfilename[0];filep++)
printf("%s offs %d @ %d flag %d addr %d\n", filep->sfilename, filep->stf_offset, filep, filep->lineflag, filep->faddr);
for(procp=procs;procp->pname[0];procp++)
printf("%8.8s addr %d; offs %d; sfptr %d; line %d\n",
procp->pname, procp->paddr, procp->st_offset, procp->sfptr,
procp->lineno);
}
/* display addr using format desc or class s */
char pd[] = "%x\n";
dispf(addr, desc, class, type, subflag)
char *desc; short type; ADDR addr; {
int i;
char *p;
char dlen, dfmt;
long value;
union {
struct {
char c[WORDSIZE];
};
struct {
int w;
};
struct {
float f;
}
} word;
union {
struct{
int w1, w2;
};
struct {
double d;
};
} dbl;
class &= STABMASK;
if (desc[0] == '\0') desc = typetodesc(type, subflag);
odesc = desc;
otype = type;
oclass = class;
if (debug) printf("dispf(%d,%s,0%o,0%o)\n", addr,desc,class,type);
pd[1] = dfmt = 'd';
dlen = '\0';
for (p = desc; *p; p++) {
switch (*p) {
case 'l':
case 'h':
case 'b':
dlen = *p;
break;
case 'c':
case 'd':
case 'o':
case 'x':
case 'u':
case 's':
case 'a':
case 'f':
case 'g':
pd[1] = dfmt = *p;
break;
default:
printf("Illegal descriptor: %c\n", *p);
return;
}
}
switch (dfmt) {
default:
if (class == N_RSYM) {
if ((addr > 0 && addr < 6) || addr > 11) {
printf("Bad register var %d\n", addr);
return;
}
value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr);
}
else {
value = getval(addr, dfmt);
}
switch (dfmt) {
case 'u':
case 'x':
case 'o':
switch (dlen) {
case 'h':
value = (unsigned short) value;
break;
case 'b':
value = (unsigned char) value;
break;
case 'l':
value = (unsigned long) value;
break;
}
break;
default:
switch (dlen) {
case 'h':
value = (short) value;
break;
case 'b':
value = (char) value;
break;
case 'l':
value = (long) value;
break;
}
}
if (value > 0) {
if (value > 9 && dfmt == 'x')
printf("0x");
else if (value > 7 && dfmt == 'o')
printf("0");
}
if (dfmt == 'c') {
if ((value & 0177) < ' ')
printf("^%c\n", value + ('A' - 1));
else if ((value & 0177) == 0177)
printf("^?\n");
else
printf(pd, value);
} else
printf(pd, value);
return;
case 'f':
pd[1] = 'g';
word.w = getval(addr,dfmt);
printf(pd, word.f);
return;
case 'g':
pd[1] = 'g';
dbl.w1 = getval(addr, dfmt);
dbl.w2 = getval(addr+WORDSIZE, dfmt);
printf(pd, dbl.d);
return;
case 's':
addr = getindir(class, addr, type);
case 'a':
for (;;) {
word.w = getval(addr, 'd');
for (i=0; i<WORDSIZE; i++) {
if (word.c[i] == 0) goto l1;
printf("%c", word.c[i]);
}
addr += WORDSIZE;
}
l1: printf("\n");
return;
}
}
/* print breakpoints */
prbkpt() {
register BKPTR bkptr;
register int cnt;
cnt = 0;
for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
if (bkptr->flag) {
cnt++;
printf("%.8s:%d\n", adrtoprocp(bkptr->loc)->pname,
adrtolineno(bkptr->loc));
}
if (cnt == 0)
printf("No breakpoints set\n");
}
idbkpt() {
register BKPTR bkptr;
register int yesflg, cnt;
register char c;
cnt = 0;
for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
if (bkptr->flag) {
printf("%.8s:%d ? ", adrtoprocp(bkptr->loc)->pname,
adrtolineno(bkptr->loc));
yesflg = 0;
cnt++;
do {
c = getchar();
if (c == 'y' || c == 'd') yesflg++;
} while (c != '\n');
if (yesflg)
bkptr->flag = 0;
}
if (cnt == 0)
printf("No breakpoints set\n");
}
char *
typetodesc(type, subflag)
short type; {
register int ptr, ftn, ary;
register char *desc;
static char *typedesc[] = {
"d", /* undef */
"d", /* farg */
"c", /* char */
"hd", /* short */
"d", /* int */
"ld", /* long */
"f", /* float */
"g", /* double */
"d", /* strty */
"d", /* unionty */
"d", /* enumty */
"d", /* moety */
"bu", /* uchar */
"hu", /* ushort */
"u", /* unsigned */
"lu", /* ulong */
"d" /* ? */
};
ptr = ftn = ary = 0;
for (;; type = DECREF(type)) {
if (ISPTR(type)) ptr++;
else if (ISFTN(type)) ftn++;
else if (ISARY(type)) ary++;
else {
desc = typedesc[type];
break;
}
}
if ((ptr-subflag == 1 || ary-subflag == 1) && desc[0] == 'c') return("s");
if (debug) printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc);
if (ptr) return("x");
return(desc);
}
typetosize(type, stsize)
short type; {
register int ptr, ftn, ary;
register int size;
static char typesize[] = {
4, /* undef */
4, /* farg */
1, /* char */
2, /* short */
WORDSIZE, /* int */
4, /* long */
4, /* float */
8, /* double */
0, /* strty */
0, /* unionty */
4, /* enumty */
4, /* moety */
1, /* uchar */
2, /* ushort */
4, /* unsigned */
4, /* ulong */
4 /* ? */
};
ptr = ftn = ary = 0;
for (;; type = DECREF(type)) {
if (ISPTR(type)) ptr++;
else if (ISFTN(type)) ftn++;
else if (ISARY(type)) ary++;
else {
size = typesize[type];
break;
}
}
if (debug) printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n",ptr,ftn,ary,size,stsize);
if (ptr>1) return(4);
if (size == 0) return(stsize ? stsize : 1);
else return(size);
}