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