blob: 96b3ae6d046b181edb1071e1f7b6f468d66015b0 [file] [log] [blame]
bellardb4608c02003-06-27 17:34:32 +00001/*
2 * gdb server stub
3 *
bellard34751872005-07-02 14:31:34 +00004 * Copyright (c) 2003-2005 Fabrice Bellard
bellardb4608c02003-06-27 17:34:32 +00005 *
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 */
bellard1fddef42005-04-17 19:16:13 +000020#ifdef CONFIG_USER_ONLY
21#include <stdlib.h>
22#include <stdio.h>
23#include <stdarg.h>
24#include <string.h>
25#include <errno.h>
26#include <unistd.h>
27
28#include "qemu.h"
29#else
bellard67b915a2004-03-31 23:37:16 +000030#include "vl.h"
bellard1fddef42005-04-17 19:16:13 +000031#endif
bellard67b915a2004-03-31 23:37:16 +000032
bellardb4608c02003-06-27 17:34:32 +000033#include <sys/socket.h>
34#include <netinet/in.h>
35#include <netinet/tcp.h>
36#include <signal.h>
bellardb4608c02003-06-27 17:34:32 +000037
bellard4abe6152003-07-26 18:01:58 +000038//#define DEBUG_GDB
bellardb4608c02003-06-27 17:34:32 +000039
bellard858693c2004-03-31 18:52:07 +000040enum RSState {
41 RS_IDLE,
42 RS_GETLINE,
43 RS_CHKSUM1,
44 RS_CHKSUM2,
45};
bellard1fddef42005-04-17 19:16:13 +000046/* XXX: This is not thread safe. Do we care? */
47static int gdbserver_fd = -1;
bellardb4608c02003-06-27 17:34:32 +000048
bellard858693c2004-03-31 18:52:07 +000049typedef struct GDBState {
bellard41625032005-04-24 10:07:11 +000050 enum RSState state; /* parsing state */
bellard858693c2004-03-31 18:52:07 +000051 int fd;
52 char line_buf[4096];
53 int line_buf_index;
54 int line_csum;
bellard41625032005-04-24 10:07:11 +000055#ifdef CONFIG_USER_ONLY
56 int running_state;
57#endif
bellard858693c2004-03-31 18:52:07 +000058} GDBState;
bellardb4608c02003-06-27 17:34:32 +000059
bellard1fddef42005-04-17 19:16:13 +000060#ifdef CONFIG_USER_ONLY
61/* XXX: remove this hack. */
62static GDBState gdbserver_state;
63#endif
64
bellard858693c2004-03-31 18:52:07 +000065static int get_char(GDBState *s)
bellardb4608c02003-06-27 17:34:32 +000066{
67 uint8_t ch;
68 int ret;
69
70 for(;;) {
bellard858693c2004-03-31 18:52:07 +000071 ret = read(s->fd, &ch, 1);
bellardb4608c02003-06-27 17:34:32 +000072 if (ret < 0) {
73 if (errno != EINTR && errno != EAGAIN)
74 return -1;
75 } else if (ret == 0) {
76 return -1;
77 } else {
78 break;
79 }
80 }
81 return ch;
82}
83
bellard858693c2004-03-31 18:52:07 +000084static void put_buffer(GDBState *s, const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +000085{
86 int ret;
87
88 while (len > 0) {
bellard858693c2004-03-31 18:52:07 +000089 ret = write(s->fd, buf, len);
bellardb4608c02003-06-27 17:34:32 +000090 if (ret < 0) {
91 if (errno != EINTR && errno != EAGAIN)
92 return;
93 } else {
94 buf += ret;
95 len -= ret;
96 }
97 }
98}
99
100static inline int fromhex(int v)
101{
102 if (v >= '0' && v <= '9')
103 return v - '0';
104 else if (v >= 'A' && v <= 'F')
105 return v - 'A' + 10;
106 else if (v >= 'a' && v <= 'f')
107 return v - 'a' + 10;
108 else
109 return 0;
110}
111
112static inline int tohex(int v)
113{
114 if (v < 10)
115 return v + '0';
116 else
117 return v - 10 + 'a';
118}
119
120static void memtohex(char *buf, const uint8_t *mem, int len)
121{
122 int i, c;
123 char *q;
124 q = buf;
125 for(i = 0; i < len; i++) {
126 c = mem[i];
127 *q++ = tohex(c >> 4);
128 *q++ = tohex(c & 0xf);
129 }
130 *q = '\0';
131}
132
133static void hextomem(uint8_t *mem, const char *buf, int len)
134{
135 int i;
136
137 for(i = 0; i < len; i++) {
138 mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
139 buf += 2;
140 }
141}
142
bellardb4608c02003-06-27 17:34:32 +0000143/* return -1 if error, 0 if OK */
bellard858693c2004-03-31 18:52:07 +0000144static int put_packet(GDBState *s, char *buf)
bellardb4608c02003-06-27 17:34:32 +0000145{
146 char buf1[3];
147 int len, csum, ch, i;
148
149#ifdef DEBUG_GDB
150 printf("reply='%s'\n", buf);
151#endif
152
153 for(;;) {
154 buf1[0] = '$';
bellard858693c2004-03-31 18:52:07 +0000155 put_buffer(s, buf1, 1);
bellardb4608c02003-06-27 17:34:32 +0000156 len = strlen(buf);
bellard858693c2004-03-31 18:52:07 +0000157 put_buffer(s, buf, len);
bellardb4608c02003-06-27 17:34:32 +0000158 csum = 0;
159 for(i = 0; i < len; i++) {
160 csum += buf[i];
161 }
162 buf1[0] = '#';
163 buf1[1] = tohex((csum >> 4) & 0xf);
164 buf1[2] = tohex((csum) & 0xf);
165
bellard858693c2004-03-31 18:52:07 +0000166 put_buffer(s, buf1, 3);
bellardb4608c02003-06-27 17:34:32 +0000167
bellard858693c2004-03-31 18:52:07 +0000168 ch = get_char(s);
bellardb4608c02003-06-27 17:34:32 +0000169 if (ch < 0)
170 return -1;
171 if (ch == '+')
172 break;
173 }
174 return 0;
175}
176
bellard6da41ea2004-01-04 15:48:38 +0000177#if defined(TARGET_I386)
178
bellard6da41ea2004-01-04 15:48:38 +0000179static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
180{
bellarde95c8d52004-09-30 22:22:08 +0000181 uint32_t *registers = (uint32_t *)mem_buf;
bellard6da41ea2004-01-04 15:48:38 +0000182 int i, fpus;
183
184 for(i = 0; i < 8; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000185 registers[i] = env->regs[i];
bellard6da41ea2004-01-04 15:48:38 +0000186 }
bellarde95c8d52004-09-30 22:22:08 +0000187 registers[8] = env->eip;
188 registers[9] = env->eflags;
189 registers[10] = env->segs[R_CS].selector;
190 registers[11] = env->segs[R_SS].selector;
191 registers[12] = env->segs[R_DS].selector;
192 registers[13] = env->segs[R_ES].selector;
193 registers[14] = env->segs[R_FS].selector;
194 registers[15] = env->segs[R_GS].selector;
bellard6da41ea2004-01-04 15:48:38 +0000195 /* XXX: convert floats */
196 for(i = 0; i < 8; i++) {
197 memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
198 }
bellarde95c8d52004-09-30 22:22:08 +0000199 registers[36] = env->fpuc;
bellard6da41ea2004-01-04 15:48:38 +0000200 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
bellarde95c8d52004-09-30 22:22:08 +0000201 registers[37] = fpus;
202 registers[38] = 0; /* XXX: convert tags */
203 registers[39] = 0; /* fiseg */
204 registers[40] = 0; /* fioff */
205 registers[41] = 0; /* foseg */
206 registers[42] = 0; /* fooff */
207 registers[43] = 0; /* fop */
208
209 for(i = 0; i < 16; i++)
210 tswapls(&registers[i]);
211 for(i = 36; i < 44; i++)
212 tswapls(&registers[i]);
bellard6da41ea2004-01-04 15:48:38 +0000213 return 44 * 4;
214}
215
216static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
217{
218 uint32_t *registers = (uint32_t *)mem_buf;
219 int i;
220
221 for(i = 0; i < 8; i++) {
222 env->regs[i] = tswapl(registers[i]);
223 }
bellarde95c8d52004-09-30 22:22:08 +0000224 env->eip = tswapl(registers[8]);
225 env->eflags = tswapl(registers[9]);
bellard6da41ea2004-01-04 15:48:38 +0000226#if defined(CONFIG_USER_ONLY)
227#define LOAD_SEG(index, sreg)\
228 if (tswapl(registers[index]) != env->segs[sreg].selector)\
229 cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
230 LOAD_SEG(10, R_CS);
231 LOAD_SEG(11, R_SS);
232 LOAD_SEG(12, R_DS);
233 LOAD_SEG(13, R_ES);
234 LOAD_SEG(14, R_FS);
235 LOAD_SEG(15, R_GS);
236#endif
237}
238
bellard9e62fd72004-01-05 22:49:06 +0000239#elif defined (TARGET_PPC)
bellard9e62fd72004-01-05 22:49:06 +0000240static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
241{
bellarda541f292004-04-12 20:39:29 +0000242 uint32_t *registers = (uint32_t *)mem_buf, tmp;
bellard9e62fd72004-01-05 22:49:06 +0000243 int i;
244
245 /* fill in gprs */
bellarda541f292004-04-12 20:39:29 +0000246 for(i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000247 registers[i] = tswapl(env->gpr[i]);
bellard9e62fd72004-01-05 22:49:06 +0000248 }
249 /* fill in fprs */
250 for (i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000251 registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
252 registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
bellard9e62fd72004-01-05 22:49:06 +0000253 }
254 /* nip, msr, ccr, lnk, ctr, xer, mq */
bellarde95c8d52004-09-30 22:22:08 +0000255 registers[96] = tswapl(env->nip);
bellard3fc6c082005-07-02 20:59:34 +0000256 registers[97] = tswapl(do_load_msr(env));
bellard9e62fd72004-01-05 22:49:06 +0000257 tmp = 0;
258 for (i = 0; i < 8; i++)
bellarda541f292004-04-12 20:39:29 +0000259 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
bellarde95c8d52004-09-30 22:22:08 +0000260 registers[98] = tswapl(tmp);
261 registers[99] = tswapl(env->lr);
262 registers[100] = tswapl(env->ctr);
bellard3fc6c082005-07-02 20:59:34 +0000263 registers[101] = tswapl(do_load_xer(env));
bellarde95c8d52004-09-30 22:22:08 +0000264 registers[102] = 0;
bellard9e62fd72004-01-05 22:49:06 +0000265
bellarda541f292004-04-12 20:39:29 +0000266 return 103 * 4;
bellard9e62fd72004-01-05 22:49:06 +0000267}
268
269static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
270{
271 uint32_t *registers = (uint32_t *)mem_buf;
272 int i;
273
274 /* fill in gprs */
275 for (i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000276 env->gpr[i] = tswapl(registers[i]);
bellard9e62fd72004-01-05 22:49:06 +0000277 }
278 /* fill in fprs */
279 for (i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000280 *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
281 *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
bellard9e62fd72004-01-05 22:49:06 +0000282 }
283 /* nip, msr, ccr, lnk, ctr, xer, mq */
bellarde95c8d52004-09-30 22:22:08 +0000284 env->nip = tswapl(registers[96]);
bellard3fc6c082005-07-02 20:59:34 +0000285 do_store_msr(env, tswapl(registers[97]));
bellarde95c8d52004-09-30 22:22:08 +0000286 registers[98] = tswapl(registers[98]);
bellard9e62fd72004-01-05 22:49:06 +0000287 for (i = 0; i < 8; i++)
bellarda541f292004-04-12 20:39:29 +0000288 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
bellarde95c8d52004-09-30 22:22:08 +0000289 env->lr = tswapl(registers[99]);
290 env->ctr = tswapl(registers[100]);
bellard3fc6c082005-07-02 20:59:34 +0000291 do_store_xer(env, tswapl(registers[101]));
bellarde95c8d52004-09-30 22:22:08 +0000292}
293#elif defined (TARGET_SPARC)
294static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
295{
bellard34751872005-07-02 14:31:34 +0000296 target_ulong *registers = (target_ulong *)mem_buf;
bellarde95c8d52004-09-30 22:22:08 +0000297 int i;
298
299 /* fill in g0..g7 */
bellard48b2c192005-10-30 16:08:23 +0000300 for(i = 0; i < 8; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000301 registers[i] = tswapl(env->gregs[i]);
302 }
303 /* fill in register window */
304 for(i = 0; i < 24; i++) {
305 registers[i + 8] = tswapl(env->regwptr[i]);
306 }
307 /* fill in fprs */
308 for (i = 0; i < 32; i++) {
309 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
310 }
bellard34751872005-07-02 14:31:34 +0000311#ifndef TARGET_SPARC64
bellarde95c8d52004-09-30 22:22:08 +0000312 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
313 registers[64] = tswapl(env->y);
bellard34751872005-07-02 14:31:34 +0000314 {
315 target_ulong tmp;
316
317 tmp = GET_PSR(env);
318 registers[65] = tswapl(tmp);
319 }
bellarde95c8d52004-09-30 22:22:08 +0000320 registers[66] = tswapl(env->wim);
321 registers[67] = tswapl(env->tbr);
322 registers[68] = tswapl(env->pc);
323 registers[69] = tswapl(env->npc);
324 registers[70] = tswapl(env->fsr);
325 registers[71] = 0; /* csr */
326 registers[72] = 0;
bellard34751872005-07-02 14:31:34 +0000327 return 73 * sizeof(target_ulong);
328#else
329 for (i = 0; i < 32; i += 2) {
330 registers[i/2 + 64] = tswapl(*((uint64_t *)&env->fpr[i]));
331 }
332 registers[81] = tswapl(env->pc);
333 registers[82] = tswapl(env->npc);
334 registers[83] = tswapl(env->tstate[env->tl]);
335 registers[84] = tswapl(env->fsr);
336 registers[85] = tswapl(env->fprs);
337 registers[86] = tswapl(env->y);
338 return 87 * sizeof(target_ulong);
339#endif
bellarde95c8d52004-09-30 22:22:08 +0000340}
341
342static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
343{
bellard34751872005-07-02 14:31:34 +0000344 target_ulong *registers = (target_ulong *)mem_buf;
bellarde95c8d52004-09-30 22:22:08 +0000345 int i;
346
347 /* fill in g0..g7 */
348 for(i = 0; i < 7; i++) {
349 env->gregs[i] = tswapl(registers[i]);
350 }
351 /* fill in register window */
352 for(i = 0; i < 24; i++) {
bellard34751872005-07-02 14:31:34 +0000353 env->regwptr[i] = tswapl(registers[i + 8]);
bellarde95c8d52004-09-30 22:22:08 +0000354 }
355 /* fill in fprs */
356 for (i = 0; i < 32; i++) {
357 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
358 }
bellard34751872005-07-02 14:31:34 +0000359#ifndef TARGET_SPARC64
bellarde95c8d52004-09-30 22:22:08 +0000360 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
361 env->y = tswapl(registers[64]);
bellarde80cfcf2004-12-19 23:18:01 +0000362 PUT_PSR(env, tswapl(registers[65]));
bellarde95c8d52004-09-30 22:22:08 +0000363 env->wim = tswapl(registers[66]);
364 env->tbr = tswapl(registers[67]);
365 env->pc = tswapl(registers[68]);
366 env->npc = tswapl(registers[69]);
367 env->fsr = tswapl(registers[70]);
bellard34751872005-07-02 14:31:34 +0000368#else
369 for (i = 0; i < 32; i += 2) {
370 uint64_t tmp;
371 tmp = tswapl(registers[i/2 + 64]) << 32;
372 tmp |= tswapl(registers[i/2 + 64 + 1]);
373 *((uint64_t *)&env->fpr[i]) = tmp;
374 }
375 env->pc = tswapl(registers[81]);
376 env->npc = tswapl(registers[82]);
377 env->tstate[env->tl] = tswapl(registers[83]);
378 env->fsr = tswapl(registers[84]);
379 env->fprs = tswapl(registers[85]);
380 env->y = tswapl(registers[86]);
381#endif
bellard9e62fd72004-01-05 22:49:06 +0000382}
bellard1fddef42005-04-17 19:16:13 +0000383#elif defined (TARGET_ARM)
384static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
385{
386 int i;
387 uint8_t *ptr;
bellard6da41ea2004-01-04 15:48:38 +0000388
bellard1fddef42005-04-17 19:16:13 +0000389 ptr = mem_buf;
390 /* 16 core integer registers (4 bytes each). */
391 for (i = 0; i < 16; i++)
392 {
393 *(uint32_t *)ptr = tswapl(env->regs[i]);
394 ptr += 4;
395 }
396 /* 8 FPA registers (12 bytes each), FPS (4 bytes).
397 Not yet implemented. */
398 memset (ptr, 0, 8 * 12 + 4);
399 ptr += 8 * 12 + 4;
400 /* CPSR (4 bytes). */
401 *(uint32_t *)ptr = tswapl (env->cpsr);
402 ptr += 4;
403
404 return ptr - mem_buf;
405}
406
407static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
408{
409 int i;
410 uint8_t *ptr;
411
412 ptr = mem_buf;
413 /* Core integer registers. */
414 for (i = 0; i < 16; i++)
415 {
416 env->regs[i] = tswapl(*(uint32_t *)ptr);
417 ptr += 4;
418 }
419 /* Ignore FPA regs and scr. */
420 ptr += 8 * 12 + 4;
421 env->cpsr = tswapl(*(uint32_t *)ptr);
422}
423#else
bellard6da41ea2004-01-04 15:48:38 +0000424static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
425{
426 return 0;
427}
428
429static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
430{
431}
432
433#endif
bellardb4608c02003-06-27 17:34:32 +0000434
bellard1fddef42005-04-17 19:16:13 +0000435static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
bellardb4608c02003-06-27 17:34:32 +0000436{
bellardb4608c02003-06-27 17:34:32 +0000437 const char *p;
bellard858693c2004-03-31 18:52:07 +0000438 int ch, reg_size, type;
bellardb4608c02003-06-27 17:34:32 +0000439 char buf[4096];
440 uint8_t mem_buf[2000];
441 uint32_t *registers;
442 uint32_t addr, len;
443
bellard858693c2004-03-31 18:52:07 +0000444#ifdef DEBUG_GDB
445 printf("command='%s'\n", line_buf);
bellard4c3a88a2003-07-26 12:06:08 +0000446#endif
bellard858693c2004-03-31 18:52:07 +0000447 p = line_buf;
448 ch = *p++;
449 switch(ch) {
450 case '?':
bellard1fddef42005-04-17 19:16:13 +0000451 /* TODO: Make this return the correct value for user-mode. */
bellard858693c2004-03-31 18:52:07 +0000452 snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
453 put_packet(s, buf);
454 break;
455 case 'c':
456 if (*p != '\0') {
457 addr = strtoul(p, (char **)&p, 16);
bellardc33a3462003-07-29 20:50:33 +0000458#if defined(TARGET_I386)
bellard858693c2004-03-31 18:52:07 +0000459 env->eip = addr;
bellard5be1a8e2004-01-04 23:51:58 +0000460#elif defined (TARGET_PPC)
bellard858693c2004-03-31 18:52:07 +0000461 env->nip = addr;
bellard8d5f07f2004-10-04 21:23:09 +0000462#elif defined (TARGET_SPARC)
463 env->pc = addr;
464 env->npc = addr + 4;
bellardc33a3462003-07-29 20:50:33 +0000465#endif
bellard858693c2004-03-31 18:52:07 +0000466 }
bellard41625032005-04-24 10:07:11 +0000467#ifdef CONFIG_USER_ONLY
468 s->running_state = 1;
469#else
470 vm_start();
471#endif
472 return RS_IDLE;
bellard858693c2004-03-31 18:52:07 +0000473 case 's':
474 if (*p != '\0') {
bellardb4608c02003-06-27 17:34:32 +0000475 addr = strtoul(p, (char **)&p, 16);
bellard858693c2004-03-31 18:52:07 +0000476#if defined(TARGET_I386)
477 env->eip = addr;
478#elif defined (TARGET_PPC)
479 env->nip = addr;
bellard8d5f07f2004-10-04 21:23:09 +0000480#elif defined (TARGET_SPARC)
481 env->pc = addr;
482 env->npc = addr + 4;
bellard858693c2004-03-31 18:52:07 +0000483#endif
484 }
485 cpu_single_step(env, 1);
bellard41625032005-04-24 10:07:11 +0000486#ifdef CONFIG_USER_ONLY
487 s->running_state = 1;
488#else
489 vm_start();
490#endif
491 return RS_IDLE;
bellard858693c2004-03-31 18:52:07 +0000492 case 'g':
493 reg_size = cpu_gdb_read_registers(env, mem_buf);
494 memtohex(buf, mem_buf, reg_size);
495 put_packet(s, buf);
496 break;
497 case 'G':
498 registers = (void *)mem_buf;
499 len = strlen(p) / 2;
500 hextomem((uint8_t *)registers, p, len);
501 cpu_gdb_write_registers(env, mem_buf, len);
502 put_packet(s, "OK");
503 break;
504 case 'm':
505 addr = strtoul(p, (char **)&p, 16);
506 if (*p == ',')
507 p++;
508 len = strtoul(p, NULL, 16);
509 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0)
510 memset(mem_buf, 0, len);
511 memtohex(buf, mem_buf, len);
512 put_packet(s, buf);
513 break;
514 case 'M':
515 addr = strtoul(p, (char **)&p, 16);
516 if (*p == ',')
517 p++;
518 len = strtoul(p, (char **)&p, 16);
bellardb328f872005-01-17 22:03:16 +0000519 if (*p == ':')
bellard858693c2004-03-31 18:52:07 +0000520 p++;
521 hextomem(mem_buf, p, len);
522 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
bellard905f20b2005-04-26 21:09:55 +0000523 put_packet(s, "E14");
bellard858693c2004-03-31 18:52:07 +0000524 else
525 put_packet(s, "OK");
526 break;
527 case 'Z':
528 type = strtoul(p, (char **)&p, 16);
529 if (*p == ',')
530 p++;
531 addr = strtoul(p, (char **)&p, 16);
532 if (*p == ',')
533 p++;
534 len = strtoul(p, (char **)&p, 16);
535 if (type == 0 || type == 1) {
536 if (cpu_breakpoint_insert(env, addr) < 0)
bellard4c3a88a2003-07-26 12:06:08 +0000537 goto breakpoint_error;
bellard858693c2004-03-31 18:52:07 +0000538 put_packet(s, "OK");
539 } else {
540 breakpoint_error:
bellard905f20b2005-04-26 21:09:55 +0000541 put_packet(s, "E22");
bellard858693c2004-03-31 18:52:07 +0000542 }
543 break;
544 case 'z':
545 type = strtoul(p, (char **)&p, 16);
546 if (*p == ',')
547 p++;
548 addr = strtoul(p, (char **)&p, 16);
549 if (*p == ',')
550 p++;
551 len = strtoul(p, (char **)&p, 16);
552 if (type == 0 || type == 1) {
553 cpu_breakpoint_remove(env, addr);
554 put_packet(s, "OK");
555 } else {
556 goto breakpoint_error;
557 }
558 break;
559 default:
560 // unknown_command:
561 /* put empty packet */
562 buf[0] = '\0';
563 put_packet(s, buf);
564 break;
565 }
566 return RS_IDLE;
567}
568
bellard612458f2005-01-03 23:34:06 +0000569extern void tb_flush(CPUState *env);
570
bellard1fddef42005-04-17 19:16:13 +0000571#ifndef CONFIG_USER_ONLY
bellard858693c2004-03-31 18:52:07 +0000572static void gdb_vm_stopped(void *opaque, int reason)
573{
574 GDBState *s = opaque;
575 char buf[256];
576 int ret;
577
578 /* disable single step if it was enable */
579 cpu_single_step(cpu_single_env, 0);
580
bellarde80cfcf2004-12-19 23:18:01 +0000581 if (reason == EXCP_DEBUG) {
582 tb_flush(cpu_single_env);
bellard858693c2004-03-31 18:52:07 +0000583 ret = SIGTRAP;
bellarde80cfcf2004-12-19 23:18:01 +0000584 }
bellard858693c2004-03-31 18:52:07 +0000585 else
586 ret = 0;
587 snprintf(buf, sizeof(buf), "S%02x", ret);
588 put_packet(s, buf);
589}
bellard1fddef42005-04-17 19:16:13 +0000590#endif
bellard858693c2004-03-31 18:52:07 +0000591
bellard1fddef42005-04-17 19:16:13 +0000592static void gdb_read_byte(GDBState *s, CPUState *env, int ch)
bellard858693c2004-03-31 18:52:07 +0000593{
594 int i, csum;
595 char reply[1];
596
bellard1fddef42005-04-17 19:16:13 +0000597#ifndef CONFIG_USER_ONLY
bellard858693c2004-03-31 18:52:07 +0000598 if (vm_running) {
599 /* when the CPU is running, we cannot do anything except stop
600 it when receiving a char */
601 vm_stop(EXCP_INTERRUPT);
bellard41625032005-04-24 10:07:11 +0000602 } else
bellard1fddef42005-04-17 19:16:13 +0000603#endif
bellard41625032005-04-24 10:07:11 +0000604 {
bellard858693c2004-03-31 18:52:07 +0000605 switch(s->state) {
606 case RS_IDLE:
607 if (ch == '$') {
608 s->line_buf_index = 0;
609 s->state = RS_GETLINE;
bellard4c3a88a2003-07-26 12:06:08 +0000610 }
611 break;
bellard858693c2004-03-31 18:52:07 +0000612 case RS_GETLINE:
613 if (ch == '#') {
614 s->state = RS_CHKSUM1;
615 } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
616 s->state = RS_IDLE;
617 } else {
618 s->line_buf[s->line_buf_index++] = ch;
619 }
620 break;
621 case RS_CHKSUM1:
622 s->line_buf[s->line_buf_index] = '\0';
623 s->line_csum = fromhex(ch) << 4;
624 s->state = RS_CHKSUM2;
625 break;
626 case RS_CHKSUM2:
627 s->line_csum |= fromhex(ch);
628 csum = 0;
629 for(i = 0; i < s->line_buf_index; i++) {
630 csum += s->line_buf[i];
631 }
632 if (s->line_csum != (csum & 0xff)) {
633 reply[0] = '-';
634 put_buffer(s, reply, 1);
635 s->state = RS_IDLE;
636 } else {
637 reply[0] = '+';
638 put_buffer(s, reply, 1);
bellard1fddef42005-04-17 19:16:13 +0000639 s->state = gdb_handle_packet(s, env, s->line_buf);
bellard858693c2004-03-31 18:52:07 +0000640 }
bellardb4608c02003-06-27 17:34:32 +0000641 break;
642 }
643 }
bellard858693c2004-03-31 18:52:07 +0000644}
645
bellard1fddef42005-04-17 19:16:13 +0000646#ifdef CONFIG_USER_ONLY
647int
648gdb_handlesig (CPUState *env, int sig)
649{
650 GDBState *s;
651 char buf[256];
652 int n;
653
654 if (gdbserver_fd < 0)
655 return sig;
656
657 s = &gdbserver_state;
658
659 /* disable single step if it was enabled */
660 cpu_single_step(env, 0);
661 tb_flush(env);
662
663 if (sig != 0)
664 {
665 snprintf(buf, sizeof(buf), "S%02x", sig);
666 put_packet(s, buf);
667 }
668
bellard1fddef42005-04-17 19:16:13 +0000669 sig = 0;
670 s->state = RS_IDLE;
bellard41625032005-04-24 10:07:11 +0000671 s->running_state = 0;
672 while (s->running_state == 0) {
bellard1fddef42005-04-17 19:16:13 +0000673 n = read (s->fd, buf, 256);
674 if (n > 0)
675 {
676 int i;
677
678 for (i = 0; i < n; i++)
679 gdb_read_byte (s, env, buf[i]);
680 }
681 else if (n == 0 || errno != EAGAIN)
682 {
683 /* XXX: Connection closed. Should probably wait for annother
684 connection before continuing. */
685 return sig;
686 }
bellard41625032005-04-24 10:07:11 +0000687 }
bellard1fddef42005-04-17 19:16:13 +0000688 return sig;
689}
bellarde9009672005-04-26 20:42:36 +0000690
691/* Tell the remote gdb that the process has exited. */
692void gdb_exit(CPUState *env, int code)
693{
694 GDBState *s;
695 char buf[4];
696
697 if (gdbserver_fd < 0)
698 return;
699
700 s = &gdbserver_state;
701
702 snprintf(buf, sizeof(buf), "W%02x", code);
703 put_packet(s, buf);
704}
705
bellard1fddef42005-04-17 19:16:13 +0000706#else
bellard858693c2004-03-31 18:52:07 +0000707static int gdb_can_read(void *opaque)
708{
709 return 256;
710}
711
712static void gdb_read(void *opaque, const uint8_t *buf, int size)
713{
714 GDBState *s = opaque;
715 int i;
716 if (size == 0) {
717 /* end of connection */
718 qemu_del_vm_stop_handler(gdb_vm_stopped, s);
719 qemu_del_fd_read_handler(s->fd);
720 qemu_free(s);
721 vm_start();
722 } else {
723 for(i = 0; i < size; i++)
bellard1fddef42005-04-17 19:16:13 +0000724 gdb_read_byte(s, cpu_single_env, buf[i]);
bellard858693c2004-03-31 18:52:07 +0000725 }
726}
727
bellard1fddef42005-04-17 19:16:13 +0000728#endif
729
bellard858693c2004-03-31 18:52:07 +0000730static void gdb_accept(void *opaque, const uint8_t *buf, int size)
731{
732 GDBState *s;
733 struct sockaddr_in sockaddr;
734 socklen_t len;
735 int val, fd;
736
737 for(;;) {
738 len = sizeof(sockaddr);
739 fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
740 if (fd < 0 && errno != EINTR) {
741 perror("accept");
742 return;
743 } else if (fd >= 0) {
744 break;
745 }
746 }
747
748 /* set short latency */
749 val = 1;
bellard7d3505c2004-05-12 19:32:15 +0000750 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
bellard858693c2004-03-31 18:52:07 +0000751
bellard1fddef42005-04-17 19:16:13 +0000752#ifdef CONFIG_USER_ONLY
753 s = &gdbserver_state;
754 memset (s, 0, sizeof (GDBState));
755#else
bellard858693c2004-03-31 18:52:07 +0000756 s = qemu_mallocz(sizeof(GDBState));
757 if (!s) {
758 close(fd);
759 return;
760 }
bellard1fddef42005-04-17 19:16:13 +0000761#endif
bellard858693c2004-03-31 18:52:07 +0000762 s->fd = fd;
763
764 fcntl(fd, F_SETFL, O_NONBLOCK);
765
bellard1fddef42005-04-17 19:16:13 +0000766#ifndef CONFIG_USER_ONLY
bellard858693c2004-03-31 18:52:07 +0000767 /* stop the VM */
768 vm_stop(EXCP_INTERRUPT);
769
770 /* start handling I/O */
771 qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
772 /* when the VM is stopped, the following callback is called */
773 qemu_add_vm_stop_handler(gdb_vm_stopped, s);
bellard1fddef42005-04-17 19:16:13 +0000774#endif
bellard858693c2004-03-31 18:52:07 +0000775}
776
777static int gdbserver_open(int port)
778{
779 struct sockaddr_in sockaddr;
780 int fd, val, ret;
781
782 fd = socket(PF_INET, SOCK_STREAM, 0);
783 if (fd < 0) {
784 perror("socket");
785 return -1;
786 }
787
788 /* allow fast reuse */
789 val = 1;
790 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
791
792 sockaddr.sin_family = AF_INET;
793 sockaddr.sin_port = htons(port);
794 sockaddr.sin_addr.s_addr = 0;
795 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
796 if (ret < 0) {
797 perror("bind");
798 return -1;
799 }
800 ret = listen(fd, 0);
801 if (ret < 0) {
802 perror("listen");
803 return -1;
804 }
bellard1fddef42005-04-17 19:16:13 +0000805#ifndef CONFIG_USER_ONLY
bellard858693c2004-03-31 18:52:07 +0000806 fcntl(fd, F_SETFL, O_NONBLOCK);
bellard1fddef42005-04-17 19:16:13 +0000807#endif
bellard858693c2004-03-31 18:52:07 +0000808 return fd;
809}
810
811int gdbserver_start(int port)
812{
813 gdbserver_fd = gdbserver_open(port);
814 if (gdbserver_fd < 0)
815 return -1;
816 /* accept connections */
bellard1fddef42005-04-17 19:16:13 +0000817#ifdef CONFIG_USER_ONLY
818 gdb_accept (NULL, NULL, 0);
819#else
bellard858693c2004-03-31 18:52:07 +0000820 qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
bellard1fddef42005-04-17 19:16:13 +0000821#endif
bellardb4608c02003-06-27 17:34:32 +0000822 return 0;
823}