Blob


1 /*
2 * db - main command loop and error/interrupt handling
3 */
4 #include "defs.h"
5 #include "fns.h"
7 int wtflag = OREAD;
8 BOOL kflag;
10 BOOL mkfault;
11 ADDR maxoff;
13 int xargc; /* bullshit */
15 extern BOOL executing;
16 extern int infile;
17 int exitflg;
18 extern int eof;
20 int alldigs(char*);
21 void fault(void*, char*);
23 extern char *Ipath;
24 jmp_buf env;
25 static char *errmsg;
27 Fhdr *symhdr, *corhdr;
29 void
30 usage(void)
31 {
32 fprint(2, "usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n");
33 exits("usage");
34 }
36 void
37 main(int argc, char **argv)
38 {
39 int i, omode;
40 char *s;
41 char *name;
42 Fhdr *hdr;
44 name = 0;
45 outputinit();
46 maxoff = MAXOFF;
47 omode = OREAD;
48 ARGBEGIN{
49 default:
50 usage();
51 case 'A':
52 abort();
53 case 'k':
54 kflag = 1;
55 break;
56 case 'w':
57 omode = ORDWR;
58 break;
59 case 'I':
60 s = ARGF();
61 if(s == 0)
62 dprint("missing -I argument\n");
63 else
64 Ipath = s;
65 break;
66 case 'm':
67 name = ARGF();
68 if(name == 0)
69 dprint("missing -m argument\n");
70 break;
71 }ARGEND
73 /*
74 * Unix and Plan 9 differ on what the right order of pid, text, and core is.
75 * I never remember anyway. Let's just accept them in any order.
76 */
77 for(i=0; i<argc; i++){
78 if(alldigs(argv[i])){
79 if(pid){
80 dprint("already have pid %d; ignoring pid %d\n", pid, argv[i]);
81 continue;
82 }
83 if(corhdr){
84 dprint("already have core %s; ignoring pid %d\n", corfil, pid);
85 continue;
86 }
87 pid = atoi(argv[i]);
88 continue;
89 }
90 if((hdr = crackhdr(argv[i], omode)) == nil){
91 dprint("crackhdr %s: %r\n", argv[i]);
92 continue;
93 }
94 dprint("%s: %s %s %s\n", argv[i], hdr->aname, hdr->mname, hdr->fname);
95 if(hdr->ftype == FCORE){
96 if(pid){
97 dprint("already have pid %d; ignoring core %s\n", pid, argv[i]);
98 uncrackhdr(hdr);
99 continue;
101 if(corhdr){
102 dprint("already have core %s; ignoring core %s\n", corfil, argv[i]);
103 uncrackhdr(hdr);
104 continue;
106 corhdr = hdr;
107 corfil = argv[i];
108 }else{
109 if(symhdr){
110 dprint("already have text %s; ignoring text %s\n", symfil, argv[i]);
111 uncrackhdr(hdr);
112 continue;
114 symhdr = hdr;
115 symfil = argv[i];
119 if(symhdr==nil){
120 symfil = "a.out";
121 if(pid){
122 if((s = proctextfile(pid)) != nil){
123 dprint("pid %d: text %s\n", pid, s);
124 symfil = s;
127 /* XXX pull command from core */
129 if((symhdr = crackhdr(symfil, omode)) == nil){
130 dprint("crackhdr %s: %r\n", symfil);
131 symfil = nil;
135 if(!mach)
136 mach = machcpu;
138 /*
139 * Set up maps.
140 */
141 symmap = allocmap();
142 cormap = allocmap();
143 if(symmap == nil || cormap == nil)
144 sysfatal("allocating maps: %r");
146 if(symhdr){
147 if(mapfile(symhdr, 0, symmap, nil) < 0)
148 dprint("mapping %s: %r\n", symfil);
149 mapfile(symhdr, 0, cormap, nil);
152 dotmap = dumbmap(-1);
154 /*
155 * show initial state and drop into the execution loop.
156 */
157 notify(fault);
158 setsym();
159 if(setjmp(env) == 0){
160 if (pid || corhdr)
161 setcor(); /* could get error */
162 if (correg) {
163 dprint("%s\n", mach->exc(cormap, correg));
164 printpc();
168 setjmp(env);
169 if (executing)
170 delbp();
171 executing = FALSE;
172 for (;;) {
173 flushbuf();
174 if (errmsg) {
175 dprint(errmsg);
176 printc('\n');
177 errmsg = 0;
178 exitflg = 0;
180 if (mkfault) {
181 mkfault=0;
182 printc('\n');
183 prints(DBNAME);
185 clrinp();
186 rdc();
187 reread();
188 if (eof) {
189 if (infile == STDIN)
190 done();
191 iclose(-1, 0);
192 eof = 0;
193 longjmp(env, 1);
195 exitflg = 0;
196 command(0, 0);
197 reread();
198 if (rdc() != '\n')
199 error("newline expected");
203 int
204 alldigs(char *s)
206 while(*s){
207 if(*s<'0' || '9'<*s)
208 return 0;
209 s++;
211 return 1;
214 void
215 done(void)
217 if (pid)
218 endpcs();
219 exits(exitflg? "error": 0);
222 /*
223 * An error occurred; save the message for later printing,
224 * close open files, and reset to main command loop.
225 */
226 void
227 error(char *n)
229 errmsg = n;
230 iclose(0, 1);
231 oclose();
232 flush();
233 delbp();
234 ending = 0;
235 longjmp(env, 1);
238 void
239 errors(char *m, char *n)
241 static char buf[128];
243 sprint(buf, "%s: %s", m, n);
244 error(buf);
247 /*
248 * An interrupt occurred;
249 * seek to the end of the current file
250 * and remember that there was a fault.
251 */
252 void
253 fault(void *a, char *s)
255 USED(a);
256 if(strncmp(s, "interrupt", 9) == 0){
257 seek(infile, 0L, 2);
258 mkfault++;
259 noted(NCONT);
261 noted(NDFLT);