1 /* 2 * db - main command loop and error/interrupt handling 3 */ 4 #include "defs.h" 5 #include "fns.h" 6 7 int wtflag = OREAD; 8 BOOL kflag; 9 10 BOOL mkfault; 11 ADDR maxoff; 12 13 int xargc; /* bullshit */ 14 15 extern BOOL executing; 16 extern int infile; 17 int exitflg; 18 extern char lastc; 19 extern int eof; 20 21 int alldigs(char*); 22 void fault(void*, char*); 23 24 extern char *Ipath; 25 jmp_buf env; 26 static char *errmsg; 27 28 void 29 main(int argc, char **argv) 30 { 31 char b1[100]; 32 char b2[100]; 33 char *s; 34 char *name; 35 36 name = 0; 37 outputinit(); 38 maxoff = MAXOFF; 39 ARGBEGIN{ 40 case 'k': 41 kflag = 1; 42 break; 43 case 'w': 44 wtflag = ORDWR; /* suitable for open() */ 45 break; 46 case 'I': 47 s = ARGF(); 48 if(s == 0) 49 dprint("missing -I argument\n"); 50 else 51 Ipath = s; 52 break; 53 case 'm': 54 name = ARGF(); 55 if(name == 0) 56 dprint("missing -m argument\n"); 57 break; 58 }ARGEND 59 symfil = 0; 60 corfil = 0; 61 if (argc > 0 && !alldigs(argv[0])) { 62 symfil = argv[0]; 63 argv++; 64 argc--; 65 } 66 if(argc==1 && alldigs(argv[0])){ 67 char *cpu, *p, *q; 68 69 pid = atoi(argv[0]); 70 pcsactive = 0; 71 if (!symfil) { 72 if(kflag){ 73 cpu = getenv("cputype"); 74 if(cpu == 0){ 75 cpu = "mips"; 76 dprint("$cputype not set; assuming %s\n", cpu); 77 } 78 p = getenv("terminal"); 79 if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){ 80 strcpy(b1, "/mips/9power"); 81 dprint("missing or bad $terminal; assuming %s\n", b1); 82 }else{ 83 p++; 84 q = strchr(p, ' '); 85 if(q) 86 *q = 0; 87 sprint(b1, "/%s/9%s", cpu, p); 88 89 } 90 }else 91 sprint(b1, "/proc/%s/text", argv[0]); 92 symfil = b1; 93 } 94 sprint(b2, "/proc/%s/mem", argv[0]); 95 corfil = b2; 96 } else if (argc > 0) { 97 fprint(2, "Usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n"); 98 exits("usage"); 99 } 100 if (!symfil) 101 symfil = "v.out"; 102 xargc = argc; 103 notify(fault); 104 setsym(); 105 dotmap = dumbmap(-1); 106 if (name && machbyname(name) == 0) 107 dprint ("unknown machine %s", name); 108 dprint("%s binary\n", mach->name); 109 if(setjmp(env) == 0){ 110 if (corfil) { 111 setcor(); /* could get error */ 112 dprint("%s\n", machdata->excep(cormap, rget)); 113 printpc(); 114 } 115 } 116 117 setjmp(env); 118 if (executing) 119 delbp(); 120 executing = FALSE; 121 for (;;) { 122 flushbuf(); 123 if (errmsg) { 124 dprint(errmsg); 125 printc('\n'); 126 errmsg = 0; 127 exitflg = 0; 128 } 129 if (mkfault) { 130 mkfault=0; 131 printc('\n'); 132 prints(DBNAME); 133 } 134 clrinp(); 135 rdc(); 136 reread(); 137 if (eof) { 138 if (infile == STDIN) 139 done(); 140 iclose(-1, 0); 141 eof = 0; 142 longjmp(env, 1); 143 } 144 exitflg = 0; 145 command(0, 0); 146 reread(); 147 if (rdc() != '\n') 148 error("newline expected"); 149 } 150 } 151 152 int 153 alldigs(char *s) 154 { 155 while(*s){ 156 if(*s<'0' || '9'<*s) 157 return 0; 158 s++; 159 } 160 return 1; 161 } 162 163 void 164 done(void) 165 { 166 if (pid) 167 endpcs(); 168 exits(exitflg? "error": 0); 169 } 170 171 /* 172 * An error occurred; save the message for later printing, 173 * close open files, and reset to main command loop. 174 */ 175 void 176 error(char *n) 177 { 178 errmsg = n; 179 iclose(0, 1); 180 oclose(); 181 flush(); 182 delbp(); 183 ending = 0; 184 longjmp(env, 1); 185 } 186 187 void 188 errors(char *m, char *n) 189 { 190 static char buf[128]; 191 192 sprint(buf, "%s: %s", m, n); 193 error(buf); 194 } 195 196 /* 197 * An interrupt occurred; 198 * seek to the end of the current file 199 * and remember that there was a fault. 200 */ 201 void 202 fault(void *a, char *s) 203 { 204 USED(a); 205 if(strncmp(s, "interrupt", 9) == 0){ 206 seek(infile, 0L, 2); 207 mkfault++; 208 noted(NCONT); 209 } 210 noted(NDFLT); 211 } 212