From: Bill Joy Date: Mon, 10 Nov 1980 02:53:38 +0000 (-0800) Subject: BSD 4 development X-Git-Tag: BSD-4~39 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/c3bd281f7c17368eb2a46a930c8a2f2737117492 BSD 4 development Work on file usr/src/cmd/adb/defs.h Work on file usr/src/cmd/adb/expr.c Work on file usr/src/cmd/adb/head.h Work on file usr/src/cmd/adb/input.c Work on file usr/src/cmd/adb/mac.h Work on file usr/src/cmd/adb/main.c Work on file usr/src/cmd/adb/format.c Work on file usr/src/cmd/adb/machine.h Work on file usr/src/cmd/adb/opset.c Work on file usr/src/cmd/adb/optab.c Work on file usr/src/cmd/adb/message.c Work on file usr/src/cmd/adb/mode.h Work on file usr/src/cmd/adb/output.c Work on file usr/src/cmd/adb/runpcs.c Work on file usr/src/cmd/adb/pcs.c Work on file usr/src/cmd/adb/print.c Work on file usr/src/cmd/adb/setup.c Work on file usr/src/cmd/adb/sym.c Synthesized-from: CSRG//cd1/4.0 --- diff --git a/usr/src/cmd/adb/defs.h b/usr/src/cmd/adb/defs.h new file mode 100644 index 0000000000..efe8a66b64 --- /dev/null +++ b/usr/src/cmd/adb/defs.h @@ -0,0 +1,116 @@ +/* + * adb - vax string table version; common definitions + */ + +#include +#include +#include +#include +#include +#include + +#include "mac.h" +#include "mode.h" +#include "head.h" + +/* access modes */ +#define RD 0 +#define WT 1 + +#define NSP 0 +#define ISP 1 +#define DSP 2 +#define STAR 4 +#define STARCOM 0200 + +/* + * Symbol types, used internally in calls to findsym routine. + * One the VAX this all degenerates since I & D symbols are indistinct. + * Basically we get NSYM==0 for `=' command, ISYM==DSYM otherwise. + */ +#define NSYM 0 +#define DSYM 1 /* Data space symbol */ +#define ISYM DSYM /* Instruction space symbol == DSYM on VAX */ + +#define BKPTSET 1 +#define BKPTEXEC 2 + +#define USERPS PSL +#define USERPC PC +#define BPT 03 +#define TBIT 020 +#define FD 0200 +#define SETTRC 0 +#define RDUSER 2 +#define RIUSER 1 +#define WDUSER 5 +#define WIUSER 4 +#define RUREGS 3 +#define WUREGS 6 +#define CONTIN 7 +#define EXIT 8 +#define SINGLE 9 + +/* the quantities involving ctob() are located in the kernel stack. */ +/* the others are in the pcb. */ +#define KSP 0 +#define ESP 4 +#define SSP 8 +#define USP (ctob(UPAGES)-5*sizeof(int)) +#define R0 (ctob(UPAGES)-18*sizeof(int)) +#define R1 (ctob(UPAGES)-17*sizeof(int)) +#define R2 (ctob(UPAGES)-16*sizeof(int)) +#define R3 (ctob(UPAGES)-15*sizeof(int)) +#define R4 (ctob(UPAGES)-14*sizeof(int)) +#define R5 (ctob(UPAGES)-13*sizeof(int)) +#define R6 (ctob(UPAGES)-12*sizeof(int)) +#define R7 (ctob(UPAGES)-11*sizeof(int)) +#define R8 (ctob(UPAGES)-10*sizeof(int)) +#define R9 (ctob(UPAGES)-9*sizeof(int)) +#define R10 (ctob(UPAGES)-8*sizeof(int)) +#define R11 (ctob(UPAGES)-7*sizeof(int)) +#define AP (ctob(UPAGES)-21*sizeof(int)) +#define FP (ctob(UPAGES)-20*sizeof(int)) +#define PC (ctob(UPAGES)-2*sizeof(int)) +#define PSL (ctob(UPAGES)-1*sizeof(int)) +#define P0BR 80 +#define P0LR 84 +#define P1BR 88 +#define P1LR 92 + +#define MAXOFF 255 +#define MAXPOS 80 +#define MAXLIN 128 +#define EOF 0 +#define EOR '\n' +#define SP ' ' +#define TB '\t' +#define QUOTE 0200 +#define STRIP 0177 +#define LOBYTE 0377 +#define EVEN -2 + +/* long to ints and back (puns) */ +union { + INT I[2]; + L_INT L; +} itolws; + +#ifndef vax +#define leng(a) ((long)((unsigned)(a))) +#define shorten(a) ((int)(a)) +#define itol(a,b) (itolws.I[0]=(a), itolws.I[1]=(b), itolws.L) +#else +#define leng(a) itol(0,a) +#define shorten(a) ((short)(a)) +#define itol(a,b) (itolws.I[0]=(b), itolws.I[1]=(a), itolws.L) +#endif + +/* result type declarations */ +L_INT inkdot(); +POS get(); +POS chkget(); +STRING exform(); +L_INT round(); +BKPTR scanbkpt(); +VOID fault(); diff --git a/usr/src/cmd/adb/expr.c b/usr/src/cmd/adb/expr.c new file mode 100644 index 0000000000..c0b9f942c8 --- /dev/null +++ b/usr/src/cmd/adb/expr.c @@ -0,0 +1,299 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; + +MSG BADSYM; +MSG BADVAR; +MSG BADKET; +MSG BADSYN; +MSG NOCFN; +MSG NOADR; +MSG BADLOC; + +ADDR lastframe; +ADDR savlastf; +ADDR savframe; +ADDR savpc; +ADDR callpc; + + + +CHAR *lp; +INT radix; +STRING errflg; +L_INT localval; +CHAR isymbol[BSIZE]; + +CHAR lastc,peekc; + +L_INT dot; +L_INT ditto; +INT dotinc; +L_INT var[]; +L_INT expv; + + + + +expr(a) +{ /* term | term dyadic expr | */ + INT rc; + L_INT lhs; + + rdc(); lp--; rc=term(a); + + WHILE rc + DO lhs = expv; + + switch ((int)readchar()) { + + case '+': + term(a|1); expv += lhs; break; + + case '-': + term(a|1); expv = lhs - expv; break; + + case '#': + term(a|1); expv = round(lhs,expv); break; + + case '*': + term(a|1); expv *= lhs; break; + + case '%': + term(a|1); expv = lhs/expv; break; + + case '&': + term(a|1); expv &= lhs; break; + + case '|': + term(a|1); expv |= lhs; break; + + case ')': + IF (a&2)==0 THEN error(BADKET); FI + + default: + lp--; + return(rc); + } + OD + return(rc); +} + +term(a) +{ /* item | monadic item | (expr) | */ + + switch ((int)readchar()) { + + case '*': + term(a|1); expv=chkget(expv,DSP); return(1); + + case '@': + term(a|1); expv=chkget(expv,ISP); return(1); + + case '-': + term(a|1); expv = -expv; return(1); + + case '~': + term(a|1); expv = ~expv; return(1); + + case '(': + expr(2); + IF *lp!=')' + THEN error(BADSYN); + ELSE lp++; return(1); + FI + + default: + lp--; + return(item(a)); + } +} + +item(a) +{ /* name [ . local ] | number | . | ^ | n_un.n_name,isymbol,'~') + THEN break; + FI + callpc=get(frame+16, DSP); + lastframe=frame; + frame=get(frame+12,DSP)&EVEN; + IF frame==0 + THEN error(NOCFN); + FI + OD + savlastf=lastframe; savframe=frame; + readchar(); + IF symchar(0) + THEN chkloc(expv=frame); + FI + ELIF (symp=lookup(isymbol))==0 THEN error(BADSYM); + ELSE expv = symp->n_value; + FI + lp--; + + + ELIF getnum(readchar) + THEN ; + ELIF lastc=='.' + THEN readchar(); + IF symchar(0) + THEN lastframe=savlastf; callpc=savpc; + chkloc(savframe); + ELSE expv=dot; + FI + lp--; + + ELIF lastc=='"' + THEN expv=ditto; + + ELIF lastc=='+' + THEN expv=inkdot(dotinc); + + ELIF lastc=='^' + THEN expv=inkdot(-dotinc); + + ELIF lastc=='<' + THEN savc=rdc(); + IF regptr=getreg(savc) + THEN expv= * (ADDR *)(((ADDR)&u)+regptr); + ELIF (base=varchk(savc)) != -1 + THEN expv=var[base]; + ELSE error(BADVAR); + FI + + ELIF lastc=='\'' + THEN d=4; expv=0; + WHILE quotchar() + DO IF d-- + THEN IF d==1 THEN expv <<=16; FI + expv |= ((d&1)?lastc:lastc<<8); + ELSE error(BADSYN); + FI + OD + + ELIF a + THEN error(NOADR); + ELSE lp--; return(0); + FI + return(1); +} + +/* service routines for expression reading */ +getnum(rdf) int (*rdf)(); +{ + INT base,d,frpt; + BOOL hex; + UNION{REAL r; L_INT i;} real; + IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)())) + THEN expv = 0; + base = (hex ? 16 : radix); + WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc)) + DO expv = (base==16 ? expv<<4 : expv*base); + IF (d=convdig(lastc))>=base THEN error(BADSYN); FI + expv += d; (*rdf)(); + IF expv==0 + THEN IF (lastc=='x' ORF lastc=='X') + THEN hex=TRUE; base=16; (*rdf)(); + ELIF (lastc=='t' ORF lastc=='T') + THEN hex=FALSE; base=10; (*rdf)(); + ELIF (lastc=='o' ORF lastc=='O') + THEN hex=FALSE; base=8; (*rdf)(); + FI + FI + OD + IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex + THEN real.r=expv; frpt=0; base=10; + WHILE isdigit((*rdf)()) + DO real.r *= base; frpt++; + real.r += lastc-'0'; + OD + WHILE frpt-- + DO real.r /= base; OD + expv = real.i; + FI + peekc=lastc; +/* lp--; */ + return(1); + ELSE return(0); + FI +} + +readsym() +{ + REG char *p; + + p = isymbol; + REP IF p < &isymbol[sizeof(isymbol)-1] + THEN *p++ = lastc; + FI + readchar(); + PER symchar(1) DONE + *p++ = 0; +} + +convdig(c) +CHAR c; +{ + IF isdigit(c) + THEN return(c-'0'); + ELIF isxdigit(c) + THEN return(c-'a'+10); + ELSE return(17); + FI +} + +symchar(dig) +{ + IF lastc=='\\' THEN readchar(); return(TRUE); FI + return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) ); +} + +varchk(name) +{ + IF isdigit(name) THEN return(name-'0'); FI + IF isalpha(name) THEN return((name&037)-1+10); FI + return(-1); +} + +chkloc(frame) +L_INT frame; +{ + readsym(); + REP IF localsym(frame)==0 THEN error(BADLOC); FI + expv=localval; + PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE +} + +eqsym(s1, s2, c) + register char *s1, *s2; +{ + + if (!strcmp(s1,s2)) + return (1); + if (*s1 == c && !strcmp(s1+1, s2)) + return (1); + return (0); +} diff --git a/usr/src/cmd/adb/format.c b/usr/src/cmd/adb/format.c new file mode 100644 index 0000000000..33ac28daac --- /dev/null +++ b/usr/src/cmd/adb/format.c @@ -0,0 +1,304 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; + +MSG BADMOD; +MSG NOFORK; +MSG ADWRAP; + +INT mkfault; +CHAR *lp; +L_INT maxoff; +ADDR sigint; +ADDR sigqit; +STRING errflg; +CHAR lastc,peekc; +L_INT dot; +INT dotinc; +L_INT expv; +L_INT var[]; + + +STRING fphack; +rdfp() +{ + return(lastc= *fphack++); +} + +scanform(icount,ifp,itype,ptype) +L_INT icount; +STRING ifp; +{ + STRING fp; + CHAR modifier; + INT fcount, init=1; + L_INT savdot; + BOOL exact; + + WHILE icount + DO fp=ifp; + savdot=dot; init=0; + + IF init==0 ANDF (exact=(findsym(dot,ptype)==0)) ANDF maxoff + THEN printf("\n%s:%16t",cursym->n_un.n_name); + FI + + /*now loop over format*/ + WHILE *fp ANDF errflg==0 + DO IF (fphack=fp, getnum(rdfp)) + THEN fcount=expv; fp= --fphack; peekc=0; + ELSE fcount=1; + FI + + IF *fp==0 THEN break; FI + IF exact ANDF dot==savdot ANDF itype==ISP ANDF cursym->n_un.n_name[0]=='_' ANDF *fp=='i' + THEN exform(1,"x",itype,ptype); fp++; printc(EOR); /* entry mask */ + ELSE fp=exform(fcount,fp,itype,ptype); + FI + OD + dotinc=dot-savdot; + dot=savdot; + + IF errflg + THEN IF icount<0 + THEN errflg=0; break; + ELSE error(errflg); + FI + FI + IF --icount + THEN dot=inkdot(dotinc); + FI + IF mkfault THEN error(0); FI + OD +} + +STRING +exform(fcount,ifp,itype,ptype) +INT fcount; +STRING ifp; +{ + /* execute single format item `fcount' times + * sets `dotinc' and moves `dot' + * returns address of next format item + */ + POS w; + L_INT savdot, wx; + STRING fp; + CHAR c, modifier, longpr; + L_REAL fw; + struct{ + L_INT sa; + INT sb,sc; + }; + + WHILE fcount>0 + DO fp = ifp; c = *fp; + longpr=(c>='A')&(c<='Z')|(c=='f')|(c=='4')|(c=='p'); + IF itype==NSP ORF *fp=='a' + THEN wx=dot; w=dot; + ELSE w=get(dot,itype); + IF longpr + THEN wx=itol(get(inkdot(2),itype),w); + ELSE wx=w; + FI + FI + IF c=='F' + THEN fw.sb=get(inkdot(4),itype); + fw.sc=get(inkdot(6),itype); + FI + IF errflg THEN return(fp); FI + IF mkfault THEN error(0); FI + var[0]=wx; + modifier = *fp++; + dotinc=(longpr?4:2);; + + IF charpos()==0 ANDF modifier!='a' THEN printf("%16m"); FI + + switch(modifier) { + + case SP: case TB: + break; + + case 't': case 'T': + printf("%T",fcount); return(fp); + + case 'r': case 'R': + printf("%M",fcount); return(fp); + + case 'a': + psymoff(dot,ptype,":%16t"); dotinc=0; break; + + case 'p': + psymoff(var[0],ptype,"%16t"); break; + + case 'u': + printf("%-8u",w); break; + + case 'U': + printf("%-16U",wx); break; + + case 'c': case 'C': + IF modifier=='C' + THEN printesc(w&LOBYTE); + ELSE printc(w&LOBYTE); + FI + dotinc=1; break; + + case 'b': case 'B': + printf("%-8o", w&LOBYTE); dotinc=1; break; + + case '1': + printf("%-8r", w&LOBYTE); dotinc=1; break; + + case '2': + case 'w': + printf("%-8r", w); break; + + case '4': + case 'W': + printf("%-16R", wx); break; + + case 's': case 'S': + savdot=dot; dotinc=1; + WHILE (c=get(dot,itype)&LOBYTE) ANDF errflg==0 + DO dot=inkdot(1); + IF modifier == 'S' + THEN printesc(c); + ELSE printc(c); + FI + endline(); + OD + dotinc=dot-savdot+1; dot=savdot; break; + + case 'x': + printf("%-8x",w); break; + + case 'X': + printf("%-16X", wx); break; + + case 'Y': + printf("%-24Y", wx); break; + + case 'q': + printf("%-8q", w); break; + + case 'Q': + printf("%-16Q", wx); break; + + case 'o': + printf("%-8o", w); break; + + case 'O': + printf("%-16O", wx); break; + + case 'i': + printins(0,itype,w); printc(EOR); break; + + case 'd': + printf("%-8d", w); break; + + case 'D': + printf("%-16D", wx); break; + + case 'f': + fw = 0; + fw.sa = wx; + printf("%-16.9f", fw); + dotinc=4; break; + + case 'F': + fw.sa = wx; + printf("%-32.18F", fw); + dotinc=8; break; + + case 'n': case 'N': + printc('\n'); dotinc=0; break; + + case '"': + dotinc=0; + WHILE *fp != '"' ANDF *fp + DO printc(*fp++); OD + IF *fp THEN fp++; FI + break; + + case '^': + dot=inkdot(-dotinc*fcount); return(fp); + + case '+': + dot=inkdot(fcount); return(fp); + + case '-': + dot=inkdot(-fcount); return(fp); + + default: error(BADMOD); + } + IF itype!=NSP + THEN dot=inkdot(dotinc); + FI + fcount--; endline(); + OD + + return(fp); +} + +shell() +{ +#ifndef EDDT + INT rc, status, unixpid; + STRING argp = lp; + STRING getenv(), shell = getenv("SHELL"); +#ifdef VFORK + char oldstlp; +#endif + + if (shell == 0) + shell = "/bin/sh"; + WHILE lastc!=EOR DO rdc(); OD +#ifndef VFORK + IF (unixpid=fork())==0 +#else + oldstlp = *lp; + IF (unixpid=vfork())==0 +#endif + THEN signal(SIGINT,sigint); signal(SIGQUIT,sigqit); + *lp=0; execl(shell, "sh", "-c", argp, 0); + _exit(16); +#ifndef VFORK + ELIF unixpid == -1 +#else + ELIF *lp = oldstlp, unixpid == -1 +#endif + THEN error(NOFORK); + ELSE signal(SIGINT,1); + WHILE (rc = wait(&status)) != unixpid ANDF rc != -1 DONE + signal(SIGINT,sigint); + prints("!"); lp--; + FI +#endif +} + + +printesc(c) +{ + c &= STRIP; + IF c==0177 THEN printf("^?"); + ELIF c> 24 THEN error(ADWRAP); FI + return(newdot); +} diff --git a/usr/src/cmd/adb/head.h b/usr/src/cmd/adb/head.h new file mode 100644 index 0000000000..1628e9f46a --- /dev/null +++ b/usr/src/cmd/adb/head.h @@ -0,0 +1,30 @@ +ADDR maxoff; +ADDR localval; + +struct nlist *symtab, *esymtab; +struct nlist *cursym; +struct nlist *lookup(); + +struct exec filhdr; + +long var[36]; + +int xargc; + +MAP txtmap; +MAP datmap; +INT wtflag; +INT fcor; +INT fsym; +L_INT maxfile; +L_INT maxstor; +INT signo; + +union { + struct user U; + char UU[ctob(UPAGES)]; +} udot; +#define u udot.U + +char *corfil, *symfil; + diff --git a/usr/src/cmd/adb/input.c b/usr/src/cmd/adb/input.c new file mode 100644 index 0000000000..96dc69aec3 --- /dev/null +++ b/usr/src/cmd/adb/input.c @@ -0,0 +1,82 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; + +INT mkfault; +CHAR line[LINSIZ]; +INT infile; +CHAR *lp; +CHAR peekc,lastc = EOR; +INT eof; + +/* input routines */ + +eol(c) +CHAR c; +{ + return(c==EOR ORF c==';'); +} + +rdc() +{ REP readchar(); + PER lastc==SP ORF lastc==TB + DONE + return(lastc); +} + +readchar() +{ + IF eof + THEN lastc=0; + ELSE IF lp==0 + THEN lp=line; + REP eof = read(infile,lp,1)==0; + IF mkfault THEN error(0); FI + PER eof==0 ANDF *lp++!=EOR DONE + *lp=0; lp=line; + FI + IF lastc = peekc THEN peekc=0; + ELIF lastc = *lp THEN lp++; + FI + FI + return(lastc); +} + +nextchar() +{ + IF eol(rdc()) + THEN lp--; return(0); + ELSE return(lastc); + FI +} + +quotchar() +{ + IF readchar()=='\\' + THEN return(readchar()); + ELIF lastc=='\'' + THEN return(0); + ELSE return(lastc); + FI +} + +getformat(deformat) +STRING deformat; +{ + REG STRING fptr; + REG BOOL quote; + fptr=deformat; quote=FALSE; + WHILE (quote ? readchar()!=EOR : !eol(readchar())) + DO IF (*fptr++ = lastc)=='"' + THEN quote = ~quote; + FI + OD + lp--; + IF fptr!=deformat THEN *fptr++ = '\0'; FI +} diff --git a/usr/src/cmd/adb/mac.h b/usr/src/cmd/adb/mac.h new file mode 100644 index 0000000000..a5510d69e4 --- /dev/null +++ b/usr/src/cmd/adb/mac.h @@ -0,0 +1,47 @@ +# +/* + * UNIX debugger + */ + +#define TYPE typedef +#define STRUCT struct +#define UNION union +#define REG register + +#define BEGIN { +#define END } + +#define IF if( +#define THEN ){ +#define ELSE } else { +#define ELIF } else if ( +#define FI } + +#define FOR for( +#define WHILE while( +#define DO ){ +#define OD } +#define REP do{ +#define PER }while( +#define DONE ); +#define LOOP for(;;){ +#define POOL } + +#define SKIP ; +#define DIV / +#define REM % +#define NEQ ^ +#define ANDF && +#define ORF || + +#define TRUE (-1) +#define FALSE 0 +#define LOBYTE 0377 +#define HIBYTE 0177400 +#define STRIP 0177 +#define HEXMSK 017 + +#define SP ' ' +#define TB '\t' +#define NL '\n' +#define EOF 0 diff --git a/usr/src/cmd/adb/machine.h b/usr/src/cmd/adb/machine.h new file mode 100644 index 0000000000..4ca1127e57 --- /dev/null +++ b/usr/src/cmd/adb/machine.h @@ -0,0 +1,28 @@ +#include + +#define PAGSIZ (NBPG*CLSIZE) + +#define DBNAME "adb\n" +#define LPRMODE "%R" +#define OFFMODE "+%R" +#define TXTRNDSIZ PAGSIZ + +#define MAXINT 0x7fffffff +#define MAXSTOR ((1L<<31) - ctob(UPAGES)) +#define MAXFILE 0xffffffff + +/* + * INSTACK tells whether its argument is a stack address. + * INUDOT tells whether its argument is in the (extended) u. area. + * These are used for consistency checking and dont have to be exact. + * + * INKERNEL tells whether its argument is a kernel space address. + * KVTOPH trims a kernel virtal address back to its offset + * in the kernel address space. + */ +#define INSTACK(x) (((x)&0xf0000000) == 0x70000000) +#define INUDOT(x) (((x)&0xf0000000) == 0x70000000) +#define INKERNEL(x) (((x)&0xf0000000) == 0x80000000) + +#define KVTOPH(x) ((x)&~ 0x80000000) +#define KERNOFF 0x80000000 diff --git a/usr/src/cmd/adb/main.c b/usr/src/cmd/adb/main.c new file mode 100644 index 0000000000..9dfdcaaf01 --- /dev/null +++ b/usr/src/cmd/adb/main.c @@ -0,0 +1,129 @@ +static char sccsid[] = "%Z%%M% %I% %G%"; +/* + * adb - main command loop and error/interrupt handling + */ +#include "defs.h" + +MSG NOEOR; + +INT mkfault; +INT executing; +INT infile; +CHAR *lp; +L_INT maxoff; +L_INT maxpos; +ADDR sigint; +ADDR sigqit; +INT wtflag; +L_INT maxfile; +STRING errflg; +L_INT exitflg; + +CHAR lastc; +INT eof; + +INT lastcom; + +long maxoff = MAXOFF; +long maxpos = MAXPOS; + +main(argc, argv) + register char **argv; + int argc; +{ + + mkioptab(); + while (argc>1 && eqstr("-w", argv[1])) { + wtflag = 2; /* suitable for open() */ + argc--, argv++; + } + if (argc > 1) + symfil = argv[1]; + if (argc > 2) + corfil = argv[2]; + xargc = argc; + setsym(); setcor(); setvar(); + + if ((sigint=signal(SIGINT,SIG_IGN)) != SIG_IGN) { + sigint = fault; + signal(SIGINT, fault); + } + sigqit = signal(SIGQUIT, SIG_IGN); + setexit(); + if (executing) + delbp(); + executing = 0; + for (;;) { + flushbuf(); + if (errflg) { + printf("%s\n", errflg); + exitflg = errflg; + errflg = 0; + } + if (mkfault) { + mkfault=0; + printc('\n'); + prints(DBNAME); + } + lp=0; rdc(); lp--; + if (eof) { + if (infile) { + iclose(); eof=0; reset(); + } else + done(); + } else + exitflg = 0; + command(0, lastcom); + if (lp && lastc!='\n') + error(NOEOR); + } +} + +done() +{ + endpcs(); + exit(exitflg); +} + +L_INT +round(a,b) +REG L_INT a, b; +{ + REG L_INT w; + w = (a/b)*b; + IF a!=w THEN w += b; FI + return(w); +} + +/* + * If there has been an error or a fault, take the error. + */ +chkerr() +{ + if (errflg || mkfault) + error(errflg); +} + +/* + * An error occurred; save the message for later printing, + * close open files, and reset to main command loop. + */ +error(n) + char *n; +{ + errflg = n; + iclose(); oclose(); + reset(); +} + +/* + * An interrupt occurred; reset the interrupt + * catch, seek to the end of the current file + * and remember that there was a fault. + */ +fault(a) +{ + signal(a, fault); + lseek(infile, 0L, 2); + mkfault++; +} diff --git a/usr/src/cmd/adb/message.c b/usr/src/cmd/adb/message.c new file mode 100644 index 0000000000..3f55092fbe --- /dev/null +++ b/usr/src/cmd/adb/message.c @@ -0,0 +1,43 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "mac.h" +static char sccsid[] = "%Z%%M% %I% %G%"; +#include "mode.h" + +MSG VERSION = "\nVERSION VM/VAX%I% DATE %G%\n"; + +MSG BADMOD = "bad modifier"; +MSG BADCOM = "bad command"; +MSG BADSYM = "symbol not found"; +MSG BADLOC = "automatic variable not found"; +MSG NOCFN = "c routine not found"; +MSG NOMATCH = "cannot locate value"; +MSG NOBKPT = "no breakpoint set"; +MSG BADKET = "unexpected ')'"; +MSG NOADR = "address expected"; +MSG NOPCS = "no process"; +MSG BADVAR = "bad variable"; +MSG BADTXT = "text address not found"; +MSG BADDAT = "data address not found"; +MSG ODDADR = "odd address"; +MSG EXBKPT = "too many breakpoints"; +MSG A68BAD = "bad a68 frame"; +MSG A68LNK = "bad a68 link"; +MSG ADWRAP = "address wrap around"; +MSG BADEQ = "unexpected `='"; +MSG BADWAIT = "wait error: process disappeared!"; +MSG ENDPCS = "process terminated"; +MSG NOFORK = "try again"; +MSG BADSYN = "syntax error"; +MSG NOEOR = "newline expected"; +MSG SZBKPT = "bkpt: command too long"; +MSG BADFIL = "bad file format"; +MSG BADNAM = "not enough space for symbols"; +MSG LONGFIL = "filename too long"; +MSG NOTOPEN = "cannot open"; +MSG BADMAG = "bad core magic number"; diff --git a/usr/src/cmd/adb/mode.h b/usr/src/cmd/adb/mode.h new file mode 100644 index 0000000000..7956ebcbdd --- /dev/null +++ b/usr/src/cmd/adb/mode.h @@ -0,0 +1,52 @@ +#include "machine.h" +/* + * sdb/adb - common definitions for old srb style code + */ + +#define MAXCOM 64 +#define MAXARG 32 +#define LINSIZ 256 +TYPE long ADDR; +TYPE short INT; +TYPE int VOID; +TYPE long int L_INT; +TYPE float REAL; +TYPE double L_REAL; +TYPE unsigned POS; +TYPE char BOOL; +TYPE char CHAR; +TYPE char *STRING; +TYPE char MSG[]; +TYPE struct map MAP; +TYPE MAP *MAPPTR; +TYPE struct bkpt BKPT; +TYPE BKPT *BKPTR; + + +/* file address maps */ +struct map { + L_INT b1; + L_INT e1; + L_INT f1; + L_INT b2; + L_INT e2; + L_INT f2; + INT ufd; +}; + +struct bkpt { + ADDR loc; + ADDR ins; + INT count; + INT initcnt; + INT flag; + CHAR comm[MAXCOM]; + BKPT *nxtbkpt; +}; + +TYPE struct reglist REGLIST; +TYPE REGLIST *REGPTR; +struct reglist { + STRING rname; + INT roffs; +}; diff --git a/usr/src/cmd/adb/opset.c b/usr/src/cmd/adb/opset.c new file mode 100644 index 0000000000..d773c62b9f --- /dev/null +++ b/usr/src/cmd/adb/opset.c @@ -0,0 +1,278 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; + +STRING errflg; +L_INT dot; +INT dotinc; +L_INT var[]; + + +/* instruction printing */ + +/* + * Argument access types + */ +#define ACCA (8<<3) /* address only */ +#define ACCR (1<<3) /* read */ +#define ACCW (2<<3) /* write */ +#define ACCM (3<<3) /* modify */ +#define ACCB (4<<3) /* branch displacement */ +#define ACCI (5<<3) /* XFC code */ + +/* + * Argument data types + */ +#define TYPB 0 /* byte */ +#define TYPW 1 /* word */ +#define TYPL 2 /* long */ +#define TYPQ 3 /* quad */ +#define TYPF 4 /* floating */ +#define TYPD 5 /* double floating */ + + +TYPE struct optab *OPTAB; +struct optab { + char *iname; + char val; + char nargs; + char argtype[6]; +} optab[]; +#define SYSTAB struct systab +SYSTAB { + int argc; + char *sname; +} systab[]; +STRING regname[]; +STRING fltimm[]; +POS type, space, incp; + +int ioptab[256]; /* index by opcode to optab */ + +mkioptab() {/* set up ioptab */ + REG OPTAB p=optab; + while (p->iname){ + ioptab[p->val&LOBYTE]=p-optab; + p++; + } +} + +extern char *fmtr; /* not used */ +extern char *fmtR; /* not used */ + +printins(f,idsp,ins) +#ifndef vax + REG INT ins; +#else + REG L_INT ins; +#endif +{ + short argno; /* argument index */ + short mode; /* mode */ + char **r; /* register name */ + long d; /* assembled byte, word, long or float */ + long snarf(); + REG char * ap; + REG OPTAB ip; + + type = DSYM; + space = idsp; + ins &= LOBYTE; + ip=optab+ioptab[ins]; + printf("%s%8t",ip->iname); + incp = 1; + ap = ip->argtype; + for (argno=0; argnonargs; argno++,ap++) { + var[argno] = 0x80000000; + if (argno!=0) printc(','); + top: + if (*ap&ACCB) + mode = 0xAF + ((*ap&7)<<5); /* branch displacement */ + else{ + mode = bchkget(inkdot(incp),idsp); ++incp; + } + if (mode & 0300) {/* not short literal */ + r = ®name[mode&0xF]; + mode >>= 4; + switch ((int)mode) { + case 4: /* [r] */ + printf("[%s]",*r); + goto top; + case 5: /* r */ + printf("%s",*r); + break; + case 6: /* (r) */ + printf("(%s)",*r); + break; + case 7: /* -(r) */ + printf("-(%s)",*r); + break; + case 9: /* *(r)+ */ + printc('*'); + case 8: /* (r)+ */ + if (r==(regname+0xF)) { + printc('$'); + if (mode==9){ /* PC absolute, always 4 bytes*/ + d = snarf(4, idsp); + goto disp; + } + switch(*ap&7){ + case TYPB: + d = snarf(1, idsp); + goto disp; + case TYPW: + d = snarf(2, idsp); + goto disp; + case TYPL: + d = snarf(4, idsp); + goto disp; + case TYPQ: + d = snarf(4, idsp); + printquad(d, snarf(4, idsp)); + break; + case TYPF: + printfloating(TYPF, snarf(4, idsp), 0); + break; + case TYPD: + d = snarf(4, idsp); + printfloating(TYPQ, d, snarf(4, idsp)); + break; + } /*end of type switch */ + /* + * here only for TYPQ, TYPf, TYPD + * others went to disp + */ + } else { /*it's not PC immediate or abs*/ + printf("(%s)+",*r); + } + break; + case 0xB: /* byte displacement defferred*/ + printc('*'); + case 0xA: /* byte displacement */ + d = snarf(1, idsp); + goto disp; + case 0xD: /* word displacement deferred */ + printc('*'); + case 0xC: /* word displacement */ + d = snarf(2, idsp); + goto disp; + case 0xF: /* long displacement deferred */ + printc('*'); + case 0xE: /* long displacement */ + d = snarf(4, idsp); + goto disp; + disp: + var[argno]=d; + if (r==(regname+0xF) && mode>=0xA){ + /* PC offset addressing */ + var[argno] += dot+incp; + } + psymoff(var[argno],type,""); + if (r != regname+0xF) + printf("(%s)",*r); + break; + } /* end of the mode switch */ + } else { /* short literal */ + var[argno]=mode; + if( (*ap&7)==TYPF + || (*ap&7)==TYPD) + printf("$%s",fltimm[mode]); + else + printf("$%r",mode); + } + } + if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */ + for (argno=0; argno<=var[2]; ++argno) { + printc(EOR); + printf(" %R: ",argno+var[1]); + d=get(inkdot(incp+argno+argno),idsp)&0xFFFF; + if (d&0x8000) d -= 0x10000; + psymoff(inkdot(incp)+d,type,""); + } + incp += var[2]+var[2]+2; + } + dotinc=incp; +} + +/* + * magic values to mung an offset to a register into + * something that psymoff can understand.. all magic + */ + /* 0 1 2 3 4 */ +static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0}; +static long magic_compl[5] = {0, 0x100, 0x10000,0, 0}; + +/* + * The following code is NO LONGER portable from the PDP 11 to the VAX + */ +long snarf (nbytes, idsp) + int nbytes; +{ + register int byteindex; + union Long{ + char long_bytes[4]; + long long_value; + } d; + + d.long_value = 0; + for (byteindex = 0; byteindex < nbytes; byteindex++){ + d.long_bytes[byteindex] = bchkget(inkdot(incp), idsp); + ++incp; + } + if (d.long_value & magic_masks[nbytes]) + d.long_value -= magic_compl[nbytes]; + return(d.long_value); +} + +printfloating(type, word_first, word_last) + int type; + long word_first; + long word_last; +{ + union Double{ + struct { + long word_first; + long word_last; + } composite; + double dvalue; + } reconstructed; + + reconstructed.composite.word_first = word_first; + reconstructed.composite.word_last = word_last; + printf( "%f", reconstructed.dvalue); +} + +printquad(word_first, word_last) + long word_first; + long word_last; +{ + union Quad { + char quad_bytes[8]; + long quad_long[2]; + } reconstructed; + int leading_zero = 1; + int byteindex; + int nibbleindex; + register int ch; + + reconstructed.quad_long[0] = word_first; + reconstructed.quad_long[1] = word_last; + for (byteindex = 7; byteindex >= 0; --byteindex){ + for (nibbleindex = 4; nibbleindex >= 0; nibbleindex -= 4){ + ch = (reconstructed.quad_bytes[byteindex] + >> nibbleindex) & 0x0F; + if ( ! (leading_zero &= (ch == 0) ) ){ + if (ch <= 0x09) + printc(ch + '0'); + else + printc(ch - 0x0A + 'a'); + } + } + } +} diff --git a/usr/src/cmd/adb/optab.c b/usr/src/cmd/adb/optab.c new file mode 100644 index 0000000000..4c67911b7a --- /dev/null +++ b/usr/src/cmd/adb/optab.c @@ -0,0 +1,120 @@ +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; +/* + * Argument access types + */ +#define ACCA (8<<3) /* address only */ +#define ACCR (1<<3) /* read */ +#define ACCW (2<<3) /* write */ +#define ACCM (3<<3) /* modify */ +#define ACCB (4<<3) /* branch displacement */ +#define ACCI (5<<3) /* XFC code */ + +/* + * Argument data types + */ +#define TYPB 0 /* byte */ +#define TYPW 1 /* word */ +#define TYPL 2 /* long */ +#define TYPQ 3 /* quad */ +#define TYPF 4 /* floating */ +#define TYPD 5 /* double floating */ + + +TYPE struct optab *OPTAB; +struct optab { + char *iname; + char val; + char nargs; + char argtype[6]; +} optab[] = { +#define OP(a,b,c,d,e,f,g,h,i) {a,b,c,d,e,f,g,h,i} +#include "/usr/src/cmd/as/instrs" +0}; + +#define SYSTAB struct systab +SYSTAB { + int argc; + char *sname; +} systab[] = { + 1, "indir", + 0, "exit", + 0, "fork", + 2, "read", + 2, "write", + 2, "open", + 0, "close", + 0, "wait", + 2, "creat", + 2, "link", + 1, "unlink", + 2, "exec", + 1, "chdir", + 0, "time", + 3, "mknod", + 2, "chmod", + 2, "chown", + 1, "break", + 2, "stat", + 2, "seek", + 0, "getpid", + 3, "mount", + 1, "umount", + 0, "setuid", + 0, "getuid", + 0, "stime", + 3, "ptrace", + 0, "alarm", + 1, "fstat", + 0, "pause", + 1, "30", + 1, "stty", + 1, "gtty", + 0, "access", + 0, "nice", + 0, "sleep", + 0, "sync", + 1, "kill", + 0, "csw", + 0, "setpgrp", + 0, "tell", + 0, "dup", + 0, "pipe", + 1, "times", + 4, "profil", + 0, "tiu", + 0, "setgid", + 0, "getgid", + 2, "signal", + 0, "49", + 0, "50", + 0, "51", + 0, "52", + 0, "53", + 0, "54", + 0, "55", + 0, "56", + 0, "57", + 0, "58", + 0, "59", + 0, "60", + 0, "61", + 0, "62", + 0, "63", +}; + +STRING regname[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10","r11","ap", "fp", "sp", "pc"}; +STRING fltimm[] = { +"0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", "0.9375", +"1.0", "1.125", "1.25", "1.375", "1.5", "1.625", "1.75", "1.875", +"2.0", "2.25", "2.5", "2.75", "3.0", "3.25", "3.5", "3.75", +"4.0", "4.5", "5.0", "5.5", "6.0", "6.5", "7.0", "7.5", +"8.0", "9.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", +"16.0", "18.0", "20.0", "22.0", "24.0", "26.0", "28.0", "30.0", +"32.0", "36.0", "40.0", "44.0", "48.0", "52.0", "56.0", "60.0", +"64.0", "72.0", "80.0", "88.0", "96.0", "104.0", "112.0", "120.0" +}; + +char *fmtr = {"%r"}; +char *fmtR = {"%R"}; diff --git a/usr/src/cmd/adb/output.c b/usr/src/cmd/adb/output.c new file mode 100644 index 0000000000..0f2f334a24 --- /dev/null +++ b/usr/src/cmd/adb/output.c @@ -0,0 +1,369 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; +#include + + +INT mkfault; +INT infile; +INT outfile = 1; +L_INT maxpos; +L_INT maxoff; +INT radix = 16; + +CHAR printbuf[MAXLIN]; +CHAR *printptr = printbuf; +CHAR *digitptr; + + +eqstr(s1, s2) + REG STRING s1, s2; +{ + REG STRING es1; + WHILE *s1++ == *s2 + DO IF *s2++ == 0 + THEN return(1); + FI + OD + return(0); +} + +length(s) + REG STRING s; +{ + INT n = 0; + WHILE *s++ DO n++; OD + return(n); +} + +printc(c) + CHAR c; +{ + CHAR d; + STRING q; + INT posn, tabs, p; + + IF mkfault + THEN return; + ELIF (*printptr=c)==EOR + THEN tabs=0; posn=0; q=printbuf; + FOR p=0; p0 DO *q++=TB; tabs--; OD + WHILE posn>0 DO *q++=SP; posn--; OD + *q++=d; + FI + OD + *q++=EOR; +#ifdef EDDT + printptr=printbuf; do putchar(*printptr++); while (printptr0 THEN decpt--; FI + *digitptr++ = '.'; + WHILE *s ANDF prec-- DO *digitptr++ = *s++; OD + WHILE *--digitptr=='0' DONE + digitptr += (digitptr-digits>=3 ? 1 : 2); + IF decpt + THEN *digitptr++ = 'e'; printnum(decpt,'d',10); + FI + s=0; prec = -1; break; +#endif +#endif + case 'm': + vptr--; break; + case 'M': + width=x; break; + case 'T': + case 't': + IF c=='T' + THEN width=x; +#ifndef vax + ELSE vptr--; +#else + ELSE dptr--; +#endif + FI + IF width + THEN width -= charpos()%width; + FI + break; + default: +#ifndef vax + printc(c); vptr--; +#else + printc(c); dptr--; +#endif + } + + IF s==0 + THEN *digitptr=0; s=digits; + FI + n=length(s); + n=(prec=0 ? prec : n); + width -= n; + IF adj=='r' + THEN WHILE width-- > 0 + DO printc(SP); OD + FI + WHILE n-- DO printc(*s++); OD + WHILE width-- > 0 DO printc(SP); OD + digitptr=digits; + FI + OD +} + +printdate(tvec) + L_INT tvec; +{ + REG INT i; + REG STRING timeptr; +#ifndef EDDT + timeptr = ctime(&tvec); +#else + timeptr="????????????????????????"; +#endif + FOR i=20; i<24; i++ DO *digitptr++ = *(timeptr+i); OD + FOR i=3; i<19; i++ DO *digitptr++ = *(timeptr+i); OD +} /*printdate*/ + +prints(s) +char *s; +{ printf("%s",s); +} + +newline() +{ + printc(EOR); +} + +convert(cp) +REG STRING *cp; +{ + REG CHAR c; + INT n; + n=0; + WHILE ((c = *(*cp)++)>='0') ANDF (c<='9') DO n=n*10+c-'0'; OD + (*cp)--; + return(n); +} + +printnum(n,fmat,base) + REG INT n; +{ + REG CHAR k; + REG INT *dptr; + INT digs[15]; + dptr=digs; + IF n<0 ANDF fmat=='d' THEN n = -n; *digitptr++ = '-'; FI + n &= 0xffff; + WHILE n + DO *dptr++ = ((POS)(n&0xffff))%base; + n=((POS)(n&0xffff))/base; + OD + IF dptr==digs THEN *dptr++=0; FI + WHILE dptr!=digs + DO k = *--dptr; + *digitptr++ = (k+(k<=9 ? '0' : 'a'-10)); + OD +} + +printoct(o,s) + L_INT o; + INT s; +{ + INT i; + L_INT po = o; + CHAR digs[12]; + + IF s + THEN IF po<0 + THEN po = -po; *digitptr++='-'; + ELSE IF s>0 THEN *digitptr++='+'; FI + FI + FI + FOR i=0;i<=11;i++ + DO digs[i] = po&7; po >>= 3; OD + digs[10] &= 03; digs[11]=0; + FOR i=11;i>=0;i-- + DO IF digs[i] THEN break; FI OD + FOR i++;i>=0;i-- + DO *digitptr++=digs[i]+'0'; OD +} + +#ifndef vax +printdbl(lx,ly,fmat,base) +INT lx, ly; char fmat; int base; +#else +printdbl(lxy,fmat,base) +L_INT lxy; char fmat; int base; +#endif +{ int digs[20]; int *dptr; char k; +#ifndef MULD2 + register char *cp1; + cp1=digs; if ((lxy&0xFFFF0000L)==0xFFFF0000L) {*cp1++='-'; lxy= -lxy;} + sprintf(cp1,base==16 ? "%X" : "%D",lxy); + cp1=digs; while (*digitptr++= *cp1++); --digitptr; +#else + L_REAL f ,g; long q; +#ifdef vax + INT lx,ly; + ly=lxy; lx=(lxy>>16)&0xFFFF; +#endif + dptr=digs; + IF fmat=='D' ORF fmat=='r' + THEN f=itol(lx,ly); + IF f<0 THEN *digitptr++='-'; f = -f; FI + ELSE + IF lx==-1 + THEN *digitptr++='-'; f=leng(-ly); + ELSE f=leng(lx); f *= itol(1,0); f += leng(ly); + FI + IF fmat=='x' THEN *digitptr++='#'; FI + FI + WHILE f + DO q=f/base; g=q; + *dptr++ = f-g*base; + f=q; + OD + IF dptr==digs ORF dptr[-1]>9 THEN *dptr++=0; FI + WHILE dptr!=digs + DO k = *--dptr; + *digitptr++ = (k+(k<=9 ? '0' : 'a'-10)); + OD +#endif +} + +iclose() +{ + IF infile + THEN close(infile); infile=0; + FI +} + +oclose() +{ + IF outfile!=1 + THEN flushbuf(); close(outfile); outfile=1; + FI +} + +endline() +{ + + if (maxpos <= charpos()) + printf("\n"); +} diff --git a/usr/src/cmd/adb/pcs.c b/usr/src/cmd/adb/pcs.c new file mode 100644 index 0000000000..c5c05e37dc --- /dev/null +++ b/usr/src/cmd/adb/pcs.c @@ -0,0 +1,125 @@ +# +/* + * + * UNIX debugger + * + */ + +#include "defs.h" +static char sccsid[] = "%Z%%M% %I% %G%"; + + +MSG NOBKPT; +MSG SZBKPT; +MSG EXBKPT; +MSG NOPCS; +MSG BADMOD; + +/* breakpoints */ +BKPTR bkpthead; + +CHAR *lp; +CHAR lastc; + +INT signo; +L_INT dot; +INT pid; +L_INT cntval; +L_INT loopcnt; + +L_INT entrypt; +INT adrflg; + + + +/* sub process control */ + +subpcs(modif) +{ + REG INT check; + INT execsig,runmode; + REG BKPTR bkptr; + STRING comptr; + execsig=0; loopcnt=cntval; + + switch (modif) { + + /* delete breakpoint */ + case 'd': case 'D': + IF (bkptr=scanbkpt(dot)) + THEN bkptr->flag=0; return; + ELSE error(NOBKPT); + FI + + /* set breakpoint */ + case 'b': case 'B': + IF (bkptr=scanbkpt(dot)) + THEN bkptr->flag=0; + FI + FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt + DO IF bkptr->flag == 0 + THEN break; + FI + OD + IF bkptr==0 + THEN IF (bkptr=sbrk(sizeof *bkptr)) == -1 + THEN error(SZBKPT); + ELSE bkptr->nxtbkpt=bkpthead; + bkpthead=bkptr; + FI + FI + bkptr->loc = dot; + bkptr->initcnt = bkptr->count = cntval; + bkptr->flag = BKPTSET; + check=MAXCOM-1; comptr=bkptr->comm; rdc(); lp--; + REP *comptr++ = readchar(); + PER check-- ANDF lastc!=EOR DONE + *comptr=0; lp--; + IF check + THEN return; + ELSE error(EXBKPT); + FI + + /* exit */ + case 'k' :case 'K': + IF pid + THEN printf("%d: killed", pid); endpcs(); return; + FI + error(NOPCS); + + /* run program */ + case 'r': case 'R': + endpcs(); + setup(); runmode=CONTIN; + IF adrflg + THEN IF !scanbkpt(dot) THEN loopcnt++; FI + ELSE IF !scanbkpt(entrypt+2) THEN loopcnt++; FI + FI + break; + + /* single step */ + case 's': case 'S': + IF pid + THEN + runmode=SINGLE; execsig=getsig(signo); + ELSE setup(); loopcnt--; + FI + break; + + /* continue with optional signal */ + case 'c': case 'C': case 0: + IF pid==0 THEN error(NOPCS); FI + runmode=CONTIN; execsig=getsig(signo); + break; + + default: error(BADMOD); + } + + IF loopcnt>0 ANDF runpcs(runmode,execsig) + THEN printf("breakpoint%16t"); + ELSE printf("stopped at%16t"); + FI + delbp(); + printpc(); +} + diff --git a/usr/src/cmd/adb/print.c b/usr/src/cmd/adb/print.c new file mode 100644 index 0000000000..3a4f93c8cc --- /dev/null +++ b/usr/src/cmd/adb/print.c @@ -0,0 +1,350 @@ +static char sccsid[] = "%Z%%M% %I% %G%"; +/* + * + * UNIX debugger + * + */ +#include "defs.h" + +MSG LONGFIL; +MSG NOTOPEN; +MSG A68BAD; +MSG A68LNK; +MSG BADMOD; + +MAP txtmap; +MAP datmap; + +ADDR lastframe; +ADDR callpc; + +INT infile; +INT outfile; +CHAR *lp; +L_INT maxoff; +L_INT maxpos; +INT radix; + +/* symbol management */ +L_INT localval; + +/* breakpoints */ +BKPTR bkpthead; + +REGLIST reglist [] = { + "p1lr", P1LR, + "p1br",P1BR, + "p0lr", P0LR, + "p0br",P0BR, + "ksp",KSP, + "esp",ESP, + "ssp",SSP, + "psl", PSL, + "pc", PC, + "usp",USP, + "fp", FP, + "ap", AP, + "r11", R11, + "r10", R10, + "r9", R9, + "r8", R8, + "r7", R7, + "r6", R6, + "r5", R5, + "r4", R4, + "r3", R3, + "r2", R2, + "r1", R1, + "r0", R0, +}; + +char lastc; + +INT fcor; +STRING errflg; +INT signo; + + +L_INT dot; +L_INT var[]; +STRING symfil; +STRING corfil; +INT pid; +L_INT adrval; +INT adrflg; +L_INT cntval; +INT cntflg; + +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", + "signal 16", + "stop (signal)", + "stop (tty)", + "continue (signal)", + "child termination", + "stop (tty input)", + "stop (tty output)", + "input available (signal)", + "cpu timelimit", + "file sizelimit", + "signal 26", + "signal 27", + "signal 28", + "signal 29", + "signal 30", + "signal 31", +}; + +/* general printing routines ($) */ + +printtrace(modif) +{ + INT narg, i, stat, name, limit; + POS dynam; + REG BKPTR bkptr; + CHAR hi, lo; + ADDR word; + STRING comptr; + ADDR argp, frame, link; + register struct nlist *sp; + + IF cntflg==0 THEN cntval = -1; FI + + switch (modif) { + + case '<': + case '>': + {CHAR file[64]; + INT index; + + index=0; + IF modif=='<' + THEN iclose(); + ELSE oclose(); + FI + IF rdc()!=EOR + THEN REP file[index++]=lastc; + IF index>=63 THEN error(LONGFIL); FI + PER readchar()!=EOR DONE + file[index]=0; + IF modif=='<' + THEN infile=open(file,0); + IF infile<0 + THEN infile=0; error(NOTOPEN); + FI + ELSE outfile=open(file,1); + IF outfile<0 + THEN outfile=creat(file,0644); +#ifndef EDDT + ELSE lseek(outfile,0L,2); +#endif + FI + FI + + FI + lp--; + } + break; + + case 'd': + if (adrflg) { + if (adrval<2 || adrval>16) {printf("must have 2 <= radix <= 16"); break;} + printf("radix=%d base ten",radix=adrval); + } + break; + + case 'q': case 'Q': case '%': + done(); + + case 'w': case 'W': + maxpos=(adrflg?adrval:MAXPOS); + break; + + case 's': case 'S': + maxoff=(adrflg?adrval:MAXOFF); + break; + + case 'v': case 'V': + prints("variables\n"); + FOR i=0;i<=35;i++ + DO IF var[i] + THEN printc((i<=9 ? '0' : 'a'-10) + i); + printf(" = %Q\n",var[i]); + FI + OD + break; + + case 'm': case 'M': + printmap("? map",&txtmap); + printmap("/ map",&datmap); + break; + + case 0: case '?': + IF pid + THEN printf("pcs id = %d\n",pid); + ELSE prints("no process\n"); + FI + sigprint(); flushbuf(); + + case 'r': case 'R': + printregs(); + return; + + case 'c': case 'C': + IF adrflg + THEN frame=adrval; + word=get(adrval+6,DSP)&0xFFFF; + IF word&0x2000 + THEN /* 'calls', can figure out argp */ + argp=adrval+20+((word>>14)&3); word &= 0xFFF; + WHILE word DO IF word&1 THEN argp+=4; FI word>>=1; OD + ELSE /* 'callg', can't tell where argp is */ argp=frame; + FI + callpc=get(frame+16,DSP); + ELSE argp= *(ADDR *)(((ADDR)&u)+AP); + frame= *(ADDR *)(((ADDR)&u)+FP); + callpc= *(ADDR *)(((ADDR)&u)+PC); + FI + lastframe=0; + WHILE cntval-- + DO chkerr(); + findsym(callpc,ISYM); + if (cursym && !strcmp(cursym->n_un.n_name, "start")) + break; + printf("%s(", cursym ? cursym->n_un.n_name : "?"); + narg = get(argp,DSP); IF narg&~0xFF THEN narg=0; FI + LOOP IF narg==0 THEN break; FI + printf("%R", get(argp += 4, DSP)); + IF --narg!=0 THEN printc(','); FI + POOL + printf(") from %X\n",callpc); /* jkf mod */ + + IF modif=='C' + THEN WHILE localsym(frame,argp) + DO word=get(localval,DSP); + printf("%8t%s:%10t", cursym->n_un.n_name); + IF errflg THEN prints("?\n"); errflg=0; ELSE printf("%R\n",word); FI + OD + FI + + callpc=get(frame+16, DSP); + argp=get(frame+8, DSP); + lastframe=frame; + frame=get(frame+12, DSP)&EVEN; + IF frame==0 ORF (!adrflg ANDF !INSTACK(frame)) + THEN break; + FI + OD + break; + + /*print externals*/ + case 'e': case 'E': + for (sp = symtab; sp < esymtab; sp++) { + if (sp->n_type==(N_DATA|N_EXT) ORF sp->n_type==(N_BSS|N_EXT)) + printf("%s:%12t%R\n", sp->n_un.n_name, get(sp->n_value,DSP)); + } + break; + + case 'a': case 'A': + error("No algol 68 on VAX"); + /*NOTREACHED*/ + + /*print breakpoints*/ + case 'b': case 'B': + printf("breakpoints\ncount%8tbkpt%24tcommand\n"); + for (bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt) + if (bkptr->flag) { + printf("%-8.8d",bkptr->count); + psymoff(leng(bkptr->loc),ISYM,"%24t"); + comptr=bkptr->comm; + WHILE *comptr DO printc(*comptr++); OD + } + break; + + default: error(BADMOD); + } + +} + +printmap(s,amap) +STRING s; MAP *amap; +{ + int file; + file=amap->ufd; + printf("%s%12t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); + printf("b1 = %-16R",amap->b1); + printf("e1 = %-16R",amap->e1); + printf("f1 = %-16R",amap->f1); + printf("\nb2 = %-16R",amap->b2); + printf("e2 = %-16R",amap->e2); + printf("f2 = %-16R",amap->f2); + printc(EOR); +} + +printregs() +{ + REG REGPTR p; + L_INT v; + + FOR p=reglist; p < ®list[24]; p++ + DO printf("%s%6t%R %16t", p->rname, v= *(ADDR *)(((ADDR)&u)+p->roffs)); + valpr(v,(p->roffs==PC?ISYM:DSYM)); + printc(EOR); + OD + printpc(); +} + +getreg(regnam) +{ + REG REGPTR p; + REG STRING regptr; + CHAR *olp; + CHAR regnxt; + + olp=lp; + FOR p=reglist; p < ®list[24]; p++ + DO regptr=p->rname; + IF (regnam == *regptr++) + THEN + WHILE *regptr + DO IF (regnxt=readchar()) != *regptr++ + THEN --regptr; break; + FI + OD + IF *regptr + THEN lp=olp; + ELSE return(p->roffs); + FI + FI + OD + lp=olp; + return(0); +} + +printpc() +{ + dot= *(ADDR *)(((ADDR)&u)+PC); + psymoff(dot,ISYM,":%16t"); printins(0,ISP,chkget(dot,ISP)); + printc(EOR); +} + +sigprint() +{ + IF (signo>=0) ANDF (signo=0 + DO +#ifdef DEBUG + printf("\ncontinue %x %d\n",userpc,execsig); +#endif + IF runmode==SINGLE + THEN delbp(); /* hardware handles single-stepping */ + ELSE /* continuing from a breakpoint is hard */ + IF bkpt=scanbkpt(userpc) + THEN execbkpt(bkpt,execsig); execsig=0; + FI + setbp(); + FI + ptrace(runmode,pid,userpc,execsig); + bpwait(); chkerr(); execsig=0; delbp(); readregs(); + + IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) + THEN /* stopped by BPT instruction */ +#ifdef DEBUG + printf("\n BPT code; '%s'%o'%o'%d", + bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); +#endif + dot=bkpt->loc; + IF bkpt->flag==BKPTEXEC + ORF ((bkpt->flag=BKPTEXEC) + ANDF bkpt->comm[0]!=EOR + ANDF command(bkpt->comm,':') + ANDF --bkpt->count) + THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; + ELSE bkpt->count=bkpt->initcnt; rc=1; + FI + ELSE execsig=signo; rc=0; + FI + OD + return(rc); +} + +#define BPOUT 0 +#define BPIN 1 +INT bpstate = BPOUT; + +endpcs() +{ + REG BKPTR bkptr; + IF pid + THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1; + FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt + DO IF bkptr->flag + THEN bkptr->flag=BKPTSET; + FI + OD + FI + bpstate=BPOUT; +} + +#ifdef VFORK +nullsig() +{ + +} +#endif + +setup() +{ + close(fsym); fsym = -1; +#ifndef VFORK + IF (pid = fork()) == 0 +#else + IF (pid = vfork()) == 0 +#endif + THEN ptrace(SETTRC,0,0,0); +#ifdef VFORK + signal(SIGTRAP,nullsig); +#endif + signal(SIGINT,sigint); signal(SIGQUIT,sigqit); + doexec(); exit(0); + ELIF pid == -1 + THEN error(NOFORK); + ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0; + fsym=open(symfil,wtflag); + IF errflg + THEN printf("%s: cannot execute\n",symfil); + endpcs(); error(0); + FI + FI + bpstate=BPOUT; +} + +execbkpt(bkptr,execsig) +BKPTR bkptr; +{ +#ifdef DEBUG + printf("exbkpt: %d\n",bkptr->count); +#endif + delbp(); + ptrace(SINGLE,pid,bkptr->loc,execsig); + bkptr->flag=BKPTSET; + bpwait(); chkerr(); readregs(); +} + + +doexec() +{ + STRING argl[MAXARG]; + CHAR args[LINSIZ]; + STRING p, *ap, filnam; + extern STRING environ; + ap=argl; p=args; + *ap++=symfil; + REP IF rdc()==EOR THEN break; FI + *ap = p; + WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD + *p++=0; filnam = *ap+1; + IF **ap=='<' + THEN close(0); + IF open(filnam,0)<0 + THEN printf("%s: cannot open\n",filnam); _exit(0); + FI + ELIF **ap=='>' + THEN close(1); + IF creat(filnam,0666)<0 + THEN printf("%s: cannot create\n",filnam); _exit(0); + FI + ELSE ap++; + FI + PER lastc!=EOR DONE + *ap++=0; + exect(symfil, argl, environ); + perror(symfil); +} + +BKPTR scanbkpt(adr) +ADDR adr; +{ + REG BKPTR bkptr; + FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt + DO IF bkptr->flag ANDF bkptr->loc==adr + THEN break; + FI + OD + return(bkptr); +} + +delbp() +{ + REG ADDR a; + REG BKPTR bkptr; + IF bpstate!=BPOUT + THEN + FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt + DO IF bkptr->flag + THEN a=bkptr->loc; + IF a < txtmap.e1 THEN + ptrace(WIUSER,pid,a, + (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF)); + ELSE + ptrace(WDUSER,pid,a, + (bkptr->ins&0xFF)|(ptrace(RDUSER,pid,a,0)&~0xFF)); + FI + FI + OD + bpstate=BPOUT; + FI +} + +setbp() +{ + REG ADDR a; + REG BKPTR bkptr; + + IF bpstate!=BPIN + THEN + FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt + DO IF bkptr->flag + THEN a = bkptr->loc; + IF a < txtmap.e1 THEN + bkptr->ins = ptrace(RIUSER, pid, a, 0); + ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF)); + ELSE + bkptr->ins = ptrace(RDUSER, pid, a, 0); + ptrace(WDUSER, pid, a, BPT | (bkptr->ins&~0xFF)); + FI + IF errno + THEN prints("cannot set breakpoint: "); + psymoff(bkptr->loc,ISYM,"\n"); + FI + FI + OD + bpstate=BPIN; + FI +} + +bpwait() +{ + REG ADDR w; + ADDR stat; + + signal(SIGINT, 1); + WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE + signal(SIGINT,sigint); + IF w == -1 + THEN pid=0; + errflg=BADWAIT; + ELIF (stat & 0177) != 0177 + THEN IF signo = stat&0177 + THEN sigprint(); + FI + IF stat&0200 + THEN prints(" - core dumped"); + close(fcor); + setcor(); + FI + pid=0; + errflg=ENDPCS; + ELSE signo = stat>>8; + IF signo!=SIGTRAP + THEN sigprint(); + ELSE signo=0; + FI + flushbuf(); + FI +} + +readregs() +{ + /*get REG values from pcs*/ + REG i; + FOR i=24; --i>=0; + DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) = + ptrace(RUREGS, pid, reglist[i].roffs, 0); + OD + userpc= *(ADDR *)(((ADDR)&u)+PC); +} + + diff --git a/usr/src/cmd/adb/setup.c b/usr/src/cmd/adb/setup.c new file mode 100644 index 0000000000..24413a5762 --- /dev/null +++ b/usr/src/cmd/adb/setup.c @@ -0,0 +1,176 @@ +static char sccsid[] = "%Z%%M% %I% %G%"; +/* + * adb - routines to read a.out+core at startup + */ +#include "defs.h" +#include + +off_t datbas; /* offset of the base of the data segment */ +off_t stksiz; /* stack size in the core image */ + +char *symfil = "a.out"; +char *corfil = "core"; + +setsym() +{ + off_t loc; + struct exec hdr; + register struct nlist *sp; + int ssiz; + char *strtab; + + fsym = getfile(symfil, 1); + txtmap.ufd = fsym; + if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr || + N_BADMAG(hdr)) { + txtmap.e1 = MAXFILE; + return; + } + filhdr = hdr; + loc = filhdr.a_text+filhdr.a_data; + txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr); + txtmap.b1 = 0; + switch (filhdr.a_magic) { + + case OMAGIC: + txtmap.e1 = loc; + txtmap.b2 = datbas = 0; + txtmap.e2 = loc; + break; + + case ZMAGIC: + case NMAGIC: + txtmap.e1 = filhdr.a_text; + txtmap.b2 = datbas = round(filhdr.a_text, PAGSIZ); + txtmap.e2 = datbas + filhdr.a_data; + txtmap.f2 += txtmap.e1; + } + loc = N_SYMOFF(filhdr); + symtab = (struct nlist *) malloc(filhdr.a_syms); + esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)]; + if (symtab == NULL) + goto nospac; + lseek(fsym, loc, 0); + if (filhdr.a_syms == 0) + goto nosymt; + /* SHOULD SQUISH OUT STABS HERE!!! */ + if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms) + goto readerr; + if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz)) + goto oldfmt; + strtab = (char *) malloc(ssiz); + if (strtab == 0) + goto nospac; + *(int *)strtab = ssiz; + ssiz -= sizeof (ssiz); + if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz) + goto readerr; + for (sp = symtab; sp < esymtab; sp++) + if (sp->n_strx) + /* SHOULD PERFORM RANGE CHECK HERE */ + sp->n_un.n_name = strtab + sp->n_un.n_strx; +nosymt: + if (INKERNEL(filhdr.a_entry)) { + txtmap.b1 += KERNOFF; + txtmap.e1 += KERNOFF; + txtmap.b2 += KERNOFF; + txtmap.e2 += KERNOFF; + } + return; +readerr: + printf("Error reading symbol|string table\n"); + exit(1); +nospac: + printf("Not enough space for symbol|string table\n"); + exit(1); +oldfmt: + printf("Old format a.out - no string table\n"); + exit(1); +} + +setcor() +{ + + if (fcor != -1 && INKERNEL(filhdr.a_magic)) { + struct stat stb; + + fstat(fcor, &stb); + if ((stb.st_mode&S_IFMT) == S_IFREG) { + datmap.b1 += KERNOFF; + datmap.e1 += KERNOFF; + } + return; + } + fcor = datmap.ufd = getfile(corfil,2); + if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES) || + !INUDOT(u.u_pcb.pcb_ksp) || !INSTACK(u.u_pcb.pcb_usp)) { + datmap.e1 = MAXFILE; + return; + } + signo = u.u_arg[0]; + filhdr.a_text = ctob(u.u_tsize); + filhdr.a_data = ctob(u.u_dsize); + stksiz = ctob(u.u_ssize); + switch (filhdr.a_magic) { + + case OMAGIC: + datmap.b1 = 0; + datmap.e1 = filhdr.a_text+filhdr.a_data; + datmap.f2 = ctob(UPAGES) + datmap.e1; + break; + + case NMAGIC: + case ZMAGIC: + datmap.b1 = round(filhdr.a_text, PAGSIZ); + datmap.e1 = datmap.b1 + filhdr.a_data; + datmap.f2 = ctob(UPAGES) + filhdr.a_data; + break; + } + datbas = datmap.b1; + datmap.f1 = ctob(UPAGES); + datmap.b2 = MAXSTOR - stksiz; + datmap.e2 = MAXSTOR; + if (filhdr.a_magic && u.u_exdata.ux_mag && + filhdr.a_magic != u.u_exdata.ux_mag) + printf("corefile not from this program"); +} + +create(f) + char *f; +{ + register int fd; + + fd = creat(f, 0644); + if (fd < 0) + return (-1); + close(fd); + return (open(f, wtflag)); +} + +getfile(filnam, cnt) + char *filnam; +{ + register int fsym; + + if (eqstr(filnam, "-")) + return (-1); + fsym = open(filnam, wtflag); + if (fsym < 0 && xargc > cnt) { + if (wtflag) + fsym = create(filnam); + if (fsym < 0) + printf("cannot open `%s'\n", filnam); + } + return (fsym); +} + +setvar() +{ + + var[varchk('b')] = datbas; + var[varchk('d')] = filhdr.a_data; + var[varchk('e')] = filhdr.a_entry; + var[varchk('m')] = filhdr.a_magic; + var[varchk('s')] = stksiz; + var[varchk('t')] = filhdr.a_text; +} diff --git a/usr/src/cmd/adb/sym.c b/usr/src/cmd/adb/sym.c new file mode 100644 index 0000000000..81b55b0714 --- /dev/null +++ b/usr/src/cmd/adb/sym.c @@ -0,0 +1,148 @@ +static char sccsid[] = "%Z%%M% %I% %G%"; +/* + * adb - symbol table routines + */ +#include "defs.h" +#include + +/* + * Lookup a symbol by name. + */ +struct nlist * +lookup(symstr) + char *symstr; +{ + register struct nlist *sp; + + cursym = 0; + if (symtab) + for (sp = symtab; sp < esymtab; sp++) + /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */ + if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_')) + return(cursym = sp); + return (0); +} + +/* + * Find the closest symbol to val, and return + * the difference between val and the symbol found. + * Leave a pointer to the symbol found as cursym. + */ +findsym(val, type) + long val; + int type; +{ + long diff; + register struct nlist *sp; + + cursym = 0; + diff = MAXINT; + if (type == NSYM || symtab == 0) + return (diff); + for (sp = symtab; sp < esymtab; sp++) { + if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0) + continue; + if (val - sp->n_value < diff && val >= sp->n_value) { + diff = val - sp->n_value; + cursym = sp; + if (diff == 0) + break; + } + } + return (diff); +} + +/* + * Advance cursym to the next local variable. + * Leave its value in localval as a side effect. + * Return 0 at end of file. + */ +localsym(cframe, cargp) + ADDR cframe, cargp; +{ + register int type; + register struct nlist *sp; + + if (cursym) + for (sp = cursym; ++sp < esymtab; ) { + if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN) + return (0); + type = sp->n_type; + switch (sp->n_type) { + + case N_TEXT: + case N_TEXT|N_EXT: + case N_DATA: + case N_DATA|N_EXT: + case N_BSS: + case N_BSS|N_EXT: + localval = sp->n_value; + cursym = sp; + return (1); + + case N_LSYM: + localval = cframe - sp->n_value; + cursym = sp; + return (1); + + case N_PSYM: + /* code below works since n_value > 0 */ + case N_ABS: + if (sp->n_value < 0) + localval = cframe + sp->n_value; + else + localval = cargp + sp->n_value; + cursym = sp; + return (1); + } + } + cursym = 0; + return (0); +} + +/* + * Print value v and then the string s. + * If v is not zero, then we look for a nearby symbol + * and print name+offset if we find a symbol for which + * offset is small enough. + * + * For values which are just into kernel address space + * that they match exactly or that they be more than maxoff + * bytes into kernel space. + */ +psymoff(v, type, s) + long v; + int type; + char *s; +{ + long w; + + if (v) + w = findsym(v, type); + if (v==0 || w >= maxoff || (KVTOPH(v) < maxoff && w)) + printf(LPRMODE, v); + else { + printf("%s", cursym->n_un.n_name); + if (w) + printf(OFFMODE, w); + } + printf(s); +} + +/* + * Print value v symbolically if it has a reasonable + * interpretation as name+offset. If not, print nothing. + * Used in printing out registers $r. + */ +valpr(v, idsp) + long v; +{ + off_t d; + + d = findsym(v, idsp); + if (d >= maxoff) + return; + printf("%s", cursym->n_un.n_name); + if (d) + printf(OFFMODE, d); +}