]> git.proxmox.com Git - qemu.git/blame - gdbstub.c
sparc update
[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
6da41eaf
FB
160static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
161{
e95c8d51 162 uint32_t *registers = (uint32_t *)mem_buf;
6da41eaf
FB
163 int i, fpus;
164
165 for(i = 0; i < 8; i++) {
e95c8d51 166 registers[i] = env->regs[i];
6da41eaf 167 }
e95c8d51
FB
168 registers[8] = env->eip;
169 registers[9] = env->eflags;
170 registers[10] = env->segs[R_CS].selector;
171 registers[11] = env->segs[R_SS].selector;
172 registers[12] = env->segs[R_DS].selector;
173 registers[13] = env->segs[R_ES].selector;
174 registers[14] = env->segs[R_FS].selector;
175 registers[15] = env->segs[R_GS].selector;
6da41eaf
FB
176 /* XXX: convert floats */
177 for(i = 0; i < 8; i++) {
178 memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
179 }
e95c8d51 180 registers[36] = env->fpuc;
6da41eaf 181 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
e95c8d51
FB
182 registers[37] = fpus;
183 registers[38] = 0; /* XXX: convert tags */
184 registers[39] = 0; /* fiseg */
185 registers[40] = 0; /* fioff */
186 registers[41] = 0; /* foseg */
187 registers[42] = 0; /* fooff */
188 registers[43] = 0; /* fop */
189
190 for(i = 0; i < 16; i++)
191 tswapls(&registers[i]);
192 for(i = 36; i < 44; i++)
193 tswapls(&registers[i]);
6da41eaf
FB
194 return 44 * 4;
195}
196
197static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
198{
199 uint32_t *registers = (uint32_t *)mem_buf;
200 int i;
201
202 for(i = 0; i < 8; i++) {
203 env->regs[i] = tswapl(registers[i]);
204 }
e95c8d51
FB
205 env->eip = tswapl(registers[8]);
206 env->eflags = tswapl(registers[9]);
6da41eaf
FB
207#if defined(CONFIG_USER_ONLY)
208#define LOAD_SEG(index, sreg)\
209 if (tswapl(registers[index]) != env->segs[sreg].selector)\
210 cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
211 LOAD_SEG(10, R_CS);
212 LOAD_SEG(11, R_SS);
213 LOAD_SEG(12, R_DS);
214 LOAD_SEG(13, R_ES);
215 LOAD_SEG(14, R_FS);
216 LOAD_SEG(15, R_GS);
217#endif
218}
219
9e62fd7f 220#elif defined (TARGET_PPC)
9e62fd7f
FB
221static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
222{
a541f297 223 uint32_t *registers = (uint32_t *)mem_buf, tmp;
9e62fd7f
FB
224 int i;
225
226 /* fill in gprs */
a541f297 227 for(i = 0; i < 32; i++) {
e95c8d51 228 registers[i] = tswapl(env->gpr[i]);
9e62fd7f
FB
229 }
230 /* fill in fprs */
231 for (i = 0; i < 32; i++) {
e95c8d51
FB
232 registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
233 registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
9e62fd7f
FB
234 }
235 /* nip, msr, ccr, lnk, ctr, xer, mq */
e95c8d51
FB
236 registers[96] = tswapl(env->nip);
237 registers[97] = tswapl(_load_msr(env));
9e62fd7f
FB
238 tmp = 0;
239 for (i = 0; i < 8; i++)
a541f297 240 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
e95c8d51
FB
241 registers[98] = tswapl(tmp);
242 registers[99] = tswapl(env->lr);
243 registers[100] = tswapl(env->ctr);
244 registers[101] = tswapl(_load_xer(env));
245 registers[102] = 0;
a541f297
FB
246
247 return 103 * 4;
9e62fd7f
FB
248}
249
250static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
251{
252 uint32_t *registers = (uint32_t *)mem_buf;
253 int i;
254
255 /* fill in gprs */
256 for (i = 0; i < 32; i++) {
e95c8d51 257 env->gpr[i] = tswapl(registers[i]);
9e62fd7f
FB
258 }
259 /* fill in fprs */
260 for (i = 0; i < 32; i++) {
e95c8d51
FB
261 *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
262 *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
9e62fd7f
FB
263 }
264 /* nip, msr, ccr, lnk, ctr, xer, mq */
e95c8d51
FB
265 env->nip = tswapl(registers[96]);
266 _store_msr(env, tswapl(registers[97]));
267 registers[98] = tswapl(registers[98]);
9e62fd7f 268 for (i = 0; i < 8; i++)
a541f297 269 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
e95c8d51
FB
270 env->lr = tswapl(registers[99]);
271 env->ctr = tswapl(registers[100]);
272 _store_xer(env, tswapl(registers[101]));
273}
274#elif defined (TARGET_SPARC)
275static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
276{
277 uint32_t *registers = (uint32_t *)mem_buf, tmp;
278 int i;
279
280 /* fill in g0..g7 */
281 for(i = 0; i < 7; i++) {
282 registers[i] = tswapl(env->gregs[i]);
283 }
284 /* fill in register window */
285 for(i = 0; i < 24; i++) {
286 registers[i + 8] = tswapl(env->regwptr[i]);
287 }
288 /* fill in fprs */
289 for (i = 0; i < 32; i++) {
290 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
291 }
292 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
293 registers[64] = tswapl(env->y);
e80cfcfc 294 tmp = GET_PSR(env);
e95c8d51
FB
295 registers[65] = tswapl(tmp);
296 registers[66] = tswapl(env->wim);
297 registers[67] = tswapl(env->tbr);
298 registers[68] = tswapl(env->pc);
299 registers[69] = tswapl(env->npc);
300 registers[70] = tswapl(env->fsr);
301 registers[71] = 0; /* csr */
302 registers[72] = 0;
303
304 return 73 * 4;
305}
306
307static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
308{
e80cfcfc 309 uint32_t *registers = (uint32_t *)mem_buf;
e95c8d51
FB
310 int i;
311
312 /* fill in g0..g7 */
313 for(i = 0; i < 7; i++) {
314 env->gregs[i] = tswapl(registers[i]);
315 }
316 /* fill in register window */
317 for(i = 0; i < 24; i++) {
318 env->regwptr[i] = tswapl(registers[i]);
319 }
320 /* fill in fprs */
321 for (i = 0; i < 32; i++) {
322 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
323 }
324 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
325 env->y = tswapl(registers[64]);
e80cfcfc 326 PUT_PSR(env, tswapl(registers[65]));
e95c8d51
FB
327 env->wim = tswapl(registers[66]);
328 env->tbr = tswapl(registers[67]);
329 env->pc = tswapl(registers[68]);
330 env->npc = tswapl(registers[69]);
331 env->fsr = tswapl(registers[70]);
9e62fd7f 332}
6da41eaf
FB
333#else
334
335static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
336{
337 return 0;
338}
339
340static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
341{
342}
343
344#endif
b4608c04
FB
345
346/* port = 0 means default port */
858693c6 347static int gdb_handle_packet(GDBState *s, const char *line_buf)
b4608c04 348{
858693c6 349 CPUState *env = cpu_single_env;
b4608c04 350 const char *p;
858693c6 351 int ch, reg_size, type;
b4608c04
FB
352 char buf[4096];
353 uint8_t mem_buf[2000];
354 uint32_t *registers;
355 uint32_t addr, len;
356
858693c6
FB
357#ifdef DEBUG_GDB
358 printf("command='%s'\n", line_buf);
359#endif
360 p = line_buf;
361 ch = *p++;
362 switch(ch) {
363 case '?':
364 snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
365 put_packet(s, buf);
366 break;
367 case 'c':
368 if (*p != '\0') {
369 addr = strtoul(p, (char **)&p, 16);
4c3a88a2 370#if defined(TARGET_I386)
858693c6 371 env->eip = addr;
5be1a8e0 372#elif defined (TARGET_PPC)
858693c6 373 env->nip = addr;
8d5f07fa
FB
374#elif defined (TARGET_SPARC)
375 env->pc = addr;
376 env->npc = addr + 4;
4c3a88a2 377#endif
858693c6
FB
378 }
379 vm_start();
380 break;
381 case 's':
382 if (*p != '\0') {
383 addr = strtoul(p, (char **)&p, 16);
c33a346e 384#if defined(TARGET_I386)
858693c6 385 env->eip = addr;
5be1a8e0 386#elif defined (TARGET_PPC)
858693c6 387 env->nip = addr;
8d5f07fa
FB
388#elif defined (TARGET_SPARC)
389 env->pc = addr;
390 env->npc = addr + 4;
c33a346e 391#endif
858693c6
FB
392 }
393 cpu_single_step(env, 1);
394 vm_start();
395 break;
396 case 'g':
397 reg_size = cpu_gdb_read_registers(env, mem_buf);
398 memtohex(buf, mem_buf, reg_size);
399 put_packet(s, buf);
400 break;
401 case 'G':
402 registers = (void *)mem_buf;
403 len = strlen(p) / 2;
404 hextomem((uint8_t *)registers, p, len);
405 cpu_gdb_write_registers(env, mem_buf, len);
406 put_packet(s, "OK");
407 break;
408 case 'm':
409 addr = strtoul(p, (char **)&p, 16);
410 if (*p == ',')
411 p++;
412 len = strtoul(p, NULL, 16);
413 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0)
414 memset(mem_buf, 0, len);
415 memtohex(buf, mem_buf, len);
416 put_packet(s, buf);
417 break;
418 case 'M':
419 addr = strtoul(p, (char **)&p, 16);
420 if (*p == ',')
421 p++;
422 len = strtoul(p, (char **)&p, 16);
b328f873 423 if (*p == ':')
858693c6
FB
424 p++;
425 hextomem(mem_buf, p, len);
426 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
427 put_packet(s, "ENN");
428 else
429 put_packet(s, "OK");
430 break;
431 case 'Z':
432 type = strtoul(p, (char **)&p, 16);
433 if (*p == ',')
434 p++;
435 addr = strtoul(p, (char **)&p, 16);
436 if (*p == ',')
437 p++;
438 len = strtoul(p, (char **)&p, 16);
439 if (type == 0 || type == 1) {
440 if (cpu_breakpoint_insert(env, addr) < 0)
441 goto breakpoint_error;
442 put_packet(s, "OK");
443 } else {
444 breakpoint_error:
445 put_packet(s, "ENN");
446 }
447 break;
448 case 'z':
449 type = strtoul(p, (char **)&p, 16);
450 if (*p == ',')
451 p++;
452 addr = strtoul(p, (char **)&p, 16);
453 if (*p == ',')
454 p++;
455 len = strtoul(p, (char **)&p, 16);
456 if (type == 0 || type == 1) {
457 cpu_breakpoint_remove(env, addr);
458 put_packet(s, "OK");
459 } else {
460 goto breakpoint_error;
461 }
462 break;
463 default:
464 // unknown_command:
465 /* put empty packet */
466 buf[0] = '\0';
467 put_packet(s, buf);
468 break;
469 }
470 return RS_IDLE;
471}
472
612458f5
FB
473extern void tb_flush(CPUState *env);
474
858693c6
FB
475static void gdb_vm_stopped(void *opaque, int reason)
476{
477 GDBState *s = opaque;
478 char buf[256];
479 int ret;
480
481 /* disable single step if it was enable */
482 cpu_single_step(cpu_single_env, 0);
483
e80cfcfc
FB
484 if (reason == EXCP_DEBUG) {
485 tb_flush(cpu_single_env);
858693c6 486 ret = SIGTRAP;
e80cfcfc 487 }
858693c6
FB
488 else
489 ret = 0;
490 snprintf(buf, sizeof(buf), "S%02x", ret);
491 put_packet(s, buf);
492}
493
494static void gdb_read_byte(GDBState *s, int ch)
495{
496 int i, csum;
497 char reply[1];
498
499 if (vm_running) {
500 /* when the CPU is running, we cannot do anything except stop
501 it when receiving a char */
502 vm_stop(EXCP_INTERRUPT);
503 } else {
504 switch(s->state) {
505 case RS_IDLE:
506 if (ch == '$') {
507 s->line_buf_index = 0;
508 s->state = RS_GETLINE;
c33a346e 509 }
b4608c04 510 break;
858693c6
FB
511 case RS_GETLINE:
512 if (ch == '#') {
513 s->state = RS_CHKSUM1;
514 } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
515 s->state = RS_IDLE;
4c3a88a2 516 } else {
858693c6 517 s->line_buf[s->line_buf_index++] = ch;
4c3a88a2
FB
518 }
519 break;
858693c6
FB
520 case RS_CHKSUM1:
521 s->line_buf[s->line_buf_index] = '\0';
522 s->line_csum = fromhex(ch) << 4;
523 s->state = RS_CHKSUM2;
524 break;
525 case RS_CHKSUM2:
526 s->line_csum |= fromhex(ch);
527 csum = 0;
528 for(i = 0; i < s->line_buf_index; i++) {
529 csum += s->line_buf[i];
530 }
531 if (s->line_csum != (csum & 0xff)) {
532 reply[0] = '-';
533 put_buffer(s, reply, 1);
534 s->state = RS_IDLE;
4c3a88a2 535 } else {
858693c6
FB
536 reply[0] = '+';
537 put_buffer(s, reply, 1);
538 s->state = gdb_handle_packet(s, s->line_buf);
4c3a88a2
FB
539 }
540 break;
858693c6
FB
541 }
542 }
543}
544
545static int gdb_can_read(void *opaque)
546{
547 return 256;
548}
549
550static void gdb_read(void *opaque, const uint8_t *buf, int size)
551{
552 GDBState *s = opaque;
553 int i;
554 if (size == 0) {
555 /* end of connection */
556 qemu_del_vm_stop_handler(gdb_vm_stopped, s);
557 qemu_del_fd_read_handler(s->fd);
558 qemu_free(s);
559 vm_start();
560 } else {
561 for(i = 0; i < size; i++)
562 gdb_read_byte(s, buf[i]);
563 }
564}
565
566static void gdb_accept(void *opaque, const uint8_t *buf, int size)
567{
568 GDBState *s;
569 struct sockaddr_in sockaddr;
570 socklen_t len;
571 int val, fd;
572
573 for(;;) {
574 len = sizeof(sockaddr);
575 fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
576 if (fd < 0 && errno != EINTR) {
577 perror("accept");
578 return;
579 } else if (fd >= 0) {
b4608c04
FB
580 break;
581 }
582 }
858693c6
FB
583
584 /* set short latency */
585 val = 1;
7d3505c5 586 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
858693c6
FB
587
588 s = qemu_mallocz(sizeof(GDBState));
589 if (!s) {
590 close(fd);
591 return;
592 }
593 s->fd = fd;
594
595 fcntl(fd, F_SETFL, O_NONBLOCK);
596
597 /* stop the VM */
598 vm_stop(EXCP_INTERRUPT);
599
600 /* start handling I/O */
601 qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
602 /* when the VM is stopped, the following callback is called */
603 qemu_add_vm_stop_handler(gdb_vm_stopped, s);
604}
605
606static int gdbserver_open(int port)
607{
608 struct sockaddr_in sockaddr;
609 int fd, val, ret;
610
611 fd = socket(PF_INET, SOCK_STREAM, 0);
612 if (fd < 0) {
613 perror("socket");
614 return -1;
615 }
616
617 /* allow fast reuse */
618 val = 1;
619 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
620
621 sockaddr.sin_family = AF_INET;
622 sockaddr.sin_port = htons(port);
623 sockaddr.sin_addr.s_addr = 0;
624 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
625 if (ret < 0) {
626 perror("bind");
627 return -1;
628 }
629 ret = listen(fd, 0);
630 if (ret < 0) {
631 perror("listen");
632 return -1;
633 }
634 fcntl(fd, F_SETFL, O_NONBLOCK);
635 return fd;
636}
637
638int gdbserver_start(int port)
639{
640 gdbserver_fd = gdbserver_open(port);
641 if (gdbserver_fd < 0)
642 return -1;
643 /* accept connections */
644 qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
b4608c04
FB
645 return 0;
646}