1 #ifndef lint 2 static char sccsid[] = "@(#)runpcs.c 1.1 (Berkeley) 02/25/86"; 3 #endif 4 /* 5 * 6 * UNIX debugger 7 * 8 */ 9 10 #include "defs.h" 11 12 extern MAP txtmap; 13 14 MSG NOFORK; 15 MSG ENDPCS; 16 MSG BADWAIT; 17 18 CHAR *lp; 19 SIG sigint; 20 SIG sigqit; 21 22 /* breakpoints */ 23 BKPTR bkpthead; 24 25 REGLIST reglist[]; 26 27 CHAR lastc; 28 29 INT fcor; 30 INT fsym; 31 STRING errflg; 32 INT errno; 33 INT signo; 34 INT sigcode; 35 36 L_INT dot; 37 STRING symfil; 38 INT wtflag; 39 L_INT pid; 40 L_INT expv; 41 INT adrflg; 42 L_INT loopcnt; 43 44 45 46 47 48 /* service routines for sub process control */ 49 50 getsig(sig) 51 { return(expr(0) ? expv : sig); 52 } 53 54 ADDR userpc = 1; 55 56 runpcs(runmode,execsig) 57 { 58 REG rc; 59 REG BKPTR bkpt; 60 IF adrflg THEN userpc=dot; FI 61 printf("%s: running\n", symfil); 62 63 WHILE --loopcnt>=0 64 DO 65 #ifdef DEBUG 66 printf("\ncontinue %X %D loopcnt=%D\n",userpc,execsig, loopcnt); 67 #endif 68 IF runmode==SINGLE 69 THEN delbp(); /* hardware handles single-stepping */ 70 ELSE /* continuing from a breakpoint is hard */ 71 IF bkpt=scanbkpt(userpc) 72 THEN execbkpt(bkpt,execsig); execsig=0; 73 FI 74 setbp(); 75 FI 76 ptrace(runmode,pid,userpc,execsig); 77 bpwait(); chkerr(); execsig=0; delbp(); readregs(); 78 79 IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) 80 THEN /* stopped by BPT instruction */ 81 #ifdef DEBUG 82 printf("\n BPT code; '%s'%o'%d", 83 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); 84 #endif 85 dot=bkpt->loc; 86 IF bkpt->flag==BKPTEXEC 87 ORF ((bkpt->flag=BKPTEXEC) 88 ANDF bkpt->comm[0]!=EOR 89 ANDF command(bkpt->comm,':') 90 ANDF --bkpt->count) 91 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; 92 ELSE bkpt->count=bkpt->initcnt; rc=1; 93 FI 94 ELSE execsig=signo; rc=0; 95 FI 96 OD 97 return(rc); 98 } 99 100 #define BPOUT 0 101 #define BPIN 1 102 INT bpstate = BPOUT; 103 104 endpcs() 105 { 106 REG BKPTR bkptr; 107 IF pid 108 THEN ptrace(EXIT,pid); pid=0; userpc=1; 109 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 110 DO IF bkptr->flag 111 THEN bkptr->flag=BKPTSET; 112 FI 113 OD 114 FI 115 bpstate=BPOUT; 116 } 117 118 #ifdef VFORK 119 nullsig() 120 { 121 122 } 123 #endif 124 125 setup() 126 { 127 close(fsym); fsym = -1; 128 #ifndef VFORK 129 IF (pid = fork()) == 0 130 #else 131 IF (pid = vfork()) == 0 132 #endif 133 THEN ptrace(SETTRC); 134 #ifdef VFORK 135 signal(SIGTRAP,nullsig); 136 #endif 137 signal(SIGINT,sigint); signal(SIGQUIT,sigqit); 138 doexec(); exit(0); 139 ELIF pid == -1 140 THEN error(NOFORK); 141 ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0; 142 fsym=open(symfil,wtflag); 143 IF errflg 144 THEN printf("%s: cannot execute\n",symfil); 145 endpcs(); error(0); 146 FI 147 FI 148 bpstate=BPOUT; 149 } 150 151 execbkpt(bkptr,execsig) 152 BKPTR bkptr; 153 { 154 #ifdef DEBUG 155 printf("exbkpt: %d\n",bkptr->count); 156 #endif 157 delbp(); 158 ptrace(SINGLE,pid,bkptr->loc,execsig); 159 bkptr->flag=BKPTSET; 160 bpwait(); chkerr(); readregs(); 161 } 162 163 164 doexec() 165 { 166 STRING argl[MAXARG]; 167 CHAR args[LINSIZ]; 168 REG STRING p, *ap, filnam; 169 extern STRING environ; 170 171 ap=argl; p=args; 172 *ap++=symfil; 173 REP IF rdc()==EOR THEN break; FI 174 *ap = p; 175 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD 176 *p++=0; filnam = *ap+1; 177 IF **ap=='<' 178 THEN close(0); 179 IF open(filnam,0)<0 180 THEN printf("%s: cannot open\n",filnam); _exit(0); 181 FI 182 ELIF **ap=='>' 183 THEN close(1); 184 IF creat(filnam,0666)<0 185 THEN printf("%s: cannot create\n",filnam); _exit(0); 186 FI 187 ELSE ap++; 188 FI 189 PER lastc!=EOR DONE 190 *ap++=0; 191 execve(symfil, argl, environ); 192 perror(symfil); 193 } 194 195 BKPTR scanbkpt(adr) 196 ADDR adr; 197 { 198 REG BKPTR bkptr; 199 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 200 DO IF bkptr->flag ANDF bkptr->loc==adr 201 THEN break; 202 FI 203 OD 204 return(bkptr); 205 } 206 207 delbp() 208 { 209 REG ADDR a; 210 REG BKPTR bkptr; 211 IF bpstate!=BPOUT 212 THEN 213 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 214 DO IF bkptr->flag 215 THEN a=bkptr->loc; 216 IF a < txtmap.e1 THEN 217 ptrace(WIUSER,pid,a,bkptr->ins); 218 ELSE 219 ptrace(WDUSER,pid,a,bkptr->ins); 220 FI 221 FI 222 OD 223 bpstate=BPOUT; 224 FI 225 } 226 227 #if defined(vax) 228 #define SETBP(ins) (BPT | ((ins) &~ 0xff)) 229 #else 230 #define SETBP(ins) ((BPT<<24) | ((ins) & 0xffffff)) 231 #endif 232 233 setbp() 234 { 235 REG ADDR a; 236 REG BKPTR bkptr; 237 238 IF bpstate!=BPIN 239 THEN 240 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 241 DO IF bkptr->flag 242 THEN a = bkptr->loc; 243 IF a < txtmap.e1 THEN 244 bkptr->ins = ptrace(RIUSER, pid, a); 245 ptrace(WIUSER, pid, a, SETBP(bkptr->ins)); 246 ELSE 247 bkptr->ins = ptrace(RDUSER, pid, a); 248 ptrace(WDUSER, pid, a, SETBP(bkptr->ins)); 249 FI 250 IF errno 251 THEN printf("cannot set breakpoint: "); 252 psymoff(bkptr->loc,ISYM,"\n"); 253 FI 254 FI 255 OD 256 bpstate=BPIN; 257 FI 258 } 259 260 bpwait() 261 { 262 REG w; 263 ADDR stat; 264 265 signal(SIGINT, 1); 266 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE 267 signal(SIGINT,sigint); 268 IF w == -1 269 THEN pid=0; 270 errflg=BADWAIT; 271 ELIF (stat & 0177) != 0177 272 THEN sigcode = 0; 273 IF signo = stat&0177 274 THEN sigprint(); 275 FI 276 IF stat&0200 277 THEN printf(" - core dumped"); 278 close(fcor); 279 setcor(); 280 FI 281 pid=0; 282 errflg=ENDPCS; 283 ELSE signo = stat>>8; 284 sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0); 285 IF signo!=SIGTRAP 286 THEN sigprint(); 287 ELSE signo=0; 288 FI 289 flushbuf(); 290 FI 291 } 292 293 readregs() 294 { 295 /*get REG values from pcs*/ 296 REG REGPTR p; 297 298 FOR p=reglist; p->rname; p++ 299 DO *(ADDR *)(((ADDR)&u)+p->roffs) = 300 ptrace(RUREGS, pid, p->roffs, 0); 301 OD 302 userpc= *(ADDR *)(((ADDR)&u)+PC); 303 } 304