]> git.proxmox.com Git - qemu.git/blame - gdbstub.c
win32 port (initial patch by kazu)
[qemu.git] / gdbstub.c
CommitLineData
b4608c04
FB
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 */
67b915a5
FB
20#include "vl.h"
21
b4608c04
FB
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <netinet/tcp.h>
25#include <signal.h>
b4608c04 26
4abe615b 27//#define DEBUG_GDB
b4608c04 28
858693c6
FB
29enum RSState {
30 RS_IDLE,
31 RS_GETLINE,
32 RS_CHKSUM1,
33 RS_CHKSUM2,
34};
b4608c04 35
858693c6 36static int gdbserver_fd;
b4608c04 37
858693c6
FB
38typedef struct GDBState {
39 enum RSState state;
40 int fd;
41 char line_buf[4096];
42 int line_buf_index;
43 int line_csum;
44} GDBState;
b4608c04 45
858693c6 46static int get_char(GDBState *s)
b4608c04
FB
47{
48 uint8_t ch;
49 int ret;
50
51 for(;;) {
858693c6 52 ret = read(s->fd, &ch, 1);
b4608c04
FB
53 if (ret < 0) {
54 if (errno != EINTR && errno != EAGAIN)
55 return -1;
56 } else if (ret == 0) {
57 return -1;
58 } else {
59 break;
60 }
61 }
62 return ch;
63}
64
858693c6 65static void put_buffer(GDBState *s, const uint8_t *buf, int len)
b4608c04
FB
66{
67 int ret;
68
69 while (len > 0) {
858693c6 70 ret = write(s->fd, buf, len);
b4608c04
FB
71 if (ret < 0) {
72 if (errno != EINTR && errno != EAGAIN)
73 return;
74 } else {
75 buf += ret;
76 len -= ret;
77 }
78 }
79}
80
81static inline int fromhex(int v)
82{
83 if (v >= '0' && v <= '9')
84 return v - '0';
85 else if (v >= 'A' && v <= 'F')
86 return v - 'A' + 10;
87 else if (v >= 'a' && v <= 'f')
88 return v - 'a' + 10;
89 else
90 return 0;
91}
92
93static inline int tohex(int v)
94{
95 if (v < 10)
96 return v + '0';
97 else
98 return v - 10 + 'a';
99}
100
101static void memtohex(char *buf, const uint8_t *mem, int len)
102{
103 int i, c;
104 char *q;
105 q = buf;
106 for(i = 0; i < len; i++) {
107 c = mem[i];
108 *q++ = tohex(c >> 4);
109 *q++ = tohex(c & 0xf);
110 }
111 *q = '\0';
112}
113
114static void hextomem(uint8_t *mem, const char *buf, int len)
115{
116 int i;
117
118 for(i = 0; i < len; i++) {
119 mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
120 buf += 2;
121 }
122}
123
b4608c04 124/* return -1 if error, 0 if OK */
858693c6 125static int put_packet(GDBState *s, char *buf)
b4608c04
FB
126{
127 char buf1[3];
128 int len, csum, ch, i;
129
130#ifdef DEBUG_GDB
131 printf("reply='%s'\n", buf);
132#endif
133
134 for(;;) {
135 buf1[0] = '$';
858693c6 136 put_buffer(s, buf1, 1);
b4608c04 137 len = strlen(buf);
858693c6 138 put_buffer(s, buf, len);
b4608c04
FB
139 csum = 0;
140 for(i = 0; i < len; i++) {
141 csum += buf[i];
142 }
143 buf1[0] = '#';
144 buf1[1] = tohex((csum >> 4) & 0xf);
145 buf1[2] = tohex((csum) & 0xf);
146
858693c6 147 put_buffer(s, buf1, 3);
b4608c04 148
858693c6 149 ch = get_char(s);
b4608c04
FB
150 if (ch < 0)
151 return -1;
152 if (ch == '+')
153 break;
154 }
155 return 0;
156}
157
6da41eaf
FB
158#if defined(TARGET_I386)
159
160static void to_le32(uint8_t *p, int v)
161{
162 p[0] = v;
163 p[1] = v >> 8;
164 p[2] = v >> 16;
165 p[3] = v >> 24;
166}
167
168static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
169{
170 int i, fpus;
171
172 for(i = 0; i < 8; i++) {
173 to_le32(mem_buf + i * 4, env->regs[i]);
174 }
175 to_le32(mem_buf + 8 * 4, env->eip);
176 to_le32(mem_buf + 9 * 4, env->eflags);
177 to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector);
178 to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector);
179 to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector);
180 to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector);
181 to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector);
182 to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector);
183 /* XXX: convert floats */
184 for(i = 0; i < 8; i++) {
185 memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
186 }
187 to_le32(mem_buf + 36 * 4, env->fpuc);
188 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
189 to_le32(mem_buf + 37 * 4, fpus);
190 to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */
191 to_le32(mem_buf + 39 * 4, 0); /* fiseg */
192 to_le32(mem_buf + 40 * 4, 0); /* fioff */
193 to_le32(mem_buf + 41 * 4, 0); /* foseg */
194 to_le32(mem_buf + 42 * 4, 0); /* fooff */
195 to_le32(mem_buf + 43 * 4, 0); /* fop */
196 return 44 * 4;
197}
198
199static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
200{
201 uint32_t *registers = (uint32_t *)mem_buf;
202 int i;
203
204 for(i = 0; i < 8; i++) {
205 env->regs[i] = tswapl(registers[i]);
206 }
207 env->eip = registers[8];
208 env->eflags = registers[9];
209#if defined(CONFIG_USER_ONLY)
210#define LOAD_SEG(index, sreg)\
211 if (tswapl(registers[index]) != env->segs[sreg].selector)\
212 cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
213 LOAD_SEG(10, R_CS);
214 LOAD_SEG(11, R_SS);
215 LOAD_SEG(12, R_DS);
216 LOAD_SEG(13, R_ES);
217 LOAD_SEG(14, R_FS);
218 LOAD_SEG(15, R_GS);
219#endif
220}
221
9e62fd7f
FB
222#elif defined (TARGET_PPC)
223static void to_le32(uint8_t *p, int v)
224{
225 p[3] = v;
226 p[2] = v >> 8;
227 p[1] = v >> 16;
228 p[0] = v >> 24;
229}
230
231static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
232{
233 uint32_t tmp;
234 int i;
235
236 /* fill in gprs */
237 for(i = 0; i < 8; i++) {
238 to_le32(mem_buf + i * 4, env->gpr[i]);
239 }
240 /* fill in fprs */
241 for (i = 0; i < 32; i++) {
242 to_le32(mem_buf + (i * 2) + 32, *((uint32_t *)&env->fpr[i]));
243 to_le32(mem_buf + (i * 2) + 33, *((uint32_t *)&env->fpr[i] + 1));
244 }
245 /* nip, msr, ccr, lnk, ctr, xer, mq */
246 to_le32(mem_buf + 96, tswapl(env->nip));
247 to_le32(mem_buf + 97, tswapl(_load_msr()));
248 to_le32(mem_buf + 98, 0);
249 tmp = 0;
250 for (i = 0; i < 8; i++)
251 tmp |= env->crf[i] << (32 - (i * 4));
252 to_le32(mem_buf + 98, tmp);
253 to_le32(mem_buf + 99, tswapl(env->lr));
254 to_le32(mem_buf + 100, tswapl(env->ctr));
255 to_le32(mem_buf + 101, tswapl(_load_xer()));
256 to_le32(mem_buf + 102, 0);
257
258 return 102;
259}
260
261static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
262{
263 uint32_t *registers = (uint32_t *)mem_buf;
264 int i;
265
266 /* fill in gprs */
267 for (i = 0; i < 32; i++) {
268 env->gpr[i] = tswapl(registers[i]);
269 }
270 /* fill in fprs */
271 for (i = 0; i < 32; i++) {
272 *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
273 *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
274 }
275 /* nip, msr, ccr, lnk, ctr, xer, mq */
276 env->nip = tswapl(registers[96]);
277 _store_msr(tswapl(registers[97]));
278 registers[98] = tswapl(registers[98]);
279 for (i = 0; i < 8; i++)
280 env->crf[i] = (registers[98] >> (32 - (i * 4))) & 0xF;
281 env->lr = tswapl(registers[99]);
282 env->ctr = tswapl(registers[100]);
283 _store_xer(tswapl(registers[101]));
284}
6da41eaf
FB
285#else
286
287static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
288{
289 return 0;
290}
291
292static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
293{
294}
295
296#endif
b4608c04
FB
297
298/* port = 0 means default port */
858693c6 299static int gdb_handle_packet(GDBState *s, const char *line_buf)
b4608c04 300{
858693c6 301 CPUState *env = cpu_single_env;
b4608c04 302 const char *p;
858693c6 303 int ch, reg_size, type;
b4608c04
FB
304 char buf[4096];
305 uint8_t mem_buf[2000];
306 uint32_t *registers;
307 uint32_t addr, len;
308
858693c6
FB
309#ifdef DEBUG_GDB
310 printf("command='%s'\n", line_buf);
311#endif
312 p = line_buf;
313 ch = *p++;
314 switch(ch) {
315 case '?':
316 snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
317 put_packet(s, buf);
318 break;
319 case 'c':
320 if (*p != '\0') {
321 addr = strtoul(p, (char **)&p, 16);
4c3a88a2 322#if defined(TARGET_I386)
858693c6 323 env->eip = addr;
5be1a8e0 324#elif defined (TARGET_PPC)
858693c6 325 env->nip = addr;
4c3a88a2 326#endif
858693c6
FB
327 }
328 vm_start();
329 break;
330 case 's':
331 if (*p != '\0') {
332 addr = strtoul(p, (char **)&p, 16);
c33a346e 333#if defined(TARGET_I386)
858693c6 334 env->eip = addr;
5be1a8e0 335#elif defined (TARGET_PPC)
858693c6 336 env->nip = addr;
c33a346e 337#endif
858693c6
FB
338 }
339 cpu_single_step(env, 1);
340 vm_start();
341 break;
342 case 'g':
343 reg_size = cpu_gdb_read_registers(env, mem_buf);
344 memtohex(buf, mem_buf, reg_size);
345 put_packet(s, buf);
346 break;
347 case 'G':
348 registers = (void *)mem_buf;
349 len = strlen(p) / 2;
350 hextomem((uint8_t *)registers, p, len);
351 cpu_gdb_write_registers(env, mem_buf, len);
352 put_packet(s, "OK");
353 break;
354 case 'm':
355 addr = strtoul(p, (char **)&p, 16);
356 if (*p == ',')
357 p++;
358 len = strtoul(p, NULL, 16);
359 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0)
360 memset(mem_buf, 0, len);
361 memtohex(buf, mem_buf, len);
362 put_packet(s, buf);
363 break;
364 case 'M':
365 addr = strtoul(p, (char **)&p, 16);
366 if (*p == ',')
367 p++;
368 len = strtoul(p, (char **)&p, 16);
369 if (*p == ',')
370 p++;
371 hextomem(mem_buf, p, len);
372 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
373 put_packet(s, "ENN");
374 else
375 put_packet(s, "OK");
376 break;
377 case 'Z':
378 type = strtoul(p, (char **)&p, 16);
379 if (*p == ',')
380 p++;
381 addr = strtoul(p, (char **)&p, 16);
382 if (*p == ',')
383 p++;
384 len = strtoul(p, (char **)&p, 16);
385 if (type == 0 || type == 1) {
386 if (cpu_breakpoint_insert(env, addr) < 0)
387 goto breakpoint_error;
388 put_packet(s, "OK");
389 } else {
390 breakpoint_error:
391 put_packet(s, "ENN");
392 }
393 break;
394 case 'z':
395 type = strtoul(p, (char **)&p, 16);
396 if (*p == ',')
397 p++;
398 addr = strtoul(p, (char **)&p, 16);
399 if (*p == ',')
400 p++;
401 len = strtoul(p, (char **)&p, 16);
402 if (type == 0 || type == 1) {
403 cpu_breakpoint_remove(env, addr);
404 put_packet(s, "OK");
405 } else {
406 goto breakpoint_error;
407 }
408 break;
409 default:
410 // unknown_command:
411 /* put empty packet */
412 buf[0] = '\0';
413 put_packet(s, buf);
414 break;
415 }
416 return RS_IDLE;
417}
418
419static void gdb_vm_stopped(void *opaque, int reason)
420{
421 GDBState *s = opaque;
422 char buf[256];
423 int ret;
424
425 /* disable single step if it was enable */
426 cpu_single_step(cpu_single_env, 0);
427
428 if (reason == EXCP_DEBUG)
429 ret = SIGTRAP;
430 else
431 ret = 0;
432 snprintf(buf, sizeof(buf), "S%02x", ret);
433 put_packet(s, buf);
434}
435
436static void gdb_read_byte(GDBState *s, int ch)
437{
438 int i, csum;
439 char reply[1];
440
441 if (vm_running) {
442 /* when the CPU is running, we cannot do anything except stop
443 it when receiving a char */
444 vm_stop(EXCP_INTERRUPT);
445 } else {
446 switch(s->state) {
447 case RS_IDLE:
448 if (ch == '$') {
449 s->line_buf_index = 0;
450 s->state = RS_GETLINE;
c33a346e 451 }
b4608c04 452 break;
858693c6
FB
453 case RS_GETLINE:
454 if (ch == '#') {
455 s->state = RS_CHKSUM1;
456 } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
457 s->state = RS_IDLE;
4c3a88a2 458 } else {
858693c6 459 s->line_buf[s->line_buf_index++] = ch;
4c3a88a2
FB
460 }
461 break;
858693c6
FB
462 case RS_CHKSUM1:
463 s->line_buf[s->line_buf_index] = '\0';
464 s->line_csum = fromhex(ch) << 4;
465 s->state = RS_CHKSUM2;
466 break;
467 case RS_CHKSUM2:
468 s->line_csum |= fromhex(ch);
469 csum = 0;
470 for(i = 0; i < s->line_buf_index; i++) {
471 csum += s->line_buf[i];
472 }
473 if (s->line_csum != (csum & 0xff)) {
474 reply[0] = '-';
475 put_buffer(s, reply, 1);
476 s->state = RS_IDLE;
4c3a88a2 477 } else {
858693c6
FB
478 reply[0] = '+';
479 put_buffer(s, reply, 1);
480 s->state = gdb_handle_packet(s, s->line_buf);
4c3a88a2
FB
481 }
482 break;
858693c6
FB
483 }
484 }
485}
486
487static int gdb_can_read(void *opaque)
488{
489 return 256;
490}
491
492static void gdb_read(void *opaque, const uint8_t *buf, int size)
493{
494 GDBState *s = opaque;
495 int i;
496 if (size == 0) {
497 /* end of connection */
498 qemu_del_vm_stop_handler(gdb_vm_stopped, s);
499 qemu_del_fd_read_handler(s->fd);
500 qemu_free(s);
501 vm_start();
502 } else {
503 for(i = 0; i < size; i++)
504 gdb_read_byte(s, buf[i]);
505 }
506}
507
508static void gdb_accept(void *opaque, const uint8_t *buf, int size)
509{
510 GDBState *s;
511 struct sockaddr_in sockaddr;
512 socklen_t len;
513 int val, fd;
514
515 for(;;) {
516 len = sizeof(sockaddr);
517 fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
518 if (fd < 0 && errno != EINTR) {
519 perror("accept");
520 return;
521 } else if (fd >= 0) {
b4608c04
FB
522 break;
523 }
524 }
858693c6
FB
525
526 /* set short latency */
527 val = 1;
528 setsockopt(fd, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
529
530 s = qemu_mallocz(sizeof(GDBState));
531 if (!s) {
532 close(fd);
533 return;
534 }
535 s->fd = fd;
536
537 fcntl(fd, F_SETFL, O_NONBLOCK);
538
539 /* stop the VM */
540 vm_stop(EXCP_INTERRUPT);
541
542 /* start handling I/O */
543 qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
544 /* when the VM is stopped, the following callback is called */
545 qemu_add_vm_stop_handler(gdb_vm_stopped, s);
546}
547
548static int gdbserver_open(int port)
549{
550 struct sockaddr_in sockaddr;
551 int fd, val, ret;
552
553 fd = socket(PF_INET, SOCK_STREAM, 0);
554 if (fd < 0) {
555 perror("socket");
556 return -1;
557 }
558
559 /* allow fast reuse */
560 val = 1;
561 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
562
563 sockaddr.sin_family = AF_INET;
564 sockaddr.sin_port = htons(port);
565 sockaddr.sin_addr.s_addr = 0;
566 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
567 if (ret < 0) {
568 perror("bind");
569 return -1;
570 }
571 ret = listen(fd, 0);
572 if (ret < 0) {
573 perror("listen");
574 return -1;
575 }
576 fcntl(fd, F_SETFL, O_NONBLOCK);
577 return fd;
578}
579
580int gdbserver_start(int port)
581{
582 gdbserver_fd = gdbserver_open(port);
583 if (gdbserver_fd < 0)
584 return -1;
585 /* accept connections */
586 qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
b4608c04
FB
587 return 0;
588}