--- /dev/null
+/*
+ * adb - vax string table version; common definitions
+ */
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/psl.h>
+#include <sys/user.h>
+#include <ctype.h>
+#include <a.out.h>
+
+#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();
--- /dev/null
+#
+/*
+ *
+ * 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 | . | ^ | <var | <register | 'x | | */
+ INT base, d, regptr;
+ CHAR savc;
+ BOOL hex;
+ L_INT frame;
+ register struct nlist *symp;
+
+ hex=FALSE;
+
+ readchar();
+ IF symchar(0)
+ THEN readsym();
+ IF lastc=='.'
+ THEN frame= *(ADDR *)(((ADDR)&u)+FP); lastframe=0;
+ callpc= *(ADDR *)(((ADDR)&u)+PC);
+ WHILE errflg==0
+ DO savpc=callpc;
+ findsym(callpc,ISYM);
+ IF eqsym(cursym->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);
+}
--- /dev/null
+#
+/*
+ *
+ * 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<SP
+ THEN printf("^%c", c + '@');
+ ELSE printc(c);
+ FI
+}
+
+L_INT inkdot(incr)
+{
+ L_INT newdot;
+
+ newdot=dot+incr;
+ IF (dot NEQ newdot) >> 24 THEN error(ADWRAP); FI
+ return(newdot);
+}
--- /dev/null
+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;
+
--- /dev/null
+#
+/*
+ *
+ * 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
+}
--- /dev/null
+#
+/*
+ * 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
--- /dev/null
+#include <sys/vm.h>
+
+#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
--- /dev/null
+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++;
+}
--- /dev/null
+#
+/*
+ *
+ * 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";
--- /dev/null
+#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;
+};
--- /dev/null
+#
+/*
+ *
+ * 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; argno<ip->nargs; 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');
+ }
+ }
+ }
+}
--- /dev/null
+#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"};
--- /dev/null
+#
+/*
+ *
+ * UNIX debugger
+ *
+ */
+
+#include "defs.h"
+static char sccsid[] = "%Z%%M% %I% %G%";
+#include <stdio.h>
+
+
+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; p<printptr-printbuf; p++
+ DO d=printbuf[p];
+ IF (p&7)==0 ANDF posn
+ THEN tabs++; posn=0;
+ FI
+ IF d==SP
+ THEN posn++;
+ ELSE WHILE tabs>0 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 (printptr<q);
+#else
+ write(outfile,printbuf,q-printbuf);
+#endif
+ printptr=printbuf;
+ ELIF c==TB
+ THEN *printptr++=SP;
+ WHILE (printptr-printbuf)&7 DO *printptr++=SP; OD
+ ELIF c
+ THEN printptr++;
+ FI
+}
+
+charpos()
+{ return(printptr-printbuf);
+}
+
+flushbuf()
+{ IF printptr!=printbuf
+ THEN printc(EOR);
+ FI
+}
+
+printf(fmat,a1)
+ STRING fmat;
+ STRING *a1;
+{
+ STRING fptr, s;
+ INT *vptr;
+ L_INT *dptr;
+ L_REAL *rptr;
+ INT width, prec;
+ CHAR c, adj;
+ INT x, decpt, n;
+ L_INT lx;
+ CHAR digits[64];
+
+ fptr = fmat; dptr = vptr = &a1;
+
+ WHILE c = *fptr++
+ DO IF c!='%'
+ THEN printc(c);
+ ELSE IF *fptr=='-' THEN adj='l'; fptr++; ELSE adj='r'; FI
+ width=convert(&fptr);
+ IF *fptr=='.' THEN fptr++; prec=convert(&fptr); ELSE prec = -1; FI
+ digitptr=digits;
+#ifndef vax
+ dptr=rptr=vptr; lx = *dptr; x = *vptr++;
+#else
+ rptr=dptr; x = shorten(lx = *dptr++);
+#endif
+ s=0;
+ switch (c = *fptr++) {
+
+ case 'd':
+ case 'u':
+ printnum(x,c,10); break;
+ case 'o':
+#ifndef vax
+ printoct(0,x,0); break;
+#else
+ printoct(itol(0,x),0); break;
+#endif
+ case 'q':
+ lx=x; printoct(lx,-1); break;
+ case 'x':
+#ifndef vax
+ printdbl(0,x,c,16); break;
+#else
+ printdbl(itol(0,x),c,16); break;
+#endif
+ case 'r':
+ printdbl(lx=x,c,radix); break;
+ case 'R':
+ printdbl(lx,c,radix); vptr++; break;
+ case 'Y':
+ printdate(lx); vptr++; break;
+ case 'D':
+ case 'U':
+ printdbl(lx,c,10); vptr++; break;
+ case 'O':
+ printoct(lx,0); vptr++; break;
+ case 'Q':
+ printoct(lx,-1); vptr++; break;
+ case 'X':
+ printdbl(lx,'x',16); vptr++; break;
+ case 'c':
+ printc(x); break;
+ case 's':
+#ifndef vax
+ s=x; break;
+#else
+ s=lx; break;
+#endif
+#ifndef EDDT
+ case 'f':
+ case 'F':
+#ifdef vax
+ dptr++;
+ sprintf(s=digits,"%+.16e",*rptr,*(rptr+4)); prec= -1; break;
+#else
+ vptr += 7;
+ s=ecvt(*rptr, prec, &decpt, &n);
+ *digitptr++=(n?'-':'+');
+ *digitptr++ = (decpt<=0 ? '0' : *s++);
+ IF decpt>0 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<n ANDF 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");
+}
--- /dev/null
+#
+/*
+ *
+ * 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();
+}
+
--- /dev/null
+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<sizeof signals/sizeof signals[0])
+ THEN prints(signals[signo]); FI
+}
--- /dev/null
+#
+/*
+ *
+ * UNIX debugger
+ *
+ */
+
+#include "defs.h"
+static char sccsid[] = "%Z%%M% %I% %G%";
+
+extern MAP txtmap;
+
+MSG NOFORK;
+MSG ENDPCS;
+MSG BADWAIT;
+
+CHAR *lp;
+ADDR sigint;
+ADDR sigqit;
+
+/* breakpoints */
+BKPTR bkpthead;
+
+REGLIST reglist[];
+
+CHAR lastc;
+
+INT fcor;
+INT fsym;
+STRING errflg;
+INT errno;
+INT signo;
+
+L_INT dot;
+STRING symfil;
+INT wtflag;
+L_INT pid;
+L_INT expv;
+INT adrflg;
+L_INT loopcnt;
+
+
+
+
+
+/* service routines for sub process control */
+
+getsig(sig)
+{ return(expr(0) ? expv : sig);
+}
+
+ADDR userpc = 1;
+
+runpcs(runmode,execsig)
+{
+ INT rc;
+ REG BKPTR bkpt;
+ IF adrflg THEN userpc=dot; FI
+ printf("%s: running\n", symfil);
+
+ WHILE --loopcnt>=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);
+}
+
+
--- /dev/null
+static char sccsid[] = "%Z%%M% %I% %G%";
+/*
+ * adb - routines to read a.out+core at startup
+ */
+#include "defs.h"
+#include <stat.h>
+
+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;
+}
--- /dev/null
+static char sccsid[] = "%Z%%M% %I% %G%";
+/*
+ * adb - symbol table routines
+ */
+#include "defs.h"
+#include <stab.h>
+
+/*
+ * 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);
+}