]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vmx/vmxgdb.c
merge
[plan9front.git] / sys / src / cmd / vmx / vmxgdb.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 char *vmxroot = "/n/vmx";
6
7 Biobuf *bin, *bout;
8 int regsfd, memfd;
9 int noack;
10
11 void *
12 emalloc(ulong sz)
13 {
14         void *v;
15         
16         v = malloc(sz);
17         if(v == nil)
18                 sysfatal("malloc: %r");
19         memset(v, 0, sz);
20         setmalloctag(v, getcallerpc(&sz));
21         return v;
22 }
23
24 int
25 eBgetc(Biobuf *bp)
26 {
27         int c;
28         
29         c = Bgetc(bp);
30         if(c < 0) sysfatal("Bgetc: %r");
31         return c;
32 }
33
34 char *
35 rpack(void)
36 {
37         int c;
38         char *pkt;
39         ulong npkt;
40         u8int csum, csum2;
41         char buf[3], *p;
42
43         while(eBgetc(bin) != '$')
44                 ;
45         if(0){
46 repeat:
47                 free(pkt);
48         }
49         pkt = nil;
50         npkt = 0;
51         csum = 0;
52         while(c = eBgetc(bin)){
53                 if(c == '#') break;
54                 if(c == '$') goto repeat;
55                 csum += c;
56                 if(c == '}'){
57                         c = eBgetc(bin);
58                         if(c == '#') break;
59                         if(c == '$') goto repeat;
60                         csum += c;
61                         c ^= 0x20;
62                 }
63                 if(npkt % 64 == 0)
64                         pkt = realloc(pkt, npkt + 64);
65                 pkt[npkt++] = c;
66         }
67         if(npkt % 64 == 0)
68                 pkt = realloc(pkt, npkt + 1);
69         pkt[npkt] = 0;
70         buf[0] = eBgetc(bin);
71         if(buf[0] == '$') goto repeat;
72         buf[1] = eBgetc(bin);
73         if(buf[1] == '$') goto repeat;
74         if(noack) return pkt;
75         buf[2] = 0;
76         csum2 = strtol(buf, &p, 16);
77         if(p != &buf[2] || csum != csum2){
78                 Bputc(bout, '-');
79                 goto repeat;
80         }
81         Bputc(bout, '+');
82         return pkt;
83 }
84
85 int
86 bflush(Biobufhdr *, void *v, long n)
87 {
88         Bflush(bout);
89         return read(bin->fid, v, n);
90 }
91
92 void
93 wpack(char *p0)
94 {
95         u8int csum;
96         char *p;
97
98         fprint(2, "-> %s\n", p0);
99 again:
100         p = p0;
101         csum = 0;
102         Bputc(bout, '$');
103         for(; *p != 0; p++)
104                 switch(*p){
105                 case '$': case '#': case '{': case '*':
106                         Bputc(bout, '{');
107                         Bputc(bout, *p ^ 0x20);
108                         csum += '{' + (*p ^ 0x20);
109                         break;
110                 default:
111                         Bputc(bout, *p);
112                         csum += *p;
113                 }
114         Bprint(bout, "#%.2uX", csum);
115         if(noack) return;
116         for(;;)
117                 switch(eBgetc(bin)){
118                 case '+': return;
119                 case '-': goto again;
120                 case '$': Bungetc(bin); return;
121                 }
122 }
123
124 static char *regname[] = {
125         "ax", "cx", "dx", "bx",
126         "sp", "bp", "si", "di",
127         "pc", "flags", "cs", "ss",
128         "ds", "es", "fs", "gs",
129 };
130
131 char *
132 regpacket(void)
133 {
134         char *buf;
135         char rbuf[8192];
136         int rc;
137         char *p, *q, *f[2];
138         int pos, i, l;
139         uvlong v;
140         char tbuf[3];
141         
142         l = 4 * nelem(regname);
143         buf = emalloc(2 * l + 1);
144         memset(buf, 'x', 2 * l);
145         rc = pread(regsfd, rbuf, sizeof(rbuf)-1, 0);
146         if(rc < 0){
147                 free(buf);
148                 return strdup("");
149         }
150         rbuf[rc] = 0;
151         p = rbuf;
152         for(;; p = q + 1){
153                 q = strchr(p, '\n');
154                 if(q == nil) break;
155                 *q = 0;
156                 if(tokenize(p, f, nelem(f)) < 2) continue;
157                 v = strtoull(f[1], nil, 0);
158                 pos = 0;
159                 for(i = 0; i < nelem(regname); i++){
160                         if(strcmp(f[0], regname[i]) == 0)
161                                 break;
162                         pos += 4;
163                 }
164                 if(i == nelem(regname)) continue;
165                 if(f[0][1] == 's' && f[0][2] == 0) v = 0;
166                 l = 4;
167                 while(l--){
168                         sprint(tbuf, "%.2ux", (u8int)v);
169                         ((u16int*)buf)[pos++] = *(u16int*)tbuf;
170                         v >>= 8;
171                 }
172         }
173         return buf;
174 }
175
176 char *
177 memread(char *p)
178 {
179         char *q;
180         uvlong addr, count;
181         char *buf;
182         int rc, i;
183         char tbuf[3];
184         
185         addr = strtoull(p, &q, 16);
186         if(p == q || *q != ',') return strdup("E99");
187         count = strtoull(q + 1, &p, 16);
188         if(q+1 == p || *p != 0) return strdup("E99");
189         if(count > 65536) count = 65536;
190         buf = emalloc(2*count+4);
191         rc = pread(memfd, buf, count, addr);
192         if(rc <= 0) return strcpy(buf, "E01");
193         for(i = rc; --i >= 0; ){
194                 sprint(tbuf, "%.2ux", (uchar)buf[i]);
195                 ((u16int*)buf)[i] = *(u16int*)tbuf;
196         }
197         return buf;
198 }
199
200 void
201 main(int, char **)
202 {
203         char *p, *msg;
204
205         bin = Bfdopen(0, OREAD);
206         if(bin == nil) sysfatal("Bfdopen: %r");
207         bout = Bfdopen(1, OWRITE);
208         if(bout == nil) sysfatal("Bfdpen: %r");
209         Biofn(bin, bflush);
210         
211         p = smprint("%s/mem", vmxroot);
212         memfd = open(p, OREAD);
213         free(p);
214         if(memfd < 0) sysfatal("open: %r");
215
216         p = smprint("%s/regs", vmxroot);
217         regsfd = open(p, OREAD);
218         free(p);
219         if(regsfd < 0) sysfatal("open: %r");
220         
221         for(;;){
222                 msg = rpack();
223                 fprint(2, "<- %s\n", msg);
224         reinterpret:
225                 switch(*msg){
226                 case 'g':
227                         p = regpacket();
228                         wpack(p);
229                         free(p);
230                         break;
231                 case '?':
232                         wpack("S00");
233                         break;
234                 case 'm':
235                         p = memread(msg+1);
236                         wpack(p);
237                         free(p);
238                         break;
239                 case 'q':
240                         if(strncmp(msg, "qSupported", 10) == 0 && (msg[10] == ':' || msg[10] == 0)){
241                                 wpack("PacketSize=4096;QStartNoAckMode+");
242                         }else
243                                 goto no;
244                         break;
245                 case 'Q':
246                         if(strcmp(msg, "QStartNoAckMode") == 0){
247                                 wpack("OK");
248                                 noack = 1;
249                         }
250                         break;
251                 case 'H':
252                         msg[0] = msg[1];
253                         msg[1] = 0;
254                         goto reinterpret;
255                 default: no: wpack(""); break;
256                 }
257                 free(msg);
258         }
259         
260 }