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