blob: e2c8b2dfa8691c2cdc9c5512908dc733e6013b79 [file] [log] [blame]
bellardb4608c02003-06-27 17:34:32 +00001/*
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 */
bellard67b915a2004-03-31 23:37:16 +000020#include "vl.h"
21
bellardb4608c02003-06-27 17:34:32 +000022#include <sys/socket.h>
23#include <netinet/in.h>
24#include <netinet/tcp.h>
25#include <signal.h>
bellardb4608c02003-06-27 17:34:32 +000026
bellard4abe6152003-07-26 18:01:58 +000027//#define DEBUG_GDB
bellardb4608c02003-06-27 17:34:32 +000028
bellard858693c2004-03-31 18:52:07 +000029enum RSState {
30 RS_IDLE,
31 RS_GETLINE,
32 RS_CHKSUM1,
33 RS_CHKSUM2,
34};
bellardb4608c02003-06-27 17:34:32 +000035
bellard858693c2004-03-31 18:52:07 +000036static int gdbserver_fd;
bellardb4608c02003-06-27 17:34:32 +000037
bellard858693c2004-03-31 18:52:07 +000038typedef 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;
bellardb4608c02003-06-27 17:34:32 +000045
bellard858693c2004-03-31 18:52:07 +000046static int get_char(GDBState *s)
bellardb4608c02003-06-27 17:34:32 +000047{
48 uint8_t ch;
49 int ret;
50
51 for(;;) {
bellard858693c2004-03-31 18:52:07 +000052 ret = read(s->fd, &ch, 1);
bellardb4608c02003-06-27 17:34:32 +000053 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
bellard858693c2004-03-31 18:52:07 +000065static void put_buffer(GDBState *s, const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +000066{
67 int ret;
68
69 while (len > 0) {
bellard858693c2004-03-31 18:52:07 +000070 ret = write(s->fd, buf, len);
bellardb4608c02003-06-27 17:34:32 +000071 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
bellardb4608c02003-06-27 17:34:32 +0000124/* return -1 if error, 0 if OK */
bellard858693c2004-03-31 18:52:07 +0000125static int put_packet(GDBState *s, char *buf)
bellardb4608c02003-06-27 17:34:32 +0000126{
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] = '$';
bellard858693c2004-03-31 18:52:07 +0000136 put_buffer(s, buf1, 1);
bellardb4608c02003-06-27 17:34:32 +0000137 len = strlen(buf);
bellard858693c2004-03-31 18:52:07 +0000138 put_buffer(s, buf, len);
bellardb4608c02003-06-27 17:34:32 +0000139 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
bellard858693c2004-03-31 18:52:07 +0000147 put_buffer(s, buf1, 3);
bellardb4608c02003-06-27 17:34:32 +0000148
bellard858693c2004-03-31 18:52:07 +0000149 ch = get_char(s);
bellardb4608c02003-06-27 17:34:32 +0000150 if (ch < 0)
151 return -1;
152 if (ch == '+')
153 break;
154 }
155 return 0;
156}
157
bellard6da41ea2004-01-04 15:48:38 +0000158#if defined(TARGET_I386)
159
bellard6da41ea2004-01-04 15:48:38 +0000160static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
161{
bellarde95c8d52004-09-30 22:22:08 +0000162 uint32_t *registers = (uint32_t *)mem_buf;
bellard6da41ea2004-01-04 15:48:38 +0000163 int i, fpus;
164
165 for(i = 0; i < 8; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000166 registers[i] = env->regs[i];
bellard6da41ea2004-01-04 15:48:38 +0000167 }
bellarde95c8d52004-09-30 22:22:08 +0000168 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;
bellard6da41ea2004-01-04 15:48:38 +0000176 /* XXX: convert floats */
177 for(i = 0; i < 8; i++) {
178 memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
179 }
bellarde95c8d52004-09-30 22:22:08 +0000180 registers[36] = env->fpuc;
bellard6da41ea2004-01-04 15:48:38 +0000181 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
bellarde95c8d52004-09-30 22:22:08 +0000182 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]);
bellard6da41ea2004-01-04 15:48:38 +0000194 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 }
bellarde95c8d52004-09-30 22:22:08 +0000205 env->eip = tswapl(registers[8]);
206 env->eflags = tswapl(registers[9]);
bellard6da41ea2004-01-04 15:48:38 +0000207#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
bellard9e62fd72004-01-05 22:49:06 +0000220#elif defined (TARGET_PPC)
bellarda541f292004-04-12 20:39:29 +0000221static uint32_t from_le32 (uint32_t *buf)
222{
223 uint8_t *p = (uint8_t *)buf;
224
225 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
226}
227
bellard9e62fd72004-01-05 22:49:06 +0000228static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
229{
bellarda541f292004-04-12 20:39:29 +0000230 uint32_t *registers = (uint32_t *)mem_buf, tmp;
bellard9e62fd72004-01-05 22:49:06 +0000231 int i;
232
233 /* fill in gprs */
bellarda541f292004-04-12 20:39:29 +0000234 for(i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000235 registers[i] = tswapl(env->gpr[i]);
bellard9e62fd72004-01-05 22:49:06 +0000236 }
237 /* fill in fprs */
238 for (i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000239 registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
240 registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
bellard9e62fd72004-01-05 22:49:06 +0000241 }
242 /* nip, msr, ccr, lnk, ctr, xer, mq */
bellarde95c8d52004-09-30 22:22:08 +0000243 registers[96] = tswapl(env->nip);
244 registers[97] = tswapl(_load_msr(env));
bellard9e62fd72004-01-05 22:49:06 +0000245 tmp = 0;
246 for (i = 0; i < 8; i++)
bellarda541f292004-04-12 20:39:29 +0000247 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
bellarde95c8d52004-09-30 22:22:08 +0000248 registers[98] = tswapl(tmp);
249 registers[99] = tswapl(env->lr);
250 registers[100] = tswapl(env->ctr);
251 registers[101] = tswapl(_load_xer(env));
252 registers[102] = 0;
bellard9e62fd72004-01-05 22:49:06 +0000253
bellarda541f292004-04-12 20:39:29 +0000254 return 103 * 4;
bellard9e62fd72004-01-05 22:49:06 +0000255}
256
257static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
258{
259 uint32_t *registers = (uint32_t *)mem_buf;
260 int i;
261
262 /* fill in gprs */
263 for (i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000264 env->gpr[i] = tswapl(registers[i]);
bellard9e62fd72004-01-05 22:49:06 +0000265 }
266 /* fill in fprs */
267 for (i = 0; i < 32; i++) {
bellarde95c8d52004-09-30 22:22:08 +0000268 *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
269 *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
bellard9e62fd72004-01-05 22:49:06 +0000270 }
271 /* nip, msr, ccr, lnk, ctr, xer, mq */
bellarde95c8d52004-09-30 22:22:08 +0000272 env->nip = tswapl(registers[96]);
273 _store_msr(env, tswapl(registers[97]));
274 registers[98] = tswapl(registers[98]);
bellard9e62fd72004-01-05 22:49:06 +0000275 for (i = 0; i < 8; i++)
bellarda541f292004-04-12 20:39:29 +0000276 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
bellarde95c8d52004-09-30 22:22:08 +0000277 env->lr = tswapl(registers[99]);
278 env->ctr = tswapl(registers[100]);
279 _store_xer(env, tswapl(registers[101]));
280}
281#elif defined (TARGET_SPARC)
282static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
283{
284 uint32_t *registers = (uint32_t *)mem_buf, tmp;
285 int i;
286
287 /* fill in g0..g7 */
288 for(i = 0; i < 7; i++) {
289 registers[i] = tswapl(env->gregs[i]);
290 }
291 /* fill in register window */
292 for(i = 0; i < 24; i++) {
293 registers[i + 8] = tswapl(env->regwptr[i]);
294 }
295 /* fill in fprs */
296 for (i = 0; i < 32; i++) {
297 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
298 }
299 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
300 registers[64] = tswapl(env->y);
bellarde80cfcf2004-12-19 23:18:01 +0000301 tmp = GET_PSR(env);
bellarde95c8d52004-09-30 22:22:08 +0000302 registers[65] = tswapl(tmp);
303 registers[66] = tswapl(env->wim);
304 registers[67] = tswapl(env->tbr);
305 registers[68] = tswapl(env->pc);
306 registers[69] = tswapl(env->npc);
307 registers[70] = tswapl(env->fsr);
308 registers[71] = 0; /* csr */
309 registers[72] = 0;
310
311 return 73 * 4;
312}
313
314static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
315{
bellarde80cfcf2004-12-19 23:18:01 +0000316 uint32_t *registers = (uint32_t *)mem_buf;
bellarde95c8d52004-09-30 22:22:08 +0000317 int i;
318
319 /* fill in g0..g7 */
320 for(i = 0; i < 7; i++) {
321 env->gregs[i] = tswapl(registers[i]);
322 }
323 /* fill in register window */
324 for(i = 0; i < 24; i++) {
325 env->regwptr[i] = tswapl(registers[i]);
326 }
327 /* fill in fprs */
328 for (i = 0; i < 32; i++) {
329 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
330 }
331 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
332 env->y = tswapl(registers[64]);
bellarde80cfcf2004-12-19 23:18:01 +0000333 PUT_PSR(env, tswapl(registers[65]));
bellarde95c8d52004-09-30 22:22:08 +0000334 env->wim = tswapl(registers[66]);
335 env->tbr = tswapl(registers[67]);
336 env->pc = tswapl(registers[68]);
337 env->npc = tswapl(registers[69]);
338 env->fsr = tswapl(registers[70]);
bellard9e62fd72004-01-05 22:49:06 +0000339}
bellard6da41ea2004-01-04 15:48:38 +0000340#else
341
342static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
343{
344 return 0;
345}
346
347static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
348{
349}
350
351#endif
bellardb4608c02003-06-27 17:34:32 +0000352
353/* port = 0 means default port */
bellard858693c2004-03-31 18:52:07 +0000354static int gdb_handle_packet(GDBState *s, const char *line_buf)
bellardb4608c02003-06-27 17:34:32 +0000355{
bellard858693c2004-03-31 18:52:07 +0000356 CPUState *env = cpu_single_env;
bellardb4608c02003-06-27 17:34:32 +0000357 const char *p;
bellard858693c2004-03-31 18:52:07 +0000358 int ch, reg_size, type;
bellardb4608c02003-06-27 17:34:32 +0000359 char buf[4096];
360 uint8_t mem_buf[2000];
361 uint32_t *registers;
362 uint32_t addr, len;
363
bellard858693c2004-03-31 18:52:07 +0000364#ifdef DEBUG_GDB
365 printf("command='%s'\n", line_buf);
bellard4c3a88a2003-07-26 12:06:08 +0000366#endif
bellard858693c2004-03-31 18:52:07 +0000367 p = line_buf;
368 ch = *p++;
369 switch(ch) {
370 case '?':
371 snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
372 put_packet(s, buf);
373 break;
374 case 'c':
375 if (*p != '\0') {
376 addr = strtoul(p, (char **)&p, 16);
bellardc33a3462003-07-29 20:50:33 +0000377#if defined(TARGET_I386)
bellard858693c2004-03-31 18:52:07 +0000378 env->eip = addr;
bellard5be1a8e2004-01-04 23:51:58 +0000379#elif defined (TARGET_PPC)
bellard858693c2004-03-31 18:52:07 +0000380 env->nip = addr;
bellard8d5f07f2004-10-04 21:23:09 +0000381#elif defined (TARGET_SPARC)
382 env->pc = addr;
383 env->npc = addr + 4;
bellardc33a3462003-07-29 20:50:33 +0000384#endif
bellard858693c2004-03-31 18:52:07 +0000385 }
386 vm_start();
387 break;
388 case 's':
389 if (*p != '\0') {
bellardb4608c02003-06-27 17:34:32 +0000390 addr = strtoul(p, (char **)&p, 16);
bellard858693c2004-03-31 18:52:07 +0000391#if defined(TARGET_I386)
392 env->eip = addr;
393#elif defined (TARGET_PPC)
394 env->nip = addr;
bellard8d5f07f2004-10-04 21:23:09 +0000395#elif defined (TARGET_SPARC)
396 env->pc = addr;
397 env->npc = addr + 4;
bellard858693c2004-03-31 18:52:07 +0000398#endif
399 }
400 cpu_single_step(env, 1);
401 vm_start();
402 break;
403 case 'g':
404 reg_size = cpu_gdb_read_registers(env, mem_buf);
405 memtohex(buf, mem_buf, reg_size);
406 put_packet(s, buf);
407 break;
408 case 'G':
409 registers = (void *)mem_buf;
410 len = strlen(p) / 2;
411 hextomem((uint8_t *)registers, p, len);
412 cpu_gdb_write_registers(env, mem_buf, len);
413 put_packet(s, "OK");
414 break;
415 case 'm':
416 addr = strtoul(p, (char **)&p, 16);
417 if (*p == ',')
418 p++;
419 len = strtoul(p, NULL, 16);
420 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0)
421 memset(mem_buf, 0, len);
422 memtohex(buf, mem_buf, len);
423 put_packet(s, buf);
424 break;
425 case 'M':
426 addr = strtoul(p, (char **)&p, 16);
427 if (*p == ',')
428 p++;
429 len = strtoul(p, (char **)&p, 16);
430 if (*p == ',')
431 p++;
432 hextomem(mem_buf, p, len);
433 if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
434 put_packet(s, "ENN");
435 else
436 put_packet(s, "OK");
437 break;
438 case 'Z':
439 type = strtoul(p, (char **)&p, 16);
440 if (*p == ',')
441 p++;
442 addr = strtoul(p, (char **)&p, 16);
443 if (*p == ',')
444 p++;
445 len = strtoul(p, (char **)&p, 16);
446 if (type == 0 || type == 1) {
447 if (cpu_breakpoint_insert(env, addr) < 0)
bellard4c3a88a2003-07-26 12:06:08 +0000448 goto breakpoint_error;
bellard858693c2004-03-31 18:52:07 +0000449 put_packet(s, "OK");
450 } else {
451 breakpoint_error:
452 put_packet(s, "ENN");
453 }
454 break;
455 case 'z':
456 type = strtoul(p, (char **)&p, 16);
457 if (*p == ',')
458 p++;
459 addr = strtoul(p, (char **)&p, 16);
460 if (*p == ',')
461 p++;
462 len = strtoul(p, (char **)&p, 16);
463 if (type == 0 || type == 1) {
464 cpu_breakpoint_remove(env, addr);
465 put_packet(s, "OK");
466 } else {
467 goto breakpoint_error;
468 }
469 break;
470 default:
471 // unknown_command:
472 /* put empty packet */
473 buf[0] = '\0';
474 put_packet(s, buf);
475 break;
476 }
477 return RS_IDLE;
478}
479
480static void gdb_vm_stopped(void *opaque, int reason)
481{
482 GDBState *s = opaque;
483 char buf[256];
484 int ret;
485
486 /* disable single step if it was enable */
487 cpu_single_step(cpu_single_env, 0);
488
bellarde80cfcf2004-12-19 23:18:01 +0000489 if (reason == EXCP_DEBUG) {
490 tb_flush(cpu_single_env);
bellard858693c2004-03-31 18:52:07 +0000491 ret = SIGTRAP;
bellarde80cfcf2004-12-19 23:18:01 +0000492 }
bellard858693c2004-03-31 18:52:07 +0000493 else
494 ret = 0;
495 snprintf(buf, sizeof(buf), "S%02x", ret);
496 put_packet(s, buf);
497}
498
499static void gdb_read_byte(GDBState *s, int ch)
500{
501 int i, csum;
502 char reply[1];
503
504 if (vm_running) {
505 /* when the CPU is running, we cannot do anything except stop
506 it when receiving a char */
507 vm_stop(EXCP_INTERRUPT);
508 } else {
509 switch(s->state) {
510 case RS_IDLE:
511 if (ch == '$') {
512 s->line_buf_index = 0;
513 s->state = RS_GETLINE;
bellard4c3a88a2003-07-26 12:06:08 +0000514 }
515 break;
bellard858693c2004-03-31 18:52:07 +0000516 case RS_GETLINE:
517 if (ch == '#') {
518 s->state = RS_CHKSUM1;
519 } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
520 s->state = RS_IDLE;
521 } else {
522 s->line_buf[s->line_buf_index++] = ch;
523 }
524 break;
525 case RS_CHKSUM1:
526 s->line_buf[s->line_buf_index] = '\0';
527 s->line_csum = fromhex(ch) << 4;
528 s->state = RS_CHKSUM2;
529 break;
530 case RS_CHKSUM2:
531 s->line_csum |= fromhex(ch);
532 csum = 0;
533 for(i = 0; i < s->line_buf_index; i++) {
534 csum += s->line_buf[i];
535 }
536 if (s->line_csum != (csum & 0xff)) {
537 reply[0] = '-';
538 put_buffer(s, reply, 1);
539 s->state = RS_IDLE;
540 } else {
541 reply[0] = '+';
542 put_buffer(s, reply, 1);
543 s->state = gdb_handle_packet(s, s->line_buf);
544 }
bellardb4608c02003-06-27 17:34:32 +0000545 break;
546 }
547 }
bellard858693c2004-03-31 18:52:07 +0000548}
549
550static int gdb_can_read(void *opaque)
551{
552 return 256;
553}
554
555static void gdb_read(void *opaque, const uint8_t *buf, int size)
556{
557 GDBState *s = opaque;
558 int i;
559 if (size == 0) {
560 /* end of connection */
561 qemu_del_vm_stop_handler(gdb_vm_stopped, s);
562 qemu_del_fd_read_handler(s->fd);
563 qemu_free(s);
564 vm_start();
565 } else {
566 for(i = 0; i < size; i++)
567 gdb_read_byte(s, buf[i]);
568 }
569}
570
571static void gdb_accept(void *opaque, const uint8_t *buf, int size)
572{
573 GDBState *s;
574 struct sockaddr_in sockaddr;
575 socklen_t len;
576 int val, fd;
577
578 for(;;) {
579 len = sizeof(sockaddr);
580 fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
581 if (fd < 0 && errno != EINTR) {
582 perror("accept");
583 return;
584 } else if (fd >= 0) {
585 break;
586 }
587 }
588
589 /* set short latency */
590 val = 1;
bellard7d3505c2004-05-12 19:32:15 +0000591 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
bellard858693c2004-03-31 18:52:07 +0000592
593 s = qemu_mallocz(sizeof(GDBState));
594 if (!s) {
595 close(fd);
596 return;
597 }
598 s->fd = fd;
599
600 fcntl(fd, F_SETFL, O_NONBLOCK);
601
602 /* stop the VM */
603 vm_stop(EXCP_INTERRUPT);
604
605 /* start handling I/O */
606 qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
607 /* when the VM is stopped, the following callback is called */
608 qemu_add_vm_stop_handler(gdb_vm_stopped, s);
609}
610
611static int gdbserver_open(int port)
612{
613 struct sockaddr_in sockaddr;
614 int fd, val, ret;
615
616 fd = socket(PF_INET, SOCK_STREAM, 0);
617 if (fd < 0) {
618 perror("socket");
619 return -1;
620 }
621
622 /* allow fast reuse */
623 val = 1;
624 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
625
626 sockaddr.sin_family = AF_INET;
627 sockaddr.sin_port = htons(port);
628 sockaddr.sin_addr.s_addr = 0;
629 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
630 if (ret < 0) {
631 perror("bind");
632 return -1;
633 }
634 ret = listen(fd, 0);
635 if (ret < 0) {
636 perror("listen");
637 return -1;
638 }
639 fcntl(fd, F_SETFL, O_NONBLOCK);
640 return fd;
641}
642
643int gdbserver_start(int port)
644{
645 gdbserver_fd = gdbserver_open(port);
646 if (gdbserver_fd < 0)
647 return -1;
648 /* accept connections */
649 qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
bellardb4608c02003-06-27 17:34:32 +0000650 return 0;
651}