29f73c9cbcff186ea1b1a5c479707ffbc5a70c81
[qemu] / gdbstub.c
1 /*
2  * gdb server stub
3  * 
4  * Copyright (c) 2003 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <netinet/tcp.h>
28 #include <signal.h>
29
30 #include "config.h"
31 #include "cpu.h"
32 #include "thunk.h"
33 #include "exec-all.h"
34
35 //#define DEBUG_GDB
36
37 int gdbstub_fd = -1;
38
39 /* return 0 if OK */
40 static int gdbstub_open(int port)
41 {
42     struct sockaddr_in sockaddr;
43     socklen_t len;
44     int fd, val, ret;
45
46     fd = socket(PF_INET, SOCK_STREAM, 0);
47     if (fd < 0) {
48         perror("socket");
49         return -1;
50     }
51
52     /* allow fast reuse */
53     val = 1;
54     setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
55
56     sockaddr.sin_family = AF_INET;
57     sockaddr.sin_port = htons(port);
58     sockaddr.sin_addr.s_addr = 0;
59     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
60     if (ret < 0) {
61         perror("bind");
62         return -1;
63     }
64     ret = listen(fd, 0);
65     if (ret < 0) {
66         perror("listen");
67         return -1;
68     }
69     
70     /* now wait for one connection */
71     for(;;) {
72         len = sizeof(sockaddr);
73         gdbstub_fd = accept(fd, (struct sockaddr *)&sockaddr, &len);
74         if (gdbstub_fd < 0 && errno != EINTR) {
75             perror("accept");
76             return -1;
77         } else if (gdbstub_fd >= 0) {
78             break;
79         }
80     }
81     
82     /* set short latency */
83     val = 1;
84     setsockopt(gdbstub_fd, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
85     return 0;
86 }
87
88 static int get_char(void)
89 {
90     uint8_t ch;
91     int ret;
92
93     for(;;) {
94         ret = read(gdbstub_fd, &ch, 1);
95         if (ret < 0) {
96             if (errno != EINTR && errno != EAGAIN)
97                 return -1;
98         } else if (ret == 0) {
99             return -1;
100         } else {
101             break;
102         }
103     }
104     return ch;
105 }
106
107 static void put_buffer(const uint8_t *buf, int len)
108 {
109     int ret;
110
111     while (len > 0) {
112         ret = write(gdbstub_fd, buf, len);
113         if (ret < 0) {
114             if (errno != EINTR && errno != EAGAIN)
115                 return;
116         } else {
117             buf += ret;
118             len -= ret;
119         }
120     }
121 }
122
123 static inline int fromhex(int v)
124 {
125     if (v >= '0' && v <= '9')
126         return v - '0';
127     else if (v >= 'A' && v <= 'F')
128         return v - 'A' + 10;
129     else if (v >= 'a' && v <= 'f')
130         return v - 'a' + 10;
131     else
132         return 0;
133 }
134
135 static inline int tohex(int v)
136 {
137     if (v < 10)
138         return v + '0';
139     else
140         return v - 10 + 'a';
141 }
142
143 static void memtohex(char *buf, const uint8_t *mem, int len)
144 {
145     int i, c;
146     char *q;
147     q = buf;
148     for(i = 0; i < len; i++) {
149         c = mem[i];
150         *q++ = tohex(c >> 4);
151         *q++ = tohex(c & 0xf);
152     }
153     *q = '\0';
154 }
155
156 static void hextomem(uint8_t *mem, const char *buf, int len)
157 {
158     int i;
159
160     for(i = 0; i < len; i++) {
161         mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
162         buf += 2;
163     }
164 }
165
166 /* return -1 if error or EOF */
167 static int get_packet(char *buf, int buf_size)
168 {
169     int ch, len, csum, csum1;
170     char reply[1];
171     
172     for(;;) {
173         for(;;) {
174             ch = get_char();
175             if (ch < 0)
176                 return -1;
177             if (ch == '$')
178                 break;
179         }
180         len = 0;
181         csum = 0;
182         for(;;) {
183             ch = get_char();
184             if (ch < 0)
185                 return -1;
186             if (ch == '#')
187                 break;
188             if (len > buf_size - 1)
189                 return -1;
190             buf[len++] = ch;
191             csum += ch;
192         }
193         buf[len] = '\0';
194         ch = get_char();
195         if (ch < 0)
196             return -1;
197         csum1 = fromhex(ch) << 4;
198         ch = get_char();
199         if (ch < 0)
200             return -1;
201         csum1 |= fromhex(ch);
202         if ((csum & 0xff) != csum1) {
203             reply[0] = '-';
204             put_buffer(reply, 1);
205         } else {
206             reply[0] = '+';
207             put_buffer(reply, 1);
208             break;
209         }
210     }
211 #ifdef DEBUG_GDB
212     printf("command='%s'\n", buf);
213 #endif
214     return len;
215 }
216
217 /* return -1 if error, 0 if OK */
218 static int put_packet(char *buf)
219 {
220     char buf1[3];
221     int len, csum, ch, i;
222
223 #ifdef DEBUG_GDB
224     printf("reply='%s'\n", buf);
225 #endif
226
227     for(;;) {
228         buf1[0] = '$';
229         put_buffer(buf1, 1);
230         len = strlen(buf);
231         put_buffer(buf, len);
232         csum = 0;
233         for(i = 0; i < len; i++) {
234             csum += buf[i];
235         }
236         buf1[0] = '#';
237         buf1[1] = tohex((csum >> 4) & 0xf);
238         buf1[2] = tohex((csum) & 0xf);
239
240         put_buffer(buf1, 3);
241
242         ch = get_char();
243         if (ch < 0)
244             return -1;
245         if (ch == '+')
246             break;
247     }
248     return 0;
249 }
250
251 #if defined(TARGET_I386)
252
253 static void to_le32(uint8_t *p, int v)
254 {
255     p[0] = v;
256     p[1] = v >> 8;
257     p[2] = v >> 16;
258     p[3] = v >> 24;
259 }
260
261 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
262 {
263     int i, fpus;
264
265     for(i = 0; i < 8; i++) {
266         to_le32(mem_buf + i * 4, env->regs[i]);
267     }
268     to_le32(mem_buf + 8 * 4, env->eip);
269     to_le32(mem_buf + 9 * 4, env->eflags);
270     to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector);
271     to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector);
272     to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector);
273     to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector);
274     to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector);
275     to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector);
276     /* XXX: convert floats */
277     for(i = 0; i < 8; i++) {
278         memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
279     }
280     to_le32(mem_buf + 36 * 4, env->fpuc);
281     fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
282     to_le32(mem_buf + 37 * 4, fpus);
283     to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */
284     to_le32(mem_buf + 39 * 4, 0); /* fiseg */
285     to_le32(mem_buf + 40 * 4, 0); /* fioff */
286     to_le32(mem_buf + 41 * 4, 0); /* foseg */
287     to_le32(mem_buf + 42 * 4, 0); /* fooff */
288     to_le32(mem_buf + 43 * 4, 0); /* fop */
289     return 44 * 4;
290 }
291
292 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
293 {
294     uint32_t *registers = (uint32_t *)mem_buf;
295     int i;
296
297     for(i = 0; i < 8; i++) {
298         env->regs[i] = tswapl(registers[i]);
299     }
300     env->eip = registers[8];
301     env->eflags = registers[9];
302 #if defined(CONFIG_USER_ONLY)
303 #define LOAD_SEG(index, sreg)\
304             if (tswapl(registers[index]) != env->segs[sreg].selector)\
305                 cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
306             LOAD_SEG(10, R_CS);
307             LOAD_SEG(11, R_SS);
308             LOAD_SEG(12, R_DS);
309             LOAD_SEG(13, R_ES);
310             LOAD_SEG(14, R_FS);
311             LOAD_SEG(15, R_GS);
312 #endif
313 }
314
315 #elif defined (TARGET_PPC)
316 static void to_le32(uint8_t *p, int v)
317 {
318     p[3] = v;
319     p[2] = v >> 8;
320     p[1] = v >> 16;
321     p[0] = v >> 24;
322 }
323
324 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
325 {
326     uint32_t tmp;
327     int i;
328
329     /* fill in gprs */
330     for(i = 0; i < 8; i++) {
331         to_le32(mem_buf + i * 4, env->gpr[i]);
332     }
333     /* fill in fprs */
334     for (i = 0; i < 32; i++) {
335         to_le32(mem_buf + (i * 2) + 32, *((uint32_t *)&env->fpr[i]));
336         to_le32(mem_buf + (i * 2) + 33, *((uint32_t *)&env->fpr[i] + 1));
337     }
338     /* nip, msr, ccr, lnk, ctr, xer, mq */
339     to_le32(mem_buf + 96, tswapl(env->nip));
340     to_le32(mem_buf + 97, tswapl(_load_msr()));
341     to_le32(mem_buf + 98, 0);
342     tmp = 0;
343     for (i = 0; i < 8; i++)
344         tmp |= env->crf[i] << (32 - (i * 4));
345     to_le32(mem_buf + 98, tmp);
346     to_le32(mem_buf + 99, tswapl(env->lr));
347     to_le32(mem_buf + 100, tswapl(env->ctr));
348     to_le32(mem_buf + 101, tswapl(_load_xer()));
349     to_le32(mem_buf + 102, 0);
350
351     return 102;
352 }
353
354 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
355 {
356     uint32_t *registers = (uint32_t *)mem_buf;
357     int i;
358
359     /* fill in gprs */
360     for (i = 0; i < 32; i++) {
361         env->gpr[i] = tswapl(registers[i]);
362     }
363     /* fill in fprs */
364     for (i = 0; i < 32; i++) {
365         *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
366         *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
367     }
368     /* nip, msr, ccr, lnk, ctr, xer, mq */
369     env->nip = tswapl(registers[96]);
370     _store_msr(tswapl(registers[97]));
371     registers[98] = tswapl(registers[98]);
372     for (i = 0; i < 8; i++)
373         env->crf[i] = (registers[98] >> (32 - (i * 4))) & 0xF;
374     env->lr = tswapl(registers[99]);
375     env->ctr = tswapl(registers[100]);
376     _store_xer(tswapl(registers[101]));
377 }
378 #else
379
380 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
381 {
382     return 0;
383 }
384
385 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
386 {
387 }
388
389 #endif
390
391 /* port = 0 means default port */
392 int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
393 {
394     CPUState *env;
395     const char *p;
396     int ret, ch, reg_size, type;
397     char buf[4096];
398     uint8_t mem_buf[2000];
399     uint32_t *registers;
400     uint32_t addr, len;
401     
402     printf("Waiting gdb connection on port %d\n", port);
403     if (gdbstub_open(port) < 0)
404         return -1;
405     printf("Connected\n");
406     for(;;) {
407         ret = get_packet(buf, sizeof(buf));
408         if (ret < 0)
409             break;
410         p = buf;
411         ch = *p++;
412         switch(ch) {
413         case '?':
414             snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
415             put_packet(buf);
416             break;
417         case 'c':
418             if (*p != '\0') {
419                 addr = strtoul(p, (char **)&p, 16);
420                 env = cpu_gdbstub_get_env(opaque);
421 #if defined(TARGET_I386)
422                 env->eip = addr;
423 #elif defined (TARGET_PPC)
424                 env->nip = addr;
425 #endif
426             }
427             ret = main_loop(opaque);
428             if (ret == EXCP_DEBUG)
429                 ret = SIGTRAP;
430             else
431                 ret = 0;
432             snprintf(buf, sizeof(buf), "S%02x", ret);
433             put_packet(buf);
434             break;
435         case 's':
436             env = cpu_gdbstub_get_env(opaque);
437             if (*p != '\0') {
438                 addr = strtoul(p, (char **)&p, 16);
439 #if defined(TARGET_I386)
440                 env->eip = addr;
441 #elif defined (TARGET_PPC)
442                 env->nip = addr;
443 #endif
444             }
445             cpu_single_step(env, 1);
446             ret = main_loop(opaque);
447             cpu_single_step(env, 0);
448             if (ret == EXCP_DEBUG)
449                 ret = SIGTRAP;
450             else
451                 ret = 0;
452             snprintf(buf, sizeof(buf), "S%02x", ret);
453             put_packet(buf);
454             break;
455         case 'g':
456             env = cpu_gdbstub_get_env(opaque);
457             reg_size = cpu_gdb_read_registers(env, mem_buf);
458             memtohex(buf, mem_buf, reg_size);
459             put_packet(buf);
460             break;
461         case 'G':
462             env = cpu_gdbstub_get_env(opaque);
463             registers = (void *)mem_buf;
464             len = strlen(p) / 2;
465             hextomem((uint8_t *)registers, p, len);
466             cpu_gdb_write_registers(env, mem_buf, len);
467             put_packet("OK");
468             break;
469         case 'm':
470             env = cpu_gdbstub_get_env(opaque);
471             addr = strtoul(p, (char **)&p, 16);
472             if (*p == ',')
473                 p++;
474             len = strtoul(p, NULL, 16);
475             if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0)
476                 memset(mem_buf, 0, len);
477             memtohex(buf, mem_buf, len);
478             put_packet(buf);
479             break;
480         case 'M':
481             env = cpu_gdbstub_get_env(opaque);
482             addr = strtoul(p, (char **)&p, 16);
483             if (*p == ',')
484                 p++;
485             len = strtoul(p, (char **)&p, 16);
486             if (*p == ',')
487                 p++;
488             hextomem(mem_buf, p, len);
489             if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
490                 put_packet("ENN");
491             else
492                 put_packet("OK");
493             break;
494         case 'Z':
495             type = strtoul(p, (char **)&p, 16);
496             if (*p == ',')
497                 p++;
498             addr = strtoul(p, (char **)&p, 16);
499             if (*p == ',')
500                 p++;
501             len = strtoul(p, (char **)&p, 16);
502             if (type == 0 || type == 1) {
503                 env = cpu_gdbstub_get_env(opaque);
504                 if (cpu_breakpoint_insert(env, addr) < 0)
505                     goto breakpoint_error;
506                 put_packet("OK");
507             } else {
508             breakpoint_error:
509                 put_packet("ENN");
510             }
511             break;
512         case 'z':
513             type = strtoul(p, (char **)&p, 16);
514             if (*p == ',')
515                 p++;
516             addr = strtoul(p, (char **)&p, 16);
517             if (*p == ',')
518                 p++;
519             len = strtoul(p, (char **)&p, 16);
520             if (type == 0 || type == 1) {
521                 env = cpu_gdbstub_get_env(opaque);
522                 cpu_breakpoint_remove(env, addr);
523                 put_packet("OK");
524             } else {
525                 goto breakpoint_error;
526             }
527             break;
528         case 'Q':
529             if (!strncmp(p, "Tinit", 5)) {
530                 /* init traces */
531                 put_packet("OK");
532             } else if (!strncmp(p, "TStart", 6)) {
533                 /* start log (gdb 'tstart' command) */
534                 env = cpu_gdbstub_get_env(opaque);
535                 tb_flush(env);
536                 cpu_set_log(CPU_LOG_ALL);
537                 put_packet("OK");
538             } else if (!strncmp(p, "TStop", 5)) {
539                 /* stop log (gdb 'tstop' command) */
540                 cpu_set_log(0);
541                 put_packet("OK");
542             } else {
543                 goto unknown_command;
544             }
545             break;
546         default:
547         unknown_command:
548             /* put empty packet */
549             buf[0] = '\0';
550             put_packet(buf);
551             break;
552         }
553     }
554     return 0;
555 }